iPlug2 - C++ Audio Plug-in Framework
Loading...
Searching...
No Matches
IGraphicsLiveEdit.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
18#ifndef NDEBUG
19
20#include "IControl.h"
21#include <fstream>
22
23BEGIN_IPLUG_NAMESPACE
24BEGIN_IGRAPHICS_NAMESPACE
25
32{
33public:
34 IGraphicsLiveEdit(bool mouseOversEnabled)
35 : IControl(IRECT())
36 , mMouseOversEnabled(mouseOversEnabled)
37 , mGridSize(10)
38 {
39 mTargetRECT = mRECT;
40 }
41
43 {
44 GetUI()->EnableMouseOver(mMouseOversEnabled); // Set it back to what it was
45 }
46
47 void OnInit() override
48 {
49 GetUI()->EnableMouseOver(true);
50 }
51
52 void OnMouseDown(float x, float y, const IMouseMod& mod) override
53 {
54 int c = GetUI()->GetMouseControlIdx(x, y, true);
55
56 if (c > 0)
57 {
58 IControl* pControl = GetUI()->GetControl(c);
59 mMouseDownRECT = pControl->GetRECT();
60 mMouseDownTargetRECT = pControl->GetTargetRECT();
61
62 if (!mod.S)
63 mSelectedControls.Empty();
64
65 mSelectedControls.Add(pControl);
66
67 if (mod.A)
68 {
69 GetUI()->AttachControl(new PlaceHolder(mMouseDownRECT));
70 mClickedOnControl = GetUI()->NControls() - 1;
71 mMouseClickedOnResizeHandle = false;
72 }
73 else if (mod.R)
74 {
75 mClickedOnControl = c;
76 GetUI()->CreatePopupMenu(*this, mRightClickOnControlMenu, x, y);
77 }
78 else
79 {
80 mClickedOnControl = c;
81
82 if (GetHandleRect(mMouseDownRECT).Contains(x, y))
83 {
84 mMouseClickedOnResizeHandle = true;
85 }
86 }
87 }
88 else if (mod.R)
89 {
90 GetUI()->CreatePopupMenu(*this, mRightClickOutsideControlMenu, x, y);
91 }
92 else
93 {
94 mSelectedControls.Empty();
95 mDragRegion.L = mDragRegion.R = x;
96 mDragRegion.T = mDragRegion.B = y;
97 }
98 }
99
100 void OnMouseUp(float x, float y, const IMouseMod& mod) override
101 {
102 if (mMouseClickedOnResizeHandle)
103 {
104 IControl* pControl = GetUI()->GetControl(mClickedOnControl);
105 IRECT r = pControl->GetRECT();
106 float w = r.R - r.L;
107 float h = r.B - r.T;
108
109 if (w < 0.f || h < 0.f)
110 {
111 pControl->SetRECT(mMouseDownRECT);
112 pControl->SetTargetRECT(mMouseDownTargetRECT);
113 }
114 }
115 mClickedOnControl = -1;
116 mMouseClickedOnResizeHandle = false;
118
119 mDragRegion = IRECT();
120 }
121
122 void OnMouseDblClick(float x, float y, const IMouseMod& mod) override
123 {
124 }
125
126 void OnMouseOver(float x, float y, const IMouseMod& mod) override
127 {
128 int c = GetUI()->GetMouseControlIdx(x, y, true);
129 if (c > 0)
130 {
131 IRECT cr = GetUI()->GetControl(c)->GetRECT();
132 IRECT h = GetHandleRect(cr);
133
134 if (h.Contains(x, y))
135 {
136 GetUI()->SetMouseCursor(ECursor::SIZENWSE);
137 return;
138 }
139 else
140 GetUI()->SetMouseCursor(ECursor::HAND);
141 }
142 else
143 GetUI()->SetMouseCursor(ECursor::ARROW);
144 }
145
146 void OnMouseDrag(float x, float y, float dX, float dY, const IMouseMod& mod) override
147 {
148 float mouseDownX, mouseDownY;
149 GetUI()->GetMouseDownPoint(mouseDownX, mouseDownY);
150
151 if (mClickedOnControl > 0)
152 {
153 IControl* pControl = GetUI()->GetControl(mClickedOnControl);
154
155 if (mMouseClickedOnResizeHandle)
156 {
157 IRECT r = pControl->GetRECT();
158 r.R = SnapToGrid(mMouseDownRECT.R + (x - mouseDownX));
159 r.B = SnapToGrid(mMouseDownRECT.B + (y - mouseDownY));
160
161 if (r.R < mMouseDownRECT.L +mGridSize) r.R = mMouseDownRECT.L+mGridSize;
162 if (r.B < mMouseDownRECT.T +mGridSize) r.B = mMouseDownRECT.T+mGridSize;
163
164 GetUI()->SetControlSize(pControl, r.W(), r.H());
165 }
166 else
167 {
168 const float x1 = SnapToGrid(mMouseDownRECT.L + (x - mouseDownX));
169 const float y1 = SnapToGrid(mMouseDownRECT.T + (y - mouseDownY));
170
171 GetUI()->SetControlPosition(pControl, x1, y1);
172 }
173 }
174 else
175 {
176 float mouseDownX, mouseDownY;
177 GetUI()->GetMouseDownPoint(mouseDownX, mouseDownY);
178 mDragRegion.L = x < mouseDownX ? x : mouseDownX;
179 mDragRegion.R = x < mouseDownX ? mouseDownX : x;
180 mDragRegion.T = y < mouseDownY ? y : mouseDownY;
181 mDragRegion.B = y < mouseDownY ? mouseDownY : y;
182
183 GetUI()->ForStandardControlsFunc([&](IControl* pControl) {
184 if (mDragRegion.Contains(pControl->GetRECT())) {
185 if (mSelectedControls.FindR(pControl) == -1)
186 mSelectedControls.Add(pControl);
187 }
188 else {
189 int idx = mSelectedControls.FindR(pControl);
190 if (idx > -1)
191 mSelectedControls.Delete(idx);
192 }
193 });
194 }
195 }
196
197 bool OnKeyDown(float x, float y, const IKeyPress& key) override
198 {
200
201 if (key.VK == kVK_BACK || key.VK == kVK_DELETE)
202 {
203 if (mSelectedControls.GetSize())
204 {
205 for (int i = 0; i < mSelectedControls.GetSize(); i++)
206 {
207 IControl* pControl = mSelectedControls.Get(i);
208 GetUI()->RemoveControl(pControl);
209 }
210
211 mSelectedControls.Empty();
213
214 return true;
215 }
216 }
217
218 return false;
219 }
220
221 void OnPopupMenuSelection(IPopupMenu* pSelectedMenu, int valIdx) override
222 {
223 if (pSelectedMenu && pSelectedMenu == &mRightClickOutsideControlMenu)
224 {
225 auto idx = pSelectedMenu->GetChosenItemIdx();
226 float x, y;
227 GetUI()->GetMouseDownPoint(x, y);
228 IRECT b = IRECT(x, y, x + 100.f, y + 100.f);
229
230 switch(idx)
231 {
232 case 0:
234 break;
235 default:
236 break;
237 }
238 }
239
240 if (pSelectedMenu && pSelectedMenu == &mRightClickOnControlMenu)
241 {
242 auto idx = pSelectedMenu->GetChosenItemIdx();
243
244 switch (idx)
245 {
246 case 0:
247 mSelectedControls.Empty();
248 GetUI()->RemoveControl(mClickedOnControl);
249 mClickedOnControl = -1;
250 break;
251 default:
252 break;
253 }
254
255 }
256 }
257
258 void Draw(IGraphics& g) override
259 {
260 IBlend b {EBlend::Add, 0.25f};
261 g.DrawGrid(mGridColor, g.GetBounds(), mGridSize, mGridSize, &b);
262
263 for (int i = 1; i < g.NControls(); i++)
264 {
265 IControl* pControl = g.GetControl(i);
266 IRECT cr = pControl->GetRECT();
267
268 if (!pControl->GetParent()) // don't allow reszing sub controls
269 {
270 if (pControl->IsHidden())
271 g.DrawDottedRect(COLOR_RED, cr);
272 else if (pControl->IsDisabled())
273 g.DrawDottedRect(COLOR_GREEN, cr);
274 else
275 g.DrawDottedRect(COLOR_BLUE, cr);
276
277 IRECT h = GetHandleRect(cr);
278 g.FillTriangle(mRectColor, h.L, h.B, h.R, h.B, h.R, h.T);
279 g.DrawTriangle(COLOR_BLACK, h.L, h.B, h.R, h.B, h.R, h.T);
280 }
281 }
282
283 for (int i = 0; i< mSelectedControls.GetSize(); i++)
284 {
285 g.DrawDottedRect(COLOR_WHITE, mSelectedControls.Get(i)->GetRECT());
286 }
287
288 if (!mDragRegion.Empty())
289 {
290 g.DrawDottedRect(COLOR_RED, mDragRegion);
291 }
292 }
293
294 void OnResize() override
295 {
296 mSelectedControls.Empty();
297 mRECT = GetUI()->GetBounds();
298 SetTargetRECT(mRECT);
299 }
300
301 bool IsDirty() override { return true; }
302
303 inline IRECT GetHandleRect(const IRECT& r)
304 {
305 return IRECT(r.R - RESIZE_HANDLE_SIZE, r.B - RESIZE_HANDLE_SIZE, r.R, r.B);
306 }
307
308 inline float SnapToGrid(float input)
309 {
310 if (mGridSize > 1)
311 return (float) std::round(input / (float) mGridSize) * mGridSize;
312 else
313 return input;
314 }
315
316private:
317 IPopupMenu mRightClickOutsideControlMenu {"Outside Control", {"Add Place Holder"}};
318 IPopupMenu mRightClickOnControlMenu{ "On Control", {"Delete Control"} };
319
320 bool mMouseOversEnabled = false;
321 bool mMouseClickedOnResizeHandle = false;
322 bool mMouseIsDragging = false;
323 WDL_String mErrorMessage;
324 WDL_PtrList<IControl> mSelectedControls;
325
326 IColor mGridColor = COLOR_WHITE;
327 IColor mRectColor = COLOR_WHITE;
328 static const int RESIZE_HANDLE_SIZE = 10;
329
330 IRECT mMouseDownRECT;
331 IRECT mMouseDownTargetRECT;
332 IRECT mDragRegion;
333
334 float mGridSize = 10;
335 int mClickedOnControl = -1;
336};
337
338END_IGRAPHICS_NAMESPACE
339END_IPLUG_NAMESPACE
340
341#endif // !NDEBUG
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
IGraphics * GetUI()
Definition: IControl.h:467
bool IsDisabled() const
Definition: IControl.h:362
const IRECT & GetTargetRECT() const
Get the rectangular mouse tracking target area, within the graphics context for this control.
Definition: IControl.h:319
const IRECT & GetRECT() const
Get the rectangular draw area for this control, within the graphics context.
Definition: IControl.h:311
void SetTargetRECT(const IRECT &bounds)
Set the rectangular mouse tracking target area, within the graphics context for this control.
Definition: IControl.h:323
void SetRECT(const IRECT &bounds)
Set the rectangular draw area for this control, within the graphics context.
Definition: IControl.h:315
IContainerBase * GetParent() const
Definition: IControl.h:462
bool IsHidden() const
Definition: IControl.h:355
The lowest level base class of an IGraphics context.
Definition: IGraphics.h:86
void RemoveControl(int idx)
Remove a control at a particular index, (frees memory).
Definition: IGraphics.cpp:167
void CreatePopupMenu(IControl &control, IPopupMenu &menu, const IRECT &bounds, int valIdx=0)
Shows a pop up/contextual menu in relation to a rectangular region of the graphics context.
Definition: IGraphics.cpp:1960
virtual ECursor SetMouseCursor(ECursor cursorType=ECursor::ARROW)
Sets the mouse cursor to one of ECursor (implementations should return the result of the base impleme...
Definition: IGraphics.h:828
virtual void DrawDottedRect(const IColor &color, const IRECT &bounds, const IBlend *pBlend=0, float thickness=1.f, float dashLen=2.f)
Draw a dotted rectangle to the graphics context.
Definition: IGraphics.cpp:2539
void ReleaseMouseCapture()
Used to tell the graphics context to stop tracking mouse interaction with a control.
Definition: IGraphics.cpp:1278
void GetMouseDownPoint(float &x, float &y) const
Get the x, y position of the last mouse down message.
Definition: IGraphics.h:1593
int NControls() const
Definition: IGraphics.h:1437
virtual void FillTriangle(const IColor &color, float x1, float y1, float x2, float y2, float x3, float y3, const IBlend *pBlend=0)
Fill a triangle with a color.
Definition: IGraphics.cpp:2562
virtual void DrawGrid(const IColor &color, const IRECT &bounds, float gridSizeH, float gridSizeV, const IBlend *pBlend=0, float thickness=1.f)
Draw a grid to the graphics context.
Definition: IGraphics.cpp:2424
void SetAllControlsDirty()
Calls SetDirty() on every control.
Definition: IGraphics.cpp:582
void SetControlSize(IControl *pControl, float w, float h)
Resize a control, redrawing the interface correctly.
Definition: IGraphics.cpp:221
IControl * GetControl(int idx)
Get the control at a certain index in the control stack.
Definition: IGraphics.h:1354
void ForStandardControlsFunc(IControlFunction func)
For all standard controls in the main control stack perform a function.
Definition: IGraphics.cpp:534
virtual void DrawTriangle(const IColor &color, float x1, float y1, float x2, float y2, float x3, float y3, const IBlend *pBlend=0, float thickness=1.f)
Draw a triangle to the graphics context.
Definition: IGraphics.cpp:2490
void SetControlPosition(IControl *pControl, float x, float y)
Reposition a control, redrawing the interface correctly.
Definition: IGraphics.cpp:214
void EnableMouseOver(bool enable)
Definition: IGraphics.h:1579
IRECT GetBounds() const
Returns an IRECT that represents the entire UI bounds This is useful for programatically arranging UI...
Definition: IGraphics.h:1194
IControl * AttachControl(IControl *pControl, int ctrlTag=kNoTag, const char *group="")
Attach an IControl to the graphics context and add it to the top of the control stack.
Definition: IGraphics.cpp:301
A control to enable live modification of control layout in an IGraphics context in debug builds This ...
void OnResize() override
Called when IControl is constructed or resized using SetRect().
bool OnKeyDown(float x, float y, const IKeyPress &key) override
Implement this method to respond to a key down event on this control.
void OnMouseOver(float x, float y, const IMouseMod &mod) override
Implement this method to respond to a mouseover event on this control.
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.
void OnPopupMenuSelection(IPopupMenu *pSelectedMenu, int valIdx) override
Implement this method to handle popup menu selection after IGraphics::CreatePopupMenu/IControlPromptU...
void OnInit() override
Called just prior to when the control is attached, after its delegate and graphics member variable se...
void OnMouseUp(float x, float y, const IMouseMod &mod) override
Implement this method to respond to a mouse up event on this control.
void OnMouseDown(float x, float y, const IMouseMod &mod) override
Implement this method to respond to a mouse down event on this control.
void OnMouseDblClick(float x, float y, const IMouseMod &mod) override
Implement this method to respond to a mouse double click event on this control.
void Draw(IGraphics &g) override
Draw the control to the graphics context.
bool IsDirty() override
Called at each display refresh by the IGraphics draw loop, after IControl::Animate(),...
A class for setting the contents of a pop up menu.
A control to use as a placeholder during development.
Definition: IControl.h:2284
Used to manage composite/blend operations, independent of draw class/platform.
Used to manage color data, independent of draw class/platform.
Used for key press info, such as ASCII representation, virtual key (mapped to win32 codes) and modifi...
Definition: IPlugStructs.h:616
Used to manage mouse modifiers i.e.
Used to manage a rectangular area, independent of draw class/platform.
bool Empty() const
float W() const
float H() const
bool Contains(const IRECT &rhs) const
Returns true if this IRECT completely contains rhs.