section_widget.h 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  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 "chat_helpers/bot_command.h"
  10. #include "dialogs/dialogs_key.h"
  11. #include "media/player/media_player_float.h" // FloatSectionDelegate
  12. #include "base/object_ptr.h"
  13. #include "window/window_section_common.h"
  14. class PeerData;
  15. namespace ChatHelpers {
  16. class Show;
  17. } // namespace ChatHelpers
  18. namespace Data {
  19. struct ReactionId;
  20. class ForumTopic;
  21. class WallPaper;
  22. class Session;
  23. } // namespace Data
  24. namespace Main {
  25. class Session;
  26. } // namespace Main
  27. namespace Ui {
  28. class LayerWidget;
  29. class ChatTheme;
  30. } // namespace Ui
  31. namespace Window {
  32. class SessionController;
  33. class SlideAnimation;
  34. struct SectionShow;
  35. enum class SlideDirection;
  36. enum class Column {
  37. First,
  38. Second,
  39. Third,
  40. };
  41. class AbstractSectionWidget
  42. : public Ui::RpWidget
  43. , public Media::Player::FloatSectionDelegate {
  44. public:
  45. AbstractSectionWidget(
  46. QWidget *parent,
  47. not_null<SessionController*> controller,
  48. rpl::producer<PeerData*> peerForBackground);
  49. [[nodiscard]] Main::Session &session() const;
  50. [[nodiscard]] not_null<SessionController*> controller() const {
  51. return _controller;
  52. }
  53. // Tabbed selector management.
  54. virtual bool pushTabbedSelectorToThirdSection(
  55. not_null<Data::Thread*> thread,
  56. const SectionShow &params) {
  57. return false;
  58. }
  59. virtual bool returnTabbedSelector() {
  60. return false;
  61. }
  62. private:
  63. const not_null<SessionController*> _controller;
  64. };
  65. class SectionMemento;
  66. struct SectionSlideParams {
  67. QPixmap oldContentCache;
  68. int topSkip = 0;
  69. QPixmap topMask;
  70. bool withTopBarShadow = false;
  71. bool withTabs = false;
  72. bool withFade = false;
  73. explicit operator bool() const {
  74. return !oldContentCache.isNull();
  75. }
  76. };
  77. class SectionWidget : public AbstractSectionWidget {
  78. public:
  79. SectionWidget(
  80. QWidget *parent,
  81. not_null<SessionController*> controller,
  82. rpl::producer<PeerData*> peerForBackground = nullptr);
  83. SectionWidget(
  84. QWidget *parent,
  85. not_null<SessionController*> controller,
  86. not_null<PeerData*> peerForBackground);
  87. virtual Dialogs::RowDescriptor activeChat() const {
  88. return {};
  89. }
  90. // When resizing the widget with top edge moved up or down and we
  91. // want to add this top movement to the scroll position, so inner
  92. // content will not move.
  93. void setGeometryWithTopMoved(const QRect &newGeometry, int topDelta);
  94. virtual bool hasTopBarShadow() const {
  95. return false;
  96. }
  97. virtual bool forceAnimateBack() const {
  98. return false;
  99. }
  100. void showAnimated(
  101. SlideDirection direction,
  102. const SectionSlideParams &params);
  103. void showFast();
  104. [[nodiscard]] bool animatingShow() const;
  105. // This can be used to grab with or without top bar shadow.
  106. // This will be protected when animation preparation will be done inside.
  107. virtual QPixmap grabForShowAnimation(const SectionSlideParams &params);
  108. // Attempt to show the required section inside the existing one.
  109. // For example if this section already shows exactly the required
  110. // memento it can simply return true - it is shown already.
  111. //
  112. // If this method returns false it is not supposed to modify the memento.
  113. // If this method returns true it may modify the memento ("take" heavy items).
  114. virtual bool showInternal(
  115. not_null<SectionMemento*> memento,
  116. const SectionShow &params) = 0;
  117. virtual bool sameTypeAs(not_null<SectionMemento*> memento) {
  118. return false;
  119. }
  120. virtual bool showMessage(
  121. PeerId peerId,
  122. const SectionShow &params,
  123. MsgId messageId) {
  124. return false;
  125. }
  126. virtual bool searchInChatEmbedded(
  127. QString query,
  128. Dialogs::Key chat,
  129. PeerData *searchFrom = nullptr) {
  130. return false;
  131. }
  132. [[nodiscard]] virtual bool preventsClose(
  133. Fn<void()> &&continueCallback) const {
  134. return false;
  135. }
  136. // Send bot command from peer info or media viewer.
  137. virtual SectionActionResult sendBotCommand(
  138. Bot::SendCommandRequest request) {
  139. return SectionActionResult::Ignore;
  140. }
  141. virtual bool confirmSendingFiles(const QStringList &files) {
  142. return false;
  143. }
  144. virtual bool confirmSendingFiles(not_null<const QMimeData*> data) {
  145. return false;
  146. }
  147. // Create a memento of that section to store it in the history stack.
  148. // This method may modify the section ("take" heavy items).
  149. virtual std::shared_ptr<SectionMemento> createMemento();
  150. void setInnerFocus() {
  151. doSetInnerFocus();
  152. }
  153. virtual void checkActivation() {
  154. }
  155. [[nodiscard]] virtual rpl::producer<int> desiredHeight() const;
  156. [[nodiscard]] virtual rpl::producer<> removeRequests() const {
  157. return rpl::never<>();
  158. }
  159. // Some sections convert to layers on some geometry sizes.
  160. [[nodiscard]] virtual object_ptr<Ui::LayerWidget> moveContentToLayer(
  161. QRect bodyGeometry) {
  162. return nullptr;
  163. }
  164. static void PaintBackground(
  165. not_null<SessionController*> controller,
  166. not_null<Ui::ChatTheme*> theme,
  167. not_null<QWidget*> widget,
  168. QRect clip);
  169. static void PaintBackground(
  170. not_null<Ui::ChatTheme*> theme,
  171. not_null<QWidget*> widget,
  172. int fillHeight,
  173. int fromy,
  174. QRect clip);
  175. static void PaintBackground(
  176. QPainter &p,
  177. not_null<Ui::ChatTheme*> theme,
  178. QSize fill,
  179. QRect clip);
  180. protected:
  181. void paintEvent(QPaintEvent *e) override;
  182. // Temp variable used in resizeEvent() implementation, that is passed
  183. // to setGeometryWithTopMoved() to adjust the scroll position with the resize.
  184. int topDelta() const {
  185. return _topDelta;
  186. }
  187. // Called after the hideChildren() call in showAnimated().
  188. virtual void showAnimatedHook(
  189. const SectionSlideParams &params) {
  190. }
  191. // Called after the showChildren() call in showFinished().
  192. virtual void showFinishedHook() {
  193. }
  194. virtual void doSetInnerFocus() {
  195. setFocus();
  196. }
  197. ~SectionWidget();
  198. private:
  199. void showFinished();
  200. std::unique_ptr<SlideAnimation> _showAnimation;
  201. // Saving here topDelta in setGeometryWithTopMoved() to get it passed to resizeEvent().
  202. int _topDelta = 0;
  203. };
  204. [[nodiscard]] auto ChatThemeValueFromPeer(
  205. not_null<SessionController*> controller,
  206. not_null<PeerData*> peer)
  207. -> rpl::producer<std::shared_ptr<Ui::ChatTheme>>;
  208. [[nodiscard]] bool ShowSendPremiumError(
  209. not_null<SessionController*> controller,
  210. not_null<DocumentData*> document);
  211. [[nodiscard]] bool ShowSendPremiumError(
  212. std::shared_ptr<ChatHelpers::Show> show,
  213. not_null<DocumentData*> document);
  214. [[nodiscard]] bool ShowReactPremiumError(
  215. not_null<SessionController*> controller,
  216. not_null<HistoryItem*> item,
  217. const Data::ReactionId &id);
  218. [[nodiscard]] rpl::producer<const Data::WallPaper*> WallPaperResolved(
  219. not_null<Data::Session*> owner,
  220. const Data::WallPaper *paper);
  221. } // namespace Window