iPlug2 - C++ Audio Plug-in Framework
Loading...
Searching...
No Matches
IControls.cpp
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
17#include "IControls.h"
18
19using namespace iplug;
20using namespace igraphics;
21
22#pragma mark - VECTOR CONTROLS
23
24const IColor IVKeyboardControl::DEFAULT_BK_COLOR = IColor(255, 70, 70, 70);
25const IColor IVKeyboardControl::DEFAULT_WK_COLOR = IColor(255, 240, 240, 240);
26const IColor IVKeyboardControl::DEFAULT_PK_COLOR = IColor(60, 0, 0, 0);
27const IColor IVKeyboardControl::DEFAULT_FR_COLOR = COLOR_BLACK;
28const IColor IVKeyboardControl::DEFAULT_HK_COLOR = COLOR_ORANGE;
29
30IVLabelControl::IVLabelControl(const IRECT& bounds, const char* label, const IVStyle& style)
31: ITextControl(bounds, label)
32, IVectorBase(style)
33{
34 mText = style.valueText;
35 AttachIControl(this, label);
36}
37
39{
40 DrawBackground(g, mRECT);
41
42 if (mStr.GetLength())
43 {
44 if (mStyle.drawShadows && !IsDisabled())
45 g.DrawText(mStyle.valueText.WithFGColor(GetColor(kSH)), mStr.Get(), mRECT.GetTranslated(mStyle.shadowOffset, mStyle.shadowOffset), &mBlend);
46
47 g.DrawText(mStyle.valueText, mStr.Get(), mRECT, &mBlend);
48 }
49
50 if (mStyle.drawFrame)
51 g.DrawRect(GetColor(kFR), mRECT, &mBlend, mStyle.frameThickness);
52}
53
54IVButtonControl::IVButtonControl(const IRECT& bounds, IActionFunction aF, const char* label, const IVStyle& style, bool labelInButton, bool valueInButton, EVShape shape)
55: IButtonControlBase(bounds, aF)
56, IVectorBase(style, labelInButton, valueInButton)
57{
58 mText = style.valueText;
59 mShape = shape;
60 AttachIControl(this, label);
61}
62
64{
65 DrawBackground(g, mRECT);
66 DrawWidget(g);
67 DrawLabel(g);
68 DrawValue(g, false);
69}
70
72{
73 bool pressed = (bool)GetValue();
74 DrawPressableShape(g, mShape, mWidgetBounds, pressed, mMouseIsOver, IsDisabled());
75}
76
78{
79 SetTargetRECT(MakeRects(mRECT, true));
80 SetDirty(false);
81}
82
83bool IVButtonControl::IsHit(float x, float y) const
84{
85 return mWidgetBounds.Contains(x, y);
86}
87
88IVSwitchControl::IVSwitchControl(const IRECT& bounds, int paramIdx, const char* label, const IVStyle& style, bool valueInButton)
90, IVectorBase(style, false, valueInButton)
91{
92 AttachIControl(this, label);
93 mText = style.valueText;
94
95 if(valueInButton)
96 mText.mVAlign = mStyle.valueText.mVAlign = EVAlign::Middle;
97}
98
99IVSwitchControl::IVSwitchControl(const IRECT& bounds, IActionFunction aF, const char* label, const IVStyle& style, int numStates, bool valueInButton)
100: ISwitchControlBase(bounds, kNoParameter, aF, numStates)
101, IVectorBase(style, false, valueInButton)
102{
103 AttachIControl(this, label);
104 mText = style.valueText;
105
106 if(valueInButton)
107 mText.mVAlign = mStyle.valueText.mVAlign = EVAlign::Middle;
108}
109
111{
112 DrawBackground(g, mRECT);
113 DrawLabel(g);
114 DrawWidget(g);
115 DrawValue(g, false);
116}
117
119{
120 DrawPressableShape(g, mShape, mWidgetBounds, mMouseDown, mMouseIsOver, IsDisabled());
121}
122
123void IVSwitchControl::SetDirty(bool push, int valIdx)
124{
125 IControl::SetDirty(push);
126
127 const IParam* pParam = GetParam();
128
129 if(pParam)
130 pParam->GetDisplay(mValueStr);
131}
132
134{
135 SetTargetRECT(MakeRects(mRECT, true));
136 SetDirty(false);
137}
138
139bool IVSwitchControl::IsHit(float x, float y) const
140{
141 return mWidgetBounds.Contains(x, y);
142}
143
145{
147
148 const IParam* pParam = GetParam();
149
150 if(pParam)
151 {
152 pParam->GetDisplayWithLabel(mValueStr);
153
154 if(!mLabelStr.GetLength())
155 mLabelStr.Set(pParam->GetName());
156 }
157}
158
159IVToggleControl::IVToggleControl(const IRECT& bounds, int paramIdx, const char* label, const IVStyle& style, const char* offText, const char* onText)
160: IVSwitchControl(bounds, paramIdx, label, style, true)
161, mOffText(offText)
162, mOnText(onText)
163{
164 //TODO: assert boolean?
165}
166
167IVToggleControl::IVToggleControl(const IRECT& bounds, IActionFunction aF, const char* label, const IVStyle& style, const char* offText, const char* onText, bool initialState)
168: IVSwitchControl(bounds, aF, label, style, 2, true)
169, mOffText(offText)
170, mOnText(onText)
171{
172 SetValue((double) initialState);
173}
174
176{
177 DrawPressableShape(g, mShape, mWidgetBounds, GetValue() > 0.5, mMouseIsOver, IsDisabled());
178}
179
180void IVToggleControl::DrawValue(IGraphics& g, bool mouseOver)
181{
182 if(mouseOver)
183 g.FillRect(GetColor(kHL), mValueBounds, &mBlend);
184
185 if(GetValue() > 0.5)
186 g.DrawText(mStyle.valueText, mOnText.Get(), mValueBounds, &mBlend);
187 else
188 g.DrawText(mStyle.valueText, mOffText.Get(), mValueBounds, &mBlend);
189}
190
191//TODO: Don't Repeat Yourself!
192IVSlideSwitchControl::IVSlideSwitchControl(const IRECT& bounds, int paramIdx, const char* label, const IVStyle& style, bool valueInButton, EDirection direction)
193: IVSwitchControl(bounds, paramIdx, label, style, valueInButton)
194, mDirection(direction)
195{
196 SetActionFunction([&](IControl* pCaller) {
197 SetAnimation([&](IControl* pCaller) {
198 auto progress = pCaller->GetAnimationProgress();
199
200 mHandleBounds = IRECT::LinearInterpolateBetween(mStartRect, mEndRect, static_cast<float>(progress));
201
202 if(mValueInWidget)
203 mValueBounds = mHandleBounds;
204
205 if(progress > 1.) {
206 pCaller->OnEndAnimation();
207 return;
208 }
209 },
210 DEFAULT_ANIMATION_DURATION);
211 });
212}
213
214IVSlideSwitchControl::IVSlideSwitchControl(const IRECT& bounds, IActionFunction aF, const char* label, const IVStyle& style, bool valueInButton, EDirection direction, int numStates, int initialState)
215: IVSwitchControl(bounds, nullptr, label, style, numStates, valueInButton)
216, mDirection(direction)
217{
218 SetValue((double) initialState);
219
220 SetActionFunction([&](IControl* pCaller) {
221 SetAnimation([&](IControl* pCaller) {
222 auto progress = pCaller->GetAnimationProgress();
223
224 mHandleBounds = IRECT::LinearInterpolateBetween(mStartRect, mEndRect, static_cast<float>(progress));
225
226 if(mValueInWidget)
227 mValueBounds = mHandleBounds;
228
229 if(progress > 1.) {
230 pCaller->OnEndAnimation();
231 return;
232 }
233
234 },
235 DEFAULT_ANIMATION_DURATION);
236 });
237
239}
240
241void IVSlideSwitchControl::UpdateRects()
242{
243 mHandleBounds = mStartRect = mWidgetBounds.SubRect(mDirection, mNumStates, GetSelectedIdx());
244 mEndRect = mWidgetBounds.SubRect(mDirection, mNumStates, (GetSelectedIdx() + 1) % mNumStates);
245
246 if(mValueInWidget)
247 mValueBounds = mHandleBounds;
248}
249
251{
253 UpdateRects();
254}
255
256void IVSlideSwitchControl::OnEndAnimation()
257{
258 UpdateRects();
259
260 IControl::OnEndAnimation();
261}
262
264{
265 DrawBackground(g, mRECT);
266 DrawWidget(g);
267 DrawLabel(g);
268
270 DrawValue(g, false);
271}
272
274{
275 DrawTrack(g, mWidgetBounds);
276 DrawHandle(g, mHandleBounds);
277}
278
279void IVSlideSwitchControl::DrawTrack(IGraphics& g, const IRECT& filledArea)
280{
281 float cR = GetRoundedCornerRadius(mHandleBounds);
282 g.FillRoundRect(GetColor(kSH), mWidgetBounds, cR);
283}
284
285void IVSlideSwitchControl::DrawHandle(IGraphics& g, const IRECT& filledArea)
286{
287 DrawPressableShape(g, mShape, filledArea, mMouseDown, mMouseIsOver, IsDisabled());
288}
289
290void IVSlideSwitchControl::SetDirty(bool push, int valIdx)
291{
292 IVSwitchControl::SetDirty(push, valIdx);
293
295 UpdateRects();
296}
297
298IVTabSwitchControl::IVTabSwitchControl(const IRECT& bounds, int paramIdx, const std::vector<const char*>& options, const char* label, const IVStyle& style, EVShape shape, EDirection direction)
299: ISwitchControlBase(bounds, paramIdx, SplashClickActionFunc, (int) options.size())
300, IVectorBase(style)
301, mDirection(direction)
302{
303 AttachIControl(this, label);
304 mText = style.valueText;
305 mText.mAlign = mStyle.valueText.mAlign = EAlign::Center;
306 mText.mVAlign = mStyle.valueText.mVAlign = EVAlign::Middle;
307 mShape = shape;
308
309 for (auto& option : options)
310 {
311 mTabLabels.Add(new WDL_String(option));
312 }
313}
314
315IVTabSwitchControl::IVTabSwitchControl(const IRECT& bounds, IActionFunction aF, const std::vector<const char*>& options, const char* label, const IVStyle& style, EVShape shape, EDirection direction)
316: ISwitchControlBase(bounds, kNoParameter, aF, static_cast<int>(options.size()))
317, IVectorBase(style)
318, mDirection(direction)
319{
320 AttachIControl(this, label);
321 mText = style.valueText;
322 mText.mAlign = mStyle.valueText.mAlign = EAlign::Center;
323 mText.mVAlign = mStyle.valueText.mVAlign = EVAlign::Middle;
324 mShape = shape;
325
326 for (auto& option : options)
327 {
328 mTabLabels.Add(new WDL_String(option));
329 }
330}
331
333{
335
336 const IParam* pParam = GetParam();
337
338 if(pParam && mTabLabels.GetSize() == 0) // don't add param display text based labels if allready added via ctor
339 {
340 for (int i = 0; i < mNumStates; i++)
341 {
342 mTabLabels.Add(new WDL_String(GetParam()->GetDisplayText(i)));
343 }
344
345 if(!mLabelStr.GetLength())
346 mLabelStr.Set(pParam->GetName());
347 }
348}
349
351{
352 DrawBackground(g, mRECT);
353 DrawLabel(g);
354 DrawWidget(g);
355}
356
357void IVTabSwitchControl::DrawButton(IGraphics& g, const IRECT& r, bool pressed, bool mouseOver, ETabSegment segment, bool disabled)
358{
359 switch (mShape)
360 {
361 case EVShape::EndsRounded:
362 if(mDirection == EDirection::Horizontal)
363 DrawPressableRectangle(g, r, pressed, mouseOver, disabled, segment == ETabSegment::Start, segment == ETabSegment::End, false, false);
364 else
365 DrawPressableRectangle(g, r, pressed, mouseOver, false, disabled, segment == ETabSegment::Start, false, segment == ETabSegment::End);
366 break;
367 case EVShape::AllRounded:
368 if(mDirection == EDirection::Horizontal)
369 DrawPressableRectangle(g, r, pressed, mouseOver, disabled, true, true, false, false);
370 else
371 DrawPressableRectangle(g, r, pressed, mouseOver, disabled, false, true, false, true);
372 break;
373 default:
374 DrawPressableShape(g, mShape, r, pressed, mouseOver, disabled);
375 break;
376 }
377}
378
379void IVTabSwitchControl::DrawButtonText(IGraphics& g, const IRECT& r, bool pressed, bool mouseOver, ETabSegment segment, bool disabled, const char* textStr)
380{
381 if (CStringHasContents(textStr))
382 {
383 g.DrawText(mStyle.valueText, textStr, r, &mBlend);
384 }
385}
386
388{
389 int selected = GetSelectedIdx();
390 ETabSegment segment = ETabSegment::Start;
391
392 for (int i = 0; i < mNumStates; i++)
393 {
394 IRECT r = mButtons.Get()[i];
395
396 if (i > 0)
397 segment = ETabSegment::Mid;
398
399 if (i == mNumStates-1)
400 segment = ETabSegment::End;
401
402 const bool isSelected = i == selected;
403 const bool isMouseOver = mMouseOverButton == i;
404 const bool isDisabled = IsDisabled() || GetStateDisabled(i);
405
406 DrawButton(g, r, isSelected, isMouseOver, segment, isDisabled);
407
408 if (mTabLabels.Get(i))
409 {
410 DrawButtonText(g, r, isSelected, isMouseOver, segment, isDisabled, mTabLabels.Get(i)->Get());
411 }
412 }
413}
414
415int IVTabSwitchControl::GetButtonForPoint(float x, float y) const
416{
417 for (int i = 0; i < mNumStates; i++)
418 {
419 if (mButtons.Get()[i].Contains(x, y))
420 return i;
421 }
422
423 return -1;
424}
425
426bool IVTabSwitchControl::IsHit(float x, float y) const
427{
428 return GetButtonForPoint(x, y) > -1;
429}
430
431void IVTabSwitchControl::OnMouseDown(float x, float y, const IMouseMod& mod)
432{
433 int index = GetButtonForPoint(x, y);
434 if (index > -1)
435 SetValue(((double) index * (1./(double) (mNumStates-1))));
436
437 SetDirty(true);
438}
439
440void IVTabSwitchControl::OnMouseOver(float x, float y, const IMouseMod& mod)
441{
442 mMouseOverButton = GetButtonForPoint(x, y);
443
445
446 SetDirty(false);
447}
448
450{
451 SetTargetRECT(MakeRects(mRECT));
452
453 mButtons.Resize(0);
454
455 for (int i = 0; i < mNumStates; i++)
456 {
457 mButtons.Add(mWidgetBounds.SubRect(mDirection, mNumStates, i));
458 }
459
460 SetDirty(false);
461}
462
464{
465 return mTabLabels.Get(GetSelectedIdx())->Get();
466}
467
468IVRadioButtonControl::IVRadioButtonControl(const IRECT& bounds, int paramIdx, const std::initializer_list<const char*>& options, const char* label, const IVStyle& style, EVShape shape, EDirection direction, float buttonSize)
469: IVTabSwitchControl(bounds, paramIdx, options, label, style, shape, direction)
470, mButtonSize(buttonSize)
471{
472 mButtonAreaWidth = buttonSize * 3.f;
473 mText.mAlign = mStyle.valueText.mAlign = EAlign::Near;
474 mText.mVAlign = mStyle.valueText.mVAlign = EVAlign::Middle;
475}
476
477IVRadioButtonControl::IVRadioButtonControl(const IRECT& bounds, IActionFunction aF, const std::initializer_list<const char*>& options, const char* label, const IVStyle& style, EVShape shape, EDirection direction, float buttonSize)
478: IVTabSwitchControl(bounds, aF, options, label, style, shape, direction)
479, mButtonSize(buttonSize)
480{
481 mButtonAreaWidth = buttonSize * 3.f;
482 mText.mAlign = mStyle.valueText.mAlign = EAlign::Near;
483 mText.mVAlign = mStyle.valueText.mVAlign = EVAlign::Middle;
484}
485
487{
488 int hit = GetSelectedIdx();
489
490 for (int i = 0; i < mNumStates; i++)
491 {
492 IRECT r = mButtons.Get()[i];
493
494 DrawButton(g, r.GetFromLeft(mButtonAreaWidth).GetCentredInside(mButtonSize), i == hit, mMouseOverButton == i, ETabSegment::Mid, IsDisabled() || GetStateDisabled(i));
495
496 if (mTabLabels.Get(i))
497 {
498 r = r.GetFromRight(r.W() - mButtonAreaWidth);
499 g.DrawText(mStyle.valueText.WithFGColor(i == hit ? GetColor(kON) : GetColor(kX1)), mTabLabels.Get(i)->Get(), r, &mBlend);
500 }
501 }
502}
503
505{
506 if (mOnlyButtonsRespondToMouse)
507 {
508 for (int i = 0; i < mNumStates; i++)
509 {
510 if (mButtons.Get()[i].GetFromLeft(mButtonAreaWidth).Contains(x, y))
511 return i;
512 }
513
514 return -1;
515 }
516 else
518}
519
520IVMenuButtonControl::IVMenuButtonControl(const IRECT& bounds, int paramIdx, const char* label, const IVStyle& style, EVShape shape)
521: IContainerBase(bounds, paramIdx)
522, IVectorBase(style)
523{
524 AttachIControl(this, "");
525
526 mText = style.valueText;
527 mDisablePrompt = false;
528
529 SetAttachFunc([&, label, style, shape](IContainerBase* pContainer, const IRECT& bounds) {
530 AddChildControl(mButtonControl = new IVButtonControl(bounds, SplashClickActionFunc, label, style.WithValueText(style.valueText.WithVAlign(EVAlign::Middle)), false, true, shape), kNoTag, GetGroup());
531
532 WDL_String str;
534 mButtonControl->SetValueStr(str.Get());
535
536 mButtonControl->SetAnimationEndActionFunction([&](IControl* pCaller){
537 PromptUserInput(mButtonControl->GetWidgetBounds());
538 });
539 });
540
541 SetResizeFunc([&](IContainerBase* pContainer, const IRECT& bounds) {
542 mButtonControl->SetTargetAndDrawRECTs(bounds);
543 });
544}
545
547{
549 mButtonControl->SetStyle(style.WithValueText(style.valueText.WithVAlign(EVAlign::Middle)));
550}
551
552void IVMenuButtonControl::SetValueFromDelegate(double value, int valIdx)
553{
555 WDL_String str;
557 mButtonControl->SetValueStr(str.Get());
558}
559
561{
562 if (pSelectedMenu)
563 {
564 mButtonControl->SetValueStr(pSelectedMenu->GetChosenItem()->GetText());
565 }
566 IControl::OnPopupMenuSelection(pSelectedMenu, valIdx);
567}
568
569void IVMenuButtonControl::SetValueFromUserInput(double value, int valIdx)
570{
571 if (GetValue(valIdx) != value)
572 {
573 SetValue(value, valIdx);
574 SetDirty(true, valIdx);
575
576 WDL_String val;
578 mButtonControl->SetValueStr(val.Get());
579 }
580}
581
582IVKnobControl::IVKnobControl(const IRECT& bounds, int paramIdx, const char* label, const IVStyle& style, bool valueIsEditable, bool valueInWidget, float a1, float a2, float aAnchor, EDirection direction, double gearing, float trackSize)
583: IKnobControlBase(bounds, paramIdx, direction, gearing)
584, IVectorBase(style, false, valueInWidget)
585, mAngle1(a1)
586, mAngle2(a2)
587, mAnchorAngle(aAnchor)
588{
589 DisablePrompt(!valueIsEditable);
590 mText = style.valueText;
591 mHideCursorOnDrag = mStyle.hideCursor;
592 mShape = EVShape::Ellipse;
593 mTrackSize = trackSize;
594 AttachIControl(this, label);
595}
596
597IVKnobControl::IVKnobControl(const IRECT& bounds, IActionFunction aF, const char* label, const IVStyle& style, bool valueIsEditable, bool valueInWidget, float a1, float a2, float aAnchor, EDirection direction, double gearing, float trackSize)
598: IKnobControlBase(bounds, kNoParameter, direction, gearing)
599, IVectorBase(style, false, valueInWidget)
600, mAngle1(a1)
601, mAngle2(a2)
602, mAnchorAngle(aAnchor)
603{
604 DisablePrompt(!valueIsEditable);
605 mText = style.valueText;
606 mHideCursorOnDrag = mStyle.hideCursor;
607 mShape = EVShape::Ellipse;
608 mTrackSize = trackSize;
610 AttachIControl(this, label);
611}
612
614{
615 DrawBackground(g, mRECT);
616 DrawLabel(g);
617 DrawWidget(g);
618 DrawValue(g, mValueMouseOver);
619}
620
622{
623 IRECT r;
624
625 if (mWidgetBounds.W() > mWidgetBounds.H())
626 r = mWidgetBounds.GetCentredInside(mWidgetBounds.H()/2.f, mWidgetBounds.H());
627 else
628 r = mWidgetBounds.GetCentredInside(mWidgetBounds.W(), mWidgetBounds.W()/2.f);
629
630 return r;
631}
632
633float IVKnobControl::GetRadius() const
634{
635 float widgetRadius;
636
637 if (mWidgetBounds.W() > mWidgetBounds.H())
638 widgetRadius = (mWidgetBounds.H()/2.f);
639 else
640 widgetRadius = (mWidgetBounds.W()/2.f);
641
642 widgetRadius -= (mTrackSize/2.f);
643
644 return widgetRadius;
645}
646
647IRECT IVKnobControl::GetTrackBounds() const
648{
649 return mWidgetBounds.GetCentredInside((GetRadius() + mTrackSize) * 2.f );
650}
651
653{
654 float widgetRadius = GetRadius();// The radius out to the indicator track arc
655 const float cx = mWidgetBounds.MW(), cy = mWidgetBounds.MH();
656 IRECT knobHandleBounds = mWidgetBounds.GetCentredInside((widgetRadius - mTrackToHandleDistance) * 2.f );
657 const float angle = mAngle1 + (static_cast<float>(GetValue()) * (mAngle2 - mAngle1));
658 DrawIndicatorTrack(g, angle, cx, cy, widgetRadius);
659 DrawHandle(g, knobHandleBounds);
660 DrawPointer(g, angle, cx, cy, knobHandleBounds.W() / 2.f);
661}
662
663void IVKnobControl::DrawHandle(IGraphics& g, const IRECT& bounds)
664{
665 DrawPressableShape(g, /*mShape*/ EVShape::Ellipse, bounds, mMouseDown, mMouseIsOver, IsDisabled());
666}
667
668void IVKnobControl::DrawIndicatorTrack(IGraphics& g, float angle, float cx, float cy, float radius)
669{
670 if (mTrackSize > 0.f)
671 {
672 g.DrawArc(GetColor(kX1), cx, cy, radius, angle >= mAnchorAngle ? mAnchorAngle : mAnchorAngle - (mAnchorAngle - angle), angle >= mAnchorAngle ? angle : mAnchorAngle, &mBlend, mTrackSize);
673 }
674}
675
676void IVKnobControl::DrawPointer(IGraphics& g, float angle, float cx, float cy, float radius)
677{
678 g.DrawRadialLine(GetColor(kFR), cx, cy, angle, mInnerPointerFrac * radius, mOuterPointerFrac * radius, &mBlend, mPointerThickness);
679}
680
681void IVKnobControl::OnMouseDown(float x, float y, const IMouseMod& mod)
682{
683 if(mStyle.showValue && mValueBounds.Contains(x, y))
684 {
685 PromptUserInput(mValueBounds);
686 }
687 else
688 {
690 }
691
692 SetDirty(false);
693}
694
695void IVKnobControl::OnMouseDblClick(float x, float y, const IMouseMod& mod)
696{
697 #ifdef AAX_API
698 PromptUserInput(mValueBounds);
699 #else
701 #endif
702}
703
704void IVKnobControl::OnMouseUp(float x, float y, const IMouseMod& mod)
705{
707 SetDirty(true);
708}
709
710void IVKnobControl::OnMouseOver(float x, float y, const IMouseMod& mod)
711{
712 if(mStyle.showValue && !mDisablePrompt)
713 mValueMouseOver = mValueBounds.Contains(x,y);
714
716
717 SetDirty(false);
718}
719
721{
722 SetTargetRECT(MakeRects(mRECT));
723 SetDirty(false);
724}
725
726bool IVKnobControl::IsHit(float x, float y) const
727{
728 if(!mDisablePrompt)
729 {
730 if(mValueBounds.Contains(x,y))
731 return true;
732 }
733
734 return mWidgetBounds.Contains(x, y);
735}
736
737void IVKnobControl::SetDirty(bool push, int valIdx)
738{
740
741 const IParam* pParam = GetParam();
742
743 if(pParam)
744 pParam->GetDisplayWithLabel(mValueStr);
745}
746
748{
749 const IParam* pParam = GetParam();
750
751 if(pParam)
752 {
753 pParam->GetDisplayWithLabel(mValueStr);
754
755 if(!mLabelStr.GetLength())
756 mLabelStr.Set(pParam->GetName());
757 }
758}
759
760IVSliderControl::IVSliderControl(const IRECT& bounds, int paramIdx, const char* label, const IVStyle& style, bool valueIsEditable, EDirection dir, double gearing, float handleSize, float trackSize, bool handleInsideTrack, float handleXOffset, float handleYOffset)
761: ISliderControlBase(bounds, paramIdx, dir, gearing, handleSize)
762, IVectorBase(style)
763, mHandleInsideTrack(handleInsideTrack)
764, mHandleXOffset(handleXOffset)
765, mHandleYOffset(handleYOffset)
766{
767 DisablePrompt(!valueIsEditable);
768 mText = style.valueText;
769 mHideCursorOnDrag = style.hideCursor;
770 mShape = EVShape::Ellipse;
771 mTrackSize = trackSize;
772 AttachIControl(this, label);
773}
774
775IVSliderControl::IVSliderControl(const IRECT& bounds, IActionFunction aF, const char* label, const IVStyle& style, bool valueIsEditable, EDirection dir, double gearing, float handleSize, float trackSize, bool handleInsideTrack, float handleXOffset, float handleYOffset)
776: ISliderControlBase(bounds, aF, dir, gearing, handleSize)
777, IVectorBase(style)
778, mHandleInsideTrack(handleInsideTrack)
779, mHandleXOffset(handleXOffset)
780, mHandleYOffset(handleYOffset)
781{
782 DisablePrompt(!valueIsEditable);
783 mText = style.valueText;
784 mHideCursorOnDrag = style.hideCursor;
785 mShape = EVShape::Ellipse;
786 mTrackSize = trackSize;
787 AttachIControl(this, label);
788}
789
791{
792 DrawBackground(g, mRECT);
793 DrawLabel(g);
794 DrawWidget(g);
795 DrawValue(g, mValueMouseOver);
796}
797
798void IVSliderControl::DrawTrack(IGraphics& g, const IRECT& filledArea)
799{
800 const float extra = mHandleInsideTrack ? mHandleSize : 0.f;
801 const IRECT adjustedTrackBounds = mDirection == EDirection::Vertical ? mTrackBounds.GetVPadded(extra) : mTrackBounds.GetHPadded(extra);
802 const IRECT adjustedFillBounds = mDirection == EDirection::Vertical ? filledArea.GetVPadded(extra) : filledArea.GetHPadded(extra);
803 const float cr = GetRoundedCornerRadius(mTrackBounds);
804
805 g.FillRoundRect(GetColor(kSH), adjustedTrackBounds, cr, &mBlend);
806 g.FillRoundRect(GetColor(kX1), adjustedFillBounds, cr, &mBlend);
807
808 if(mStyle.drawFrame)
809 g.DrawRoundRect(GetColor(kFR), adjustedTrackBounds, cr, &mBlend, mStyle.frameThickness);
810}
811
813{
814 IRECT filledTrack = mTrackBounds.FracRect(mDirection, (float) GetValue());
815
816 if(mTrackSize > 0.f)
817 DrawTrack(g, filledTrack);
818
819 float cx, cy;
820
821 const float offset = (mStyle.drawShadows && mShape != EVShape::Ellipse /* TODO? */) ? mStyle.shadowOffset * 0.5f : 0.f;
822
823 if(mDirection == EDirection::Vertical)
824 {
825 cx = filledTrack.MW() + offset;
826 cy = filledTrack.T;
827 }
828 else
829 {
830 cx = filledTrack.R;
831 cy = filledTrack.MH() + offset;
832 }
833
834 if(mHandleSize > 0.f)
835 {
836 DrawHandle(g, {cx+mHandleXOffset-mHandleSize, cy+mHandleYOffset-mHandleSize, cx+mHandleXOffset+mHandleSize, cy+mHandleYOffset+mHandleSize});
837 }
838}
839
840void IVSliderControl::DrawHandle(IGraphics& g, const IRECT& bounds)
841{
842 DrawPressableShape(g, mShape, bounds, mMouseDown, mMouseIsOver, IsDisabled());
843}
844
845void IVSliderControl::OnMouseDown(float x, float y, const IMouseMod& mod)
846{
847 if(mStyle.showValue && mValueBounds.Contains(x, y))
848 {
849 PromptUserInput(mValueBounds);
850 }
851 else
852 {
854 }
855}
856
857void IVSliderControl::OnMouseDblClick(float x, float y, const IMouseMod& mod)
858{
859 #ifdef AAX_API
860 PromptUserInput(mValueBounds);
861 #else
863 #endif
864}
865
866void IVSliderControl::OnMouseUp(float x, float y, const IMouseMod& mod)
867{
869 SetDirty(true);
870}
871
872void IVSliderControl::OnMouseOver(float x, float y, const IMouseMod& mod)
873{
874 if(mStyle.showValue && !mDisablePrompt)
875 mValueMouseOver = mValueBounds.Contains(x,y);
876
878 SetDirty(false);
879}
880
882{
883 SetTargetRECT(MakeRects(mRECT));
884
885 if(mDirection == EDirection::Vertical)
886 mTrackBounds = mWidgetBounds.GetPadded(-mHandleSize).GetMidHPadded(mTrackSize);
887 else
888 mTrackBounds = mWidgetBounds.GetPadded(-mHandleSize).GetMidVPadded(mTrackSize);
889
890 SetDirty(false);
891}
892
893bool IVSliderControl::IsHit(float x, float y) const
894{
895 if(!mDisablePrompt)
896 {
897 if(mValueBounds.Contains(x,y))
898 {
899 return true;
900 }
901 }
902
903 return mWidgetBounds.Contains(x, y);
904}
905
906void IVSliderControl::SetDirty(bool push, int valIdx)
907{
909
910 const IParam* pParam = GetParam();
911
912 if(pParam)
913 pParam->GetDisplayWithLabel(mValueStr);
914}
915
917{
918 const IParam* pParam = GetParam();
919
920 if(pParam)
921 {
922 if(!mLabelStr.GetLength())
923 mLabelStr.Set(pParam->GetName());
924
925 pParam->GetDisplayWithLabel(mValueStr);
926 }
927}
928
929IVRangeSliderControl::IVRangeSliderControl(const IRECT& bounds, const std::initializer_list<int>& params, const char* label, const IVStyle& style, EDirection dir, bool onlyHandle, float handleSize, float trackSize)
930: IVTrackControlBase(bounds, label, style, params, 0, dir)
931, mHandleSize(handleSize)
932{
933 mTrackSize = trackSize;
934}
935
937{
938 DrawBackground(g, mRECT);
939 DrawLabel(g);
940 DrawWidget(g);
941// DrawValue(g, mValueMouseOver);
942}
943
944void IVRangeSliderControl::MakeTrackRects(const IRECT& bounds)
945{
946 for (int ch = 0; ch < NVals(); ch++)
947 {
948 if(mDirection == EDirection::Vertical)
949 mTrackBounds.Get()[ch] = bounds.GetPadded(-mHandleSize).GetMidHPadded(mTrackSize);
950 else
951 mTrackBounds.Get()[ch] = bounds.GetPadded(-mHandleSize).GetMidVPadded(mTrackSize);
952 }
953}
954
955void IVRangeSliderControl::DrawTrack(IGraphics& g, const IRECT& r, int chIdx)
956{
957 bool thisTrack = mMouseOverHandle == chIdx;
958 float angle = 0.f;
959
960 if(mDirection == EDirection::Horizontal)
961 angle = chIdx % 2 ? 180.f : 0.f;
962 else
963 angle = chIdx % 2 ? 270.f : 90.f;
964
965 DrawPressableTriangle(g, GetHandleBounds(chIdx), thisTrack && mMouseIsDown, thisTrack, angle, IsDisabled());
966}
967
968IRECT IVRangeSliderControl::GetHandleBounds(int trackIdx)
969{
970 IRECT filledTrack = mTrackBounds.Get()[trackIdx].FracRect(mDirection, (float) GetValue(trackIdx));
971 float cx, cy;
972 const float offset = (mStyle.drawShadows && mShape != EVShape::Ellipse /* TODO? */) ? mStyle.shadowOffset * 0.5f : 0.f;
973 if(mDirection == EDirection::Vertical)
974 {
975 cx = filledTrack.MW() + offset;
976 cy = filledTrack.T;
977
978 if(trackIdx % 2)
979 return IRECT(cx+mTrackSize, cy-mHandleSize, cx+(2.f*mHandleSize)+mTrackSize, cy+mHandleSize);
980 else
981 return IRECT(cx-(2.f*mHandleSize), cy-mHandleSize, cx, cy+mHandleSize);
982 }
983 else
984 {
985 cx = filledTrack.R;
986 cy = filledTrack.MH() + offset;
987
988 if(trackIdx % 2)
989 return IRECT(cx-mHandleSize, cy-(2.f*mHandleSize), cx+mHandleSize, cy);
990 else
991 return IRECT(cx-mHandleSize, cy+mTrackSize, cx+mHandleSize, cy+(2.f*mHandleSize)+mTrackSize);
992 }
993}
994
996{
997 IRECT r = mTrackBounds.Get()[0];
998
999 DrawTrackBackground(g, r, 0);
1000
1001 for(int i=0;i<NVals()-1;i++)
1002 {
1003 IRECT filled1 = mTrackBounds.Get()[i].FracRect(mDirection, (float) GetValue(i));
1004 IRECT filled2 = mTrackBounds.Get()[i+1].FracRect(mDirection, (float) GetValue(i+1));
1005
1006 if(mDirection == EDirection::Vertical)
1007 g.FillRect(GetColor(kX1), IRECT(filled1.L, filled1.T < filled2.T ? filled1.T : filled2.T, filled1.R, filled1.T > filled2.T ? filled1.T : filled2.T), &mBlend);
1008 else
1009 g.FillRect(GetColor(kX1), IRECT(filled1.R < filled2.R ? filled1.R : filled2.R, filled1.T, filled1.R > filled2.R ? filled1.R : filled2.R, filled1.B), &mBlend);
1010 }
1011
1012 if(mStyle.drawFrame && mDrawTrackFrame)
1013 g.DrawRect(GetColor(kFR), r, &mBlend, mStyle.frameThickness);
1014
1016}
1017
1018void IVRangeSliderControl::OnMouseOver(float x, float y, const IMouseMod& mod)
1019{
1020 IRECT bounds;
1021 int hitHandle = -1;
1022
1023 for(int i=0;i<NVals();i++)
1024 {
1025 bounds = GetHandleBounds(i);
1026 if(bounds.Contains(x, y))
1027 {
1028 hitHandle = i;
1029 break;
1030 }
1031 }
1032
1033 mMouseOverHandle = hitHandle;
1034
1036 SetDirty(false);
1037}
1038
1039void IVRangeSliderControl::OnMouseDown(float x, float y, const IMouseMod& mod)
1040{
1041 mMouseIsDown = true;
1042 OnMouseDrag(x, y, 0., 0., mod);
1043}
1044
1045void IVRangeSliderControl::OnMouseDrag(float x, float y, float dX, float dY, const IMouseMod& mod)
1046{
1047 if(mMouseOverHandle == -1)
1048 return;
1049
1050 auto minClip = mMouseOverHandle == 0 ? 0. : GetValue(mMouseOverHandle-1);
1051 auto maxClip = mMouseOverHandle == NVals()-1 ? 1. : GetValue(mMouseOverHandle+1);
1052 SnapToMouse(x, y, mDirection, mWidgetBounds, mMouseOverHandle, minClip, maxClip);
1053}
1054
1055
1056IVXYPadControl::IVXYPadControl(const IRECT& bounds, const std::initializer_list<int>& params, const char* label, const IVStyle& style, float handleRadius, bool trackClipsHandle, bool drawCross)
1057: IControl(bounds, params)
1058, IVectorBase(style)
1059, mHandleRadius(handleRadius)
1060, mTrackClipsHandle(trackClipsHandle)
1061, mDrawCross(drawCross)
1062{
1063 mShape = EVShape::Ellipse;
1064 AttachIControl(this, label);
1065}
1066
1068{
1069 DrawBackground(g, mRECT);
1070 DrawLabel(g);
1071
1072 if(mStyle.drawFrame)
1073 g.DrawRect(GetColor(kFR), mWidgetBounds, &mBlend, mStyle.frameThickness);
1074
1075 DrawWidget(g);
1076}
1077
1079{
1080 DrawTrack(g);
1081
1082 const IRECT trackBounds = mWidgetBounds.GetPadded(mTrackClipsHandle ? 0 : -mHandleRadius);
1083
1084 const float xpos = static_cast<float>(GetValue(0)) * trackBounds.W();
1085 const float ypos = static_cast<float>(GetValue(1)) * trackBounds.H();
1086 const IRECT handleBounds = IRECT(trackBounds.L + xpos-mHandleRadius, trackBounds.B - ypos-mHandleRadius, trackBounds.L + xpos+mHandleRadius, trackBounds.B -ypos+mHandleRadius);
1087
1088 DrawHandle(g, trackBounds, handleBounds);
1089}
1090
1091void IVXYPadControl::DrawHandle(IGraphics& g, const IRECT& trackBounds, const IRECT& handleBounds)
1092{
1093 if (mTrackClipsHandle)
1094 g.PathClipRegion(trackBounds.GetPadded(-0.5f * mStyle.frameThickness));
1095
1096 DrawPressableShape(g, mShape, handleBounds, mMouseDown, mMouseIsOver, IsDisabled());
1097}
1098
1099void IVXYPadControl::DrawTrack(IGraphics& g)
1100{
1101 if (mDrawCross)
1102 {
1103 g.DrawVerticalLine(GetColor(kSH), mWidgetBounds, 0.5);
1104 g.DrawHorizontalLine(GetColor(kSH), mWidgetBounds, 0.5);
1105 }
1106}
1107
1108void IVXYPadControl::OnMouseDown(float x, float y, const IMouseMod& mod)
1109{
1110 mMouseDown = true;
1111 if (mStyle.hideCursor)
1112 GetUI()->HideMouseCursor(true, false);
1113
1114 OnMouseDrag(x, y, 0., 0., mod);
1115}
1116
1117void IVXYPadControl::OnMouseUp(float x, float y, const IMouseMod& mod)
1118{
1119 if (mStyle.hideCursor)
1120 GetUI()->HideMouseCursor(false);
1121
1122 mMouseDown = false;
1123 SetDirty(true);
1124}
1125
1126void IVXYPadControl::OnMouseDrag(float x, float y, float dX, float dY, const IMouseMod& mod)
1127{
1128 mRECT.Constrain(x, y);
1129 float xn = (x - mRECT.L) / mRECT.W();
1130 float yn = 1.f - ((y - mRECT.T) / mRECT.H());
1131 SetValue(xn, 0);
1132 SetValue(yn, 1);
1133 SetDirty(true);
1134}
1135
1137{
1138 SetTargetRECT(MakeRects(mRECT));
1139 SetDirty(false);
1140}
1141
1142IVPlotControl::IVPlotControl(const IRECT& bounds, const std::initializer_list<Plot>& plots, int numPoints, const char* label, const IVStyle& style, float min, float max, bool useLayer)
1143: IControl(bounds)
1144, IVectorBase(style)
1145, mMin(min)
1146, mMax(max)
1147, mUseLayer(useLayer)
1148{
1149 mPoints.resize(numPoints);
1150
1151 AttachIControl(this, label);
1152
1153 for(auto plot : plots)
1154 {
1155 AddPlotFunc(plot.color, plot.func);
1156 }
1157}
1158
1160{
1161 DrawBackground(g, mRECT);
1162 DrawLabel(g);
1163
1164 float hdiv = mWidgetBounds.W() / static_cast<float>(mHorizontalDivisions);
1165 float vdiv = mWidgetBounds.H() / static_cast<float>(mVerticalDivisions + 2);
1166
1167 IRECT plotsRECT = mWidgetBounds.GetVPadded(-vdiv);
1168
1169 auto drawFunc = [&](){
1170 g.DrawGrid(GetColor(kSH), mWidgetBounds, hdiv, vdiv, &mBlend);
1171
1172 for (int p=0; p<mPlots.size(); p++)
1173 {
1174 for (int i=0; i<mPoints.size(); i++)
1175 {
1176 auto v = mPlots[p].func((static_cast<float>(i)/static_cast<float>(mPoints.size() - 1)));
1177 v = (v - mMin) / (mMax-mMin);
1178 mPoints[i] = static_cast<float>(v);
1179 }
1180
1181 g.DrawData(mPlots[p].color, plotsRECT, mPoints.data(), static_cast<int>(mPoints.size()), nullptr, &mBlend, mTrackSize);
1182 }
1183
1184 if (mStyle.drawFrame)
1185 g.DrawRect(GetColor(kFR), mWidgetBounds, &mBlend, mStyle.frameThickness);
1186 };
1187
1188 if(mUseLayer)
1189 {
1190 if (!g.CheckLayer(mLayer))
1191 {
1192 g.StartLayer(this, mRECT);
1193 drawFunc();
1194 mLayer = g.EndLayer();
1195 }
1196
1197 g.DrawLayer(mLayer, &mBlend);
1198 }
1199 else
1200 drawFunc();
1201}
1202
1204{
1205 SetTargetRECT(MakeRects(mRECT));
1206 SetDirty(false);
1207}
1208
1209void IVPlotControl::AddPlotFunc(const IColor& color, const IPlotFunc& func)
1210{
1211 mPlots.push_back({color, func});
1212
1213 if(mLayer)
1214 mLayer->Invalidate();
1215 SetDirty(false);
1216}
1217
1218IVGroupControl::IVGroupControl(const IRECT& bounds, const char* label, float labelOffset, const IVStyle& style, IContainerBase::AttachFunc attachFunc, IContainerBase::ResizeFunc resizeFunc)
1219: IContainerBase(bounds, attachFunc, resizeFunc)
1220, IVectorBase(style)
1221, mLabelOffset(labelOffset)
1222{
1223 AttachIControl(this, label);
1224 mIgnoreMouse = true;
1225}
1226
1227IVGroupControl::IVGroupControl(const char* label, const char* groupName, float padL, float padT, float padR, float padB, const IVStyle& style)
1229, IVectorBase(style)
1230, mGroupName(groupName)
1231, mPadL(padL)
1232, mPadT(padT)
1233, mPadR(padR)
1234, mPadB(padB)
1235{
1236 AttachIControl(this, label);
1237 mIgnoreMouse = true;
1238}
1239
1241{
1242 if(mGroupName.GetLength())
1243 {
1244 SetBoundsBasedOnGroup(mGroupName.Get(), mPadL, mPadT, mPadR, mPadB);
1245 }
1246}
1247
1249{
1250// const float cr = GetRoundedCornerRadius(mWidgetBounds);
1251// g.FillRoundRect(GetColor(kBG), mWidgetBounds, cr);
1252// g.FillRect(GetColor(kBG), mLabelBounds);
1253 DrawLabel(g);
1254 DrawWidget(g);
1255}
1256
1258{
1259 const float cr = GetRoundedCornerRadius(mWidgetBounds);
1260 const float ft = mStyle.frameThickness;
1261 const float hft = ft/2.f;
1262
1263 int nPaths = /*mStyle.drawShadows ? 2 :*/ 1;
1264
1265 auto b = mWidgetBounds.GetPadded(/*mStyle.drawShadows ? -mStyle.shadowOffset :*/ 0.f);
1266
1267 auto labelR = mLabelBounds.Empty() ? mRECT.MW() : mLabelBounds.R;
1268 auto labelL = mLabelBounds.Empty() ? mRECT.MW() : mLabelBounds.L;
1269
1270 for(int i=0; i < nPaths; i++)
1271 {
1272 const float offset = i == 0 ? 0.f : mStyle.shadowOffset;
1273 g.PathClear();
1274 g.PathMoveTo(labelR, b.T + hft - offset);
1275 g.PathArc(b.R - cr - hft - offset, b.T + cr + hft - offset, cr, 0.f, 90.f);
1276 g.PathArc(b.R - cr - hft - offset, b.B - cr - hft - offset, cr, 90.f, 180.f);
1277 g.PathArc(b.L + cr + hft - offset, b.B - cr - hft - offset, cr, 180.f, 270.f);
1278 g.PathArc(b.L + cr + hft - offset, b.T + cr + hft - offset, cr, 270.f, 360.f);
1279 g.PathLineTo(labelL, b.T + hft - offset);
1280 g.PathStroke(mStyle.drawShadows ? GetColor(i == 0 ? kSH : kFR) : GetColor(kFR), ft);
1281 }
1282}
1283
1285{
1286 SetTargetRECT(MakeRects(mRECT));
1287 mLabelBounds.HPad(mLabelPadding);
1288 mWidgetBounds.Offset(0, -(mLabelBounds.H()/2.f) - (mStyle.frameThickness/2.f), 0, 0);
1289 const float cr = GetRoundedCornerRadius(mWidgetBounds);
1290 mLabelBounds.Translate(mRECT.L - mLabelBounds.L + mStyle.frameThickness + mLabelOffset + cr, 0.f);
1291 SetDirty(false);
1292}
1293
1294void IVGroupControl::SetBoundsBasedOnGroup(const char* groupName, float padL, float padT, float padR, float padB)
1295{
1296 mGroupName.Set(groupName);
1297
1298 IRECT unionRect;
1299 GetUI()->ForControlInGroup(mGroupName.Get(), [&unionRect](IControl* pControl) { unionRect = unionRect.Union(pControl->GetRECT()); });
1300 float halfLabelHeight = mLabelBounds.H()/2.f;
1301 unionRect.GetVPadded(halfLabelHeight);
1302 mRECT = unionRect.GetPadded(padL, padT, padR, padB);
1303
1304 OnResize();
1305}
1306
1307IVColorSwatchControl::IVColorSwatchControl(const IRECT& bounds, const char* label, ColorChosenFunc func, const IVStyle& style, ECellLayout layout,
1308 const std::initializer_list<EVColor>& colorIDs, const std::initializer_list<const char*>& labelsForIDs)
1309: IControl(bounds)
1310, IVectorBase(style)
1311, mColorChosenFunc(func)
1312, mLayout(layout)
1313, mColorIdForCells(colorIDs)
1314{
1315 assert(colorIDs.size() == labelsForIDs.size());
1316
1317 AttachIControl(this, label);
1318 mCellRects.Resize(static_cast<int>(mColorIdForCells.size()));
1319 mText.mAlign = mStyle.valueText.mAlign = EAlign::Far;
1320
1321 for (int i=0;i<colorIDs.size();i++)
1322 {
1323 mLabels.Add(new WDL_String(labelsForIDs.begin()[i]));
1324 }
1325}
1326
1328{
1329 DrawWidget(g);
1330 DrawLabel(g);
1331}
1332
1334{
1335 for (int i=0; i< mColorIdForCells.size(); i++)
1336 {
1337 WDL_String* pStr = mLabels.Get(i);
1338 IRECT r = mCellRects.Get()[i];
1339 IRECT buttonBounds = r.FracRectHorizontal(pStr->GetLength() ? 0.25f : 1.f, true);
1340 g.FillRect(GetColor(mColorIdForCells[i]), buttonBounds, &mBlend);
1341 g.DrawRect(i == mCellOver ? COLOR_GRAY : COLOR_DARK_GRAY, buttonBounds.GetPadded(0.5f), &mBlend);
1342
1343 if(pStr->GetLength())
1344 g.DrawText(mStyle.valueText, mLabels.Get(i)->Get(), r.FracRectHorizontal(0.7f, false), &mBlend);
1345 }
1346}
1347
1349{
1350 SetTargetRECT(MakeRects(mRECT, true));
1351
1352 int rows = 3;
1353 int columns = 3;
1354
1355 if(mLayout == ECellLayout::kGrid)
1356 {
1357 rows = 3;
1358 columns = 3;
1359 }
1360 else if (mLayout == ECellLayout::kHorizontal)
1361 {
1362 rows = 1;
1363 columns = static_cast<int>(mColorIdForCells.size());
1364 }
1365 else if (mLayout == ECellLayout::kVertical)
1366 {
1367 rows = static_cast<int>(mColorIdForCells.size());
1368 columns = 1;
1369 }
1370
1371 for (int i=0; i< mColorIdForCells.size(); i++)
1372 {
1373 mCellRects.Get()[i] = mWidgetBounds.GetGridCell(i, rows, columns).GetPadded(-2);
1374 }
1375
1376 SetDirty(false);
1377}
1378
1379void IVColorSwatchControl::OnMouseOver(float x, float y, const IMouseMod& mod)
1380{
1381 for (int i=0; i<mColorIdForCells.size(); i++)
1382 {
1383 if(mCellRects.Get()[i].Contains(x, y))
1384 {
1385 mCellOver = i;
1386 SetDirty();
1387 return;
1388 }
1389 }
1390
1391 mCellOver = -1;
1392 SetDirty();
1393}
1394
1396{
1397 mCellOver = -1;
1398 SetDirty();
1399}
1400
1401void IVColorSwatchControl::OnMouseDown(float x, float y, const IMouseMod& mod)
1402{
1403 int cellClicked=-1;
1404
1405 for (int i=0; i<mColorIdForCells.size(); i++)
1406 {
1407 if(mCellRects.Get()[i].Contains(x, y))
1408 {
1409 cellClicked = i;
1410 break;
1411 }
1412 }
1413
1414 if(cellClicked > -1)
1415 {
1416 EVColor vColorClicked = mColorIdForCells[cellClicked];
1417 IColor color = GetColor(vColorClicked);
1418 GetUI()->PromptForColor(color, "Choose a color", [this, cellClicked, vColorClicked](IColor result) {
1419 SetColor(vColorClicked, result);
1420 if(mColorChosenFunc)
1421 mColorChosenFunc(cellClicked, result);
1422 });
1423 }
1424}
1425
1426#pragma mark - SVG CONTROLS
1427
1428ISVGButtonControl::ISVGButtonControl(const IRECT& bounds, IActionFunction aF, const ISVG& offImage, const ISVG& onImage)
1429: IButtonControlBase(bounds, aF)
1430, mOffSVG(offImage)
1431, mOnSVG(onImage)
1432{
1433}
1434
1435
1436ISVGButtonControl::ISVGButtonControl(const IRECT& bounds, IActionFunction aF, const ISVG& image, const std::array<IColor, 4> colors, EColorReplacement colorReplacement)
1437: IButtonControlBase(bounds, aF)
1438, mOffSVG(image)
1439, mOnSVG(image)
1440, mColors(colors)
1441, mColorReplacement(colorReplacement)
1442{
1443}
1444
1446{
1447 IColor* pOnColorFill = nullptr;
1448 IColor* pOffColorFill = nullptr;
1449 IColor* pOnColorStroke = nullptr;
1450 IColor* pOffColorStroke = nullptr;
1451
1452 switch (mColorReplacement) {
1453
1454 case EColorReplacement::None:
1455 break;
1456 case EColorReplacement::Fill:
1457 pOnColorFill = mMouseIsOver ? &mColors[3] : &mColors[1];
1458 pOffColorFill = mMouseIsOver ? &mColors[2] : &mColors[0];
1459 break;
1460 case EColorReplacement::Stroke:
1461 pOnColorStroke = mMouseIsOver ? &mColors[3] : &mColors[1];
1462 pOffColorStroke = mMouseIsOver ? &mColors[2] : &mColors[0];
1463 break;
1464 }
1465
1466 if (GetValue() > 0.5)
1467 g.DrawSVG(mOnSVG, mRECT, &mBlend, pOnColorStroke, pOnColorFill);
1468 else
1469 g.DrawSVG(mOffSVG, mRECT, &mBlend, pOffColorStroke, pOffColorFill);
1470}
1471
1472ISVGToggleControl::ISVGToggleControl(const IRECT& bounds, IActionFunction aF, const ISVG& offImage, const ISVG& onImage)
1473: ISwitchControlBase(bounds, kNoParameter, aF)
1474, mOffSVG(offImage)
1475, mOnSVG(onImage)
1476{
1477}
1478
1479ISVGToggleControl::ISVGToggleControl(const IRECT& bounds, int paramIdx, const ISVG& offImage, const ISVG& onImage)
1480: ISwitchControlBase(bounds, paramIdx)
1481, mOffSVG(offImage)
1482, mOnSVG(onImage)
1483{
1484}
1485
1486ISVGToggleControl::ISVGToggleControl(const IRECT& bounds, IActionFunction aF, const ISVG& image, const std::array<IColor, 4> colors, EColorReplacement colorReplacement)
1487: ISwitchControlBase(bounds, kNoParameter, aF)
1488, mOffSVG(image)
1489, mOnSVG(image)
1490, mColors(colors)
1491, mColorReplacement(colorReplacement)
1492{
1493}
1494
1495ISVGToggleControl::ISVGToggleControl(const IRECT& bounds, int paramIdx, const ISVG& image, const std::array<IColor, 4> colors, EColorReplacement colorReplacement)
1496: ISwitchControlBase(bounds, paramIdx)
1497, mOffSVG(image)
1498, mOnSVG(image)
1499, mColors(colors)
1500, mColorReplacement(colorReplacement)
1501{
1502}
1503
1505{
1506 IColor* pOnColorFill = nullptr;
1507 IColor* pOffColorFill = nullptr;
1508 IColor* pOnColorStroke = nullptr;
1509 IColor* pOffColorStroke = nullptr;
1510
1511 switch (mColorReplacement) {
1512 case EColorReplacement::None:
1513 break;
1514 case EColorReplacement::Fill:
1515 pOnColorFill = mMouseIsOver ? &mColors[3] : &mColors[1];
1516 pOffColorFill = mMouseIsOver ? &mColors[2] : &mColors[0];
1517 break;
1518 case EColorReplacement::Stroke:
1519 pOnColorStroke = mMouseIsOver ? &mColors[3] : &mColors[1];
1520 pOffColorStroke = mMouseIsOver ? &mColors[2] : &mColors[0];
1521 break;
1522 }
1523
1524 if (GetValue() > 0.5)
1525 g.DrawSVG(mOnSVG, mRECT, &mBlend, pOnColorStroke, pOnColorFill);
1526 else
1527 g.DrawSVG(mOffSVG, mRECT, &mBlend, pOffColorStroke, pOffColorFill);
1528}
1529
1530ISVGKnobControl::ISVGKnobControl(const IRECT& bounds, const ISVG& svg, int paramIdx)
1531: IKnobControlBase(bounds, paramIdx)
1532, mSVG(svg)
1533{
1534}
1535
1537{
1538 g.DrawRotatedSVG(mSVG, mRECT.MW(), mRECT.MH(), mRECT.W(), mRECT.H(), mStartAngle + GetValue() * (mEndAngle - mStartAngle), &mBlend);
1539}
1540
1541void ISVGKnobControl::SetSVG(ISVG& svg)
1542{
1543 mSVG = svg;
1544 SetDirty(false);
1545}
1546
1547ISVGSwitchControl::ISVGSwitchControl(const IRECT& bounds, const std::initializer_list<ISVG>& svgs, int paramIdx, IActionFunction aF)
1548: ISwitchControlBase(bounds, paramIdx, aF, static_cast<int>(svgs.size()))
1549, mSVGs(svgs)
1550{
1551}
1552
1554{
1555 g.DrawSVG(mSVGs[GetSelectedIdx()], mRECT, &mBlend);
1556}
1557
1558ISVGSliderControl::ISVGSliderControl(const IRECT& bounds, const ISVG& handleSVG, const ISVG& trackSVG, int paramIdx, EDirection dir, double gearing)
1559: ISliderControlBase(bounds, paramIdx, dir, gearing)
1560, mHandleSVG(handleSVG)
1561, mTrackSVG(trackSVG)
1562{
1563}
1564
1566{
1567 g.DrawSVG(mTrackSVG, mTrackSVGBounds, &mBlend);
1568 g.DrawSVG(mHandleSVG, GetHandleBounds(GetValue()), &mBlend);
1569}
1570
1572{
1573 auto trackAspectRatio = mTrackSVG.W() / mTrackSVG.H();
1574 auto handleAspectRatio = mHandleSVG.W() / mHandleSVG.H();
1575 auto handleOverTrackHeight = mHandleSVG.H() / mTrackSVG.H();
1576
1577 IRECT handleBoundsAtMidPoint;
1578
1579 if (mDirection == EDirection::Vertical)
1580 {
1581 mTrackSVGBounds = mRECT.GetCentredInside(mRECT.H() * trackAspectRatio, mRECT.H());
1582
1583 handleBoundsAtMidPoint = mRECT.GetCentredInside(mRECT.H() * handleAspectRatio * handleOverTrackHeight, mRECT.H() * handleOverTrackHeight);
1584 mHandleBoundsAtMax = { handleBoundsAtMidPoint.L, mTrackSVGBounds.T, handleBoundsAtMidPoint.R, mTrackSVGBounds.T + handleBoundsAtMidPoint.H() };
1585 mTrackBounds = mTrackSVGBounds.GetPadded(0, -handleBoundsAtMidPoint.H(), 0, 0);
1586 }
1587 else
1588 {
1589 mTrackSVGBounds = mRECT.GetCentredInside(mRECT.W(), mRECT.W() / trackAspectRatio);
1590 auto handleHeight = mTrackSVGBounds.H() * handleOverTrackHeight;
1591 handleBoundsAtMidPoint = mRECT.GetCentredInside(handleHeight * handleAspectRatio, handleHeight);
1592 auto halfHeight = handleBoundsAtMidPoint.H() / 2.f;
1593 mHandleBoundsAtMax = { mTrackSVGBounds.R - handleBoundsAtMidPoint.W(), mTrackSVGBounds.MH() - halfHeight, mTrackSVGBounds.R, mTrackSVGBounds.MH() + halfHeight };
1594 mTrackBounds = mTrackSVGBounds.GetPadded(-handleBoundsAtMidPoint.W(), 0, 0, 0);
1595 }
1596
1597 SetDirty(false);
1598}
1599
1600IRECT ISVGSliderControl::GetHandleBounds(double value) const
1601{
1602 if (value < 0.0)
1603 value = GetValue();
1604
1605 IRECT r = mHandleBoundsAtMax;
1606
1607 if (mDirection == EDirection::Vertical)
1608 {
1609 float offs = (1.f - (float) value) * mTrackBounds.H();
1610 r.T += offs;
1611 r.B += offs;
1612 }
1613 else
1614 {
1615 float offs = (1.f - (float) value) * mTrackBounds.W();
1616 r.L -= offs;
1617 r.R -= offs;
1618 }
1619
1620 return r;
1621}
1622
1623#pragma mark - BITMAP CONTROLS
1624
1625IBButtonControl::IBButtonControl(float x, float y, const IBitmap& bitmap, IActionFunction aF)
1626 : IButtonControlBase(IRECT(x, y, bitmap), aF)
1627 , IBitmapBase(bitmap)
1628{
1629 AttachIControl(this);
1630}
1631
1632IBButtonControl::IBButtonControl(const IRECT& bounds, const IBitmap& bitmap, IActionFunction aF)
1633 : IButtonControlBase(bounds.GetCentredInside(bitmap), aF)
1634 , IBitmapBase(bitmap)
1635{
1636 AttachIControl(this);
1637}
1638
1639IBSwitchControl::IBSwitchControl(float x, float y, const IBitmap& bitmap, int paramIdx)
1640: ISwitchControlBase(IRECT(x, y, bitmap), paramIdx)
1641, IBitmapBase(bitmap)
1642{
1643 AttachIControl(this);
1644}
1645
1646IBSwitchControl::IBSwitchControl(const IRECT& bounds, const IBitmap& bitmap, int paramIdx)
1647: ISwitchControlBase(bounds.GetCentredInside(bitmap), paramIdx)
1648, IBitmapBase(bitmap)
1649{
1650 AttachIControl(this);
1651}
1652
1653void IBSwitchControl::OnMouseDown(float x, float y, const IMouseMod& mod)
1654{
1655 if (mBitmap.N() > 1)
1656 SetValue(GetValue() + 1.0 / static_cast<double>(mBitmap.N() - 1));
1657 else
1658 SetValue(GetValue() + 1.0);
1659
1660 if (GetValue() > 1.001)
1661 SetValue(0.);
1662
1663 SetDirty();
1664}
1665
1666IBSliderControl::IBSliderControl(float x, float y, float trackLength, const IBitmap& handleBitmap, const IBitmap& trackBitmap, int paramIdx, EDirection dir, double gearing)
1667: ISliderControlBase(IRECT::MakeXYWH(x, y,
1668 dir == EDirection::Vertical ? handleBitmap.W() : trackLength,
1669 dir == EDirection::Vertical ? trackLength : handleBitmap.H()),
1670 paramIdx, dir, gearing,
1671 float(dir == EDirection::Vertical ? handleBitmap.H() : handleBitmap.W()))
1672, IBitmapBase(handleBitmap)
1673, mTrackBitmap(trackBitmap)
1674{
1675 AttachIControl(this);
1676}
1677
1678IBSliderControl::IBSliderControl(const IRECT& bounds, const IBitmap& handleBitmap, const IBitmap& trackBitmap, int paramIdx, EDirection dir, double gearing)
1679: ISliderControlBase(bounds, paramIdx, dir, gearing, float(dir == EDirection::Vertical ? handleBitmap.H() : handleBitmap.W()))
1680, IBitmapBase(handleBitmap)
1681, mTrackBitmap(trackBitmap)
1682{
1683 AttachIControl(this);
1684}
1685
1687{
1688 if(mTrackBitmap.IsValid())
1689 g.DrawBitmap(mTrackBitmap, mRECT.GetCentredInside(IRECT(0, 0, mTrackBitmap)), 0, 0, &mBlend);
1690
1691 g.DrawBitmap(mBitmap, GetHandleBounds(), 1, &mBlend);
1692}
1693
1694IRECT IBSliderControl::GetHandleBounds(double value) const
1695{
1696 if (value < 0.0)
1697 value = GetValue();
1698
1699 IRECT r(mTrackBounds.L, mTrackBounds.T, mBitmap);
1700
1701 if (mDirection == EDirection::Vertical)
1702 r.Translate(0.f, (1.f - static_cast<float>(value)) * (mTrackBounds.H() - static_cast<float>(mBitmap.H())));
1703 else
1704 r.Translate(static_cast<float>(value) * (mTrackBounds.W() - static_cast<float>(mBitmap.W())), 0.f);
1705
1706 return r;
1707}
1708
1710{
1711 if (mDirection == EDirection::Vertical)
1712 {
1713 if(mTrackBitmap.IsValid())
1714 mTrackBounds = mRECT.GetCentredInside(IRECT(0, 0, mTrackBitmap));
1715 else
1716 {
1717 const float halfWidth = static_cast<float>(mBitmap.W()) / 2.f;
1718 mTrackBounds = mRECT.GetMidHPadded(halfWidth);
1719 }
1720 }
1721 else
1722 {
1723 if(mTrackBitmap.IsValid())
1724 mTrackBounds = mRECT.GetCentredInside(IRECT(0, 0, mTrackBitmap));
1725 else
1726 {
1727 const float halfHeight = static_cast<float>(mBitmap.H()) / 2.f;
1728 mTrackBounds = mRECT.GetMidVPadded(halfHeight);
1729 }
1730 }
1731
1732 SetDirty(false);
1733}
1734
1736{
1737 const double angle = -130.0 + GetValue() * 260.0;
1738 g.DrawRotatedBitmap(mBitmap, mRECT.MW(), mRECT.MH(), angle, &mBlend);
1739}
1740
1741IBTextControl::IBTextControl(const IRECT& bounds, const IBitmap& bitmap, const IText& text, const char* str, int charWidth, int charHeight, int charOffset, bool multiLine, bool vCenter, EBlend blend)
1742: ITextControl(bounds, str, text)
1743, IBitmapBase(bitmap)
1744, mCharWidth(charWidth)
1745, mCharHeight(charHeight)
1746, mCharOffset(charOffset)
1747, mMultiLine(multiLine)
1748, mVCentre(vCenter)
1749{
1750 mBlend = blend;
1751}
1752
1754{
1755 g.DrawBitmapedText(mBitmap, mRECT, mText, &mBlend, mStr.Get(), mVCentre, mMultiLine, mCharWidth, mCharHeight, mCharOffset);
1756}
1757
1758void IBMeterControl::OnMsgFromDelegate(int msgTag, int dataSize, const void* pData)
1759{
1760 if (!IsDisabled() && msgTag == ISender<>::kUpdateMessage)
1761 {
1762 IByteStream stream(pData, dataSize);
1763
1764 int pos = 0;
1766 pos = stream.Get(&d, pos);
1767
1768 if (mResponse == EResponse::Log)
1769 {
1770 auto lowPointAbs = std::fabs(mLowRangeDB);
1771 auto rangeDB = std::fabs(mHighRangeDB - mLowRangeDB);
1772 for (auto c = d.chanOffset; c < (d.chanOffset + d.nChans); c++)
1773 {
1774 auto avg = d.vals[c].second;
1775 auto ampValue = AmpToDB(avg);
1776 auto linearPos = (ampValue + lowPointAbs)/rangeDB;
1777 SetValue(Clip(linearPos, 0., 1.), c);
1778 }
1779 }
1780 else
1781 {
1782 for (auto c = d.chanOffset; c < (d.chanOffset + d.nChans); c++)
1783 {
1784 auto avg = d.vals[c].second;
1785 SetValue(Clip(avg, 0.f, 1.f), c);
1786 }
1787 }
1788
1789 SetDirty(false);
1790 }
1791}
A collection of IControls for common UI widgets, such as knobs, sliders, switches.
void Draw(IGraphics &g) override
Draw the control to the graphics context.
Definition: IControls.cpp:1735
void OnMsgFromDelegate(int msgTag, int dataSize, const void *pData) override
Implement to receive messages sent to the control, see IEditorDelegate:SendControlMsgFromDelegate()
Definition: IControls.cpp:1758
void OnResize() override
Called when IControl is constructed or resized using SetRect().
Definition: IControls.cpp:1709
void Draw(IGraphics &g) override
Draw the control to the graphics context.
Definition: IControls.cpp:1686
IBSwitchControl(float x, float y, const IBitmap &bitmap, int paramIdx=kNoParameter)
Constructs a bitmap switch control.
Definition: IControls.cpp:1639
void OnMouseDown(float x, float y, const IMouseMod &mod) override
Implement this method to respond to a mouse down event on this control.
Definition: IControls.cpp:1653
void Draw(IGraphics &g) override
Draw the control to the graphics context.
Definition: IControls.cpp:1753
A base interface to be combined with IControl for bitmap-based controls "IBControls",...
Definition: IControl.h:724
void AttachIControl(IControl *pControl)
Call in the constructor of your IBControl to link the IBitmapBase and IControl.
Definition: IControl.h:737
User-facing bitmap abstraction that you use to manage bitmap data, independant of draw class/platform...
int W() const
int N() const
int H() const
bool IsValid() const
A base class for buttons/momentary switches - cannot be linked to parameters.
Definition: IControl.h:1868
Manages a non-owned block of memory, for receiving arbitrary message byte streams.
Definition: IPlugStructs.h:268
int Get(T *pDst, int startPos) const
Get arbitary typed data from the stream.
Definition: IPlugStructs.h:289
IContainerBase allows a control to nest sub controls and it clips the drawing of those subcontrols In...
Definition: IControl.h:611
The lowest level base class of an IGraphics control.
Definition: IControl.h:49
const char * GetGroup() const
Get the group that the control belongs to, if any.
Definition: IControl.h:289
IGraphics * GetUI()
Definition: IControl.h:472
bool mMouseIsOver
if mGraphics::mHandleMouseOver = true, this will be true when the mouse is over control.
Definition: IControl.h:565
virtual void OnMouseOver(float x, float y, const IMouseMod &mod)
Implement this method to respond to a mouseover event on this control.
Definition: IControl.cpp:267
virtual void SetValueFromDelegate(double value, int valIdx=0)
Set the control's value from the delegate This method is called from the class implementing the IEdit...
Definition: IControl.cpp:159
virtual void OnPopupMenuSelection(IPopupMenu *pSelectedMenu, int valIdx)
Implement this method to handle popup menu selection after IGraphics::CreatePopupMenu/IControlPromptU...
Definition: IControl.cpp:283
bool IsDisabled() const
Definition: IControl.h:367
void SetTargetRECT(const IRECT &bounds)
Set the rectangular mouse tracking target area, within the graphics context for this control.
Definition: IControl.h:328
double GetAnimationProgress() const
Get the progress in a control's animation, in the range 0-1.
Definition: IControl.cpp:431
void PromptUserInput(int valIdx=0)
Call this method in response to a mouse event to create an edit box so the user can enter a value,...
Definition: IControl.cpp:334
virtual void SnapToMouse(float x, float y, EDirection direction, const IRECT &bounds, int valIdx=-1, double minClip=0., double maxClip=1.)
Set control value based on x, y position within a rectangle.
Definition: IControl.cpp:397
IControl * SetAnimationEndActionFunction(IActionFunction actionFunc)
Set an Action Function to be called at the end of an animation.
Definition: IControl.h:216
virtual void SetValueToDefault(int valIdx=kNoValIdx)
Set one or all of the control's values to the default value of the associated parameter.
Definition: IControl.cpp:183
const IParam * GetParam(int valIdx=0) const
Get a const pointer to the IParam object (owned by the editor delegate class), associated with this c...
Definition: IControl.cpp:122
virtual void SetValue(double value, int valIdx=0)
Set one of the control's values.
Definition: IControl.cpp:147
double GetValue(int valIdx=0) const
Get the control's value.
Definition: IControl.cpp:153
void SetTargetAndDrawRECTs(const IRECT &bounds)
Set BOTH the draw rect and the target area, within the graphics context for this control.
Definition: IControl.h:332
virtual int GetValIdxForPos(float x, float y) const
Check to see which of the control's values relates to this x and y coordinate.
Definition: IControl.h:250
int NVals() const
Definition: IControl.h:244
IAnimationFunction GetAnimationFunction()
Get the control's animation function, if it exists.
Definition: IControl.h:505
virtual void SetDirty(bool triggerAction=true, int valIdx=kNoValIdx)
Mark the control as dirty, i.e.
Definition: IControl.cpp:198
void DisablePrompt(bool disable)
Disable/enable default prompt for user input.
Definition: IControl.h:420
IControl * SetActionFunction(IActionFunction actionFunc)
Set an Action Function for this control.
Definition: IControl.h:211
void SetAnimation(IAnimationFunction func)
Set the animation function.
Definition: IControl.h:497
The lowest level base class of an IGraphics context.
Definition: IGraphics.h:86
virtual void DrawRotatedSVG(const ISVG &svg, float destCentreX, float destCentreY, float width, float height, double angle, const IBlend *pBlend=0)
Draw an SVG image to the graphics context with rotation.
Definition: IGraphics.cpp:2808
virtual void DrawRect(const IColor &color, const IRECT &bounds, const IBlend *pBlend=0, float thickness=1.f)
Draw a rectangle to the graphics context.
Definition: IGraphics.cpp:2508
void DrawBitmapedText(const IBitmap &bitmap, const IRECT &bounds, IText &text, IBlend *pBlend, const char *str, bool vCenter=true, bool multiline=false, int charWidth=6, int charHeight=12, int charOffset=0)
Draws mono spaced bitmap text.
Definition: IGraphics.cpp:722
void DrawText(const IText &text, const char *str, const IRECT &bounds, const IBlend *pBlend=0)
Draw some text to the graphics context in a specific rectangle.
Definition: IGraphics.cpp:678
virtual void PathClear()=0
Clear the stack of path drawing commands.
void DrawRadialLine(const IColor &color, float cx, float cy, float angle, float rMin, float rMax, const IBlend *pBlend=0, float thickness=1.f)
Draw a radial line to the graphics context, useful for pointers on dials.
Definition: IGraphics.cpp:819
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:2515
virtual void DrawRotatedBitmap(const IBitmap &bitmap, float destCentreX, float destCentreY, double angle, const IBlend *pBlend=0)
Draw a bitmap (raster) image to the graphics context with rotation.
Definition: IGraphics.cpp:2410
virtual void PathStroke(const IPattern &pattern, float thickness, const IStrokeOptions &options=IStrokeOptions(), const IBlend *pBlend=0)=0
Stroke the current current path.
bool CheckLayer(const ILayerPtr &layer)
Test to see if a layer needs drawing, for instance if the control's bounds were changed.
Definition: IGraphics.cpp:2043
void DrawLayer(const ILayerPtr &layer, const IBlend *pBlend=nullptr)
Draw a layer to the main IGraphics context.
Definition: IGraphics.cpp:2056
virtual void FillRect(const IColor &color, const IRECT &bounds, const IBlend *pBlend=0)
Fill a rectangular region of the graphics context with a color.
Definition: IGraphics.cpp:2580
virtual bool PromptForColor(IColor &color, const char *str="", IColorPickerHandlerFunc func=nullptr)=0
Create a platform color chooser dialog.
virtual void DrawArc(const IColor &color, float cx, float cy, float r, float a1, float a2, const IBlend *pBlend=0, float thickness=1.f)
Draw an arc to the graphics context.
Definition: IGraphics.cpp:2536
void PathClipRegion(const IRECT r=IRECT())
Clip the current path to a particular region.
Definition: IGraphics.cpp:2776
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:2587
virtual void DrawData(const IColor &color, const IRECT &bounds, float *normYPoints, int nPoints, float *normXPoints=nullptr, const IBlend *pBlend=0, float thickness=1.f, const IColor *pFillColor=nullptr)
Draw a line between a collection of normalized points.
Definition: IGraphics.cpp:2461
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:2435
void DrawVerticalLine(const IColor &color, const IRECT &bounds, float x, const IBlend *pBlend=0, float thickness=1.f)
Draw a vertical line, within a rectangular region of the graphics context.
Definition: IGraphics.cpp:795
virtual void PathMoveTo(float x, float y)=0
Move the current point in the current path.
virtual void PathArc(float cx, float cy, float r, float a1, float a2, EWinding winding=EWinding::CW)=0
Add an arc to the current path.
virtual void HideMouseCursor(bool hide=true, bool lock=true)=0
Call to hide/show the mouse cursor.
void DrawHorizontalLine(const IColor &color, const IRECT &bounds, float y, const IBlend *pBlend=0, float thickness=1.f)
Draw a horizontal line, within a rectangular region of the graphics context.
Definition: IGraphics.cpp:802
void ForControlInGroup(const char *group, IControlFunction func)
For all standard controls in the main control stack that are linked to a group, execute a function.
Definition: IGraphics.cpp:527
virtual void PathLineTo(float x, float y)=0
Add a line to the current path from the current point to the specified location.
void StartLayer(IControl *pOwner, const IRECT &r, bool cacheable=false)
Create an IGraphics layer.
Definition: IGraphics.cpp:1988
virtual void DrawSVG(const ISVG &svg, const IRECT &bounds, const IBlend *pBlend=0, const IColor *pStrokeColor=nullptr, const IColor *pFillColor=nullptr)
Draw an SVG image to the graphics context.
Definition: IGraphics.cpp:2795
ILayerPtr EndLayer()
End an IGraphics layer.
Definition: IGraphics.cpp:2011
virtual void DrawBitmap(const IBitmap &bitmap, const IRECT &bounds, int srcX, int srcY, const IBlend *pBlend=0)=0
Draw a bitmap (raster) image to the graphics context.
A base class for knob/dial controls, to handle mouse action and Sender.
Definition: IControl.h:1373
void OnMouseDown(float x, float y, const IMouseMod &mod) override
Implement this method to respond to a mouse down event on this control.
Definition: IControl.cpp:810
void OnMouseUp(float x, float y, const IMouseMod &mod) override
Implement this method to respond to a mouse up event on this control.
Definition: IControl.cpp:821
IPlug's parameter class.
void GetDisplay(WDL_String &display, bool withDisplayText=true) const
Get the current textual display for the current parameter value.
const char * GetName() const
Returns the parameter's name.
void GetDisplayWithLabel(WDL_String &display, bool withDisplayText=true) const
Fills the WDL_String the value of the parameter along with the label, e.g.
A class for setting the contents of a pop up menu.
void Draw(IGraphics &g) override
Draw the control to the graphics context.
Definition: IControls.cpp:1445
ISVGButtonControl(const IRECT &bounds, IActionFunction aF, const ISVG &offImage, const ISVG &onImage)
Constructs an SVG button control, with an action function.
Definition: IControls.cpp:1428
void Draw(IGraphics &g) override
Draw the control to the graphics context.
Definition: IControls.cpp:1536
void Draw(IGraphics &g) override
Draw the control to the graphics context.
Definition: IControls.cpp:1565
void OnResize() override
Called when IControl is constructed or resized using SetRect().
Definition: IControls.cpp:1571
ISVGSliderControl(const IRECT &bounds, const ISVG &handleSvg, const ISVG &trackSVG, int paramIdx=kNoParameter, EDirection dir=EDirection::Vertical, double gearing=DEFAULT_GEARING)
Constructs an ISVGSliderControl.
Definition: IControls.cpp:1558
void Draw(IGraphics &g) override
Draw the control to the graphics context.
Definition: IControls.cpp:1553
ISVGSwitchControl(const IRECT &bounds, const std::initializer_list< ISVG > &svgs, int paramIdx=kNoParameter, IActionFunction aF=nullptr)
Constructs a SVG switch control.
Definition: IControls.cpp:1547
void Draw(IGraphics &g) override
Draw the control to the graphics context.
Definition: IControls.cpp:1504
ISVGToggleControl(const IRECT &bounds, IActionFunction aF, const ISVG &offImage, const ISVG &onImage)
Constructs an SVG button control, with an action function.
Definition: IControls.cpp:1472
ISender is a utility class which can be used to defer data from the realtime audio processing and sen...
Definition: ISender.h:66
A base class for slider/fader controls, to handle mouse action and Sender.
Definition: IControl.h:1403
void OnMouseDown(float x, float y, const IMouseMod &mod) override
Implement this method to respond to a mouse down event on this control.
Definition: IControl.cpp:906
void OnMouseUp(float x, float y, const IMouseMod &mod) override
Implement this method to respond to a mouse up event on this control.
Definition: IControl.cpp:926
A base class for switch controls.
Definition: IControl.h:1879
void OnInit() override
Called just prior to when the control is attached, after its delegate and graphics member variable se...
Definition: IControl.cpp:765
A basic control to display some text.
Definition: IControl.h:2157
A vector button/momentary switch control.
Definition: IControls.h:54
void Draw(IGraphics &g) override
Draw the control to the graphics context.
Definition: IControls.cpp:63
bool IsHit(float x, float y) const override
Hit test the control.
Definition: IControls.cpp:83
virtual void DrawWidget(IGraphics &g) override
Draw the IVControl main widget (override)
Definition: IControls.cpp:71
IVButtonControl(const IRECT &bounds, IActionFunction aF=SplashClickActionFunc, const char *label="", const IVStyle &style=DEFAULT_STYLE, bool labelInButton=true, bool valueInButton=true, EVShape shape=EVShape::Rectangle)
Constructs a vector button control, with an action function.
Definition: IControls.cpp:54
void OnResize() override
Called when IControl is constructed or resized using SetRect().
Definition: IControls.cpp:77
void OnMouseOut() override
Implement this method to respond to a mouseout event on this control.
Definition: IControls.cpp:1395
void OnResize() override
Called when IControl is constructed or resized using SetRect().
Definition: IControls.cpp:1348
void Draw(IGraphics &g) override
Draw the control to the graphics context.
Definition: IControls.cpp:1327
void OnMouseDown(float x, float y, const IMouseMod &mod) override
Implement this method to respond to a mouse down event on this control.
Definition: IControls.cpp:1401
void DrawWidget(IGraphics &g) override
Draw the IVControl main widget (override)
Definition: IControls.cpp:1333
void OnMouseOver(float x, float y, const IMouseMod &mod) override
Implement this method to respond to a mouseover event on this control.
Definition: IControls.cpp:1379
void Draw(IGraphics &g) override
Draw the control to the graphics context.
Definition: IControls.cpp:1248
void DrawWidget(IGraphics &g) override
Draw the IVControl main widget (override)
Definition: IControls.cpp:1257
void OnInit() override
Called just prior to when the control is attached, after its delegate and graphics member variable se...
Definition: IControls.cpp:1240
IVGroupControl(const IRECT &bounds, const char *label="", float labelOffset=10.f, const IVStyle &style=DEFAULT_STYLE, IContainerBase::AttachFunc attachFunc=nullptr, IContainerBase::ResizeFunc resizeFunc=nullptr)
Construct the group control.
Definition: IControls.cpp:1218
void SetBoundsBasedOnGroup(const char *groupName, float padL, float padT, float padR, float padB)
Set the bounds of the group control based on the area occupied by the controls in a particular group.
Definition: IControls.cpp:1294
void OnResize() override
Called when IControl is constructed or resized using SetRect().
Definition: IControls.cpp:1284
void OnInit() override
Called just prior to when the control is attached, after its delegate and graphics member variable se...
Definition: IControls.cpp:747
void Draw(IGraphics &g) override
Draw the control to the graphics context.
Definition: IControls.cpp:613
void OnMouseOver(float x, float y, const IMouseMod &mod) override
Implement this method to respond to a mouseover event on this control.
Definition: IControls.cpp:710
bool IsHit(float x, float y) const override
Hit test the control.
Definition: IControls.cpp:726
void OnResize() override
Called when IControl is constructed or resized using SetRect().
Definition: IControls.cpp:720
virtual void DrawWidget(IGraphics &g) override
Draw the IVControl main widget (override)
Definition: IControls.cpp:652
void OnMouseDblClick(float x, float y, const IMouseMod &mod) override
Implement this method to respond to a mouse double click event on this control.
Definition: IControls.cpp:695
void OnMouseUp(float x, float y, const IMouseMod &mod) override
Implement this method to respond to a mouse up event on this control.
Definition: IControls.cpp:704
virtual IRECT GetKnobDragBounds() override
Get the area for which mouse deltas will be used to calculate the amount dragging changes the control...
Definition: IControls.cpp:621
void OnMouseDown(float x, float y, const IMouseMod &mod) override
Implement this method to respond to a mouse down event on this control.
Definition: IControls.cpp:681
void SetDirty(bool push, int valIdx=kNoValIdx) override
Mark the control as dirty, i.e.
Definition: IControls.cpp:737
void Draw(IGraphics &g) override
Draw the control to the graphics context.
Definition: IControls.cpp:38
void SetValueFromDelegate(double value, int valIdx=0) override
Set the control's value from the delegate This method is called from the class implementing the IEdit...
Definition: IControls.cpp:552
void SetValueFromUserInput(double value, int valIdx) override
Set the control's value after user input.
Definition: IControls.cpp:569
IVMenuButtonControl(const IRECT &bounds, int paramIdx, const char *label="", const IVStyle &style=DEFAULT_STYLE, EVShape shape=EVShape::Rectangle)
Constructs a vector button control, with an action function.
Definition: IControls.cpp:520
void SetStyle(const IVStyle &style) override
Set the Style of this IVControl.
Definition: IControls.cpp:546
void OnPopupMenuSelection(IPopupMenu *pSelectedMenu, int valIdx) override
Implement this method to handle popup menu selection after IGraphics::CreatePopupMenu/IControlPromptU...
Definition: IControls.cpp:560
void Draw(IGraphics &g) override
Draw the control to the graphics context.
Definition: IControls.cpp:1159
void OnResize() override
Called when IControl is constructed or resized using SetRect().
Definition: IControls.cpp:1203
void AddPlotFunc(const IColor &color, const IPlotFunc &func)
add a new function to the plot
Definition: IControls.cpp:1209
IVPlotControl(const IRECT &bounds, const std::initializer_list< Plot > &funcs, int numPoints, const char *label="", const IVStyle &style=DEFAULT_STYLE, float min=-1., float max=1., bool useLayer=false)
Constructs an IVPlotControl.
Definition: IControls.cpp:1142
std::function< double(double)> IPlotFunc
IVPlotControl passes values between 0 and 1 to this object, that are the plot normalized x values.
Definition: IControls.h:406
int GetButtonForPoint(float x, float y) const override
Definition: IControls.cpp:504
IVRadioButtonControl(const IRECT &bounds, int paramIdx=kNoParameter, const std::initializer_list< const char * > &options={}, const char *label="", const IVStyle &style=DEFAULT_STYLE, EVShape shape=EVShape::Ellipse, EDirection direction=EDirection::Vertical, float buttonSize=10.f)
Constructs a vector radio button control, linked to a parameter.
Definition: IControls.cpp:468
virtual void DrawWidget(IGraphics &g) override
Draw the IVControl main widget (override)
Definition: IControls.cpp:486
void OnMouseOver(float x, float y, const IMouseMod &mod) override
Implement this method to respond to a mouseover event on this control.
Definition: IControls.cpp:1018
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.
Definition: IControls.cpp:1045
void OnMouseDown(float x, float y, const IMouseMod &mod) override
Implement this method to respond to a mouse down event on this control.
Definition: IControls.cpp:1039
void Draw(IGraphics &g) override
Draw the control to the graphics context.
Definition: IControls.cpp:936
void DrawWidget(IGraphics &g) override
Draw the IVControl main widget (override)
Definition: IControls.cpp:995
IVSlideSwitchControl(const IRECT &bounds, int paramIdx=kNoParameter, const char *label="", const IVStyle &style=DEFAULT_STYLE, bool valueInButton=false, EDirection direction=EDirection::Horizontal)
Construct a new IVSlideSwitchControl, with a parameter.
Definition: IControls.cpp:192
virtual void DrawWidget(IGraphics &g) override
Draw the IVControl main widget (override)
Definition: IControls.cpp:273
void SetDirty(bool push, int valIdx=kNoValIdx) override
Mark the control as dirty, i.e.
Definition: IControls.cpp:290
void Draw(IGraphics &g) override
Draw the control to the graphics context.
Definition: IControls.cpp:263
void OnResize() override
Called when IControl is constructed or resized using SetRect().
Definition: IControls.cpp:250
void OnResize() override
Called when IControl is constructed or resized using SetRect().
Definition: IControls.cpp:881
void OnMouseOver(float x, float y, const IMouseMod &mod) override
Implement this method to respond to a mouseover event on this control.
Definition: IControls.cpp:872
void SetDirty(bool push, int valIdx=kNoValIdx) override
Mark the control as dirty, i.e.
Definition: IControls.cpp:906
void OnMouseUp(float x, float y, const IMouseMod &mod) override
Implement this method to respond to a mouse up event on this control.
Definition: IControls.cpp:866
void OnMouseDown(float x, float y, const IMouseMod &mod) override
Implement this method to respond to a mouse down event on this control.
Definition: IControls.cpp:845
void OnMouseDblClick(float x, float y, const IMouseMod &mod) override
Implement this method to respond to a mouse double click event on this control.
Definition: IControls.cpp:857
virtual void DrawWidget(IGraphics &g) override
Draw the IVControl main widget (override)
Definition: IControls.cpp:812
bool IsHit(float x, float y) const override
Hit test the control.
Definition: IControls.cpp:893
void OnInit() override
Called just prior to when the control is attached, after its delegate and graphics member variable se...
Definition: IControls.cpp:916
void Draw(IGraphics &g) override
Draw the control to the graphics context.
Definition: IControls.cpp:790
A vector switch control.
Definition: IControls.h:75
void OnInit() override
Called just prior to when the control is attached, after its delegate and graphics member variable se...
Definition: IControls.cpp:144
bool IsHit(float x, float y) const override
Hit test the control.
Definition: IControls.cpp:139
virtual void DrawWidget(IGraphics &g) override
Draw the IVControl main widget (override)
Definition: IControls.cpp:118
void SetDirty(bool push, int valIdx=kNoValIdx) override
Mark the control as dirty, i.e.
Definition: IControls.cpp:123
void OnResize() override
Called when IControl is constructed or resized using SetRect().
Definition: IControls.cpp:133
void Draw(IGraphics &g) override
Draw the control to the graphics context.
Definition: IControls.cpp:110
A vector "tab" multi switch control.
Definition: IControls.h:148
void OnResize() override
Called when IControl is constructed or resized using SetRect().
Definition: IControls.cpp:449
virtual bool IsHit(float x, float y) const override
Hit test the control.
Definition: IControls.cpp:426
void OnMouseDown(float x, float y, const IMouseMod &mod) override
Implement this method to respond to a mouse down event on this control.
Definition: IControls.cpp:431
virtual void DrawWidget(IGraphics &g) override
Draw the IVControl main widget (override)
Definition: IControls.cpp:387
IVTabSwitchControl(const IRECT &bounds, int paramIdx=kNoParameter, const std::vector< const char * > &options={}, const char *label="", const IVStyle &style=DEFAULT_STYLE, EVShape shape=EVShape::Rectangle, EDirection direction=EDirection::Horizontal)
Constructs a vector tab switch control, linked to a parameter.
Definition: IControls.cpp:298
void Draw(IGraphics &g) override
Draw the control to the graphics context.
Definition: IControls.cpp:350
void OnMouseOver(float x, float y, const IMouseMod &mod) override
Implement this method to respond to a mouseover event on this control.
Definition: IControls.cpp:440
virtual int GetButtonForPoint(float x, float y) const
Definition: IControls.cpp:415
void OnInit() override
Called just prior to when the control is attached, after its delegate and graphics member variable se...
Definition: IControls.cpp:332
const char * GetSelectedLabelStr() const
returns the label string on the selected tab
Definition: IControls.cpp:463
void DrawValue(IGraphics &g, bool mouseOver) override
Draw the IVControl value text.
Definition: IControls.cpp:180
void DrawWidget(IGraphics &g) override
Draw the IVControl main widget (override)
Definition: IControls.cpp:175
A base class for mult-strip/track controls, such as multi-sliders, meters Track refers to the channel...
Definition: IControl.h:1431
void OnMouseOver(float x, float y, const IMouseMod &mod) override
Implement this method to respond to a mouseover event on this control.
Definition: IControl.h:1521
void DrawWidget(IGraphics &g) override
Draw the IVControl main widget (override)
Definition: IControl.h:1556
virtual void DrawBackground(IGraphics &g, const IRECT &r) override
Draw the IVControl background (usually transparent)
Definition: IControl.h:1668
void OnMouseDown(float x, float y, const IMouseMod &mod) override
Implement this method to respond to a mouse down event on this control.
Definition: IControls.cpp:1108
void DrawWidget(IGraphics &g) override
Draw the IVControl main widget (override)
Definition: IControls.cpp:1078
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.
Definition: IControls.cpp:1126
void OnResize() override
Called when IControl is constructed or resized using SetRect().
Definition: IControls.cpp:1136
void Draw(IGraphics &g) override
Draw the control to the graphics context.
Definition: IControls.cpp:1067
void OnMouseUp(float x, float y, const IMouseMod &mod) override
Implement this method to respond to a mouse up event on this control.
Definition: IControls.cpp:1117
A base interface to be combined with IControl for vectorial controls "IVControls",...
Definition: IControl.h:762
virtual void DrawPressableShape(IGraphics &g, EVShape shape, const IRECT &bounds, bool pressed, bool mouseOver, bool disabled)
Call one of the DrawPressableShape methods.
Definition: IControl.h:923
void SetColor(EVColor colorIdx, const IColor &color)
Set one of the IVColors that style the IVControl.
Definition: IControl.h:792
IRECT MakeRects(const IRECT &parent, bool hasHandle=false)
Calculate the rectangles for the various areas, depending on the style.
Definition: IControl.h:1163
virtual void DrawBackground(IGraphics &g, const IRECT &rect)
Draw the IVControl background (usually transparent)
Definition: IControl.h:881
virtual void SetStyle(const IVStyle &style)
Set the Style of this IVControl.
Definition: IControl.h:830
IRECT DrawPressableTriangle(IGraphics &g, const IRECT &bounds, bool pressed, bool mouseOver, float angle, bool disabled)
Draw a triangle-shaped vector button.
Definition: IControl.h:1108
float GetRoundedCornerRadius(const IRECT &bounds) const
Get the radius of rounded corners for a rectangle, based on the style roundness factor.
Definition: IControl.h:858
virtual void DrawValue(IGraphics &g, bool mouseOver)
Draw the IVControl value text.
Definition: IControl.h:904
void AttachIControl(IControl *pControl, const char *label)
Call in the constructor of your IVControl to link the IVectorBase and IControl.
Definition: IControl.h:780
IRECT DrawPressableRectangle(IGraphics &g, const IRECT &bounds, bool pressed, bool mouseOver, bool disabled, bool rtl=true, bool rtr=true, bool rbl=true, bool rbr=true)
Draw a rectangle-shaped vector button.
Definition: IControl.h:1025
virtual void DrawLabel(IGraphics &g)
Draw the IVControl label text.
Definition: IControl.h:894
const IColor & GetColor(EVColor color) const
Get value of a specific EVColor in the IVControl.
Definition: IControl.h:806
void SplashClickActionFunc(IControl *pCaller)
The splash click action function is used by IVControls to start SplashAnimationFunc.
Definition: IControl.cpp:47
BEGIN_IPLUG_NAMESPACE T Clip(T x, T lo, T hi)
Clips the value x between lo and hi.
static double AmpToDB(double amp)
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.
IRECT GetFromRight(float amount) const
Get a subrect of this IRECT bounded in X by 'amount' and the right edge.
IRECT GetCentredInside(const IRECT &sr) const
Get a rectangle the size of sr but with the same center point as this rectangle.
IRECT GetTranslated(float x, float y) const
Get a translated copy of this rectangle.
float MH() const
void Offset(float l, float t, float r, float b)
Offset each field of the rectangle.
IRECT SubRect(EDirection layoutDir, int numSlices, int sliceIdx) const
Get a new rectangle which is a "slice" of this rectangle.
bool Empty() const
IRECT GetGridCell(int row, int col, int nRows, int nColumns) const
Get a subrect (by row, column) of this IRECT which is a cell in a grid of size (nRows * nColumns)
IRECT GetVPadded(float padding) const
Get a copy of this IRECT padded in the Y-axis N.B.
IRECT FracRect(EDirection layoutDir, float frac, bool fromTopOrRight=false) const
Get a new rectangle which is a fraction of this rectangle.
float W() const
static IRECT LinearInterpolateBetween(const IRECT &start, const IRECT &dest, float progress)
Get a rectangle that is a linear interpolation between start and dest
IRECT FracRectHorizontal(float frac, bool rhs=false) const
Returns a new IRECT with a width that is multiplied by frac.
void HPad(float padding)
Pad this IRECT in the X-axis N.B.
void Constrain(float &x, float &y) const
Ensure the point (x,y) is inside this IRECT.
IRECT GetFromLeft(float amount) const
Get a subrect of this IRECT bounded in X by the left edge and 'amount'.
float H() const
void Translate(float x, float y)
Translate this rectangle.
IRECT GetMidHPadded(float padding) const
Get a copy of this IRECT where its width = 2 * padding but the center point on the X-axis has not cha...
float MW() const
bool Contains(const IRECT &rhs) const
Returns true if this IRECT completely contains rhs.
IRECT GetPadded(float padding) const
Get a copy of this IRECT with each value padded by padding N.B.
IRECT GetHPadded(float padding) const
Get a copy of this IRECT padded in the X-axis N.B.
IRECT GetMidVPadded(float padding) const
Get a copy of this IRECT where its height = 2 * padding but the center point on the Y-axis has not ch...
User-facing SVG abstraction that you use to manage SVG data ISVG doesn't actually own the image data.
float H() const
float W() const
ISenderData is used to represent a typed data packet, that may contain values for multiple channels.
Definition: ISender.h:35
IText is used to manage font and text/text entry style for a piece of text on the UI,...
A struct encapsulating a set of properties used to configure IVControls.