invite_link_buttons.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  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_buttons.h"
  8. #include "ui/widgets/buttons.h"
  9. #include "ui/wrap/vertical_layout.h"
  10. #include "ui/wrap/padding_wrap.h"
  11. #include "ui/wrap/slide_wrap.h"
  12. #include "lang/lang_keys.h"
  13. #include "styles/style_chat_helpers.h"
  14. #include "styles/style_info.h"
  15. namespace Ui {
  16. namespace {
  17. class JoinedCountButton final : public AbstractButton {
  18. public:
  19. using AbstractButton::AbstractButton;
  20. void onStateChanged(State was, StateChangeSource source) override {
  21. update();
  22. }
  23. };
  24. } // namespace
  25. void AddCopyShareLinkButtons(
  26. not_null<VerticalLayout*> container,
  27. Fn<void()> copyLink,
  28. Fn<void()> shareLink) {
  29. const auto wrap = container->add(
  30. object_ptr<FixedHeightWidget>(
  31. container,
  32. st::inviteLinkButton.height),
  33. st::inviteLinkButtonsPadding);
  34. const auto copy = CreateChild<RoundButton>(
  35. wrap,
  36. tr::lng_group_invite_copy(),
  37. st::inviteLinkCopy);
  38. copy->setTextTransform(RoundButton::TextTransform::NoTransform);
  39. copy->setClickedCallback(copyLink);
  40. const auto share = CreateChild<RoundButton>(
  41. wrap,
  42. tr::lng_group_invite_share(),
  43. st::inviteLinkShare);
  44. share->setTextTransform(RoundButton::TextTransform::NoTransform);
  45. share->setClickedCallback(shareLink);
  46. wrap->widthValue(
  47. ) | rpl::start_with_next([=](int width) {
  48. const auto buttonWidth = (width - st::inviteLinkButtonsSkip) / 2;
  49. copy->setFullWidth(buttonWidth);
  50. share->setFullWidth(buttonWidth);
  51. copy->moveToLeft(0, 0, width);
  52. share->moveToRight(0, 0, width);
  53. }, wrap->lifetime());
  54. }
  55. void AddReactivateLinkButton(
  56. not_null<VerticalLayout*> container,
  57. Fn<void()> editLink) {
  58. const auto button = container->add(
  59. object_ptr<RoundButton>(
  60. container,
  61. tr::lng_group_invite_reactivate(),
  62. st::inviteLinkReactivate),
  63. st::inviteLinkButtonsPadding);
  64. button->setTextTransform(RoundButton::TextTransform::NoTransform);
  65. button->setClickedCallback(editLink);
  66. }
  67. void AddDeleteLinkButton(
  68. not_null<VerticalLayout*> container,
  69. Fn<void()> deleteLink) {
  70. const auto button = container->add(
  71. object_ptr<RoundButton>(
  72. container,
  73. tr::lng_group_invite_delete(),
  74. st::inviteLinkDelete),
  75. st::inviteLinkButtonsPadding);
  76. button->setTextTransform(RoundButton::TextTransform::NoTransform);
  77. button->setClickedCallback(deleteLink);
  78. }
  79. not_null<AbstractButton*> AddJoinedCountButton(
  80. not_null<VerticalLayout*> container,
  81. rpl::producer<JoinedCountContent> content,
  82. style::margins padding) {
  83. struct State {
  84. JoinedCountContent content;
  85. QString phrase;
  86. int addedWidth = 0;
  87. };
  88. const auto wrap = container->add(
  89. object_ptr<Ui::SlideWrap<Ui::FixedHeightWidget>>(
  90. container,
  91. object_ptr<Ui::FixedHeightWidget>(
  92. container,
  93. st::inviteLinkUserpics.size),
  94. QMargins(padding.left(), padding.top(), padding.right(), 0)),
  95. QMargins(0, 0, 0, padding.bottom()));
  96. const auto result = CreateChild<JoinedCountButton>(wrap->entity());
  97. const auto state = result->lifetime().make_state<State>();
  98. std::move(
  99. content
  100. ) | rpl::start_with_next([=](JoinedCountContent &&content) {
  101. state->content = std::move(content);
  102. wrap->toggle(state->content.count > 0, anim::type::instant);
  103. if (state->content.count <= 0) {
  104. return;
  105. }
  106. result->setAttribute(
  107. Qt::WA_TransparentForMouseEvents,
  108. !state->content.count);
  109. if (!state->content.count) {
  110. result->clearState();
  111. }
  112. const auto &st = st::inviteLinkUserpics;
  113. const auto imageWidth = !state->content.userpics.isNull()
  114. ? state->content.userpics.width() / style::DevicePixelRatio()
  115. : !state->content.count
  116. ? 0
  117. : ((std::min(state->content.count, 3) - 1) * (st.size - st.shift)
  118. + st.size);
  119. state->addedWidth = imageWidth
  120. ? (imageWidth + st::inviteLinkUserpicsSkip)
  121. : 0;
  122. state->phrase = tr::lng_group_invite_joined(
  123. tr::now,
  124. lt_count_decimal,
  125. state->content.count);
  126. const auto fullWidth = st::inviteLinkJoinedFont->width(state->phrase)
  127. + state->addedWidth;
  128. result->resize(fullWidth, st.size);
  129. result->move((wrap->width() - fullWidth) / 2, 0);
  130. result->update();
  131. }, result->lifetime());
  132. result->paintRequest(
  133. ) | rpl::start_with_next([=] {
  134. auto p = QPainter(result);
  135. if (!state->content.userpics.isNull()) {
  136. p.drawImage(0, 0, state->content.userpics);
  137. }
  138. const auto &font = st::inviteLinkJoinedFont;
  139. p.setPen(st::defaultLinkButton.color);
  140. p.setFont((result->isOver() || result->isDown())
  141. ? font->underline()
  142. : font);
  143. const auto top = (result->height() - font->height) / 2;
  144. p.drawText(
  145. state->addedWidth,
  146. top + font->ascent,
  147. state->phrase);
  148. }, result->lifetime());
  149. wrap->widthValue(
  150. ) | rpl::start_with_next([=](int width) {
  151. result->move((width - result->width()) / 2, 0);
  152. }, wrap->lifetime());
  153. return result;
  154. }
  155. } // namespace Ui