iPlug2 - C++ Audio Plug-in Framework
Loading...
Searching...
No Matches
IVTabbedPagesControl.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 "IControls.h"
20#include "IBubbleControl.h"
21
22#include <map>
23
24BEGIN_IPLUG_NAMESPACE
25BEGIN_IGRAPHICS_NAMESPACE
26
29class IVTabPage : public IContainerBase, public IVectorBase
30{
31public:
32 using TabAttachFunc = std::function<void(IVTabPage* pParent, const IRECT& bounds)>;
33 static constexpr double kDefaultPadding = 10.0;
34
35 static void DefaultResizeFunc(IContainerBase* pTab, const IRECT& r) {
36 if (pTab->NChildren() == 1)
37 {
38 auto innerBounds = r.GetPadded(float(- pTab->As<IVTabPage>()->GetPadding()));
39 pTab->GetChild(0)->SetTargetAndDrawRECTs(innerBounds);
40 }
41 }
42
50 IVTabPage(TabAttachFunc attachFunc = nullptr, ResizeFunc resizeFunc = DefaultResizeFunc, const IVStyle& style = DEFAULT_STYLE, double padding = kDefaultPadding)
51 : IContainerBase(IRECT(), [attachFunc](IContainerBase* pParent, const IRECT& bounds){
52 attachFunc(pParent->As<IVTabPage>(), bounds);
53 }, resizeFunc)
54 , IVectorBase(style)
55 , mPadding(padding)
56 {
57 AttachIControl(this, "");
58 }
59
60 virtual void Draw(IGraphics &g) override
61 {
62 /* NO-OP */
63 }
64
65 double GetPadding() const { return mPadding; }
66
67 void SetPadding(double padding) { mPadding = padding; }
68
69 void OnStyleChanged() override
70 {
71 ForAllChildrenFunc([this](int childIdx, IControl* pChild) {
72 if (auto pVectorBase = pChild->As<IVectorBase>())
73 {
74 pVectorBase->SetStyle(GetStyle());
75 }
76 });
77 }
78
79private:
80 double mPadding = 0.0;
81};
82
83using PageMap = std::map<const char*, IVTabPage*>;
84
107{
108public:
109 IVTabbedPagesControl(const IRECT& bounds, const PageMap& pages, const char* label = "",
110 const IVStyle& style = DEFAULT_STYLE, float tabBarHeight = 20.0f,
111 float tabBarFrac = 0.5f, EAlign tabsAlign = EAlign::Near)
112 : IContainerBase(bounds)
113 , IVectorBase(style.WithDrawFrame(false).WithDrawShadows(false))
114 , mTabBarHeight(tabBarHeight)
115 , mTabBarFrac(tabBarFrac)
116 , mTabsAlign(tabsAlign)
117 {
118 AttachIControl(this, label);
119
120 for (auto& page : pages)
121 {
122 AddPage(page.first, page.second);
123 }
124 }
125
127 {
128 mPages.Empty(false);
129 }
130
131 void Hide(bool hide) override
132 {
133 if (hide)
134 {
135 ForAllChildrenFunc([hide](int childIdx, IControl* pChild) {
136 pChild->Hide(hide);
137 });
138 }
139 else
140 {
141 ForAllPagesFunc([&](IVTabPage* pPage) {
142 pPage->Hide(true);
143 });
144
145 // Show the tabs and first page
146 GetTabSwitchControl()->Hide(false);
147 GetPage(GetTabSwitchControl()->GetSelectedIdx())->Hide(false);
148 }
149
150 IControl::Hide(hide);
151 }
152
153 void Draw(IGraphics& g) override
154 {
155 DrawLabel(g);
156
157 auto rcr = GetRoundedCornerRadius(GetTabBarArea());
158
159 auto rcrForTabCorners = mTabBarFrac == 1.0f ? 0.0f : rcr;
160
161 g.FillRoundRect(GetColor(kPR), GetPageArea(), mTabsAlign == EAlign::Near ? 0.0f : rcrForTabCorners,
162 mTabsAlign == EAlign::Far ? 0.0f : rcrForTabCorners,
163 rcr, rcr);
164
165 if (mStyle.drawFrame)
166 g.DrawRoundRect(GetColor(kFR), mRECT, rcr);
167 }
168
169 void OnAttached() override
170 {
171 // Set up tabs
172 AddChildControl(new IVTabSwitchControl(GetTabBarArea(),
173 [&](IControl* pCaller) {
174 ShowSelectedPage();
175 }, mPageNames, "", GetStyle().WithWidgetFrac(1.0f)));
176
177 GetTabSwitchControl()->SetShape(EVShape::EndsRounded);
178
179 // Add all pages, set their bounds and hide them
180 ForAllPagesFunc([&](IVTabPage* pPage) {
181 AddChildControl(pPage);
182 pPage->SetTargetAndDrawRECTs(GetPageArea());
183 pPage->Hide(true);
184 });
185
186 // Show the tabs and first page
187 GetTabSwitchControl()->Hide(false);
188 GetPage(0)->Hide(false);
189 }
190
191 void OnStyleChanged() override
192 {
193 ForAllChildrenFunc([this](int childIdx, IControl* pChild) {
194 if (auto pVectorBase = pChild->As<IVectorBase>())
195 {
196 pVectorBase->SetStyle(GetStyle());
197 }
198 });
199
200 auto adjustedStyle = GetStyle().WithDrawFrame(false).WithDrawShadows(false);
201 GetTabSwitchControl()->SetStyle(adjustedStyle.WithWidgetFrac(1.0));
202 GetTabSwitchControl()->SetShape(EVShape::EndsRounded);
203 }
204
205 void OnResize() override
206 {
207 SetTargetRECT(MakeRects(mRECT));
208
209 if (NChildren())
210 {
211 GetTabSwitchControl()->SetTargetAndDrawRECTs(GetTabBarArea());
212
213 ForAllPagesFunc([&](IVTabPage* pPage) {
214 pPage->SetTargetAndDrawRECTs(GetPageArea());
215 });
216 }
217 }
218
219 float GetTabHeight() const { return mTabBarHeight; }
220
221 IRECT GetPageArea() const { return mWidgetBounds.GetReducedFromTop(GetTabHeight()); }
222
223 IRECT GetTabBarArea() const
224 {
225 return mWidgetBounds.GetFromTop(GetTabHeight()).FracRectHorizontal(mTabBarFrac, mTabsAlign == EAlign::Far);
226 }
227
228 int NPages() const { return mPages.GetSize(); }
229
230private:
231 void AddPage(const char* pageName, IVTabPage* pPage)
232 {
233 pPage->SetLabelStr(pageName);
234 mPageNames.push_back(pageName);
235 mPages.Add(pPage);
236 }
237
238 void ForAllPagesFunc(std::function<void(IVTabPage* pControl)> func)
239 {
240 for (int i=0; i<mPages.GetSize(); i++)
241 {
242 func(mPages.Get(i));
243 }
244 }
245
246 IVTabSwitchControl* GetTabSwitchControl() { return GetChild(0)->As<IVTabSwitchControl>(); }
247
248 IVTabPage* GetPage(int pageIdx) { return mPages.Get(pageIdx); }
249
250 void SelectPage(int index)
251 {
252 GetTabSwitchControl()->SetValue(static_cast<double>(index));
253 ShowSelectedPage();
254 }
255
256private:
257 void ShowSelectedPage()
258 {
259 ForAllPagesFunc([&](IVTabPage* pPage) {
260 bool hide = strcmp(GetTabSwitchControl()->GetSelectedLabelStr(),
261 pPage->GetLabelStr());
262 pPage->Hide(hide);
263 });
264
265 if (IBubbleControl* pControl = GetUI()->GetBubbleControl())
266 {
267 pControl->Hide(true);
268 }
269 }
270
271 WDL_PtrList<IVTabPage> mPages;
272 std::vector<const char*> mPageNames;
273 float mTabBarHeight;
274 float mTabBarFrac;
275 EAlign mTabsAlign;
276};
277
278END_IGRAPHICS_NAMESPACE
279END_IPLUG_NAMESPACE
A collection of IControls for common UI widgets, such as knobs, sliders, switches.
A special control to draw contextual info as a slider etc is moved If used in the main IControl stack...
IContainerBase allows a control to nest sub controls and it clips the drawing of those subcontrols In...
Definition: IControl.h:606
void Hide(bool hide) override
Shows or hides the IControl.
Definition: IControl.h:674
The lowest level base class of an IGraphics control.
Definition: IControl.h:49
IGraphics * GetUI()
Definition: IControl.h:467
virtual void Hide(bool hide)
Shows or hides the IControl.
Definition: IControl.cpp:239
void SetTargetRECT(const IRECT &bounds)
Set the rectangular mouse tracking target area, within the graphics context for this control.
Definition: IControl.h:323
T * As()
Helper function to dynamic cast an IControl to a subclass.
Definition: IControl.h:513
virtual void SetValue(double value, int valIdx=0)
Set one of the control's values.
Definition: IControl.cpp:147
void SetTargetAndDrawRECTs(const IRECT &bounds)
Set BOTH the draw rect and the target area, within the graphics context for this control.
Definition: IControl.h:327
The lowest level base class of an IGraphics context.
Definition: IGraphics.h:86
virtual void DrawRoundRect(const IColor &color, const IRECT &bounds, float cornerRadius=5.f, const IBlend *pBlend=0, float thickness=1.f)
Draw a rounded rectangle to the graphics context.
Definition: IGraphics.cpp:2504
IBubbleControl * GetBubbleControl(int i=0)
Definition: IGraphics.h:1422
virtual void FillRoundRect(const IColor &color, const IRECT &bounds, float cornerRadius=5.f, const IBlend *pBlend=0)
Fill a rounded rectangle with a color.
Definition: IGraphics.cpp:2576
A control used as the base class for a tabbed page of subcontrols.
void OnStyleChanged() override
Implement if extra changes are required in response to style changing.
virtual void Draw(IGraphics &g) override
Draw the control to the graphics context.
IVTabPage(TabAttachFunc attachFunc=nullptr, ResizeFunc resizeFunc=DefaultResizeFunc, const IVStyle &style=DEFAULT_STYLE, double padding=kDefaultPadding)
Constructor.
A vector "tab" multi switch control.
Definition: IControls.h:131
A control to manage tabbed pages of sub controls Basic usage example:
void OnResize() override
Called when IControl is constructed or resized using SetRect().
void OnAttached() override
Called after the control has been attached, and its delegate and graphics member variable set.
void Hide(bool hide) override
Shows or hides the IControl.
void OnStyleChanged() override
Implement if extra changes are required in response to style changing.
void Draw(IGraphics &g) override
Draw the control to the graphics context.
A base interface to be combined with IControl for vectorial controls "IVControls",...
Definition: IControl.h:757
IRECT MakeRects(const IRECT &parent, bool hasHandle=false)
Calculate the rectangles for the various areas, depending on the style.
Definition: IControl.h:1158
virtual void SetStyle(const IVStyle &style)
Set the Style of this IVControl.
Definition: IControl.h:825
float GetRoundedCornerRadius(const IRECT &bounds) const
Get the radius of rounded corners for a rectangle, based on the style roundness factor.
Definition: IControl.h:853
void AttachIControl(IControl *pControl, const char *label)
Call in the constructor of your IVControl to link the IVectorBase and IControl.
Definition: IControl.h:775
virtual void DrawLabel(IGraphics &g)
Draw the IVControl label text.
Definition: IControl.h:889
const IColor & GetColor(EVColor color) const
Get value of a specific EVColor in the IVControl.
Definition: IControl.h:801
IVStyle GetStyle() const
Get the style of this IVControl.
Definition: IControl.h:834
Used to manage a rectangular area, independent of draw class/platform.
IRECT GetReducedFromTop(float amount) const
Get a subrect of this IRECT reduced in height from the top edge by 'amount'.
IRECT FracRectHorizontal(float frac, bool rhs=false) const
Returns a new IRECT with a width that is multiplied by frac.
IRECT GetFromTop(float amount) const
Get a subrect of this IRECT bounded in Y by the top edge and 'amount'.
IRECT GetPadded(float padding) const
Get a copy of this IRECT with each value padded by padding N.B.
A struct encapsulating a set of properties used to configure IVControls.