/* This file is part of Telegram Desktop, the official desktop application for the Telegram messaging service. For license and copyright information please follow this link: https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #pragma once #include "styles/style_widgets.h" namespace Ui { class ToggleView; class RippleAnimation; class Menu : public TWidget { Q_OBJECT public: Menu(QWidget *parent, const style::Menu &st = st::defaultMenu); Menu(QWidget *parent, QMenu *menu, const style::Menu &st = st::defaultMenu); not_null addAction(const QString &text, const QObject *receiver, const char* member, const style::icon *icon = nullptr, const style::icon *iconOver = nullptr); not_null addAction(const QString &text, Fn callback, const style::icon *icon = nullptr, const style::icon *iconOver = nullptr); not_null addSeparator(); void clearActions(); void finishAnimating(); void clearSelection(); enum class TriggeredSource { Mouse, Keyboard, }; void setChildShown(bool shown) { _childShown = shown; } void setShowSource(TriggeredSource source); void setForceWidth(int forceWidth); const std::vector> &actions() const; void setResizedCallback(Fn callback) { _resizedCallback = std::move(callback); } void setActivatedCallback(Fn callback) { _activatedCallback = std::move(callback); } void setTriggeredCallback(Fn callback) { _triggeredCallback = std::move(callback); } void setKeyPressDelegate(Fn delegate) { _keyPressDelegate = std::move(delegate); } void handleKeyPress(int key); void setMouseMoveDelegate(Fn delegate) { _mouseMoveDelegate = std::move(delegate); } void handleMouseMove(QPoint globalPosition); void setMousePressDelegate(Fn delegate) { _mousePressDelegate = std::move(delegate); } void handleMousePress(QPoint globalPosition); void setMouseReleaseDelegate(Fn delegate) { _mouseReleaseDelegate = std::move(delegate); } void handleMouseRelease(QPoint globalPosition); protected: void paintEvent(QPaintEvent *e) override; void keyPressEvent(QKeyEvent *e) override; void mouseMoveEvent(QMouseEvent *e) override; void mousePressEvent(QMouseEvent *e) override; void mouseReleaseEvent(QMouseEvent *e) override; void enterEventHook(QEvent *e) override; void leaveEventHook(QEvent *e) override; private slots: void actionChanged(); private: struct ActionData { ActionData() = default; ActionData(const ActionData &other) = delete; ActionData &operator=(const ActionData &other) = delete; ActionData(ActionData &&other) = default; ActionData &operator=(ActionData &&other) = default; ~ActionData(); bool hasSubmenu = false; QString text; QString shortcut; const style::icon *icon = nullptr; const style::icon *iconOver = nullptr; std::unique_ptr ripple; std::unique_ptr toggle; }; void updateSelected(QPoint globalPosition); void init(); // Returns the new width. int processAction(not_null action, int index, int width); not_null addAction(not_null action, const style::icon *icon = nullptr, const style::icon *iconOver = nullptr); void setSelected(int selected); void setPressed(int pressed); void clearMouseSelection(); int itemTop(int index); void updateItem(int index); void updateSelectedItem(); void itemPressed(TriggeredSource source); void itemReleased(TriggeredSource source); const style::Menu &_st; Fn _resizedCallback; Fn _activatedCallback; Fn _triggeredCallback; Fn _keyPressDelegate; Fn _mouseMoveDelegate; Fn _mousePressDelegate; Fn _mouseReleaseDelegate; QMenu *_wappedMenu = nullptr; std::vector> _actions; std::vector _actionsData; int _forceWidth = 0; int _itemHeight, _separatorHeight; bool _mouseSelection = false; int _selected = -1; int _pressed = -1; bool _childShown = false; }; } // namespace Ui