iPlug2 - C++ Audio Plug-in Framework
IVMultiSliderControl.h
Go to the documentation of this file.
1 /*
2  ==============================================================================
3 
4  This file is part of the iPlug 2 library. Copyright (C) the iPlug 2 developers.
5 
6  See LICENSE.txt for more info.
7 
8  ==============================================================================
9 */
10 
11 #pragma once
12 
18 #include "IControl.h"
19 
20 BEGIN_IPLUG_NAMESPACE
21 BEGIN_IGRAPHICS_NAMESPACE
22 
25 template <int MAXNC = 1>
27 {
28 public:
29  using OnNewValueFunc = std::function<void(int trackIdx, double val)>;
30 
31  static constexpr int kMsgTagSetHighlight = 0;
32 
39  IVMultiSliderControl(const IRECT& bounds, const char* label, const IVStyle& style = DEFAULT_STYLE, int nSteps = 0, EDirection dir = EDirection::Vertical)
40  : IVTrackControlBase(bounds, label, style, MAXNC, nSteps, dir)
41  {
42  mDrawTrackFrame = false;
43  mTrackPadding = 1.f;
44  }
45 
53  IVMultiSliderControl(const IRECT& bounds, const char* label, const IVStyle& style, int loParamIdx, int nSteps, EDirection dir)
54  : IVTrackControlBase(bounds, label, style, loParamIdx, MAXNC, nSteps, dir)
55  {
56  mDrawTrackFrame = false;
57  mTrackPadding = 1.f;
58  }
59 
67  IVMultiSliderControl(const IRECT& bounds, const char* label, const IVStyle& style, const std::initializer_list<int>& params, int nSteps, EDirection dir)
68  : IVTrackControlBase(bounds, label, style, params, nSteps, dir)
69  {
70  mDrawTrackFrame = false;
71  mTrackPadding = 1.f;
72  }
73 
74  void Draw(IGraphics& g) override
75  {
76  DrawBackground(g, mRECT);
77  DrawWidget(g);
78  DrawLabel(g);
79 
80  if(mStyle.drawFrame)
81  g.DrawRect(GetColor(kFR), mWidgetBounds, &mBlend, mStyle.frameThickness);
82  }
83 
84  void SnapToMouse(float x, float y, EDirection direction, const IRECT& bounds, int valIdx = -1 /* TODO:: not used*/, double minClip = 0., double maxClip = 1.) override
85  {
86  bounds.Constrain(x, y);
87  int nVals = NVals();
88 
89  double value = 0.;
90  int sliderTest = -1;
91 
92  int step = GetStepIdxForPos(x, y);
93 
94  if(direction == EDirection::Vertical)
95  {
96  if(step > -1)
97  {
98  y = mStepBounds.Get()[step].T;
99 
100  if(mStepBounds.GetSize() == 1)
101  value = 1.f;
102  else
103  value = step * (1.f/float(mStepBounds.GetSize()-1));
104  }
105  else
106  {
107  value = 1.f - (y-bounds.T) / bounds.H();
108  }
109 
110  for(auto i = 0; i < nVals; i++)
111  {
112  if(mTrackBounds.Get()[i].ContainsEdge(x, mTrackBounds.Get()[i].MH()))
113  {
114  sliderTest = i;
115  break;
116  }
117  }
118  }
119  else
120  {
121  if(step > -1)
122  {
123  x = mStepBounds.Get()[step].L;
124 
125  if(mStepBounds.GetSize() == 1)
126  value = 1.f;
127  else
128  value = 1.- (step * (1.f/float(mStepBounds.GetSize()-1)));
129  }
130  else
131  {
132  value = (x-bounds.L) / bounds.W();
133  }
134  for(auto i = 0; i < nVals; i++)
135  {
136  if(mTrackBounds.Get()[i].ContainsEdge(mTrackBounds.Get()[i].MW(), y))
137  {
138  sliderTest = i;
139  break;
140  }
141  }
142  }
143 
144  if(!GetStepped())
145  value = std::round(value / mGrain) * mGrain;
146 
147  if (sliderTest > -1)
148  {
149  SetValue(Clip(value, 0., 1.), sliderTest);
150  OnNewValue(sliderTest, GetValue(sliderTest));
151 
152  mSliderHit = sliderTest;
153  mMouseOverTrack = mSliderHit;
154 
155  if (!GetStepped() && mPrevSliderHit != -1) // LERP disabled when stepped
156  {
157  if (abs(mPrevSliderHit - mSliderHit) > 1 /*|| shiftClicked*/)
158  {
159  int lowBounds, highBounds;
160 
161  if (mPrevSliderHit < mSliderHit)
162  {
163  lowBounds = mPrevSliderHit;
164  highBounds = mSliderHit;
165  }
166  else
167  {
168  lowBounds = mSliderHit;
169  highBounds = mPrevSliderHit;
170  }
171 
172  for (auto i = lowBounds; i < highBounds; i++)
173  {
174  double frac = (double)(i - lowBounds) / double(highBounds-lowBounds);
175  SetValue(iplug::Lerp(GetValue(lowBounds), GetValue(highBounds), frac), i);
176  OnNewValue(i, GetValue(i));
177  }
178  }
179  }
180  mPrevSliderHit = mSliderHit;
181  }
182  else
183  {
184  mSliderHit = -1;
185  }
186 
187  SetDirty(true); // will send all param vals to delegate
188  }
189 
190  void OnMouseDown(float x, float y, const IMouseMod& mod) override
191  {
192  // This allows single clicking to remove a step entry when !mZeroValueStepHasBounds
193  if(GetStepped() && !mZeroValueStepHasBounds && mPrevSliderHit != -1)
194  {
195  int ch = GetValIdxForPos(x, y);
196 
197  if(ch > -1)
198  {
199  int step = GetStepIdxForPos(x, y);
200 
201  if(step > -1)
202  {
203  float y = mStepBounds.Get()[step].T;
204  double valueAtStep = 1.f - (y-mWidgetBounds.T) / mWidgetBounds.H();
205 
206  if(GetValue(ch) == valueAtStep)
207  {
208  SetValue(0., ch);
209  OnNewValue(ch, 0.);
210  SetDirty(true);
211  return;
212  }
213  }
214  }
215  }
216 
217  if (!mod.S)
218  mPrevSliderHit = -1;
219 
220  SnapToMouse(x, y, mDirection, mWidgetBounds);
221  }
222 
223  void OnMouseDrag(float x, float y, float dX, float dY, const IMouseMod& mod) override
224  {
225  SnapToMouse(x, y, mDirection, mWidgetBounds);
226  }
227 
228  void OnMsgFromDelegate(int msgTag, int dataSize, const void* pData) override
229  {
230  if (!IsDisabled() && msgTag == kMsgTagSetHighlight && dataSize == sizeof(int))
231  {
232  SetHighlightedTrack(*reinterpret_cast<const int*>(pData));
233  }
234  }
235 
237  virtual void OnNewValue(int trackIdx, double val)
238  {
239  if(mOnNewValueFunc)
240  mOnNewValueFunc(trackIdx, val);
241  }
242 
243  void SetOnNewValueFunc(OnNewValueFunc func)
244  {
245  mOnNewValueFunc = func;
246  }
247 
248  int GetLastSliderHit() const
249  {
250  return mSliderHit;
251  }
252 
253 protected:
254  OnNewValueFunc mOnNewValueFunc = nullptr;
255  int mPrevSliderHit = -1;
256  int mSliderHit = -1;
257  double mGrain = 0.001;
258 };
259 
262 template <int MAXNC = 1>
264 {
265 public:
266  IVMultiToggleControl(const IRECT& bounds, const char* label, const IVStyle& style = DEFAULT_STYLE, EDirection dir = EDirection::Vertical)
267  : IVMultiSliderControl<MAXNC>(bounds, label, style, 1, dir)
268  {
271  }
272 };
273 
274 END_IGRAPHICS_NAMESPACE
275 END_IPLUG_NAMESPACE
Used to manage a rectangular area, independent of draw class/platform.
virtual void OnNewValue(int trackIdx, double val)
override to do something when an individual slider is dragged
void OnMouseDown(float x, float y, const IMouseMod &mod) override
Implement this method to respond to a mouse down event on this control.
void Draw(IGraphics &g) override
Draw the control to the graphics context.
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
IVMultiSliderControl(const IRECT &bounds, const char *label, const IVStyle &style=DEFAULT_STYLE, int nSteps=0, EDirection dir=EDirection::Vertical)
Constructs a vector multi slider control that is not linked to parameters.
Used to manage mouse modifiers i.e.
T Lerp(T a, T b, T f)
Linear interpolate between values a and b.
void OnMouseDrag(float x, float y, float dX, float dY, const IMouseMod &mod) override
Implement this method to respond to a mouse drag event on this control.
void OnMsgFromDelegate(int msgTag, int dataSize, const void *pData) override
Implement to receive messages sent to the control, see IEditorDelegate:SendControlMsgFromDelegate() ...
This file contains the base IControl implementation, along with some base classes for specific types ...
bool IsDisabled() const
Definition: IControl.h:356
A base class for mult-strip/track controls, such as multi-sliders, meters Track refers to the channel...
Definition: IControl.h:1248
float H() const
float W() const
const IColor & GetColor(EVColor color) const
Get value of a specific EVColor in the IVControl.
Definition: IControl.h:664
void DrawWidget(IGraphics &g) override
Draw the IVControl main widget (override)
Definition: IControl.h:1375
The lowest level base class of an IGraphics context.
Definition: IGraphics.h:86
virtual void DrawLabel(IGraphics &g)
Draw the IVControl label text.
Definition: IControl.h:746
BEGIN_IPLUG_NAMESPACE T Clip(T x, T lo, T hi)
Clips the value x between lo and hi.
int NVals() const
Definition: IControl.h:233
void Constrain(float &x, float &y) const
Ensure the point (x,y) is inside this IRECT.
IVMultiSliderControl(const IRECT &bounds, const char *label, const IVStyle &style, const std::initializer_list< int > &params, int nSteps, EDirection dir)
Constructs a vector multi slider control that is linked to a list of parameters that need not be sequ...
double GetValue(int valIdx=0) const
Get the control&#39;s value.
Definition: IControl.cpp:151
void SnapToMouse(float x, float y, EDirection direction, const IRECT &bounds, int valIdx=-1, double minClip=0., double maxClip=1.) override
Set control value based on x, y position within a rectangle.
float L
Left side of the rectangle (X)
int GetValIdxForPos(float x, float y) const override
Check to see which of the control&#39;s values relates to this x and y coordinate.
Definition: IControl.h:1360
A vectorial multi-slider control.
A vectorial multi-toggle control, could be used for a trigger in a step sequencer or tarnce gate...
virtual void SetValue(double value, int valIdx=0)
Set one of the control&#39;s values.
Definition: IControl.cpp:145
IVMultiSliderControl(const IRECT &bounds, const char *label, const IVStyle &style, int loParamIdx, int nSteps, EDirection dir)
Constructs a vector multi slider control that is linked to sequential parameters. ...
float T
Top of the rectangle (Y)
virtual void DrawBackground(IGraphics &g, const IRECT &r) override
Draw the IVControl background (usually transparent)
Definition: IControl.h:1480
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