iPlug2 - C++ Audio Plug-in Framework
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 
19 using namespace iplug;
20 using namespace igraphics;
21 
22 #pragma mark - VECTOR CONTROLS
23 
24 const IColor IVKeyboardControl::DEFAULT_BK_COLOR = IColor(255, 70, 70, 70);
25 const IColor IVKeyboardControl::DEFAULT_WK_COLOR = IColor(255, 240, 240, 240);
26 const IColor IVKeyboardControl::DEFAULT_PK_COLOR = IColor(60, 0, 0, 0);
27 const IColor IVKeyboardControl::DEFAULT_FR_COLOR = COLOR_BLACK;
28 const IColor IVKeyboardControl::DEFAULT_HK_COLOR = COLOR_ORANGE;
29 
30 IVLabelControl::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 
54 IVButtonControl::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 
83 bool IVButtonControl::IsHit(float x, float y) const
84 {
85  return mWidgetBounds.Contains(x, y);
86 }
87 
88 IVSwitchControl::IVSwitchControl(const IRECT& bounds, int paramIdx, const char* label, const IVStyle& style, bool valueInButton)
89 : ISwitchControlBase(bounds, paramIdx, SplashClickActionFunc)
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 
99 IVSwitchControl::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 
123 void 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 
139 bool 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 
159 IVToggleControl::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 
167 IVToggleControl::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 
180 void 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!
192 IVSlideSwitchControl::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 
214 IVSlideSwitchControl::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 
241 void 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 
256 void IVSlideSwitchControl::OnEndAnimation()
257 {
258  UpdateRects();
259 
260  IControl::OnEndAnimation();
261 }
262 
264 {
265  DrawBackground(g, mRECT);
266  DrawWidget(g);
267  DrawLabel(g);
268 
269  if(!GetAnimationFunction())
270  DrawValue(g, false);
271 }
272 
274 {
275  DrawTrack(g, mWidgetBounds);
276  DrawPressableShape(g, mShape, mHandleBounds, mMouseDown, mMouseIsOver, IsDisabled());
277 }
278 
279 void IVSlideSwitchControl::DrawTrack(IGraphics& g, const IRECT& filledArea)
280 {
281  float cR = GetRoundedCornerRadius(mHandleBounds);
282  g.FillRoundRect(GetColor(kSH), mWidgetBounds, cR);
283 }
284 
285 void IVSlideSwitchControl::SetDirty(bool push, int valIdx)
286 {
287  IVSwitchControl::SetDirty(push, valIdx);
288 
289  if(!GetAnimationFunction())
290  UpdateRects();
291 }
292 
293 IVTabSwitchControl::IVTabSwitchControl(const IRECT& bounds, int paramIdx, const std::initializer_list<const char*>& options, const char* label, const IVStyle& style, EVShape shape, EDirection direction)
294 : ISwitchControlBase(bounds, paramIdx, SplashClickActionFunc, (int) options.size())
295 , IVectorBase(style)
296 , mDirection(direction)
297 {
298  AttachIControl(this, label);
299  mText = style.valueText;
300  mText.mAlign = mStyle.valueText.mAlign = EAlign::Center;
301  mText.mVAlign = mStyle.valueText.mVAlign = EVAlign::Middle;
302  mShape = shape;
303 
304  for (auto& option : options)
305  {
306  mTabLabels.Add(new WDL_String(option));
307  }
308 }
309 
310 IVTabSwitchControl::IVTabSwitchControl(const IRECT& bounds, IActionFunction aF, const std::initializer_list<const char*>& options, const char* label, const IVStyle& style, EVShape shape, EDirection direction)
311 : ISwitchControlBase(bounds, kNoParameter, aF, static_cast<int>(options.size()))
312 , IVectorBase(style)
313 , mDirection(direction)
314 {
315  AttachIControl(this, label);
316  mText = style.valueText;
317  mText.mAlign = mStyle.valueText.mAlign = EAlign::Center;
318  mText.mVAlign = mStyle.valueText.mVAlign = EVAlign::Middle;
319  mShape = shape;
320 
321  for (auto& option : options)
322  {
323  mTabLabels.Add(new WDL_String(option));
324  }
325 }
326 
328 {
330 
331  const IParam* pParam = GetParam();
332 
333  if(pParam && mTabLabels.GetSize() == 0) // don't add param display text based labels if allready added via ctor
334  {
335  for (int i = 0; i < mNumStates; i++)
336  {
337  mTabLabels.Add(new WDL_String(GetParam()->GetDisplayText(i)));
338  }
339 
340  if(!mLabelStr.GetLength())
341  mLabelStr.Set(pParam->GetName());
342  }
343 }
344 
346 {
347  DrawBackground(g, mRECT);
348  DrawLabel(g);
349  DrawWidget(g);
350 }
351 
352 void IVTabSwitchControl::DrawButton(IGraphics& g, const IRECT& r, bool pressed, bool mouseOver, ETabSegment segment, bool disabled)
353 {
354  switch (mShape)
355  {
356  case EVShape::EndsRounded:
357  if(mDirection == EDirection::Horizontal)
358  DrawPressableRectangle(g, r, pressed, mouseOver, disabled, segment == ETabSegment::Start, segment == ETabSegment::End, false, false);
359  else
360  DrawPressableRectangle(g, r, pressed, mouseOver, false, disabled, segment == ETabSegment::Start, false, segment == ETabSegment::End);
361  break;
362  case EVShape::AllRounded:
363  if(mDirection == EDirection::Horizontal)
364  DrawPressableRectangle(g, r, pressed, mouseOver, disabled, true, true, false, false);
365  else
366  DrawPressableRectangle(g, r, pressed, mouseOver, disabled, false, true, false, true);
367  break;
368  default:
369  DrawPressableShape(g, mShape, r, pressed, mouseOver, disabled);
370  break;
371  }
372 }
373 
375 {
376  int selected = GetSelectedIdx();
377  ETabSegment segment = ETabSegment::Start;
378 
379  for (int i = 0; i < mNumStates; i++)
380  {
381  IRECT r = mButtons.Get()[i];
382 
383  if(i > 0)
384  segment = ETabSegment::Mid;
385 
386  if(i == mNumStates-1)
387  segment = ETabSegment::End;
388 
389  DrawButton(g, r, i == selected, mMouseOverButton == i, segment, IsDisabled() || GetStateDisabled(i));
390 
391  if(mTabLabels.Get(i))
392  {
393  g.DrawText(mStyle.valueText, mTabLabels.Get(i)->Get(), r, &mBlend);
394  }
395  }
396 }
397 
398 int IVTabSwitchControl::GetButtonForPoint(float x, float y) const
399 {
400  for (int i = 0; i < mNumStates; i++)
401  {
402  if (mButtons.Get()[i].Contains(x, y))
403  return i;
404  }
405 
406  return -1;
407 }
408 
409 bool IVTabSwitchControl::IsHit(float x, float y) const
410 {
411  return GetButtonForPoint(x, y) > -1;
412 }
413 
414 void IVTabSwitchControl::OnMouseDown(float x, float y, const IMouseMod& mod)
415 {
416  int index = GetButtonForPoint(x, y);
417  if (index > -1)
418  SetValue(((double) index * (1./(double) (mNumStates-1))));
419 
420  SetDirty(true);
421 }
422 
423 void IVTabSwitchControl::OnMouseOver(float x, float y, const IMouseMod& mod)
424 {
425  mMouseOverButton = GetButtonForPoint(x, y);
426 
428 
429  SetDirty(false);
430 }
431 
433 {
434  SetTargetRECT(MakeRects(mRECT));
435 
436  mButtons.Resize(0);
437 
438  for (int i = 0; i < mNumStates; i++)
439  {
440  mButtons.Add(mWidgetBounds.SubRect(mDirection, mNumStates, i));
441  }
442 
443  SetDirty(false);
444 }
445 
447 {
448  return mTabLabels.Get(GetSelectedIdx())->Get();
449 }
450 
451 IVRadioButtonControl::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)
452 : IVTabSwitchControl(bounds, paramIdx, options, label, style, shape, direction)
453 , mButtonSize(buttonSize)
454 {
455  mButtonAreaWidth = buttonSize * 3.f;
456  mText.mAlign = mStyle.valueText.mAlign = EAlign::Near;
457  mText.mVAlign = mStyle.valueText.mVAlign = EVAlign::Middle;
458 }
459 
460 IVRadioButtonControl::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)
461 : IVTabSwitchControl(bounds, aF, options, label, style, shape, direction)
462 , mButtonSize(buttonSize)
463 {
464  mButtonAreaWidth = buttonSize * 3.f;
465  mText.mAlign = mStyle.valueText.mAlign = EAlign::Near;
466  mText.mVAlign = mStyle.valueText.mVAlign = EVAlign::Middle;
467 }
468 
470 {
471  int hit = GetSelectedIdx();
472 
473  for (int i = 0; i < mNumStates; i++)
474  {
475  IRECT r = mButtons.Get()[i];
476 
477  DrawButton(g, r.GetFromLeft(mButtonAreaWidth).GetCentredInside(mButtonSize), i == hit, mMouseOverButton == i, ETabSegment::Mid, IsDisabled() || GetStateDisabled(i));
478 
479  if (mTabLabels.Get(i))
480  {
481  r = r.GetFromRight(r.W() - mButtonAreaWidth);
482  g.DrawText(mStyle.valueText.WithFGColor(i == hit ? GetColor(kON) : GetColor(kX1)), mTabLabels.Get(i)->Get(), r, &mBlend);
483  }
484  }
485 }
486 
487 int IVRadioButtonControl::GetButtonForPoint(float x, float y) const
488 {
489  if (mOnlyButtonsRespondToMouse)
490  {
491  for (int i = 0; i < mNumStates; i++)
492  {
493  if (mButtons.Get()[i].GetFromLeft(mButtonAreaWidth).Contains(x, y))
494  return i;
495  }
496 
497  return -1;
498  }
499  else
501 }
502 
503 IVKnobControl::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)
504 : IKnobControlBase(bounds, paramIdx, direction, gearing)
505 , IVectorBase(style, false, valueInWidget)
506 , mAngle1(a1)
507 , mAngle2(a2)
508 , mAnchorAngle(aAnchor)
509 {
510  DisablePrompt(!valueIsEditable);
511  mText = style.valueText;
512  mHideCursorOnDrag = mStyle.hideCursor;
513  mShape = EVShape::Ellipse;
514  mTrackSize = trackSize;
515  AttachIControl(this, label);
516 }
517 
518 IVKnobControl::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)
519 : IKnobControlBase(bounds, kNoParameter, direction, gearing)
520 , IVectorBase(style, false, valueInWidget)
521 , mAngle1(a1)
522 , mAngle2(a2)
523 , mAnchorAngle(aAnchor)
524 {
525  DisablePrompt(!valueIsEditable);
526  mText = style.valueText;
527  mHideCursorOnDrag = mStyle.hideCursor;
528  mShape = EVShape::Ellipse;
529  mTrackSize = trackSize;
530  SetActionFunction(aF);
531  AttachIControl(this, label);
532 }
533 
535 {
536  DrawBackground(g, mRECT);
537  DrawLabel(g);
538  DrawWidget(g);
539  DrawValue(g, mValueMouseOver);
540 }
541 
543 {
544  IRECT r;
545 
546  if(mWidgetBounds.W() > mWidgetBounds.H())
547  r = mWidgetBounds.GetCentredInside(mWidgetBounds.H()/2.f, mWidgetBounds.H());
548  else
549  r = mWidgetBounds.GetCentredInside(mWidgetBounds.W(), mWidgetBounds.W()/2.f);
550 
551  return r;
552 }
553 
555 {
556  float widgetRadius; // The radius out to the indicator track arc
557 
558  if(mWidgetBounds.W() > mWidgetBounds.H())
559  widgetRadius = (mWidgetBounds.H()/2.f);
560  else
561  widgetRadius = (mWidgetBounds.W()/2.f);
562 
563  const float cx = mWidgetBounds.MW(), cy = mWidgetBounds.MH();
564 
565  widgetRadius -= (mTrackSize/2.f);
566 
567  IRECT knobHandleBounds = mWidgetBounds.GetCentredInside((widgetRadius - mTrackToHandleDistance) * 2.f );
568  const float angle = mAngle1 + (static_cast<float>(GetValue()) * (mAngle2 - mAngle1));
569  DrawIndicatorTrack(g, angle, cx, cy, widgetRadius);
570  DrawPressableShape(g, /*mShape*/ EVShape::Ellipse, knobHandleBounds, mMouseDown, mMouseIsOver, IsDisabled());
571  DrawPointer(g, angle, cx, cy, knobHandleBounds.W() / 2.f);
572 }
573 
574 void IVKnobControl::DrawIndicatorTrack(IGraphics& g, float angle, float cx, float cy, float radius)
575 {
576  if (mTrackSize > 0.f)
577  {
578  g.DrawArc(GetColor(kX1), cx, cy, radius, angle >= mAnchorAngle ? mAnchorAngle : mAnchorAngle - (mAnchorAngle - angle), angle >= mAnchorAngle ? angle : mAnchorAngle, &mBlend, mTrackSize);
579  }
580 }
581 
582 void IVKnobControl::DrawPointer(IGraphics& g, float angle, float cx, float cy, float radius)
583 {
584  g.DrawRadialLine(GetColor(kFR), cx, cy, angle, mInnerPointerFrac * radius, mOuterPointerFrac * radius, &mBlend, mPointerThickness);
585 }
586 
587 void IVKnobControl::OnMouseDown(float x, float y, const IMouseMod& mod)
588 {
589  if(mStyle.showValue && mValueBounds.Contains(x, y))
590  {
591  PromptUserInput(mValueBounds);
592  }
593  else
594  {
596  }
597 
598  SetDirty(false);
599 }
600 
601 void IVKnobControl::OnMouseDblClick(float x, float y, const IMouseMod& mod)
602 {
603  #ifdef AAX_API
604  PromptUserInput(mValueBounds);
605  #else
607  #endif
608 }
609 
610 void IVKnobControl::OnMouseUp(float x, float y, const IMouseMod& mod)
611 {
612  IKnobControlBase::OnMouseUp(x, y, mod);
613  SetDirty(true);
614 }
615 
616 void IVKnobControl::OnMouseOver(float x, float y, const IMouseMod& mod)
617 {
618  if(mStyle.showValue && !mDisablePrompt)
619  mValueMouseOver = mValueBounds.Contains(x,y);
620 
622 
623  SetDirty(false);
624 }
625 
627 {
628  SetTargetRECT(MakeRects(mRECT));
629  SetDirty(false);
630 }
631 
632 bool IVKnobControl::IsHit(float x, float y) const
633 {
634  if(!mDisablePrompt)
635  {
636  if(mValueBounds.Contains(x,y))
637  return true;
638  }
639 
640  return mWidgetBounds.Contains(x, y);
641 }
642 
643 void IVKnobControl::SetDirty(bool push, int valIdx)
644 {
646 
647  const IParam* pParam = GetParam();
648 
649  if(pParam)
650  pParam->GetDisplayWithLabel(mValueStr);
651 }
652 
654 {
655  const IParam* pParam = GetParam();
656 
657  if(pParam)
658  {
659  pParam->GetDisplayWithLabel(mValueStr);
660 
661  if(!mLabelStr.GetLength())
662  mLabelStr.Set(pParam->GetName());
663  }
664 }
665 
666 IVSliderControl::IVSliderControl(const IRECT& bounds, int paramIdx, const char* label, const IVStyle& style, bool valueIsEditable, EDirection dir, double gearing, float handleSize, float trackSize, bool handleInsideTrack)
667 : ISliderControlBase(bounds, paramIdx, dir, gearing, handleSize)
668 , IVectorBase(style)
669 , mHandleInsideTrack(handleInsideTrack)
670 {
671  DisablePrompt(!valueIsEditable);
672  mText = style.valueText;
673  mHideCursorOnDrag = style.hideCursor;
674  mShape = EVShape::Ellipse;
675  mTrackSize = trackSize;
676  AttachIControl(this, label);
677 }
678 
679 IVSliderControl::IVSliderControl(const IRECT& bounds, IActionFunction aF, const char* label, const IVStyle& style, bool valueIsEditable, EDirection dir, double gearing, float handleSize, float trackSize, bool handleInsideTrack)
680 : ISliderControlBase(bounds, aF, dir, gearing, handleSize)
681 , IVectorBase(style)
682 , mHandleInsideTrack(handleInsideTrack)
683 {
684  DisablePrompt(!valueIsEditable);
685  mText = style.valueText;
686  mHideCursorOnDrag = style.hideCursor;
687  mShape = EVShape::Ellipse;
688  mTrackSize = trackSize;
689  AttachIControl(this, label);
690 }
691 
693 {
694  DrawBackground(g, mRECT);
695  DrawLabel(g);
696  DrawWidget(g);
697  DrawValue(g, mValueMouseOver);
698 }
699 
700 void IVSliderControl::DrawTrack(IGraphics& g, const IRECT& filledArea)
701 {
702  const float extra = mHandleInsideTrack ? mHandleSize : 0.f;
703  const IRECT adjustedTrackBounds = mDirection == EDirection::Vertical ? mTrackBounds.GetVPadded(extra) : mTrackBounds.GetHPadded(extra);
704  const IRECT adjustedFillBounds = mDirection == EDirection::Vertical ? filledArea.GetVPadded(extra) : filledArea.GetHPadded(extra);
705  const float cr = GetRoundedCornerRadius(mTrackBounds);
706 
707  g.FillRoundRect(GetColor(kSH), adjustedTrackBounds, cr, &mBlend);
708  g.FillRoundRect(GetColor(kX1), adjustedFillBounds, cr, &mBlend);
709 
710  if(mStyle.drawFrame)
711  g.DrawRoundRect(GetColor(kFR), adjustedTrackBounds, cr, &mBlend, mStyle.frameThickness);
712 }
713 
715 {
716  IRECT filledTrack = mTrackBounds.FracRect(mDirection, (float) GetValue());
717 
718  if(mTrackSize > 0.f)
719  DrawTrack(g, filledTrack);
720 
721  float cx, cy;
722 
723  const float offset = (mStyle.drawShadows && mShape != EVShape::Ellipse /* TODO? */) ? mStyle.shadowOffset * 0.5f : 0.f;
724 
725  if(mDirection == EDirection::Vertical)
726  {
727  cx = filledTrack.MW() + offset;
728  cy = filledTrack.T;
729  }
730  else
731  {
732  cx = filledTrack.R;
733  cy = filledTrack.MH() + offset;
734  }
735 
736  if(mHandleSize > 0.f)
737  {
738  DrawHandle(g, {cx-mHandleSize, cy-mHandleSize, cx+mHandleSize, cy+mHandleSize});
739  }
740 }
741 
742 void IVSliderControl::DrawHandle(IGraphics& g, const IRECT& bounds)
743 {
744  DrawPressableShape(g, mShape, bounds, mMouseDown, mMouseIsOver, IsDisabled());
745 }
746 
747 void IVSliderControl::OnMouseDown(float x, float y, const IMouseMod& mod)
748 {
749  if(mStyle.showValue && mValueBounds.Contains(x, y))
750  {
751  PromptUserInput(mValueBounds);
752  }
753  else
754  {
756  }
757 }
758 
759 void IVSliderControl::OnMouseDblClick(float x, float y, const IMouseMod& mod)
760 {
761  #ifdef AAX_API
762  PromptUserInput(mValueBounds);
763  #else
765  #endif
766 }
767 
768 void IVSliderControl::OnMouseUp(float x, float y, const IMouseMod& mod)
769 {
771  SetDirty(true);
772 }
773 
774 void IVSliderControl::OnMouseOver(float x, float y, const IMouseMod& mod)
775 {
776  if(mStyle.showValue && !mDisablePrompt)
777  mValueMouseOver = mValueBounds.Contains(x,y);
778 
780  SetDirty(false);
781 }
782 
784 {
785  SetTargetRECT(MakeRects(mRECT));
786 
787  if(mDirection == EDirection::Vertical)
788  mTrackBounds = mWidgetBounds.GetPadded(-mHandleSize).GetMidHPadded(mTrackSize);
789  else
790  mTrackBounds = mWidgetBounds.GetPadded(-mHandleSize).GetMidVPadded(mTrackSize);
791 
792  SetDirty(false);
793 }
794 
795 bool IVSliderControl::IsHit(float x, float y) const
796 {
797  if(!mDisablePrompt)
798  {
799  if(mValueBounds.Contains(x,y))
800  {
801  return true;
802  }
803  }
804 
805  return mWidgetBounds.Contains(x, y);
806 }
807 
808 void IVSliderControl::SetDirty(bool push, int valIdx)
809 {
811 
812  const IParam* pParam = GetParam();
813 
814  if(pParam)
815  pParam->GetDisplayWithLabel(mValueStr);
816 }
817 
819 {
820  const IParam* pParam = GetParam();
821 
822  if(pParam)
823  {
824  if(!mLabelStr.GetLength())
825  mLabelStr.Set(pParam->GetName());
826 
827  pParam->GetDisplayWithLabel(mValueStr);
828  }
829 }
830 
831 IVRangeSliderControl::IVRangeSliderControl(const IRECT& bounds, const std::initializer_list<int>& params, const char* label, const IVStyle& style, EDirection dir, bool onlyHandle, float handleSize, float trackSize)
832 : IVTrackControlBase(bounds, label, style, params, 0, dir)
833 , mHandleSize(handleSize)
834 {
835  mTrackSize = trackSize;
836 }
837 
839 {
840  DrawBackground(g, mRECT);
841  DrawLabel(g);
842  DrawWidget(g);
843 // DrawValue(g, mValueMouseOver);
844 }
845 
846 void IVRangeSliderControl::MakeTrackRects(const IRECT& bounds)
847 {
848  for (int ch = 0; ch < NVals(); ch++)
849  {
850  if(mDirection == EDirection::Vertical)
851  mTrackBounds.Get()[ch] = bounds.GetPadded(-mHandleSize).GetMidHPadded(mTrackSize);
852  else
853  mTrackBounds.Get()[ch] = bounds.GetPadded(-mHandleSize).GetMidVPadded(mTrackSize);
854  }
855 }
856 
857 void IVRangeSliderControl::DrawTrack(IGraphics& g, const IRECT& r, int chIdx)
858 {
859  bool thisTrack = mMouseOverHandle == chIdx;
860  float angle = 0.f;
861 
862  if(mDirection == EDirection::Horizontal)
863  angle = chIdx % 2 ? 180.f : 0.f;
864  else
865  angle = chIdx % 2 ? 270.f : 90.f;
866 
867  DrawPressableTriangle(g, GetHandleBounds(chIdx), thisTrack && mMouseIsDown, thisTrack, angle, IsDisabled());
868 }
869 
870 IRECT IVRangeSliderControl::GetHandleBounds(int trackIdx)
871 {
872  IRECT filledTrack = mTrackBounds.Get()[trackIdx].FracRect(mDirection, (float) GetValue(trackIdx));
873  float cx, cy;
874  const float offset = (mStyle.drawShadows && mShape != EVShape::Ellipse /* TODO? */) ? mStyle.shadowOffset * 0.5f : 0.f;
875  if(mDirection == EDirection::Vertical)
876  {
877  cx = filledTrack.MW() + offset;
878  cy = filledTrack.T;
879 
880  if(trackIdx % 2)
881  return IRECT(cx+mTrackSize, cy-mHandleSize, cx+(2.f*mHandleSize)+mTrackSize, cy+mHandleSize);
882  else
883  return IRECT(cx-(2.f*mHandleSize), cy-mHandleSize, cx, cy+mHandleSize);
884  }
885  else
886  {
887  cx = filledTrack.R;
888  cy = filledTrack.MH() + offset;
889 
890  if(trackIdx % 2)
891  return IRECT(cx-mHandleSize, cy-(2.f*mHandleSize), cx+mHandleSize, cy);
892  else
893  return IRECT(cx-mHandleSize, cy+mTrackSize, cx+mHandleSize, cy+(2.f*mHandleSize)+mTrackSize);
894  }
895 }
896 
898 {
899  IRECT r = mTrackBounds.Get()[0];
900 
901  DrawTrackBackground(g, r, 0);
902 
903  for(int i=0;i<NVals()-1;i++)
904  {
905  IRECT filled1 = mTrackBounds.Get()[i].FracRect(mDirection, (float) GetValue(i));
906  IRECT filled2 = mTrackBounds.Get()[i+1].FracRect(mDirection, (float) GetValue(i+1));
907 
908  if(mDirection == EDirection::Vertical)
909  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);
910  else
911  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);
912  }
913 
914  if(mStyle.drawFrame && mDrawTrackFrame)
915  g.DrawRect(GetColor(kFR), r, &mBlend, mStyle.frameThickness);
916 
918 }
919 
920 void IVRangeSliderControl::OnMouseOver(float x, float y, const IMouseMod& mod)
921 {
922  IRECT bounds;
923  int hitHandle = -1;
924 
925  for(int i=0;i<NVals();i++)
926  {
927  bounds = GetHandleBounds(i);
928  if(bounds.Contains(x, y))
929  {
930  hitHandle = i;
931  break;
932  }
933  }
934 
935  mMouseOverHandle = hitHandle;
936 
938  SetDirty(false);
939 }
940 
941 void IVRangeSliderControl::OnMouseDown(float x, float y, const IMouseMod& mod)
942 {
943  mMouseIsDown = true;
944  OnMouseDrag(x, y, 0., 0., mod);
945 }
946 
947 void IVRangeSliderControl::OnMouseDrag(float x, float y, float dX, float dY, const IMouseMod& mod)
948 {
949  if(mMouseOverHandle == -1)
950  return;
951 
952  auto minClip = mMouseOverHandle == 0 ? 0. : GetValue(mMouseOverHandle-1);
953  auto maxClip = mMouseOverHandle == NVals()-1 ? 1. : GetValue(mMouseOverHandle+1);
954  SnapToMouse(x, y, mDirection, mWidgetBounds, mMouseOverHandle, minClip, maxClip);
955 }
956 
957 IVXYPadControl::IVXYPadControl(const IRECT& bounds, const std::initializer_list<int>& params, const char* label, const IVStyle& style, float handleRadius)
958 : IControl(bounds, params)
959 , IVectorBase(style)
960 , mHandleRadius(handleRadius)
961 {
962  mShape = EVShape::Ellipse;
963  AttachIControl(this, label);
964 }
965 
967 {
968  DrawBackground(g, mRECT);
969  DrawLabel(g);
970 
971  if(mStyle.drawFrame)
972  g.DrawRect(GetColor(kFR), mWidgetBounds, &mBlend, mStyle.frameThickness);
973 
974  DrawWidget(g);
975 }
976 
978 {
979  DrawTrack(g);
980 
981  const IRECT trackBounds = mWidgetBounds.GetPadded(mTrackClipsHandle ? 0 : -mHandleRadius);
982 
983  const float xpos = static_cast<float>(GetValue(0)) * trackBounds.W();
984  const float ypos = static_cast<float>(GetValue(1)) * trackBounds.H();
985  const IRECT handleBounds = IRECT(trackBounds.L + xpos-mHandleRadius, trackBounds.B - ypos-mHandleRadius, trackBounds.L + xpos+mHandleRadius, trackBounds.B -ypos+mHandleRadius);
986 
987  DrawHandle(g, trackBounds, handleBounds);
988 }
989 
990 void IVXYPadControl::DrawHandle(IGraphics& g, const IRECT& trackBounds, const IRECT& handleBounds)
991 {
992  if(mTrackClipsHandle)
993  g.PathClipRegion(trackBounds.GetPadded(-0.5f * mStyle.frameThickness));
994 
995  DrawPressableShape(g, mShape, handleBounds, mMouseDown, mMouseIsOver, IsDisabled());
996 }
997 
998 void IVXYPadControl::DrawTrack(IGraphics& g)
999 {
1000  g.DrawVerticalLine(GetColor(kSH), mWidgetBounds, 0.5);
1001  g.DrawHorizontalLine(GetColor(kSH), mWidgetBounds, 0.5);
1002 }
1003 
1004 void IVXYPadControl::OnMouseDown(float x, float y, const IMouseMod& mod)
1005 {
1006  mMouseDown = true;
1007  if(mStyle.hideCursor)
1008  GetUI()->HideMouseCursor(true, false);
1009 
1010  OnMouseDrag(x, y, 0., 0., mod);
1011 }
1012 
1013 void IVXYPadControl::OnMouseUp(float x, float y, const IMouseMod& mod)
1014 {
1015  if(mStyle.hideCursor)
1016  GetUI()->HideMouseCursor(false);
1017 
1018  mMouseDown = false;
1019  SetDirty(true);
1020 }
1021 
1022 void IVXYPadControl::OnMouseDrag(float x, float y, float dX, float dY, const IMouseMod& mod)
1023 {
1024  mRECT.Constrain(x, y);
1025  float xn = (x - mRECT.L) / mRECT.W();
1026  float yn = 1.f - ((y - mRECT.T) / mRECT.H());
1027  SetValue(xn, 0);
1028  SetValue(yn, 1);
1029  SetDirty(true);
1030 }
1031 
1033 {
1034  SetTargetRECT(MakeRects(mRECT));
1035  SetDirty(false);
1036 }
1037 
1038 IVPlotControl::IVPlotControl(const IRECT& bounds, const std::initializer_list<Plot>& plots, int numPoints, const char* label, const IVStyle& style, float min, float max, bool useLayer)
1039 : IControl(bounds)
1040 , IVectorBase(style)
1041 , mMin(min)
1042 , mMax(max)
1043 , mUseLayer(useLayer)
1044 {
1045  mPoints.resize(numPoints);
1046 
1047  AttachIControl(this, label);
1048 
1049  for(auto plot : plots)
1050  {
1051  AddPlotFunc(plot.color, plot.func);
1052  }
1053 }
1054 
1056 {
1057  DrawBackground(g, mRECT);
1058  DrawLabel(g);
1059 
1060  float hdiv = mWidgetBounds.W() / static_cast<float>(mHorizontalDivisions);
1061  float vdiv = mWidgetBounds.H() / static_cast<float>(mVerticalDivisions + 2);
1062 
1063  IRECT plotsRECT = mWidgetBounds.GetVPadded(-vdiv);
1064 
1065  auto drawFunc = [&](){
1066  g.DrawGrid(GetColor(kSH), mWidgetBounds, hdiv, vdiv, &mBlend);
1067 
1068  for (int p=0; p<mPlots.size(); p++)
1069  {
1070  for (int i=0; i<mPoints.size(); i++)
1071  {
1072  auto v = mPlots[p].func((static_cast<float>(i)/static_cast<float>(mPoints.size() - 1)));
1073  v = (v - mMin) / (mMax-mMin);
1074  mPoints[i] = static_cast<float>(v);
1075  }
1076 
1077  g.DrawData(mPlots[p].color, plotsRECT, mPoints.data(), static_cast<int>(mPoints.size()), nullptr, &mBlend, mTrackSize);
1078  }
1079 
1080  if (mStyle.drawFrame)
1081  g.DrawRect(GetColor(kFR), mWidgetBounds, &mBlend, mStyle.frameThickness);
1082  };
1083 
1084  if(mUseLayer)
1085  {
1086  if (!g.CheckLayer(mLayer))
1087  {
1088  g.StartLayer(this, mRECT);
1089  drawFunc();
1090  mLayer = g.EndLayer();
1091  }
1092 
1093  g.DrawLayer(mLayer, &mBlend);
1094  }
1095  else
1096  drawFunc();
1097 }
1098 
1100 {
1101  SetTargetRECT(MakeRects(mRECT));
1102  SetDirty(false);
1103 }
1104 
1105 void IVPlotControl::AddPlotFunc(const IColor& color, const IPlotFunc& func)
1106 {
1107  mPlots.push_back({color, func});
1108 
1109  if(mLayer)
1110  mLayer->Invalidate();
1111  SetDirty(false);
1112 }
1113 
1114 IVGroupControl::IVGroupControl(const IRECT& bounds, const char* label, float labelOffset, const IVStyle& style)
1115 : IControl(bounds)
1116 , IVectorBase(style)
1117 , mLabelOffset(labelOffset)
1118 {
1119  AttachIControl(this, label);
1120  mIgnoreMouse = true;
1121 }
1122 
1123 IVGroupControl::IVGroupControl(const char* label, const char* groupName, float padL, float padT, float padR, float padB, const IVStyle& style)
1124 : IControl(IRECT())
1125 , IVectorBase(style)
1126 , mGroupName(groupName)
1127 , mPadL(padL)
1128 , mPadT(padT)
1129 , mPadR(padR)
1130 , mPadB(padB)
1131 {
1132  AttachIControl(this, label);
1133  mIgnoreMouse = true;
1134 }
1135 
1137 {
1138  if(mGroupName.GetLength())
1139  {
1140  SetBoundsBasedOnGroup(mGroupName.Get(), mPadL, mPadT, mPadR, mPadB);
1141  }
1142 }
1143 
1145 {
1146 // const float cr = GetRoundedCornerRadius(mWidgetBounds);
1147 // g.FillRoundRect(GetColor(kBG), mWidgetBounds, cr);
1148 // g.FillRect(GetColor(kBG), mLabelBounds);
1149  DrawLabel(g);
1150  DrawWidget(g);
1151 }
1152 
1154 {
1155  const float cr = GetRoundedCornerRadius(mWidgetBounds);
1156  const float ft = mStyle.frameThickness;
1157  const float hft = ft/2.f;
1158 
1159  int nPaths = /*mStyle.drawShadows ? 2 :*/ 1;
1160 
1161  auto b = mWidgetBounds.GetPadded(/*mStyle.drawShadows ? -mStyle.shadowOffset :*/ 0.f);
1162 
1163  auto labelR = mLabelBounds.Empty() ? mRECT.MW() : mLabelBounds.R;
1164  auto labelL = mLabelBounds.Empty() ? mRECT.MW() : mLabelBounds.L;
1165 
1166  for(int i=0; i < nPaths; i++)
1167  {
1168  const float offset = i == 0 ? 0.f : mStyle.shadowOffset;
1169  g.PathClear();
1170  g.PathMoveTo(labelR, b.T + hft - offset);
1171  g.PathArc(b.R - cr - hft - offset, b.T + cr + hft - offset, cr, 0.f, 90.f);
1172  g.PathArc(b.R - cr - hft - offset, b.B - cr - hft - offset, cr, 90.f, 180.f);
1173  g.PathArc(b.L + cr + hft - offset, b.B - cr - hft - offset, cr, 180.f, 270.f);
1174  g.PathArc(b.L + cr + hft - offset, b.T + cr + hft - offset, cr, 270.f, 360.f);
1175  g.PathLineTo(labelL, b.T + hft - offset);
1176  g.PathStroke(mStyle.drawShadows ? GetColor(i == 0 ? kSH : kFR) : GetColor(kFR), ft);
1177  }
1178 }
1179 
1181 {
1182  SetTargetRECT(MakeRects(mRECT));
1183  mLabelBounds.HPad(mLabelPadding);
1184  mWidgetBounds.Offset(0, -(mLabelBounds.H()/2.f) - (mStyle.frameThickness/2.f), 0, 0);
1185  const float cr = GetRoundedCornerRadius(mWidgetBounds);
1186  mLabelBounds.Translate(mRECT.L - mLabelBounds.L + mStyle.frameThickness + mLabelOffset + cr, 0.f);
1187  SetDirty(false);
1188 }
1189 
1190 void IVGroupControl::SetBoundsBasedOnGroup(const char* groupName, float padL, float padT, float padR, float padB)
1191 {
1192  mGroupName.Set(groupName);
1193 
1194  IRECT unionRect;
1195  GetUI()->ForControlInGroup(mGroupName.Get(), [&unionRect](IControl* pControl) { unionRect = unionRect.Union(pControl->GetRECT()); });
1196  float halfLabelHeight = mLabelBounds.H()/2.f;
1197  unionRect.GetVPadded(halfLabelHeight);
1198  mRECT = unionRect.GetPadded(padL, padT, padR, padB);
1199 
1200  OnResize();
1201 }
1202 
1203 IVColorSwatchControl::IVColorSwatchControl(const IRECT& bounds, const char* label, ColorChosenFunc func, const IVStyle& style, ECellLayout layout,
1204  const std::initializer_list<EVColor>& colorIDs, const std::initializer_list<const char*>& labelsForIDs)
1205 : IControl(bounds)
1206 , IVectorBase(style)
1207 , mColorChosenFunc(func)
1208 , mLayout(layout)
1209 , mColorIdForCells(colorIDs)
1210 {
1211  assert(colorIDs.size() == labelsForIDs.size());
1212 
1213  AttachIControl(this, label);
1214  mCellRects.Resize(static_cast<int>(mColorIdForCells.size()));
1215  mText.mAlign = mStyle.valueText.mAlign = EAlign::Far;
1216 
1217  for (int i=0;i<colorIDs.size();i++)
1218  {
1219  mLabels.Add(new WDL_String(labelsForIDs.begin()[i]));
1220  }
1221 }
1222 
1224 {
1225  DrawWidget(g);
1226  DrawLabel(g);
1227 }
1228 
1230 {
1231  for (int i=0; i< mColorIdForCells.size(); i++)
1232  {
1233  WDL_String* pStr = mLabels.Get(i);
1234  IRECT r = mCellRects.Get()[i];
1235  IRECT buttonBounds = r.FracRectHorizontal(pStr->GetLength() ? 0.25f : 1.f, true);
1236  g.FillRect(GetColor(mColorIdForCells[i]), buttonBounds, &mBlend);
1237  g.DrawRect(i == mCellOver ? COLOR_GRAY : COLOR_DARK_GRAY, buttonBounds.GetPadded(0.5f), &mBlend);
1238 
1239  if(pStr->GetLength())
1240  g.DrawText(mStyle.valueText, mLabels.Get(i)->Get(), r.FracRectHorizontal(0.7f, false), &mBlend);
1241  }
1242 }
1243 
1245 {
1246  SetTargetRECT(MakeRects(mRECT, true));
1247 
1248  int rows = 3;
1249  int columns = 3;
1250 
1251  if(mLayout == ECellLayout::kGrid)
1252  {
1253  rows = 3;
1254  columns = 3;
1255  }
1256  else if (mLayout == ECellLayout::kHorizontal)
1257  {
1258  rows = 1;
1259  columns = static_cast<int>(mColorIdForCells.size());
1260  }
1261  else if (mLayout == ECellLayout::kVertical)
1262  {
1263  rows = static_cast<int>(mColorIdForCells.size());
1264  columns = 1;
1265  }
1266 
1267  for (int i=0; i< mColorIdForCells.size(); i++)
1268  {
1269  mCellRects.Get()[i] = mWidgetBounds.GetGridCell(i, rows, columns).GetPadded(-2);
1270  }
1271 
1272  SetDirty(false);
1273 }
1274 
1275 void IVColorSwatchControl::OnMouseOver(float x, float y, const IMouseMod& mod)
1276 {
1277  for (int i=0; i<mColorIdForCells.size(); i++)
1278  {
1279  if(mCellRects.Get()[i].Contains(x, y))
1280  {
1281  mCellOver = i;
1282  SetDirty();
1283  return;
1284  }
1285  }
1286 
1287  mCellOver = -1;
1288  SetDirty();
1289 }
1290 
1292 {
1293  mCellOver = -1;
1294  SetDirty();
1295 }
1296 
1297 void IVColorSwatchControl::OnMouseDown(float x, float y, const IMouseMod& mod)
1298 {
1299  int cellClicked=-1;
1300 
1301  for (int i=0; i<mColorIdForCells.size(); i++)
1302  {
1303  if(mCellRects.Get()[i].Contains(x, y))
1304  {
1305  cellClicked = i;
1306  break;
1307  }
1308  }
1309 
1310  if(cellClicked > -1)
1311  {
1312  EVColor vColorClicked = mColorIdForCells[cellClicked];
1313  IColor color = GetColor(vColorClicked);
1314  GetUI()->PromptForColor(color, "Choose a color", [this, cellClicked, vColorClicked](IColor result) {
1315  SetColor(vColorClicked, result);
1316  if(mColorChosenFunc)
1317  mColorChosenFunc(cellClicked, result);
1318  });
1319  }
1320 }
1321 
1322 #pragma mark - SVG CONTROLS
1323 
1324 ISVGButtonControl::ISVGButtonControl(const IRECT& bounds, IActionFunction aF, const ISVG& offImage, const ISVG& onImage)
1325 : IButtonControlBase(bounds, aF)
1326 , mOffSVG(offImage)
1327 , mOnSVG(onImage)
1328 {
1329 }
1330 
1332 {
1333  if (GetValue() > 0.5)
1334  g.DrawSVG(mOnSVG, mRECT, &mBlend);
1335  else
1336  g.DrawSVG(mOffSVG, mRECT, &mBlend);
1337 }
1338 
1339 ISVGKnobControl::ISVGKnobControl(const IRECT& bounds, const ISVG& svg, int paramIdx)
1340 : IKnobControlBase(bounds, paramIdx)
1341 , mSVG(svg)
1342 {
1343 }
1344 
1346 {
1347  g.DrawRotatedSVG(mSVG, mRECT.MW(), mRECT.MH(), mRECT.W(), mRECT.H(), mStartAngle + GetValue() * (mEndAngle - mStartAngle), &mBlend);
1348 }
1349 
1350 void ISVGKnobControl::SetSVG(ISVG& svg)
1351 {
1352  mSVG = svg;
1353  SetDirty(false);
1354 }
1355 
1356 ISVGSwitchControl::ISVGSwitchControl(const IRECT& bounds, const std::initializer_list<ISVG>& svgs, int paramIdx, IActionFunction aF)
1357 : ISwitchControlBase(bounds, paramIdx, aF, static_cast<int>(svgs.size()))
1358 , mSVGs(svgs)
1359 {
1360 }
1361 
1363 {
1364  g.DrawSVG(mSVGs[GetSelectedIdx()], mRECT, &mBlend);
1365 }
1366 
1367 ISVGSliderControl::ISVGSliderControl(const IRECT& bounds, const ISVG& handleSVG, const ISVG& trackSVG, int paramIdx, EDirection dir, double gearing)
1368 : ISliderControlBase(bounds, paramIdx, dir, gearing)
1369 , mHandleSVG(handleSVG)
1370 , mTrackSVG(trackSVG)
1371 {
1372 }
1373 
1375 {
1376  g.DrawSVG(mTrackSVG, mTrackSVGBounds, &mBlend);
1377  g.DrawSVG(mHandleSVG, GetHandleBounds(GetValue()), &mBlend);
1378 }
1379 
1381 {
1382  auto trackAspectRatio = mTrackSVG.W() / mTrackSVG.H();
1383  auto handleAspectRatio = mHandleSVG.W() / mHandleSVG.H();
1384  auto handleOverTrackHeight = mHandleSVG.H() / mTrackSVG.H();
1385 
1386  IRECT handleBoundsAtMidPoint;
1387 
1388  if (mDirection == EDirection::Vertical)
1389  {
1390  mTrackSVGBounds = mRECT.GetCentredInside(mRECT.H() * trackAspectRatio, mRECT.H());
1391 
1392  handleBoundsAtMidPoint = mRECT.GetCentredInside(mRECT.H() * handleAspectRatio * handleOverTrackHeight, mRECT.H() * handleOverTrackHeight);
1393  mHandleBoundsAtMax = { handleBoundsAtMidPoint.L, mTrackSVGBounds.T, handleBoundsAtMidPoint.R, mTrackSVGBounds.T + handleBoundsAtMidPoint.H() };
1394  mTrackBounds = mTrackSVGBounds.GetPadded(0, -handleBoundsAtMidPoint.H(), 0, 0);
1395  }
1396  else
1397  {
1398  mTrackSVGBounds = mRECT.GetCentredInside(mRECT.W(), mRECT.W() / trackAspectRatio);
1399  auto handleHeight = mTrackSVGBounds.H() * handleOverTrackHeight;
1400  handleBoundsAtMidPoint = mRECT.GetCentredInside(handleHeight * handleAspectRatio, handleHeight);
1401  auto halfHeight = handleBoundsAtMidPoint.H() / 2.f;
1402  mHandleBoundsAtMax = { mTrackSVGBounds.R - handleBoundsAtMidPoint.W(), mTrackSVGBounds.MH() - halfHeight, mTrackSVGBounds.R, mTrackSVGBounds.MH() + halfHeight };
1403  mTrackBounds = mTrackSVGBounds.GetPadded(-handleBoundsAtMidPoint.W(), 0, 0, 0);
1404  }
1405 
1406  SetDirty(false);
1407 }
1408 
1409 IRECT ISVGSliderControl::GetHandleBounds(double value) const
1410 {
1411  if (value < 0.0)
1412  value = GetValue();
1413 
1414  IRECT r = mHandleBoundsAtMax;
1415 
1416  if (mDirection == EDirection::Vertical)
1417  {
1418  float offs = (1.f - (float) value) * mTrackBounds.H();
1419  r.T += offs;
1420  r.B += offs;
1421  }
1422  else
1423  {
1424  float offs = (1.f - (float) value) * mTrackBounds.W();
1425  r.L -= offs;
1426  r.R -= offs;
1427  }
1428 
1429  return r;
1430 }
1431 
1432 #pragma mark - BITMAP CONTROLS
1433 
1434 IBButtonControl::IBButtonControl(float x, float y, const IBitmap& bitmap, IActionFunction aF)
1435  : IButtonControlBase(IRECT(x, y, bitmap), aF)
1436  , IBitmapBase(bitmap)
1437 {
1438  AttachIControl(this);
1439 }
1440 
1441 IBButtonControl::IBButtonControl(const IRECT& bounds, const IBitmap& bitmap, IActionFunction aF)
1442  : IButtonControlBase(bounds.GetCentredInside(bitmap), aF)
1443  , IBitmapBase(bitmap)
1444 {
1445  AttachIControl(this);
1446 }
1447 
1448 IBSwitchControl::IBSwitchControl(float x, float y, const IBitmap& bitmap, int paramIdx)
1449 : ISwitchControlBase(IRECT(x, y, bitmap), paramIdx)
1450 , IBitmapBase(bitmap)
1451 {
1452  AttachIControl(this);
1453 }
1454 
1455 IBSwitchControl::IBSwitchControl(const IRECT& bounds, const IBitmap& bitmap, int paramIdx)
1456 : ISwitchControlBase(bounds.GetCentredInside(bitmap), paramIdx)
1457 , IBitmapBase(bitmap)
1458 {
1459  AttachIControl(this);
1460 }
1461 
1462 void IBSwitchControl::OnMouseDown(float x, float y, const IMouseMod& mod)
1463 {
1464  if (mBitmap.N() > 1)
1465  SetValue(GetValue() + 1.0 / static_cast<double>(mBitmap.N() - 1));
1466  else
1467  SetValue(GetValue() + 1.0);
1468 
1469  if (GetValue() > 1.001)
1470  SetValue(0.);
1471 
1472  SetDirty();
1473 }
1474 
1475 IBSliderControl::IBSliderControl(float x, float y, float trackLength, const IBitmap& handleBitmap, const IBitmap& trackBitmap, int paramIdx, EDirection dir, double gearing)
1477  dir == EDirection::Vertical ? handleBitmap.W() : trackLength,
1478  dir == EDirection::Vertical ? trackLength : handleBitmap.H()),
1479  paramIdx, dir, gearing,
1480  float(dir == EDirection::Vertical ? handleBitmap.H() : handleBitmap.W()))
1481 , IBitmapBase(handleBitmap)
1482 , mTrackBitmap(trackBitmap)
1483 {
1484  AttachIControl(this);
1485 }
1486 
1487 IBSliderControl::IBSliderControl(const IRECT& bounds, const IBitmap& handleBitmap, const IBitmap& trackBitmap, int paramIdx, EDirection dir, double gearing)
1488 : ISliderControlBase(bounds, paramIdx, dir, gearing, float(dir == EDirection::Vertical ? handleBitmap.H() : handleBitmap.W()))
1489 , IBitmapBase(handleBitmap)
1490 , mTrackBitmap(trackBitmap)
1491 {
1492  AttachIControl(this);
1493 }
1494 
1496 {
1497  if(mTrackBitmap.IsValid())
1498  g.DrawBitmap(mTrackBitmap, mRECT.GetCentredInside(IRECT(0, 0, mTrackBitmap)), 0, 0, &mBlend);
1499 
1500  g.DrawBitmap(mBitmap, GetHandleBounds(), 1, &mBlend);
1501 }
1502 
1503 IRECT IBSliderControl::GetHandleBounds(double value) const
1504 {
1505  if (value < 0.0)
1506  value = GetValue();
1507 
1508  IRECT r(mTrackBounds.L, mTrackBounds.T, mBitmap);
1509 
1510  if (mDirection == EDirection::Vertical)
1511  r.Translate(0.f, (1.f - static_cast<float>(value)) * (mTrackBounds.H() - static_cast<float>(mBitmap.H())));
1512  else
1513  r.Translate(static_cast<float>(value) * (mTrackBounds.W() - static_cast<float>(mBitmap.W())), 0.f);
1514 
1515  return r;
1516 }
1517 
1519 {
1520  if (mDirection == EDirection::Vertical)
1521  {
1522  if(mTrackBitmap.IsValid())
1523  mTrackBounds = mRECT.GetCentredInside(IRECT(0, 0, mTrackBitmap));
1524  else
1525  {
1526  const float halfWidth = static_cast<float>(mBitmap.W()) / 2.f;
1527  mTrackBounds = mRECT.GetMidHPadded(halfWidth);
1528  }
1529  }
1530  else
1531  {
1532  if(mTrackBitmap.IsValid())
1533  mTrackBounds = mRECT.GetCentredInside(IRECT(0, 0, mTrackBitmap));
1534  else
1535  {
1536  const float halfHeight = static_cast<float>(mBitmap.H()) / 2.f;
1537  mTrackBounds = mRECT.GetMidVPadded(halfHeight);
1538  }
1539  }
1540 
1541  SetDirty(false);
1542 }
1543 
1545 {
1546  const double angle = -130.0 + GetValue() * 260.0;
1547  g.DrawRotatedBitmap(mBitmap, mRECT.MW(), mRECT.MH(), angle, &mBlend);
1548 }
1549 
1550 IBTextControl::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)
1551 : ITextControl(bounds, str, text)
1552 , IBitmapBase(bitmap)
1553 , mCharWidth(charWidth)
1554 , mCharHeight(charHeight)
1555 , mCharOffset(charOffset)
1556 , mMultiLine(multiLine)
1557 , mVCentre(vCenter)
1558 {
1559  mBlend = blend;
1560 }
1561 
1563 {
1564  g.DrawBitmapedText(mBitmap, mRECT, mText, &mBlend, mStr.Get(), mVCentre, mMultiLine, mCharWidth, mCharHeight, mCharOffset);
1565 }
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:347
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:876
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:947
void Draw(IGraphics &g) override
Draw the control to the graphics context.
Definition: IControls.cpp:1223
void OnResize() override
Called when IControl is constructed or resized using SetRect().
Definition: IControls.cpp:626
bool Contains(const IRECT &rhs) const
Returns true if this IRECT completely contains rhs.
void Draw(IGraphics &g) override
Draw the control to the graphics context.
Definition: IControls.cpp:1331
void Draw(IGraphics &g) override
Draw the control to the graphics context.
Definition: IControls.cpp:966
void OnResize() override
Called when IControl is constructed or resized using SetRect().
Definition: IControls.cpp:77
virtual void PathMoveTo(float x, float y)=0
Move the current point in the current path.
float MW() const
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:1004
virtual void DrawWidget(IGraphics &g) override
Draw the IVControl main widget (override)
Definition: IControls.cpp:469
const char * GetName() const
Returns the parameter&#39;s name.
float MH() const
IRECT SubRect(EDirection layoutDir, int numSlices, int sliceIdx) const
Get a new rectangle which is a "slice" of this rectangle.
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:774
void StartLayer(IControl *pOwner, const IRECT &r, bool cacheable=false)
Create an IGraphics layer.
Definition: IGraphics.cpp:1954
The lowest level base class of an IGraphics control.
Definition: IControl.h:42
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:1038
void DrawWidget(IGraphics &g) override
Draw the IVControl main widget (override)
Definition: IControls.cpp:977
Used to manage a rectangular area, independent of draw class/platform.
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:2410
const char * GetSelectedLabelStr() const
returns the label string on the selected tab
Definition: IControls.cpp:446
void SetColor(EVColor colorIdx, const IColor &color)
Set one of the IVColors that style the IVControl.
Definition: IControl.h:650
virtual void DrawValue(IGraphics &g, bool mouseOver)
Draw the IVControl value text.
Definition: IControl.h:756
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:2475
A basic control to display some text.
Definition: IControl.h:1945
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 DrawBackground(IGraphics &g, const IRECT &rect)
Draw the IVControl background (usually transparent)
Definition: IControl.h:733
User-facing bitmap abstraction that you use to manage bitmap data, independant of draw class/platform...
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:920
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:1275
void DisablePrompt(bool disable)
Disable/enable default prompt for user input.
Definition: IControl.h:405
Used to manage mouse modifiers i.e.
A base class for switch controls.
Definition: IControl.h:1690
virtual void PathLineTo(float x, float y)=0
Add a line to the current path from the current point to the specified location.
bool mMouseIsOver
if mGraphics::mHandleMouseOver = true, this will be true when the mouse is over control.
Definition: IControl.h:545
virtual void DrawData(const IColor &color, const IRECT &bounds, float *normYPoints, int nPoints, float *normXPoints=nullptr, const IBlend *pBlend=0, float thickness=1.f)
Draw a line between a collection of normalized points.
Definition: IGraphics.cpp:2436
virtual bool IsHit(float x, float y) const override
Hit test the control.
Definition: IControls.cpp:409
virtual void DrawWidget(IGraphics &g) override
Draw the IVControl main widget (override)
Definition: IControls.cpp:554
void Draw(IGraphics &g) override
Draw the control to the graphics context.
Definition: IControls.cpp:838
void OnResize() override
Called when IControl is constructed or resized using SetRect().
Definition: IControls.cpp:1518
void Draw(IGraphics &g) override
Draw the control to the graphics context.
Definition: IControls.cpp:534
IRECT FracRectHorizontal(float frac, bool rhs=false) const
Returns a new IRECT with a width that is multiplied by frac.
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:120
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:886
void Draw(IGraphics &g) override
Draw the control to the graphics context.
Definition: IControls.cpp:1144
IPlug&#39;s parameter class.
void Translate(float x, float y)
Translate this rectangle.
IRECT FracRect(EDirection layoutDir, float frac, bool fromTopOrRight=false) const
Get a new rectangle which is a fraction of this rectangle.
virtual void SetValueToDefault(int valIdx=kNoValIdx)
Set one or all of the control&#39;s values to the default value of the associated parameter.
Definition: IControl.cpp:181
float GetRoundedCornerRadius(const IRECT &bounds) const
Get the radius of rounded corners for a rectangle, based on the style roundness factor.
Definition: IControl.h:714
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:1340
IControl * SetActionFunction(IActionFunction actionFunc)
Set an Action Function for this control.
Definition: IControl.h:201
void DrawWidget(IGraphics &g) override
Draw the IVControl main widget (override)
Definition: IControls.cpp:1153
static IRECT MakeXYWH(float l, float t, float w, float h)
Create a new IRECT with the given position and size.
IRECT GetVPadded(float padding) const
Get a copy of this IRECT padded in the Y-axis N.B.
A vector "tab" multi switch control.
Definition: IControls.h:127
virtual void PathStroke(const IPattern &pattern, float thickness, const IStrokeOptions &options=IStrokeOptions(), const IBlend *pBlend=0)=0
Stroke the current current path.
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:2482
Used to manage color data, independent of draw class/platform.
IRECT GetTranslated(float x, float y) const
Get a translated copy of this rectangle.
void HPad(float padding)
Pad this IRECT in the X-axis N.B.
A base interface to be combined with IControl for bitmap-based controls "IBControls", managing an IBitmap.
Definition: IControl.h:586
void DrawWidget(IGraphics &g) override
Draw the IVControl main widget (override)
Definition: IControls.cpp:175
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:631
A base class for buttons/momentary switches - cannot be linked to parameters.
Definition: IControl.h:1679
virtual void OnMouseDrag(float x, float y, float dX, float dY, const IMouseMod &mod)
Implement this method to respond to a mouse drag event on this control.
Definition: IControl.h:99
void OnInit() override
Called just prior to when the control is attached, after its delegate and graphics member variable se...
Definition: IControls.cpp:144
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:941
IVTabSwitchControl(const IRECT &bounds, int paramIdx=kNoParameter, const std::initializer_list< 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:293
IControl * SetAnimationEndActionFunction(IActionFunction actionFunc)
Set an Action Function to be called at the end of an animation.
Definition: IControl.h:206
void OnMouseOut() override
Implement this method to respond to a mouseout event on this control.
Definition: IControls.cpp:1291
User-facing SVG abstraction that you use to manage SVG data ISVG doesn&#39;t actually own the image data...
void AttachIControl(IControl *pControl, const char *label)
Call in the constructor of your IVControl to link the IVectorBase and IControl.
Definition: IControl.h:641
ISVGSwitchControl(const IRECT &bounds, const std::initializer_list< ISVG > &svgs, int paramIdx=kNoParameter, IActionFunction aF=nullptr)
Constructs a SVG switch control.
Definition: IControls.cpp:1356
void OnResize() override
Called when IControl is constructed or resized using SetRect().
Definition: IControls.cpp:432
IBSwitchControl(float x, float y, const IBitmap &bitmap, int paramIdx=kNoParameter)
Constructs a bitmap switch control.
Definition: IControls.cpp:1448
void Draw(IGraphics &g) override
Draw the control to the graphics context.
Definition: IControls.cpp:1562
virtual int GetValIdxForPos(float x, float y) const
Check to see which of the control&#39;s values relates to this x and y coordinate.
Definition: IControl.h:239
IRECT GetFromLeft(float amount) const
Get a subrect of this IRECT bounded in X by the left edge and &#39;amount&#39;.
float R
Right side of the rectangle (X + W)
void Draw(IGraphics &g) override
Draw the control to the graphics context.
Definition: IControls.cpp:345
bool IsDisabled() const
Definition: IControl.h:356
void OnInit() override
Called just prior to when the control is attached, after its delegate and graphics member variable se...
Definition: IControl.cpp:752
IRECT DrawPressableTriangle(IGraphics &g, const IRECT &bounds, bool pressed, bool mouseOver, float angle, bool disabled)
Draw a triangle-shaped vector button.
Definition: IControl.h:959
bool IsHit(float x, float y) const override
Hit test the control.
Definition: IControls.cpp:632
void SetDirty(bool push, int valIdx=kNoValIdx) override
Mark the control as dirty, i.e.
Definition: IControls.cpp:123
A base class for mult-strip/track controls, such as multi-sliders, meters Track refers to the channel...
Definition: IControl.h:1248
IRECT MakeRects(const IRECT &parent, bool hasHandle=false)
Calculate the rectangles for the various areas, depending on the style.
Definition: IControl.h:1014
float H() const
double GetAnimationProgress() const
Get the progress in a control&#39;s animation, in the range 0-1.
Definition: IControl.cpp:429
void Draw(IGraphics &g) override
Draw the control to the graphics context.
Definition: IControls.cpp:1055
float W() const
IBitmapBase(const IBitmap &bitmap)
IBitmapBase Constructor.
Definition: IControl.h:591
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...
void OnResize() override
Called when IControl is constructed or resized using SetRect().
Definition: IControls.cpp:250
virtual void DrawWidget(IGraphics &g) override
Draw the IVControl main widget (override)
Definition: IControls.cpp:374
void Draw(IGraphics &g) override
Draw the control to the graphics context.
Definition: IControls.cpp:63
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:764
IText is used to manage font and text/text entry style for a piece of text on the UI...
void Offset(float l, float t, float r, float b)
Offset each field of the rectangle.
bool CheckLayer(const ILayerPtr &layer)
Test to see if a layer needs drawing, for instance if the control&#39;s bounds were changed.
Definition: IGraphics.cpp:2009
void OnInit() override
Called just prior to when the control is attached, after its delegate and graphics member variable se...
Definition: IControls.cpp:653
const IColor & GetColor(EVColor color) const
Get value of a specific EVColor in the IVControl.
Definition: IControl.h:664
int W() const
virtual void DrawSVG(const ISVG &svg, const IRECT &bounds, const IBlend *pBlend=0)
Draw an SVG image to the graphics context.
Definition: IGraphics.cpp:2762
void OnResize() override
Called when IControl is constructed or resized using SetRect().
Definition: IControls.cpp:783
IControl(const IRECT &bounds, int paramIdx=kNoParameter, IActionFunction actionFunc=nullptr)
Constructor.
Definition: IControl.cpp:81
void DrawWidget(IGraphics &g) override
Draw the IVControl main widget (override)
Definition: IControl.h:1375
A collection of IControls for common UI widgets, such as knobs, sliders, switches.
static IRECT LinearInterpolateBetween(const IRECT &start, const IRECT &dest, float progress)
Get a rectangle that is a linear interpolation between start and dest
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:414
bool Empty() const
int GetButtonForPoint(float x, float y) const override
Definition: IControls.cpp:487
void PathClipRegion(const IRECT r=IRECT())
Clip the current path to a particular region.
Definition: IGraphics.cpp:2743
int H() const
void AddPlotFunc(const IColor &color, const IPlotFunc &func)
add a new function to the plot
Definition: IControls.cpp:1105
The lowest level base class of an IGraphics context.
Definition: IGraphics.h:86
IVectorBase(const IVStyle &style, bool labelInWidget=false, bool valueInWidget=false)
IVectorBase Constructor.
Definition: IControl.h:631
void SetAnimation(IAnimationFunction func)
Set the animation function.
Definition: IControl.h:477
void Draw(IGraphics &g) override
Draw the control to the graphics context.
Definition: IControls.cpp:263
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:775
void DrawValue(IGraphics &g, bool mouseOver) override
Draw the IVControl value text.
Definition: IControls.cpp:180
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:265
virtual void DrawLabel(IGraphics &g)
Draw the IVControl label text.
Definition: IControl.h:746
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:906
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:1367
void GetDisplay(WDL_String &display, bool withDisplayText=true) const
Get the current textual display for the current parameter value.
void DrawWidget(IGraphics &g) override
Draw the IVControl main widget (override)
Definition: IControls.cpp:273
void Draw(IGraphics &g) override
Draw the control to the graphics context.
Definition: IControls.cpp:1544
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:2554
virtual void DrawWidget(IGraphics &g) override
Draw the IVControl main widget (override)
Definition: IControls.cpp:714
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:332
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:395
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:2547
int NVals() const
Definition: IControl.h:233
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:759
void OnResize() override
Called when IControl is constructed or resized using SetRect().
Definition: IControls.cpp:1380
void OnResize() override
Called when IControl is constructed or resized using SetRect().
Definition: IControls.cpp:133
void Constrain(float &x, float &y) const
Ensure the point (x,y) is inside this IRECT.
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:1022
IAnimationFunction GetAnimationFunction()
Get the control&#39;s animation function, if it exists.
Definition: IControl.h:485
A base class for knob/dial controls, to handle mouse action and Sender.
Definition: IControl.h:1191
virtual void HideMouseCursor(bool hide=true, bool lock=true)=0
Call to hide/show the mouse cursor.
void SplashClickActionFunc(IControl *pCaller)
The splash click action function is used by IVControls to start SplashAnimationFunc.
Definition: IControl.cpp:47
virtual void PathClear()=0
Clear the stack of path drawing commands.
IRECT Union(const IRECT &rhs) const
Create a new IRECT that is a union of this IRECT and rhs.
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:610
void DrawLayer(const ILayerPtr &layer, const IBlend *pBlend=nullptr)
Draw a layer to the main IGraphics context.
Definition: IGraphics.cpp:2022
void Draw(IGraphics &g) override
Draw the control to the graphics context.
Definition: IControls.cpp:692
float W() const
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:747
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:587
IRECT GetFromRight(float amount) const
Get a subrect of this IRECT bounded in X by &#39;amount&#39; and the right edge.
void DrawWidget(IGraphics &g) override
Draw the IVControl main widget (override)
Definition: IControls.cpp:1229
virtual int GetButtonForPoint(float x, float y) const
Definition: IControls.cpp:398
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.
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:747
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) ...
A base class for slider/fader controls, to handle mouse action and Sender.
Definition: IControl.h:1221
void OnResize() override
Called when IControl is constructed or resized using SetRect().
Definition: IControls.cpp:1099
bool IsHit(float x, float y) const override
Hit test the control.
Definition: IControls.cpp:83
bool IsHit(float x, float y) const override
Hit test the control.
Definition: IControls.cpp:795
void ForControlInGroup(const char *group, std::function< void(IControl *pControl)> func)
For all standard controls in the main control stack that are linked to a group, execute a function...
Definition: IGraphics.cpp:480
double GetValue(int valIdx=0) const
Get the control&#39;s value.
Definition: IControl.cpp:151
virtual void DrawWidget(IGraphics &g) override
Draw the IVControl main widget (override)
Definition: IControls.cpp:71
void SetDirty(bool push, int valIdx=kNoValIdx) override
Mark the control as dirty, i.e.
Definition: IControls.cpp:285
void SetTargetRECT(const IRECT &bounds)
Set the rectangular mouse tracking target area, within the graphics context for this control...
Definition: IControl.h:317
IGraphics * GetUI()
Definition: IControl.h:452
float L
Left side of the rectangle (X)
void Draw(IGraphics &g) override
Draw the control to the graphics context.
Definition: IControls.cpp:110
void GetDisplayWithLabel(WDL_String &display, bool withDisplayText=true) const
Fills the WDL_String the value of the parameter along with the label, e.g.
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:2385
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:643
ILayerPtr EndLayer()
End an IGraphics layer.
Definition: IGraphics.cpp:1977
IRECT GetHPadded(float padding) const
Get a copy of this IRECT padded in the X-axis N.B.
ISVGButtonControl(const IRECT &bounds, IActionFunction aF, const ISVG &offImage, const ISVG &onImage)
Constructs a vector button control, with an action function.
Definition: IControls.cpp:1324
virtual void DrawWidget(IGraphics &g)
Draw the IVControl main widget (override)
Definition: IControl.h:740
IRECT GetCentredInside(const IRECT &sr) const
Get a rectangle the size of sr but with the same center point as this rectangle.
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:675
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:808
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:601
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:740
void OnInit() override
Called just prior to when the control is attached, after its delegate and graphics member variable se...
Definition: IControls.cpp:818
void Draw(IGraphics &g) override
Draw the control to the graphics context.
Definition: IControls.cpp:1495
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:768
void Draw(IGraphics &g) override
Draw the control to the graphics context.
Definition: IControls.cpp:1374
IRECT GetPadded(float padding) const
Get a copy of this IRECT with each value padded by padding N.B.
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:451
void DrawWidget(IGraphics &g) override
Draw the IVControl main widget (override)
Definition: IControls.cpp:897
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:797
void Draw(IGraphics &g) override
Draw the control to the graphics context.
Definition: IControls.cpp:1345
virtual void SetValue(double value, int valIdx=0)
Set one of the control&#39;s values.
Definition: IControl.cpp:145
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:616
A vector switch control.
Definition: IControls.h:71
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:1462
int N() const
bool IsHit(float x, float y) const override
Hit test the control.
Definition: IControls.cpp:139
void OnResize() override
Called when IControl is constructed or resized using SetRect().
Definition: IControls.cpp:1244
A base interface to be combined with IControl for vectorial controls "IVControls", in order for them to share a common style If you need more flexibility, you&#39;re on your own!
Definition: IControl.h:624
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:2775
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:2503
virtual bool PromptForColor(IColor &color, const char *str="", IColorPickerHandlerFunc func=nullptr)=0
Create a platform color chooser dialog.
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:1297
void OnResize() override
Called when IControl is constructed or resized using SetRect().
Definition: IControls.cpp:1180
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:423
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 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:1013
void Draw(IGraphics &g) override
Draw the control to the graphics context.
Definition: IControls.cpp:1362
void SetDirty(bool push, int valIdx=kNoValIdx) override
Mark the control as dirty, i.e.
Definition: IControls.cpp:808
void AttachIControl(IControl *pControl)
Call in the constructor of your IBControl to link the IBitmapBase and IControl.
Definition: IControl.h:600
float T
Top of the rectangle (Y)
void OnInit() override
Called just prior to when the control is attached, after its delegate and graphics member variable se...
Definition: IControls.cpp:327
void OnInit() override
Called just prior to when the control is attached, after its delegate and graphics member variable se...
Definition: IControls.cpp:1136
A struct encapsulating a set of properties used to configure IVControls.
virtual void SetDirty(bool triggerAction=true, int valIdx=kNoValIdx)
Mark the control as dirty, i.e.
Definition: IControl.cpp:196
float H() const
float B
Bottom of the rectangle (Y + H)
void OnResize() override
Called when IControl is constructed or resized using SetRect().
Definition: IControls.cpp:1032
void Draw(IGraphics &g) override
Draw the control to the graphics context.
Definition: IControls.cpp:38
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...
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:542