Menu.h 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. #ifndef MENU_H
  2. #define MENU_H
  3. #include <Common/SmoothScroll.h>
  4. #include <QMenu>
  5. #include <QListWidget>
  6. #include <QProxyStyle>
  7. #include <QHBoxLayout>
  8. #include <QPropertyAnimation>
  9. #include <QGraphicsDropShadowEffect>
  10. #include <QPair>
  11. #include <QLineEdit>
  12. #include <QTextEdit>
  13. #include <QPlainTextEdit>
  14. #include <QEventLoop>
  15. class SmoothScroll;
  16. class MenuActionListWidget;
  17. class SubMenuItemWidget;
  18. class CustomMenuStyle : public QProxyStyle
  19. {
  20. Q_OBJECT
  21. public:
  22. explicit CustomMenuStyle(int iconSize = 14);
  23. private:
  24. int m_iconSize;
  25. // QStyle interface
  26. public:
  27. virtual int pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const override;
  28. };
  29. class DWMMenu : public QMenu
  30. {
  31. Q_OBJECT
  32. public:
  33. explicit DWMMenu(const QString &title = "", QWidget *parent = nullptr);
  34. // QObject interface
  35. public:
  36. virtual bool event(QEvent *event) override;
  37. private:
  38. QScopedPointer<CustomMenuStyle> m_customMenuStyle;
  39. };
  40. class MenuSeparator : public QWidget
  41. {
  42. Q_OBJECT
  43. public:
  44. explicit MenuSeparator(QWidget *parent = nullptr);
  45. // QWidget interface
  46. protected:
  47. virtual void paintEvent(QPaintEvent *event) override;
  48. };
  49. class RoundMenu : public QWidget
  50. {
  51. Q_OBJECT
  52. public:
  53. explicit RoundMenu(const QString &title = "", QWidget *parent = nullptr);
  54. void setShadowEffect(qreal blurRadius = 30, const QPointF &offset = QPoint(0, 8),
  55. const QColor &color = QColor(0, 0, 0, 30));
  56. void setItemHeight(int itemHeight);
  57. void adjustSize();
  58. QString title() const;
  59. QIcon icon() const;
  60. void setIcon(const QIcon &icon);
  61. void clear();
  62. void removeAction(QAction *action);
  63. void addAction(QAction *const action);
  64. void insertAction(QAction *const before, QAction *const action);
  65. void addActions(const QList<QAction *> &actions);
  66. void insertActions(QAction *const before, const QList<QAction *> &actions);
  67. void setDefaultAction(QAction *const action);
  68. void addMenu(RoundMenu *const menu);
  69. void insertMenu(QAction *const before, RoundMenu *const menu);
  70. RoundMenu *parentMenu() const;
  71. QList<QAction *> menuActions() const;
  72. MenuActionListWidget *view() const;
  73. void addSeparator();
  74. virtual void exec(const QPoint &pos, bool ani = true);
  75. protected:
  76. void setParentMenu(RoundMenu *parent, QListWidgetItem *item);
  77. QListWidgetItem *createActionItem(QAction *const action, QAction *const before = nullptr);
  78. bool hasItemIcon();
  79. QIcon createItemIcon(QAction *const action);
  80. QIcon createItemIcon(RoundMenu *const menu);
  81. QPair<QListWidgetItem *, SubMenuItemWidget *> createSubMenuItem(RoundMenu *const menu);
  82. void hideMenu(bool hideBySystem = false);
  83. void closeParentMenu();
  84. void mouseMoveEvent(QMouseEvent *event) override;
  85. void closeEvent(QCloseEvent *event) override;
  86. void hideEvent(QHideEvent *event) override;
  87. private:
  88. void initWidgets();
  89. protected slots:
  90. void onShowMenuTimeOut();
  91. virtual void onItemClicked(QListWidgetItem *item);
  92. void onItemEntered(QListWidgetItem *item);
  93. void onSlideValueChanged(const QVariant &value);
  94. void onActionChanged();
  95. void showSubMenu(QListWidgetItem *const item);
  96. signals:
  97. void closedSignal();
  98. private:
  99. QString m_title;
  100. QIcon m_icon;
  101. QList<QAction *> m_actions;
  102. QList<RoundMenu *> m_subMenus;
  103. bool m_isSubMenu;
  104. RoundMenu *m_parentMenu;
  105. QListWidgetItem *m_menuItem;
  106. QListWidgetItem *m_lastHoverItem;
  107. QListWidgetItem *m_lastHoverSubMenuItem;
  108. bool m_isHideBySystem;
  109. int m_itemHeight;
  110. QHBoxLayout *m_hBoxLayout;
  111. MenuActionListWidget *m_view;
  112. QPropertyAnimation *m_ani;
  113. QTimer *m_timer;
  114. QGraphicsDropShadowEffect *m_shadowEffect;
  115. QEventLoop *m_eventLoop; //模态堵塞使用
  116. };
  117. Q_DECLARE_METATYPE(QListWidgetItem *)
  118. Q_DECLARE_METATYPE(QAction *)
  119. Q_DECLARE_METATYPE(RoundMenu *)
  120. class SubMenuItemWidget : public QWidget
  121. {
  122. Q_OBJECT
  123. public:
  124. explicit SubMenuItemWidget(QMenu *menu, QListWidgetItem *item, QWidget *parent = nullptr);
  125. explicit SubMenuItemWidget(RoundMenu *menu, QListWidgetItem *item, QWidget *parent = nullptr);
  126. // QWidget interface
  127. RoundMenu *roundMenu() const;
  128. protected:
  129. virtual void enterEvent(QEvent *event) override;
  130. virtual void paintEvent(QPaintEvent *event) override;
  131. signals:
  132. void showMenuSig(QListWidgetItem *const);
  133. private:
  134. QMenu *m_menu;
  135. RoundMenu *m_roundMenu;
  136. QListWidgetItem *m_item;
  137. };
  138. class MenuActionListWidget : public QListWidget
  139. {
  140. Q_OBJECT
  141. public:
  142. explicit MenuActionListWidget(QWidget *parent = nullptr);
  143. void insertItem(int row, QListWidgetItem *item);
  144. void addItem(QListWidgetItem *item);
  145. QListWidgetItem *takeItem(int row);
  146. void adjustSize();
  147. void setItemHeight(int height);
  148. QMargins viewportMargins() { return QListWidget::viewportMargins(); }
  149. // QWidget interface
  150. protected:
  151. virtual void wheelEvent(QWheelEvent *event) override;
  152. private:
  153. QScopedPointer<SmoothScroll> m_smoothScroll;
  154. };
  155. class EditMenu : public RoundMenu
  156. {
  157. Q_OBJECT
  158. public:
  159. explicit EditMenu(QWidget *parent = nullptr);
  160. void createActions();
  161. void exec(const QPoint &pos, bool ani = true) override;
  162. QAction *cutAct;
  163. QAction *copyAct;
  164. QAction *pasteAct;
  165. QAction *cancelAct;
  166. QAction *selectAllAct;
  167. QList<QAction *> actionList;
  168. protected:
  169. virtual QString parentText() = 0;
  170. virtual QString parentSelectedText() = 0;
  171. };
  172. class LineEditMenu : public EditMenu
  173. {
  174. Q_OBJECT
  175. public:
  176. explicit LineEditMenu(QLineEdit *parent);
  177. // RoundMenu interface
  178. protected slots:
  179. void onItemClicked(QListWidgetItem *item) override;
  180. // EditMenu interface
  181. protected:
  182. QString parentText() override;
  183. QString parentSelectedText() override;
  184. private:
  185. int m_selectionStart;
  186. int m_selectionLength;
  187. };
  188. class TextEditMenu : public EditMenu
  189. {
  190. Q_OBJECT
  191. public:
  192. explicit TextEditMenu(QTextEdit *parent);
  193. explicit TextEditMenu(QPlainTextEdit *parent);
  194. // RoundMenu interface
  195. protected slots:
  196. void onItemClicked(QListWidgetItem *item) override;
  197. // EditMenu interface
  198. protected:
  199. QString parentText() override;
  200. QString parentSelectedText() override;
  201. private:
  202. int m_selectionStart;
  203. int m_selectionLength;
  204. QTextEdit *m_textEdit;
  205. QPlainTextEdit *m_plainTextEdit;
  206. };
  207. #endif // MENU_H