invite_link_label.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. /*
  2. This file is part of Telegram Desktop,
  3. the official desktop application for the Telegram messaging service.
  4. For license and copyright information please follow this link:
  5. https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
  6. */
  7. #include "ui/controls/invite_link_label.h"
  8. #include "ui/painter.h"
  9. #include "ui/rp_widget.h"
  10. #include "ui/widgets/labels.h"
  11. #include "ui/widgets/buttons.h"
  12. #include "ui/widgets/popup_menu.h"
  13. #include "styles/style_info.h"
  14. namespace Ui {
  15. InviteLinkLabel::InviteLinkLabel(
  16. not_null<QWidget*> parent,
  17. rpl::producer<QString> text,
  18. Fn<base::unique_qptr<PopupMenu>()> createMenu)
  19. : _outer(std::in_place, parent) {
  20. _outer->resize(_outer->width(), st::inviteLinkFieldHeight);
  21. const auto label = CreateChild<FlatLabel>(
  22. _outer.get(),
  23. std::move(text),
  24. createMenu ? st::defaultFlatLabel : st::inviteLinkFieldLabel);
  25. label->setAttribute(Qt::WA_TransparentForMouseEvents);
  26. const auto button = createMenu
  27. ? CreateChild<IconButton>(_outer.get(), st::inviteLinkThreeDots)
  28. : (IconButton*)(nullptr);
  29. _outer->widthValue(
  30. ) | rpl::start_with_next([=](int width) {
  31. const auto margin = st::inviteLinkFieldMargin;
  32. const auto labelWidth = width - margin.left() - margin.right();
  33. label->resizeToWidth(labelWidth);
  34. label->moveToLeft(
  35. createMenu
  36. ? margin.left()
  37. : (width - labelWidth) / 2,
  38. margin.top());
  39. if (button) {
  40. button->moveToRight(0, 0);
  41. }
  42. }, _outer->lifetime());
  43. _outer->paintRequest(
  44. ) | rpl::start_with_next([=] {
  45. auto p = QPainter(_outer.get());
  46. p.setPen(Qt::NoPen);
  47. p.setBrush(st::filterInputInactiveBg);
  48. {
  49. PainterHighQualityEnabler hq(p);
  50. p.drawRoundedRect(
  51. _outer->rect(),
  52. st::inviteLinkFieldRadius,
  53. st::inviteLinkFieldRadius);
  54. }
  55. }, _outer->lifetime());
  56. _outer->setCursor(style::cur_pointer);
  57. if (createMenu) {
  58. rpl::merge(
  59. button->clicks() | rpl::to_empty,
  60. _outer->events(
  61. ) | rpl::filter([=](not_null<QEvent*> event) {
  62. return (event->type() == QEvent::MouseButtonPress)
  63. && (static_cast<QMouseEvent*>(event.get())->button()
  64. == Qt::RightButton);
  65. }) | rpl::to_empty
  66. ) | rpl::start_with_next([=] {
  67. if (_menu) {
  68. _menu = nullptr;
  69. } else if ((_menu = createMenu())) {
  70. _menu->popup(QCursor::pos());
  71. }
  72. }, _outer->lifetime());
  73. }
  74. }
  75. object_ptr<RpWidget> InviteLinkLabel::take() {
  76. return object_ptr<RpWidget>::fromRaw(_outer.get());
  77. }
  78. rpl::producer<> InviteLinkLabel::clicks() {
  79. return _outer->events(
  80. ) | rpl::filter([=](not_null<QEvent*> event) {
  81. return (event->type() == QEvent::MouseButtonPress)
  82. && (static_cast<QMouseEvent*>(event.get())->button()
  83. == Qt::LeftButton);
  84. }) | rpl::map([=](not_null<QEvent*> event) {
  85. return _outer->events(
  86. ) | rpl::filter([=](not_null<QEvent*> event) {
  87. return (event->type() == QEvent::MouseButtonRelease)
  88. && (static_cast<QMouseEvent*>(event.get())->button()
  89. == Qt::LeftButton);
  90. }) | rpl::take(1) | rpl::filter([=](not_null<QEvent*> event) {
  91. return (_outer->rect().contains(
  92. static_cast<QMouseEvent*>(event.get())->pos()));
  93. });
  94. }) | rpl::flatten_latest() | rpl::to_empty;
  95. }
  96. rpl::lifetime &InviteLinkLabel::lifetime() {
  97. return _outer->lifetime();
  98. }
  99. } // namespace Ui