menu.h 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  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/unique_qptr.h"
  9. #include "ui/rp_widget.h"
  10. #include "ui/widgets/menu/menu_common.h"
  11. #include <QtWidgets/QMenu>
  12. namespace Ui {
  13. struct ScrollToRequest;
  14. } // namespace Ui
  15. namespace style {
  16. struct Menu;
  17. struct MenuSeparator;
  18. } // namespace style
  19. namespace st {
  20. extern const style::Menu &defaultMenu;
  21. } // namespace st
  22. namespace Ui::Menu {
  23. class ItemBase;
  24. class RippleAnimation;
  25. class Menu : public RpWidget {
  26. public:
  27. Menu(QWidget *parent, const style::Menu &st = st::defaultMenu);
  28. Menu(QWidget *parent, QMenu *menu, const style::Menu &st = st::defaultMenu);
  29. ~Menu();
  30. [[nodiscard]] const style::Menu &st() const {
  31. return _st;
  32. }
  33. not_null<QAction*> addAction(base::unique_qptr<ItemBase> widget);
  34. not_null<QAction*> addAction(
  35. const QString &text,
  36. Fn<void()> callback,
  37. const style::icon *icon = nullptr,
  38. const style::icon *iconOver = nullptr);
  39. not_null<QAction*> addAction(
  40. const QString &text,
  41. std::unique_ptr<QMenu> submenu,
  42. const style::icon *icon = nullptr,
  43. const style::icon *iconOver = nullptr);
  44. not_null<QAction*> addSeparator(
  45. const style::MenuSeparator *st = nullptr);
  46. not_null<QAction*> insertAction(
  47. int position,
  48. base::unique_qptr<ItemBase> widget);
  49. void removeAction(int position);
  50. void clearActions();
  51. void clearLastSeparator();
  52. void finishAnimating();
  53. bool empty() const;
  54. void clearSelection();
  55. void setChildShownAction(QAction *action) {
  56. _childShownAction = action;
  57. }
  58. void setShowSource(TriggeredSource source);
  59. void setForceWidth(int forceWidth);
  60. const std::vector<not_null<QAction*>> &actions() const;
  61. void setActivatedCallback(Fn<void(const CallbackData &data)> callback) {
  62. _activatedCallback = std::move(callback);
  63. }
  64. void setTriggeredCallback(Fn<void(const CallbackData &data)> callback) {
  65. _triggeredCallback = std::move(callback);
  66. }
  67. [[nodiscard]] ItemBase *findSelectedAction() const;
  68. void setKeyPressDelegate(Fn<bool(int key)> delegate) {
  69. _keyPressDelegate = std::move(delegate);
  70. }
  71. void handleKeyPress(not_null<QKeyEvent*> e);
  72. void setMouseMoveDelegate(Fn<void(QPoint globalPosition)> delegate) {
  73. _mouseMoveDelegate = std::move(delegate);
  74. }
  75. void handleMouseMove(QPoint globalPosition);
  76. void setMousePressDelegate(Fn<void(QPoint globalPosition)> delegate) {
  77. _mousePressDelegate = std::move(delegate);
  78. }
  79. void handleMousePress(QPoint globalPosition);
  80. void setMouseReleaseDelegate(Fn<void(QPoint globalPosition)> delegate) {
  81. _mouseReleaseDelegate = std::move(delegate);
  82. }
  83. void handleMouseRelease(QPoint globalPosition);
  84. void setSelected(int selected, bool isMouseSelection);
  85. [[nodiscard]] rpl::producer<> resizesFromInner() const;
  86. [[nodiscard]] rpl::producer<ScrollToRequest> scrollToRequests() const;
  87. protected:
  88. void keyPressEvent(QKeyEvent *e) override;
  89. void mouseMoveEvent(QMouseEvent *e) override;
  90. void mousePressEvent(QMouseEvent *e) override;
  91. void mouseReleaseEvent(QMouseEvent *e) override;
  92. private:
  93. void updateSelected(QPoint globalPosition);
  94. void init();
  95. not_null<QAction*> addAction(
  96. not_null<QAction*> action,
  97. const style::icon *icon = nullptr,
  98. const style::icon *iconOver = nullptr);
  99. void clearMouseSelection();
  100. void itemPressed(TriggeredSource source);
  101. [[nodiscard]] int recountWidth() const;
  102. [[nodiscard]] int recountHeight() const;
  103. void resizeFromInner(int w, int h);
  104. const style::Menu &_st;
  105. Fn<void(const CallbackData &data)> _activatedCallback;
  106. Fn<void(const CallbackData &data)> _triggeredCallback;
  107. Fn<bool(int key)> _keyPressDelegate;
  108. Fn<void(QPoint globalPosition)> _mouseMoveDelegate;
  109. Fn<void(QPoint globalPosition)> _mousePressDelegate;
  110. Fn<void(QPoint globalPosition)> _mouseReleaseDelegate;
  111. QMenu *_wappedMenu = nullptr;
  112. std::vector<not_null<QAction*>> _actions;
  113. std::vector<base::unique_qptr<ItemBase>> _actionWidgets;
  114. int _forceWidth = 0;
  115. bool _lastSelectedByMouse = false;
  116. QPointer<QAction> _childShownAction;
  117. rpl::event_stream<> _resizesFromInner;
  118. rpl::event_stream<ScrollToRequest> _scrollToRequests;
  119. };
  120. } // namespace Ui::Menu