info_top_bar.h 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  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. #pragma once
  8. #include "ui/rp_widget.h"
  9. #include "ui/round_rect.h"
  10. #include "ui/wrap/fade_wrap.h"
  11. #include "ui/effects/animations.h"
  12. #include "ui/effects/numbers_animation.h"
  13. #include "info/info_wrap_widget.h"
  14. namespace style {
  15. struct InfoTopBar;
  16. } // namespace style
  17. namespace Dialogs::Stories {
  18. class List;
  19. struct Content;
  20. } // namespace Dialogs::Stories
  21. namespace Window {
  22. class SessionNavigation;
  23. } // namespace Window
  24. namespace Ui {
  25. class AbstractButton;
  26. class IconButton;
  27. class FlatLabel;
  28. class InputField;
  29. class SearchFieldController;
  30. class LabelWithNumbers;
  31. } // namespace Ui
  32. namespace Info {
  33. class Key;
  34. class Section;
  35. struct TitleDescriptor {
  36. rpl::producer<QString> title;
  37. rpl::producer<QString> subtitle;
  38. };
  39. class TopBar : public Ui::RpWidget {
  40. public:
  41. TopBar(
  42. QWidget *parent,
  43. not_null<Window::SessionNavigation*> navigation,
  44. const style::InfoTopBar &st,
  45. SelectedItems &&items);
  46. [[nodiscard]] auto backRequest() const {
  47. return _backClicks.events();
  48. }
  49. [[nodiscard]] auto storyClicks() const {
  50. return _storyClicks.events();
  51. }
  52. void setTitle(TitleDescriptor descriptor);
  53. void setStories(rpl::producer<Dialogs::Stories::Content> content);
  54. void setStoriesArchive(bool archive);
  55. void enableBackButton();
  56. void highlight();
  57. template <typename ButtonWidget>
  58. ButtonWidget *addButton(base::unique_qptr<ButtonWidget> button) {
  59. auto result = button.get();
  60. pushButton(std::move(button));
  61. return result;
  62. }
  63. template <typename ButtonWidget>
  64. ButtonWidget *addButtonWithVisibility(
  65. base::unique_qptr<ButtonWidget> button,
  66. rpl::producer<bool> shown) {
  67. auto result = button.get();
  68. forceButtonVisibility(
  69. pushButton(std::move(button)),
  70. std::move(shown));
  71. return result;
  72. }
  73. void createSearchView(
  74. not_null<Ui::SearchFieldController*> controller,
  75. rpl::producer<bool> &&shown,
  76. bool startsFocused);
  77. bool focusSearchField();
  78. void setSelectedItems(SelectedItems &&items);
  79. SelectedItems takeSelectedItems();
  80. [[nodiscard]] auto selectionActionRequests() const
  81. -> rpl::producer<SelectionAction>;
  82. void finishAnimating() {
  83. updateControlsVisibility(anim::type::instant);
  84. }
  85. void showSearch();
  86. void checkBeforeCloseByEscape(Fn<void()> close);
  87. protected:
  88. int resizeGetHeight(int newWidth) override;
  89. void paintEvent(QPaintEvent *e) override;
  90. private:
  91. void updateControlsGeometry(int newWidth);
  92. void updateDefaultControlsGeometry(int newWidth);
  93. void updateSelectionControlsGeometry(int newWidth);
  94. void updateStoriesGeometry(int newWidth);
  95. Ui::FadeWrap<Ui::RpWidget> *pushButton(
  96. base::unique_qptr<Ui::RpWidget> button);
  97. void forceButtonVisibility(
  98. Ui::FadeWrap<Ui::RpWidget> *button,
  99. rpl::producer<bool> shown);
  100. void removeButton(not_null<Ui::RpWidget*> button);
  101. void startHighlightAnimation();
  102. void updateControlsVisibility(anim::type animated);
  103. [[nodiscard]] bool selectionMode() const;
  104. [[nodiscard]] bool storiesTitle() const;
  105. [[nodiscard]] bool searchMode() const;
  106. [[nodiscard]] Ui::StringWithNumbers generateSelectedText() const;
  107. [[nodiscard]] bool computeCanDelete() const;
  108. [[nodiscard]] bool computeCanForward() const;
  109. [[nodiscard]] bool computeCanUnpinStories() const;
  110. [[nodiscard]] bool computeCanToggleStoryPin() const;
  111. void updateSelectionState();
  112. void createSelectionControls();
  113. void performForward();
  114. void performDelete();
  115. void performToggleStoryPin();
  116. void setSearchField(
  117. base::unique_qptr<Ui::InputField> field,
  118. rpl::producer<bool> &&shown,
  119. bool startsFocused);
  120. void clearSearchField();
  121. void createSearchView(
  122. not_null<Ui::InputField*> field,
  123. rpl::producer<bool> &&shown,
  124. bool startsFocused);
  125. template <typename Callback>
  126. void registerUpdateControlCallback(QObject *guard, Callback &&callback);
  127. template <typename Widget, typename IsVisible>
  128. void registerToggleControlCallback(Widget *widget, IsVisible &&callback);
  129. const not_null<Window::SessionNavigation*> _navigation;
  130. const style::InfoTopBar &_st;
  131. std::optional<Ui::RoundRect> _roundRect;
  132. Ui::Animations::Simple _a_highlight;
  133. bool _highlight = false;
  134. QPointer<Ui::FadeWrap<Ui::IconButton>> _back;
  135. std::vector<base::unique_qptr<Ui::RpWidget>> _buttons;
  136. QPointer<Ui::FadeWrap<Ui::FlatLabel>> _title;
  137. QPointer<Ui::FadeWrap<Ui::FlatLabel>> _subtitle;
  138. bool _searchModeEnabled = false;
  139. bool _searchModeAvailable = false;
  140. base::unique_qptr<Ui::RpWidget> _searchView;
  141. QPointer<Ui::InputField> _searchField;
  142. rpl::event_stream<> _backClicks;
  143. rpl::event_stream<uint64> _storyClicks;
  144. SelectedItems _selectedItems;
  145. bool _canDelete = false;
  146. bool _canForward = false;
  147. bool _canToggleStoryPin = false;
  148. bool _canUnpinStories = false;
  149. bool _storiesArchive = false;
  150. QPointer<Ui::FadeWrap<Ui::IconButton>> _cancelSelection;
  151. QPointer<Ui::FadeWrap<Ui::LabelWithNumbers>> _selectionText;
  152. QPointer<Ui::FadeWrap<Ui::IconButton>> _forward;
  153. QPointer<Ui::FadeWrap<Ui::IconButton>> _delete;
  154. QPointer<Ui::FadeWrap<Ui::IconButton>> _toggleStoryInProfile;
  155. QPointer<Ui::FadeWrap<Ui::IconButton>> _toggleStoryPin;
  156. rpl::event_stream<SelectionAction> _selectionActionRequests;
  157. QPointer<Ui::FadeWrap<Ui::AbstractButton>> _storiesWrap;
  158. QPointer<Dialogs::Stories::List> _stories;
  159. rpl::lifetime _storiesLifetime;
  160. int _storiesCount = 0;
  161. using UpdateCallback = Fn<bool(anim::type)>;
  162. std::map<QObject*, UpdateCallback> _updateControlCallbacks;
  163. };
  164. } // namespace Info