separate_panel.h 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. // This file is part of Desktop App Toolkit,
  2. // a set of libraries for developing nice desktop applications.
  3. //
  4. // For license and copyright information please follow this link:
  5. // https://github.com/desktop-app/legal/blob/master/LEGAL
  6. //
  7. #pragma once
  8. #include "base/flat_map.h"
  9. #include "base/weak_ptr.h"
  10. #include "ui/rp_widget.h"
  11. #include "ui/effects/animations.h"
  12. #include "ui/layers/layer_widget.h"
  13. #include "ui/text/text_entity.h"
  14. #include <rpl/variable.h>
  15. class Painter;
  16. namespace style {
  17. struct IconButton;
  18. struct PopupMenu;
  19. } // namespace style
  20. namespace Ui::Menu {
  21. struct MenuCallback;
  22. } // namespace Ui::Menu
  23. namespace Ui::Toast {
  24. struct Config;
  25. class Instance;
  26. } // namespace Ui::Toast
  27. namespace Ui {
  28. class Show;
  29. class BoxContent;
  30. class IconButton;
  31. class PopupMenu;
  32. class LayerStackWidget;
  33. class LayerWidget;
  34. class FlatLabel;
  35. class InputField;
  36. template <typename Widget>
  37. class FadeWrapScaled;
  38. template <typename Widget>
  39. class FadeWrap;
  40. struct SeparatePanelArgs {
  41. QWidget *parent = nullptr;
  42. bool onAllSpaces = false;
  43. Fn<bool(int zorder)> animationsPaused;
  44. const style::PopupMenu *menuSt = nullptr;
  45. };
  46. class SeparatePanel final : public RpWidget {
  47. public:
  48. explicit SeparatePanel(SeparatePanelArgs &&args = {});
  49. ~SeparatePanel();
  50. void setTitle(rpl::producer<QString> title);
  51. void setTitleHeight(int height);
  52. void setTitleBadge(object_ptr<RpWidget> badge);
  53. void setInnerSize(QSize size, bool allowResize = false);
  54. [[nodiscard]] QRect innerGeometry() const;
  55. void toggleFullScreen(bool fullscreen);
  56. void allowChildFullScreenControls(bool allow);
  57. [[nodiscard]] rpl::producer<bool> fullScreenValue() const;
  58. [[nodiscard]] QMargins computePadding() const;
  59. void setHideOnDeactivate(bool hideOnDeactivate);
  60. void showAndActivate();
  61. int hideGetDuration();
  62. [[nodiscard]] RpWidget *inner() const;
  63. void showInner(base::unique_qptr<RpWidget> inner);
  64. void showBox(
  65. object_ptr<BoxContent> box,
  66. LayerOptions options,
  67. anim::type animated);
  68. void showLayer(
  69. std::unique_ptr<LayerWidget> layer,
  70. LayerOptions options,
  71. anim::type animated);
  72. void hideLayer(anim::type animated);
  73. [[nodiscard]] rpl::producer<> backRequests() const;
  74. [[nodiscard]] rpl::producer<> closeRequests() const;
  75. [[nodiscard]] rpl::producer<> closeEvents() const;
  76. void setBackAllowed(bool allowed);
  77. void updateBackToggled();
  78. void setMenuAllowed(
  79. Fn<void(const Menu::MenuCallback&)> fill,
  80. Fn<void(not_null<RpWidget*>, bool fullscreen)> created = nullptr);
  81. void setSearchAllowed(
  82. rpl::producer<QString> placeholder,
  83. Fn<void(std::optional<QString>)> queryChanged);
  84. bool closeSearch();
  85. void overrideTitleColor(std::optional<QColor> color);
  86. void overrideBodyColor(std::optional<QColor> color);
  87. void overrideBottomBarColor(std::optional<QColor> color);
  88. void setBottomBarHeight(int height);
  89. [[nodiscard]] style::palette *titleOverridePalette() const;
  90. base::weak_ptr<Toast::Instance> showToast(Toast::Config &&config);
  91. base::weak_ptr<Toast::Instance> showToast(
  92. TextWithEntities &&text,
  93. crl::time duration = 0);
  94. base::weak_ptr<Toast::Instance> showToast(
  95. const QString &text,
  96. crl::time duration = 0);
  97. [[nodiscard]] std::shared_ptr<Show> uiShow();
  98. protected:
  99. void paintEvent(QPaintEvent *e) override;
  100. void closeEvent(QCloseEvent *e) override;
  101. void resizeEvent(QResizeEvent *e) override;
  102. void focusInEvent(QFocusEvent *e) override;
  103. void mousePressEvent(QMouseEvent *e) override;
  104. void mouseReleaseEvent(QMouseEvent *e) override;
  105. void mouseMoveEvent(QMouseEvent *e) override;
  106. void leaveEventHook(QEvent *e) override;
  107. void leaveToChildEvent(QEvent *e, QWidget *child) override;
  108. void keyPressEvent(QKeyEvent *e) override;
  109. bool eventHook(QEvent *e) override;
  110. private:
  111. class ResizeEdge;
  112. class FullScreenButton;
  113. void initControls();
  114. void initLayout(const SeparatePanelArgs &args);
  115. void initGeometry(QSize size);
  116. void updateGeometry(QSize size);
  117. void showControls();
  118. void updateControlsGeometry();
  119. void updateControlsVisibility(bool fullscreen);
  120. void validateBorderImage();
  121. [[nodiscard]] QPixmap createBorderImage(QColor color) const;
  122. void opacityCallback();
  123. void ensureLayerCreated();
  124. void destroyLayer();
  125. void updateTitleGeometry(int newWidth) const;
  126. void paintShadowBorder(QPainter &p) const;
  127. void paintOpaqueBorder(QPainter &p) const;
  128. void paintBodyBg(QPainter &p, int radius = 0) const;
  129. void toggleOpacityAnimation(bool visible);
  130. void finishAnimating();
  131. void finishClose();
  132. void showMenu(Fn<void(const Menu::MenuCallback&)> fill);
  133. [[nodiscard]] bool createMenu(not_null<IconButton*> button);
  134. void createFullScreenButtons();
  135. void initFullScreenButton(not_null<QWidget*> button);
  136. void updateTitleButtonColors(not_null<IconButton*> button);
  137. void updateTitleColors();
  138. void toggleSearch(bool shown);
  139. [[nodiscard]] rpl::producer<> allBackRequests() const;
  140. [[nodiscard]] rpl::producer<> allCloseRequests() const;
  141. const style::PopupMenu &_menuSt;
  142. object_ptr<IconButton> _close;
  143. object_ptr<IconButton> _menuToggle = { nullptr };
  144. Fn<void(not_null<RpWidget*>, bool fullscreen)> _menuToggleCreated;
  145. object_ptr<FadeWrapScaled<IconButton>> _searchToggle = { nullptr };
  146. rpl::variable<QString> _searchPlaceholder;
  147. Fn<void(std::optional<QString>)> _searchQueryChanged;
  148. object_ptr<FadeWrap<RpWidget>> _searchWrap = { nullptr };
  149. InputField *_searchField = nullptr;
  150. object_ptr<FlatLabel> _title = { nullptr };
  151. object_ptr<RpWidget> _titleBadge = { nullptr };
  152. object_ptr<FadeWrapScaled<IconButton>> _back;
  153. object_ptr<RpWidget> _body;
  154. base::unique_qptr<RpWidget> _inner;
  155. base::unique_qptr<LayerStackWidget> _layer = { nullptr };
  156. base::unique_qptr<PopupMenu> _menu;
  157. std::vector<std::unique_ptr<ResizeEdge>> _resizeEdges;
  158. std::unique_ptr<FullScreenButton> _fsClose;
  159. std::unique_ptr<FullScreenButton> _fsMenuToggle;
  160. std::unique_ptr<FadeWrapScaled<FullScreenButton>> _fsBack;
  161. bool _fsAllowChildControls = false;
  162. rpl::event_stream<> _synteticBackRequests;
  163. rpl::event_stream<> _userCloseRequests;
  164. rpl::event_stream<> _closeEvents;
  165. int _titleHeight = 0;
  166. bool _allowResize = false;
  167. bool _hideOnDeactivate = false;
  168. bool _useTransparency = true;
  169. bool _backAllowed = false;
  170. style::margins _padding;
  171. bool _dragging = false;
  172. QPoint _dragStartMousePosition;
  173. QPoint _dragStartMyPosition;
  174. Animations::Simple _titleLeft;
  175. bool _visible = false;
  176. rpl::variable<bool> _fullscreen = false;
  177. Animations::Simple _opacityAnimation;
  178. QPixmap _animationCache;
  179. QPixmap _borderParts;
  180. std::optional<QColor> _titleOverrideColor;
  181. QPixmap _titleOverrideBorderParts;
  182. std::unique_ptr<style::palette> _titleOverridePalette;
  183. base::flat_map<
  184. not_null<IconButton*>,
  185. std::unique_ptr<style::IconButton>> _titleOverrideStyles;
  186. std::optional<QColor> _bodyOverrideColor;
  187. QPixmap _bodyOverrideBorderParts;
  188. std::optional<QColor> _bottomBarOverrideColor;
  189. QPixmap _bottomBarOverrideBorderParts;
  190. int _bottomBarHeight = 0;
  191. Fn<bool(int zorder)> _animationsPaused;
  192. };
  193. } // namespace Ui