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 9 #include "styles/style_widgets.h" 10 #include "ui/widgets/inner_dropdown.h" 11 #include "ui/widgets/menu/menu.h" 12 13 namespace Ui { 14 15 class DropdownMenu : public InnerDropdown { 16 Q_OBJECT 17 18 public: 19 DropdownMenu(QWidget *parent, const style::DropdownMenu &st = st::defaultDropdownMenu); 20 21 not_null<QAction*> addAction(base::unique_qptr<Menu::ItemBase> widget); 22 not_null<QAction*> addAction(const QString &text, Fn<void()> callback, const style::icon *icon = nullptr, const style::icon *iconOver = nullptr); 23 not_null<QAction*> addSeparator(); 24 void clearActions(); 25 setHiddenCallback(Fn<void ()> callback)26 void setHiddenCallback(Fn<void()> callback) { 27 _hiddenCallback = std::move(callback); 28 } 29 30 [[nodiscard]] const std::vector<not_null<QAction*>> &actions() const; 31 [[nodiscard]] bool empty() const; 32 menu()33 [[nodiscard]] not_null<Menu::Menu*> menu() const { 34 return _menu; 35 } 36 37 ~DropdownMenu(); 38 39 protected: 40 void focusOutEvent(QFocusEvent *e) override; 41 void hideEvent(QHideEvent *e) override; 42 void keyPressEvent(QKeyEvent *e) override; 43 void mouseMoveEvent(QMouseEvent *e) override; 44 void mousePressEvent(QMouseEvent *e) override; 45 46 private Q_SLOTS: onHidden()47 void onHidden() { 48 hideFinish(); 49 } 50 51 private: 52 // Not ready with submenus yet. 53 DropdownMenu(QWidget *parent, QMenu *menu, const style::DropdownMenu &st = st::defaultDropdownMenu); 54 void deleteOnHide(bool del); 55 void popup(const QPoint &p); 56 void hideMenu(bool fast = false); 57 58 void childHiding(DropdownMenu *child); 59 60 void init(); 61 void hideFinish(); 62 63 using TriggeredSource = Menu::TriggeredSource; 64 void handleActivated(const Menu::CallbackData &data); 65 void handleTriggered(const Menu::CallbackData &data); 66 void forwardKeyPress(not_null<QKeyEvent*> e); 67 bool handleKeyPress(int key); forwardMouseMove(QPoint globalPosition)68 void forwardMouseMove(QPoint globalPosition) { 69 _menu->handleMouseMove(globalPosition); 70 } 71 void handleMouseMove(QPoint globalPosition); forwardMousePress(QPoint globalPosition)72 void forwardMousePress(QPoint globalPosition) { 73 _menu->handleMousePress(globalPosition); 74 } 75 void handleMousePress(QPoint globalPosition); forwardMouseRelease(QPoint globalPosition)76 void forwardMouseRelease(QPoint globalPosition) { 77 _menu->handleMouseRelease(globalPosition); 78 } 79 void handleMouseRelease(QPoint globalPosition); 80 81 using SubmenuPointer = QPointer<DropdownMenu>; 82 bool popupSubmenuFromAction(const Menu::CallbackData &data); 83 void popupSubmenu(SubmenuPointer submenu, int actionTop, TriggeredSource source); 84 void showMenu(const QPoint &p, DropdownMenu *parent, TriggeredSource source); 85 86 const style::DropdownMenu &_st; 87 Fn<void()> _hiddenCallback; 88 89 QPointer<Menu::Menu> _menu; 90 91 // Not ready with submenus yet. 92 //using Submenus = QMap<QAction*, SubmenuPointer>; 93 //Submenus _submenus; 94 95 DropdownMenu *_parent = nullptr; 96 97 SubmenuPointer _activeSubmenu; 98 99 bool _deleteOnHide = false; 100 bool _triggering = false; 101 bool _deleteLater = false; 102 103 }; 104 105 } // namespace Ui 106