iPlug2 - C++ Audio Plug-in Framework
Loading...
Searching...
No Matches
IPopupMenuControl.h
Go to the documentation of this file.
1/*
2 ==============================================================================
3
4 This file is part of the iPlug 2 library. Copyright (C) the iPlug 2 developers.
5
6 See LICENSE.txt for more info.
7
8 ==============================================================================
9*/
10
11#pragma once
12
19#include "IControl.h"
20
21BEGIN_IPLUG_NAMESPACE
22BEGIN_IGRAPHICS_NAMESPACE
23
30{
31 class MenuPanel;
32
33public:
36 {
37 kCollapsed = 0,
38 kExpanding,
39 kExpanded,
40 kCollapsing,
41 kFlickering, // on click
42 kSubMenuAppearing, // when a submenu appears, only that menu is faded in
43 kIdling,
44 };
45
46 enum EArrowDir
47 {
48 kNorth,
49 kEast,
50 kSouth,
51 kWest
52 };
53
59 IPopupMenuControl(int paramIdx = kNoParameter, IText text = IText(16), IRECT collapsedBounds = IRECT(), IRECT expandedBounds = IRECT());
60 virtual ~IPopupMenuControl();
61
62 //IControl
63 void Draw(IGraphics& g) override;
64 void OnMouseDown(float x, float y, const IMouseMod& mod) override;
65 void OnMouseDrag(float x, float y, float dX, float dY, const IMouseMod& mod) override;
66 void OnMouseOver(float x, float y, const IMouseMod& mod) override;
67 void OnMouseOut() override;
68 void OnMouseWheel(float x, float y, const IMouseMod& mod, float d) override;
69 void OnEndAnimation() override;
70
71 //IPopupMenuControl
72
76 void CalculateMenuPanels(float x, float y);
77
79 virtual void DrawCalloutArrow(IGraphics& g, const IRECT& bounds, IBlend* pBlend);
81 virtual void DrawSubMenuCalloutArrow(IGraphics& g, const IRECT& bounds, IBlend* pBlend);
83 virtual void DrawPanelBackground(IGraphics& g, MenuPanel* panel);
85 virtual void DrawPanelShadow(IGraphics& g, MenuPanel* panel);
87 virtual void DrawCellBackground(IGraphics& g, const IRECT& bounds, const IPopupMenu::Item* pItem, bool sel, IBlend* pBlend);
89 virtual void DrawCellText(IGraphics& g, const IRECT& bounds, const IPopupMenu::Item* pItem, bool sel, IBlend* pBlend);
91 virtual void DrawTick(IGraphics& g, const IRECT& bounds, const IPopupMenu::Item* pItem, bool sel, IBlend* pBlend);
93 virtual void DrawSubMenuArrow(IGraphics& g, const IRECT& bounds, const IPopupMenu::Item* pItem, bool sel, IBlend* pBlend);
95 virtual void DrawUpArrow(IGraphics& g, const IRECT& bounds, bool sel, IBlend* pBlend);
97 virtual void DrawDownArrow(IGraphics& g, const IRECT& bounds, bool sel, IBlend* pBlend);
99 virtual void DrawSeparator(IGraphics& g, const IRECT& bounds, IBlend* pBlend);
100
102 void SetPanelColor(IColor color) { mPanelBackgroundColor = color; }
104 void SetCellBackgroundColor(IColor color) { mCellBackGroundColor = color; }
106 void SetItemMouseoverColor(IColor color) { mItemMouseoverColor = color; }
108 void SetItemColor(IColor color) { mItemColor = color; }
110 void SetDisabledItemColor(IColor color) { mDisabledItemColor = color; }
112 void SetSeparatorColor(IColor color) { mSeparatorColor = color; }
117 void SetShiftForSubmenus(float distance) { mMenuShift = distance; }
119 void SetMenuForcedSouth(bool isForcedSouth) { mForcedSouth = isForcedSouth;}
120
124 void CreatePopupMenu(IPopupMenu& menu, const IRECT& anchorArea);
125
127 bool GetExpanded() const { return mState == kExpanded; }
128
130 EPopupState GetState() const { return mState; }
131
133 void SetExpandedBounds(const IRECT& bounds) { mSpecifiedExpandedBounds = bounds; }
134
136 void SetCallout(bool callout) { mCallOut = callout; }
137
139 void SetMaxBounds(const IRECT& bounds) { mMaxBounds = bounds; }
140
141private:
143 IRECT GetLargestCellRectForMenu(IPopupMenu& menu, float x, float y) const;
144
149 void GetPanelDimensions(IPopupMenu&menu, float& width, float& height) const;
150
152 void Expand(const IRECT& bounds);
153
155 virtual void CollapseEverything();
156
157private:
158
160 class MenuPanel
161 {
162 public:
163 MenuPanel(IPopupMenuControl& owner, IPopupMenu& menu, float x, float y, int parentIdx);
164 ~MenuPanel();
165
166 MenuPanel(const MenuPanel&) = delete;
167 MenuPanel& operator=(const MenuPanel&) = delete;
168
170 float CellWidth() const { return mSingleCellBounds.W(); }
171
173 float CellHeight() const { return mSingleCellBounds.H(); }
174
175 void ScrollUp() { mScrollItemOffset--; mScrollItemOffset = Clip(mScrollItemOffset, 0, mCellBounds.GetSize()-1); }
176
177 void ScrollDown() { mScrollItemOffset++; mScrollItemOffset = Clip(mScrollItemOffset, 0, mMenu.NItems()-mCellBounds.GetSize()); }
178
183 IRECT* HitTestCells(float x, float y) const;
184
185 public:
186 IPopupMenu& mMenu; // The IPopupMenu that this MenuPanel is displaying
187 WDL_PtrList<IRECT> mCellBounds; // The size of this array will always correspond to the number of items in the top level of the menu
188
189 IRECT mRECT; // The drawing bounds for this panel
190 IRECT mTargetRECT; // The mouse target bounds for this panel
191 int mScrollMaxRows = 0; // 0 when no scroll
192 bool mShouldDraw = true; // boolean determining whether this panel should be drawn
193 IBlend mBlend = { EBlend::Default, 0.f }; // blend for sub panels appearing
194
195 IRECT mSingleCellBounds; // The dimensions of the largest cell for the menu
196 IRECT* mHighlightedCell = nullptr; // A pointer to one of the IRECTs in mCellBounds, if one should be highlighted
197 IRECT* mClickedCell = nullptr; // A pointer to one of the IRECTs in mCellBounds, if one has been clicked
198 int mParentIdx = 0; // An index into the IPopupMenuControl::mMenuPanels lists, representing the parent menu panel
199 bool mScroller = false;
200 int mScrollItemOffset = 0;
201
202#ifndef IGRAPHICS_NANOVG
203 ILayerPtr mShadowLayer;
204#endif
205 };
206
207 WDL_PtrList<MenuPanel> mMenuPanels; // An array of ptrs to MenuPanel objects for every panel, expands as sub menus are revealed, contents deleted when the menu is dismissed
208 MenuPanel* mActiveMenuPanel = nullptr; // A pointer to the active MenuPanel within the mMenuPanels array
209 MenuPanel* mAppearingMenuPanel = nullptr; // A pointer to a MenuPanel that's in the process of fading in
210 EPopupState mState = kCollapsed; // The state of the pop-up, mainly used for animation
211 IRECT* mMouseCellBounds = nullptr;
212 IPopupMenu* mMenu = nullptr; // Pointer to the main IPopupMenu, that this control is visualising. This control does not own the menu.
213
214 int mMaxColumnItems = 0; // How long the list can get before adding a new column - 0 equals no limit
215 bool mScrollIfTooBig = true; // If the menu is higher than the graphics context, should it scroll or should it start a new column
216 bool mCallOut = false; // set true if popup should be outside of bounds (i.e. on a tablet touchscreen interface)
217 bool mMenuHasSubmenu = false; // Gets automatically set to true in CreatePopupMenu() if *mMenu contains any submenus... false if not.
218 bool mForcedSouth = true; // if set true, a menu in the lower half of the GUI will appear below it's control if there is enough room for it.
219 bool mSubmenuOnRight = true; // If set true, the submenu will be drawn on the right of the parent menu.... on the left if false.
220 bool mSubMenuOpened = false; // Is set true when a submenu panel is open and false when menu is collapsed.
221
222 float mCellGap = 2.f; // The gap between cells in pixels
223 float mSeparatorSize = 2.; // The size in pixels of a separator. This could be width or height
224 float mRoundness = 5.f; // The roundness of the corners of the menu panel backgrounds
225 float mDropShadowSize = 10.f; // The size in pixels of the drop shadow
226 float mOpacity = 0.95f; // The opacity of the menu panel backgrounds when fully faded in
227 float mMenuShift = 0.f; // The distance in pixels the main menu is shifted to make room for submenus (only if one exist). Set by SetShiftForSubmenus()
228
229 const float TEXT_HPAD = 5.; // The amount of horizontal padding on either side of cell text in pixels
230 const float TICK_SIZE = 10.; // The size of the area on the left of the cell where a tick mark appears on checked items - actual
231 const float ARROW_SIZE = 8; // The width of the area on the right of the cell where an arrow appears for new submenus
232 const float PAD = 5.; // How much white space between the background and the cells
233 const float CALLOUT_SPACE = 8; // The space between start bounds and callout
234 IRECT mAnchorArea; // The area where the menu was triggered; menu will be adjacent, but won't occupy it.
235 EArrowDir mCalloutArrowDir = kEast;
236 IRECT mCalloutArrowBounds; // The rectangle in which the CallOut arrow is drawn.
237 IRECT mSubMenuCalloutArrowBounds; // The rectangle in which the CallOut arrow for a submenus is drawn.
238
239 IRECT mMaxBounds; // if view is only showing a part of the graphics context, we need to know because menus can't go there
240
241 IColor mPanelBackgroundColor = COLOR_WHITE;
242 IColor mCellBackGroundColor = COLOR_BLUE;
243 IColor mItemMouseoverColor = COLOR_WHITE;
244 IColor mItemColor = COLOR_BLACK;
245 IColor mDisabledItemColor = COLOR_GRAY;
246 IColor mSeparatorColor = COLOR_MID_GRAY;
247
248protected:
249 IRECT mSpecifiedCollapsedBounds;
250 IRECT mSpecifiedExpandedBounds;
251};
252
253END_IGRAPHICS_NAMESPACE
254END_IPLUG_NAMESPACE
This file contains the base IControl implementation, along with some base classes for specific types ...
The lowest level base class of an IGraphics control.
Definition: IControl.h:49
The lowest level base class of an IGraphics context.
Definition: IGraphics.h:86
A class to specify an item of a pop up menu.
A base control for a pop-up menu/drop-down list that stays within the bounds of the IGraphics context...
void SetSeparatorColor(IColor color)
Call this to set the Separator color on menu panels.
void OnMouseOut() override
Implement this method to respond to a mouseout event on this control.
void CreatePopupMenu(IPopupMenu &menu, const IRECT &anchorArea)
Call this to create a pop-up menu.
virtual void DrawUpArrow(IGraphics &g, const IRECT &bounds, bool sel, IBlend *pBlend)
Override this method to change the way a scroll up cell's arrow is drawn.
void SetMenuForcedSouth(bool isForcedSouth)
If set true, the menu (kNorth) is forced to appear below it's control(kSouth) when it would normally ...
EPopupState GetState() const
void OnMouseWheel(float x, float y, const IMouseMod &mod, float d) override
Implement this method to respond to a mouse wheel event on this control.
void SetItemColor(IColor color)
Call this to set the color of enabled text items, ticks and arrows on menu panels.
void SetExpandedBounds(const IRECT &bounds)
Force the menu to open with a specific bounds - useful on small screens for making it modal.
void Draw(IGraphics &g) override
Draw the control to the graphics context.
void SetCellBackgroundColor(IColor color)
Call this to set the Cell color when mouse is over it.
void CalculateMenuPanels(float x, float y)
Called as the user moves the mouse around, in order to work out which menu panel should be on the scr...
void OnMouseDrag(float x, float y, float dX, float dY, const IMouseMod &mod) override
Implement this method to respond to a mouse drag event on this control.
virtual void DrawSeparator(IGraphics &g, const IRECT &bounds, IBlend *pBlend)
Override this method to change the way a cell separator is drawn
EPopupState
An enumerated list, that is used to determine the state of the menu, mainly for animations.
void OnMouseOver(float x, float y, const IMouseMod &mod) override
Implement this method to respond to a mouseover event on this control.
virtual void DrawCellText(IGraphics &g, const IRECT &bounds, const IPopupMenu::Item *pItem, bool sel, IBlend *pBlend)
Override this method to change the way a cell's text is drawn.
void SetCallout(bool callout)
Set if the menu is shifted away from where the control is created with a callout arrow (for fat finge...
void SetItemMouseoverColor(IColor color)
Call this to set the mouseover color for text, tick, and arrows on menu panels.
virtual void DrawSubMenuArrow(IGraphics &g, const IRECT &bounds, const IPopupMenu::Item *pItem, bool sel, IBlend *pBlend)
Override this method to change the way a submenu cell's arrow is drawn.
virtual void DrawTick(IGraphics &g, const IRECT &bounds, const IPopupMenu::Item *pItem, bool sel, IBlend *pBlend)
Override this method to change the way a checked cell's "tick" is drawn.
virtual void DrawDownArrow(IGraphics &g, const IRECT &bounds, bool sel, IBlend *pBlend)
Override this method to change the way a scroll Down cell's arrow is drawn.
void SetMaxBounds(const IRECT &bounds)
Set the bounds that the menu can potentially occupy, if not the full graphics context.
virtual void DrawCellBackground(IGraphics &g, const IRECT &bounds, const IPopupMenu::Item *pItem, bool sel, IBlend *pBlend)
Override this method to change the way a cell's background is drawn.
virtual void DrawPanelBackground(IGraphics &g, MenuPanel *panel)
Override this method to change the background of the pop-up menu panel.
void SetShiftForSubmenus(float distance)
Sets the amount the main menu is shifted to make room for submenus.
bool GetExpanded() const
void SetDisabledItemColor(IColor color)
Call this to set the text color of disabled items on menu panels.
void OnMouseDown(float x, float y, const IMouseMod &mod) override
Implement this method to respond to a mouse down event on this control.
void SetPanelColor(IColor color)
Call this to set the Panel color.
virtual void DrawPanelShadow(IGraphics &g, MenuPanel *panel)
Override this method to change the shadow of the pop-up menu panel.
virtual void DrawSubMenuCalloutArrow(IGraphics &g, const IRECT &bounds, IBlend *pBlend)
Override this method to change the way Callout arrows for Submenus are drawn.
virtual void DrawCalloutArrow(IGraphics &g, const IRECT &bounds, IBlend *pBlend)
Override this method to change the way Callout arrows are drawn.
A class for setting the contents of a pop up menu.
std::unique_ptr< ILayer > ILayerPtr
ILayerPtr is a managed pointer for transferring the ownership of layers.
BEGIN_IPLUG_NAMESPACE T Clip(T x, T lo, T hi)
Clips the value x between lo and hi.
Used to manage composite/blend operations, independent of draw class/platform.
Used to manage color data, independent of draw class/platform.
Used to manage mouse modifiers i.e.
Used to manage a rectangular area, independent of draw class/platform.
IText is used to manage font and text/text entry style for a piece of text on the UI,...