// This file is part of VSTGUI. It is subject to the license terms // in the LICENSE file found in the top-level directory of this // distribution and at http://github.com/steinbergmedia/vstgui/LICENSE #pragma once #include "cparamdisplay.h" #include "icommandmenuitemtarget.h" #include "ioptionmenulistener.h" #include "../cstring.h" #include "../dispatchlist.h" #include "../cbitmap.h" #include #include namespace VSTGUI { //----------------------------------------------------------------------------- // CMenuItem Declaration //! @brief a menu item //----------------------------------------------------------------------------- class CMenuItem : public CBaseObject { public: enum Flags { kNoFlags = 0, /** item is gray and not selectable */ kDisabled = 1 << 0, /** item indicates a title and is not selectable */ kTitle = 1 << 1, /** item has a checkmark */ kChecked = 1 << 2, /** item is a separator */ kSeparator = 1 << 3 }; CMenuItem (const UTF8String& title, const UTF8String& keycode = "", int32_t keyModifiers = 0, CBitmap* icon = nullptr, int32_t flags = kNoFlags); CMenuItem (const UTF8String& title, COptionMenu* submenu, CBitmap* icon = nullptr); CMenuItem (const UTF8String& title, int32_t tag); CMenuItem (const CMenuItem& item); //----------------------------------------------------------------------------- /// @name CMenuItem Methods //----------------------------------------------------------------------------- //@{ /** set title of menu item */ virtual void setTitle (const UTF8String& title); /** set submenu of menu item */ virtual void setSubmenu (COptionMenu* submenu); /** set keycode and key modifiers of menu item */ virtual void setKey (const UTF8String& keyCode, int32_t keyModifiers = 0); /** set virtual key and key modifiers of menu item */ virtual void setVirtualKey (VirtualKey virtualKey, int32_t keyModifiers = 0); /** set menu item enabled state */ virtual void setEnabled (bool state = true); /** set menu item checked state */ virtual void setChecked (bool state = true); /** set menu item title state */ virtual void setIsTitle (bool state = true); /** set menu item separator state */ virtual void setIsSeparator (bool state = true); /** set menu item icon */ virtual void setIcon (CBitmap* icon); /** set menu item tag */ virtual void setTag (int32_t tag); /** returns whether the item is enabled or not */ bool isEnabled () const; /** returns whether the item is checked or not */ bool isChecked () const; /** returns whether the item is a title item or not */ bool isTitle () const; /** returns whether the item is a separator or not */ bool isSeparator () const; /** returns the title of the item */ const UTF8String& getTitle () const; /** returns the key modifiers of the item */ int32_t getKeyModifiers () const; /** returns the keycode of the item */ const UTF8String& getKeycode () const; /** returns the virtual key of the item */ VirtualKey getVirtualKey () const; /** returns the submenu of the item */ COptionMenu* getSubmenu () const; /** returns the icon of the item */ CBitmap* getIcon () const; /** returns the tag of the item */ int32_t getTag () const; //@} #if VSTGUI_ENABLE_DEPRECATED_METHODS int32_t getVirtualKeyCode () const; virtual void setVirtualKey (int32_t virtualKeyCode, int32_t keyModifiers = 0); #endif //------------------------------------------------------------------------ protected: CMenuItem (); ~CMenuItem () noexcept override; struct Impl; std::unique_ptr impl; }; //----------------------------------------------------------------------------- // CCommandMenuItem Declaration /// @brief a command menu item /// @ingroup new_in_4_1 //----------------------------------------------------------------------------- class CCommandMenuItem : public CMenuItem { public: struct Desc { UTF8String title; UTF8String commandCategory; UTF8String commandName; UTF8String keycode; SharedPointer target; SharedPointer icon; int32_t keyModifiers {0}; int32_t flags {kNoFlags}; int32_t tag {-1}; Desc () = default; ~Desc () noexcept = default; Desc (const UTF8String& title, const UTF8String& keycode = nullptr, int32_t keyModifiers = 0, CBitmap* icon = nullptr, int32_t flags = kNoFlags, ICommandMenuItemTarget* target = nullptr, const UTF8String& commandCategory = nullptr, const UTF8String& commandName = nullptr) : title (title) , commandCategory (commandCategory) , commandName (commandName) , keycode (keycode) , target (target) , icon (icon) , keyModifiers (keyModifiers) , flags (flags) { } Desc (const UTF8String& title, int32_t tag, ICommandMenuItemTarget* target = nullptr, const UTF8String& commandCategory = nullptr, const UTF8String& commandName = nullptr) : title (title) , commandCategory (commandCategory) , commandName (commandName) , target (target) , tag (tag) { } Desc (const UTF8String& title, ICommandMenuItemTarget* target, const UTF8String& commandCategory = nullptr, const UTF8String& commandName = nullptr) : title (title) , commandCategory (commandCategory) , commandName (commandName) , target (target) { } }; CCommandMenuItem (Desc&& args); CCommandMenuItem (const Desc& args); CCommandMenuItem (const CCommandMenuItem& item); ~CCommandMenuItem () noexcept override = default; //----------------------------------------------------------------------------- /// @name CCommandMenuItem Methods //----------------------------------------------------------------------------- //@{ void setCommandCategory (const UTF8String& category); const UTF8String& getCommandCategory () const { return commandCategory; } bool isCommandCategory (const UTF8String& category) const; void setCommandName (const UTF8String& name); const UTF8String& getCommandName () const { return commandName; } bool isCommandName (const UTF8String& name) const; void setItemTarget (ICommandMenuItemTarget* target); ICommandMenuItemTarget* getItemTarget () const { return itemTarget; } using ValidateCallbackFunction = std::function; using SelectedCallbackFunction = std::function; void setActions (SelectedCallbackFunction&& selected, ValidateCallbackFunction&& validate = [](CCommandMenuItem*){}); //@} void execute (); void validate (); protected: ValidateCallbackFunction validateFunc; SelectedCallbackFunction selectedFunc; UTF8String commandCategory; UTF8String commandName; SharedPointer itemTarget; }; using CMenuItemList = std::vector>; using CMenuItemIterator = CMenuItemList::iterator; using CConstMenuItemIterator = CMenuItemList::const_iterator; //----------------------------------------------------------------------------- // COptionMenu Declaration //! @brief a popup menu control /// @ingroup controls //----------------------------------------------------------------------------- class COptionMenu : public CParamDisplay { private: enum StyleEnum { StylePopup = CParamDisplay::LastStyle, StyleCheck, StyleMultipleCheck, }; public: COptionMenu (); COptionMenu (const CRect& size, IControlListener* listener, int32_t tag, CBitmap* background = nullptr, CBitmap* bgWhenClick = nullptr, const int32_t style = 0); COptionMenu (const COptionMenu& menu); ~COptionMenu () noexcept override; enum Style { kPopupStyle = 1 << StylePopup, kCheckStyle = 1 << StyleCheck, kMultipleCheckStyle = 1 << StyleMultipleCheck }; bool isPopupStyle () const { return hasBit (getStyle (), kPopupStyle); } bool isCheckStyle () const { return hasBit (getStyle (), kCheckStyle); } bool isMultipleCheckStyle () const { return hasBit (getStyle (), kMultipleCheckStyle); } //----------------------------------------------------------------------------- /// @name COptionMenu Methods //----------------------------------------------------------------------------- //@{ /** add a new entry */ virtual CMenuItem* addEntry (CMenuItem* item, int32_t index = -1); /** add a new submenu entry */ virtual CMenuItem* addEntry (COptionMenu* submenu, const UTF8String& title); /** add a new entry */ virtual CMenuItem* addEntry (const UTF8String& title, int32_t index = -1, int32_t itemFlags = CMenuItem::kNoFlags); /** add a new separator entry */ virtual CMenuItem* addSeparator (int32_t index = -1); /** get current entry */ virtual CMenuItem* getCurrent () const; /** TODO: Doc */ virtual int32_t getCurrentIndex (bool countSeparator = false) const; /** get entry at index position */ virtual CMenuItem* getEntry (int32_t index) const; /** get number of entries */ virtual int32_t getNbEntries () const; /** set current entry */ virtual bool setCurrent (int32_t index, bool countSeparator = true); /** remove an entry */ virtual bool removeEntry (int32_t index); /** remove all entries */ virtual bool removeAllEntry (); /** change check state of entry at index */ virtual bool checkEntry (int32_t index, bool state); /** check entry at index and uncheck every other item */ virtual bool checkEntryAlone (int32_t index); /** get check state of entry at index */ virtual bool isCheckEntry (int32_t index) const; /** Windows only */ virtual void setNbItemsPerColumn (int32_t val) { nbItemsPerColumn = val; } /** Windows only */ virtual int32_t getNbItemsPerColumn () const { return nbItemsPerColumn; } /** get last index of choosen entry */ int32_t getLastResult () const { return lastResult; } /** get last menu and index of choosen entry */ COptionMenu* getLastItemMenu (int32_t& idxInMenu) const; /** set prefix numbering */ virtual void setPrefixNumbers (int32_t preCount); /** get prefix numbering */ int32_t getPrefixNumbers () const { return prefixNumbers; } /** get a submenu */ COptionMenu* getSubMenu (int32_t idx) const; /** popup callback function */ using PopupCallback = std::function; /** pops up the menu */ bool popup (const PopupCallback& callback = {}); /** pops up the menu at frameLocation */ bool popup (CFrame* frame, const CPoint& frameLocation, const PopupCallback& callback = {}); CMenuItemList* getItems () const { return menuItems; } /** remove separators as first and last item and double separators */ void cleanupSeparators (bool deep); void registerOptionMenuListener (IOptionMenuListener* listener); void unregisterOptionMenuListener (IOptionMenuListener* listener); //@} // overrides void setValue (float val) override; void setMin (float val) override {} float getMin () const override { return 0; } void setMax (float val) override {} float getMax () const override; void draw (CDrawContext* pContext) override; CMouseEventResult onMouseDown (CPoint& where, const CButtonState& buttons) override; void onKeyboardEvent (KeyboardEvent& event) override; void takeFocus () override; void looseFocus () override; CLASS_METHODS(COptionMenu, CParamDisplay) protected: bool doPopup (); void beforePopup (); void afterPopup (); CMenuItemList* menuItems; bool inPopup {false}; int32_t currentIndex {-1}; CButtonState lastButton {0}; int32_t nbItemsPerColumn {-1}; int32_t lastResult {-1}; int32_t prefixNumbers {0}; SharedPointer bgWhenClick; COptionMenu* lastMenu {nullptr}; using MenuListenerList = DispatchList; std::unique_ptr listeners; }; } // VSTGUI