info_content_widget.h 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  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 "info/info_wrap_widget.h"
  9. #include "info/statistics/info_statistics_tag.h"
  10. #include "ui/controls/swipe_handler_data.h"
  11. namespace Api {
  12. struct WhoReadList;
  13. } // namespace Api
  14. namespace Dialogs::Stories {
  15. struct Content;
  16. } // namespace Dialogs::Stories
  17. namespace Storage {
  18. enum class SharedMediaType : signed char;
  19. } // namespace Storage
  20. namespace Ui {
  21. class RoundRect;
  22. class ScrollArea;
  23. class InputField;
  24. struct ScrollToRequest;
  25. template <typename Widget>
  26. class PaddingWrap;
  27. } // namespace Ui
  28. namespace Ui::Menu {
  29. struct MenuCallback;
  30. } // namespace Ui::Menu
  31. namespace Info::Settings {
  32. struct Tag;
  33. } // namespace Info::Settings
  34. namespace Info::Downloads {
  35. struct Tag;
  36. } // namespace Info::Downloads
  37. namespace Info::Stories {
  38. struct Tag;
  39. enum class Tab;
  40. } // namespace Info::Stories
  41. namespace Info::Statistics {
  42. struct Tag;
  43. } // namespace Info::Statistics
  44. namespace Info::BotStarRef {
  45. enum class Type : uchar;
  46. struct Tag;
  47. } // namespace Info::BotStarRef
  48. namespace Info::GlobalMedia {
  49. struct Tag;
  50. } // namespace Info::GlobalMedia
  51. namespace Info {
  52. class ContentMemento;
  53. class Controller;
  54. class ContentWidget : public Ui::RpWidget {
  55. public:
  56. ContentWidget(
  57. QWidget *parent,
  58. not_null<Controller*> controller);
  59. virtual bool showInternal(
  60. not_null<ContentMemento*> memento) = 0;
  61. std::shared_ptr<ContentMemento> createMemento();
  62. virtual void setIsStackBottom(bool isStackBottom);
  63. [[nodiscard]] bool isStackBottom() const;
  64. rpl::producer<int> scrollHeightValue() const;
  65. rpl::producer<int> desiredHeightValue() const override;
  66. virtual rpl::producer<bool> desiredShadowVisibility() const;
  67. bool hasTopBarShadow() const;
  68. virtual void setInnerFocus();
  69. virtual void showFinished() {
  70. }
  71. virtual void enableBackButton() {
  72. }
  73. // When resizing the widget with top edge moved up or down and we
  74. // want to add this top movement to the scroll position, so inner
  75. // content will not move.
  76. void setGeometryWithTopMoved(
  77. const QRect &newGeometry,
  78. int topDelta);
  79. void applyAdditionalScroll(int additionalScroll);
  80. void applyMaxVisibleHeight(int maxVisibleHeight);
  81. int scrollTillBottom(int forHeight) const;
  82. [[nodiscard]] rpl::producer<int> scrollTillBottomChanges() const;
  83. [[nodiscard]] virtual const Ui::RoundRect *bottomSkipRounding() const {
  84. return nullptr;
  85. }
  86. // Float player interface.
  87. bool floatPlayerHandleWheelEvent(QEvent *e);
  88. QRect floatPlayerAvailableRect() const;
  89. virtual rpl::producer<SelectedItems> selectedListValue() const;
  90. virtual void selectionAction(SelectionAction action) {
  91. }
  92. virtual void fillTopBarMenu(const Ui::Menu::MenuCallback &addAction);
  93. [[nodiscard]] virtual bool closeByOutsideClick() const {
  94. return true;
  95. }
  96. virtual void checkBeforeClose(Fn<void()> close) {
  97. close();
  98. }
  99. virtual void checkBeforeCloseByEscape(Fn<void()> close);
  100. [[nodiscard]] virtual rpl::producer<QString> title() = 0;
  101. [[nodiscard]] virtual rpl::producer<QString> subtitle() {
  102. return nullptr;
  103. }
  104. [[nodiscard]] virtual auto titleStories()
  105. -> rpl::producer<Dialogs::Stories::Content>;
  106. virtual void saveChanges(FnMut<void()> done);
  107. [[nodiscard]] int scrollBottomSkip() const;
  108. [[nodiscard]] rpl::producer<int> scrollBottomSkipValue() const;
  109. [[nodiscard]] virtual auto desiredBottomShadowVisibility()
  110. -> rpl::producer<bool>;
  111. protected:
  112. template <typename Widget>
  113. Widget *setInnerWidget(object_ptr<Widget> inner) {
  114. return static_cast<Widget*>(
  115. doSetInnerWidget(std::move(inner)));
  116. }
  117. [[nodiscard]] not_null<Controller*> controller() const {
  118. return _controller;
  119. }
  120. [[nodiscard]] not_null<Ui::ScrollArea*> scroll() const;
  121. [[nodiscard]] int maxVisibleHeight() const {
  122. return _maxVisibleHeight;
  123. }
  124. void resizeEvent(QResizeEvent *e) override;
  125. void paintEvent(QPaintEvent *e) override;
  126. void setScrollTopSkip(int scrollTopSkip);
  127. void setScrollBottomSkip(int scrollBottomSkip);
  128. int scrollTopSave() const;
  129. void scrollTopRestore(int scrollTop);
  130. void scrollTo(const Ui::ScrollToRequest &request);
  131. [[nodiscard]] rpl::producer<int> scrollTopValue() const;
  132. void setPaintPadding(const style::margins &padding);
  133. void setViewport(rpl::producer<not_null<QEvent*>> &&events) const;
  134. private:
  135. RpWidget *doSetInnerWidget(object_ptr<RpWidget> inner);
  136. void updateControlsGeometry();
  137. void refreshSearchField(bool shown);
  138. void setupSwipeHandler(not_null<Ui::RpWidget*> widget);
  139. void updateInnerPadding();
  140. virtual std::shared_ptr<ContentMemento> doCreateMemento() = 0;
  141. const not_null<Controller*> _controller;
  142. style::color _bg;
  143. rpl::variable<int> _scrollTopSkip = -1;
  144. rpl::variable<int> _scrollBottomSkip = 0;
  145. rpl::event_stream<int> _scrollTillBottomChanges;
  146. object_ptr<Ui::ScrollArea> _scroll;
  147. Ui::PaddingWrap<Ui::RpWidget> *_innerWrap = nullptr;
  148. base::unique_qptr<Ui::RpWidget> _searchWrap = nullptr;
  149. QPointer<Ui::InputField> _searchField;
  150. int _innerDesiredHeight = 0;
  151. int _additionalScroll = 0;
  152. int _addedHeight = 0;
  153. int _maxVisibleHeight = 0;
  154. bool _isStackBottom = false;
  155. // Saving here topDelta in setGeometryWithTopMoved() to get it passed to resizeEvent().
  156. int _topDelta = 0;
  157. // To paint round edges from content.
  158. style::margins _paintPadding;
  159. Ui::Controls::SwipeBackResult _swipeBackData;
  160. };
  161. class ContentMemento {
  162. public:
  163. ContentMemento(
  164. not_null<PeerData*> peer,
  165. Data::ForumTopic *topic,
  166. PeerId migratedPeerId);
  167. explicit ContentMemento(Settings::Tag settings);
  168. explicit ContentMemento(Downloads::Tag downloads);
  169. explicit ContentMemento(Stories::Tag stories);
  170. explicit ContentMemento(Statistics::Tag statistics);
  171. explicit ContentMemento(BotStarRef::Tag starref);
  172. explicit ContentMemento(GlobalMedia::Tag global);
  173. ContentMemento(not_null<PollData*> poll, FullMsgId contextId)
  174. : _poll(poll)
  175. , _pollReactionsContextId(contextId) {
  176. }
  177. ContentMemento(
  178. std::shared_ptr<Api::WhoReadList> whoReadIds,
  179. FullMsgId contextId,
  180. Data::ReactionId selected);
  181. virtual object_ptr<ContentWidget> createWidget(
  182. QWidget *parent,
  183. not_null<Controller*> controller,
  184. const QRect &geometry) = 0;
  185. PeerData *peer() const {
  186. return _peer;
  187. }
  188. PeerId migratedPeerId() const {
  189. return _migratedPeerId;
  190. }
  191. Data::ForumTopic *topic() const {
  192. return _topic;
  193. }
  194. UserData *settingsSelf() const {
  195. return _settingsSelf;
  196. }
  197. PeerData *storiesPeer() const {
  198. return _storiesPeer;
  199. }
  200. Stories::Tab storiesTab() const {
  201. return _storiesTab;
  202. }
  203. Statistics::Tag statisticsTag() const {
  204. return _statisticsTag;
  205. }
  206. PeerData *starrefPeer() const {
  207. return _starrefPeer;
  208. }
  209. BotStarRef::Type starrefType() const {
  210. return _starrefType;
  211. }
  212. PollData *poll() const {
  213. return _poll;
  214. }
  215. FullMsgId pollContextId() const {
  216. return _poll ? _pollReactionsContextId : FullMsgId();
  217. }
  218. std::shared_ptr<Api::WhoReadList> reactionsWhoReadIds() const {
  219. return _reactionsWhoReadIds;
  220. }
  221. Data::ReactionId reactionsSelected() const {
  222. return _reactionsSelected;
  223. }
  224. FullMsgId reactionsContextId() const {
  225. return _reactionsWhoReadIds ? _pollReactionsContextId : FullMsgId();
  226. }
  227. UserData *globalMediaSelf() const {
  228. return _globalMediaSelf;
  229. }
  230. Key key() const;
  231. virtual Section section() const = 0;
  232. virtual ~ContentMemento() = default;
  233. void setScrollTop(int scrollTop) {
  234. _scrollTop = scrollTop;
  235. }
  236. int scrollTop() const {
  237. return _scrollTop;
  238. }
  239. void setSearchFieldQuery(const QString &query) {
  240. _searchFieldQuery = query;
  241. }
  242. QString searchFieldQuery() const {
  243. return _searchFieldQuery;
  244. }
  245. void setSearchEnabledByContent(bool enabled) {
  246. _searchEnabledByContent = enabled;
  247. }
  248. bool searchEnabledByContent() const {
  249. return _searchEnabledByContent;
  250. }
  251. void setSearchStartsFocused(bool focused) {
  252. _searchStartsFocused = focused;
  253. }
  254. bool searchStartsFocused() const {
  255. return _searchStartsFocused;
  256. }
  257. private:
  258. PeerData * const _peer = nullptr;
  259. const PeerId _migratedPeerId = 0;
  260. Data::ForumTopic *_topic = nullptr;
  261. UserData * const _settingsSelf = nullptr;
  262. PeerData * const _storiesPeer = nullptr;
  263. Stories::Tab _storiesTab = {};
  264. Statistics::Tag _statisticsTag;
  265. PeerData * const _starrefPeer = nullptr;
  266. BotStarRef::Type _starrefType = {};
  267. PollData * const _poll = nullptr;
  268. std::shared_ptr<Api::WhoReadList> _reactionsWhoReadIds;
  269. Data::ReactionId _reactionsSelected;
  270. const FullMsgId _pollReactionsContextId;
  271. UserData * const _globalMediaSelf = nullptr;
  272. int _scrollTop = 0;
  273. QString _searchFieldQuery;
  274. bool _searchEnabledByContent = false;
  275. bool _searchStartsFocused = false;
  276. rpl::lifetime _lifetime;
  277. };
  278. } // namespace Info