iPlug2 - C++ Audio Plug-in Framework
IVMeterControl.h
Go to the documentation of this file.
1 /*
2  ==============================================================================
3 
4  This file is part of the iPlug 2 library. Copyright (C) the iPlug 2 developers.
5 
6  See LICENSE.txt for more info.
7 
8  ==============================================================================
9 */
10 
11 #pragma once
12 
19 #include "IControl.h"
20 #include "ISender.h"
21 #include "IPlugStructs.h"
22 
23 BEGIN_IPLUG_NAMESPACE
24 BEGIN_IGRAPHICS_NAMESPACE
25 
28 template <int MAXNC = 1>
30 {
31 public:
32  IVMeterControl(const IRECT& bounds, const char* label, const IVStyle& style = DEFAULT_STYLE, EDirection dir = EDirection::Vertical, std::initializer_list<const char*> trackNames = {}, int totalNSegs = 0, float lowRangeDB = -72.f, float highRangeDB = 12.f)
33  : IVTrackControlBase(bounds, label, style, MAXNC, totalNSegs, dir, trackNames)
34  , mLowRangeDB(lowRangeDB)
35  , mHighRangeDB(highRangeDB)
36  {
37  }
38 
39  void Draw(IGraphics& g) override
40  {
41  DrawBackground(g, mRECT);
42  DrawWidget(g);
43  DrawLabel(g);
44 
45  if(mStyle.drawFrame)
46  g.DrawRect(GetColor(kFR), mWidgetBounds, &mBlend, mStyle.frameThickness);
47  }
48 
49  void OnMsgFromDelegate(int msgTag, int dataSize, const void* pData) override
50  {
51  if (!IsDisabled() && msgTag == ISender<>::kUpdateMessage)
52  {
53  IByteStream stream(pData, dataSize);
54 
55  int pos = 0;
57  pos = stream.Get(&d, pos);
58 
59  double lowPointAbs = std::fabs(mLowRangeDB);
60  double rangeDB = std::fabs(mHighRangeDB - mLowRangeDB);
61  for (auto c = d.chanOffset; c < (d.chanOffset + d.nChans); c++)
62  {
63  double ampValue = AmpToDB(static_cast<double>(d.vals[c]));
64  double linearPos = (ampValue + lowPointAbs)/rangeDB;
65  SetValue(Clip(linearPos, 0., 1.), c);
66  }
67 
68  SetDirty(false);
69  }
70  }
71 protected:
72  float mHighRangeDB;
73  float mLowRangeDB;
74 };
75 
76 const static IColor LED1 = {255, 36, 157, 16};
77 const static IColor LED2 = {255, 153, 191, 28};
78 const static IColor LED3 = {255, 215, 222, 37};
79 const static IColor LED4 = {255, 247, 153, 33};
80 const static IColor LED5 = COLOR_RED;
81 
84 template <int MAXNC = 1>
85 class IVLEDMeterControl : public IVMeterControl<MAXNC>
86 {
87 public:
89  struct LEDRange
90  {
91  float lowRangeDB; // The lower bounds of the decibel range for this group of LED segments
92  float highRangeDB; // The upper bounds of the decibel range for this group of LED segments
93  int nSegs; // The number of LED segments
94  IColor color; // The color of the LEDs in this range
95 
96  LEDRange(float lowRangeDB, float highRangeDB, int nSegs, IColor color)
97  : lowRangeDB(lowRangeDB)
98  , highRangeDB(highRangeDB)
99  , nSegs(nSegs)
100  , color(color)
101  {
102  }
103  };
104 
105  IVLEDMeterControl(const IRECT& bounds, int totalNSegs = 13, const std::vector<LEDRange>& ranges = {{0., 6., 1, LED5},{-18., 0., 3, LED4}, {-36., -18., 3, LED3}, {-54., -36., 3, LED2}, {-72., -54., 3, LED1}}, const char* label = "", const IVStyle& style = DEFAULT_STYLE, EDirection dir = EDirection::Vertical, std::initializer_list<const char*> trackNames = {})
106  : IVMeterControl<MAXNC>(bounds, label, style, dir, trackNames, totalNSegs)
107  , mLEDRanges(ranges)
108  {
110 
111  float minRange = 0.;
112  float maxRange = 0.;
113  int nSegs = 0;
114 
115  for (auto ledRange : ranges)
116  {
117  if(ledRange.lowRangeDB < minRange)
118  minRange = ledRange.lowRangeDB;
119 
120  if(ledRange.highRangeDB > maxRange)
121  maxRange = ledRange.highRangeDB;
122 
123  nSegs += ledRange.nSegs;
124  }
125 
126  assert(totalNSegs == nSegs); // The ranges argument must contain the same number of segments as totalNSegs
127 
130  }
131 
132  void Draw(IGraphics& g) override
133  {
137  }
138 
139  void DrawTrackBackground(IGraphics &g, const IRECT &r, int chIdx) override
140  {
141  const int totalNSegs = IVMeterControl<MAXNC>::mNSteps;
142  const EDirection dir = IVMeterControl<MAXNC>::mDirection;
143  const float val = IVMeterControl<MAXNC>::GetValue(chIdx);
144  const float valPos = (dir == EDirection::Vertical) ? r.B - (val * r.H()) : r.R - ((1.f-val) * r.W()); // threshold position for testing segment
145 
146  int segIdx = 0; // keep track of how many segments have been drawn
147 
148  for (auto ledRange : mLEDRanges)
149  {
150  for (auto i = 0; i < ledRange.nSegs; i++)
151  {
152  IRECT segRect;
153  if(dir == EDirection::Vertical)
154  {
155  segRect = r.GetGridCell(segIdx + i, totalNSegs, 1, dir, 1);
156 
157  if(segRect.MH() > valPos)
158  g.FillRect(ledRange.color, segRect.GetPadded(-1.f));
159  }
160  else
161  {
162  segRect = r.GetGridCell(totalNSegs - 1 - (segIdx + i), 1, totalNSegs, dir, 1);
163 
164  if(segRect.MW() < valPos)
165  g.FillRect(ledRange.color, segRect.GetPadded(-1.f));
166  }
167  }
168  segIdx += ledRange.nSegs;
169  }
170  }
171 
172  void DrawTrackHandle(IGraphics &g, const IRECT &r, int chIdx, bool aboveBaseValue) override
173  {
174  /* NO-OP */
175  }
176 
177 private:
178  std::vector<LEDRange> mLEDRanges;
179 };
180 
181 END_IGRAPHICS_NAMESPACE
182 END_IPLUG_NAMESPACE
int Get(T *pDst, int startPos) const
Get arbitary typed data from the stream.
Definition: IPlugStructs.h:289
float MW() const
float MH() const
Used to manage a rectangular area, independent of draw class/platform.
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
void DrawTrackHandle(IGraphics &g, const IRECT &r, int chIdx, bool aboveBaseValue) override
Draw the main body of the track.
Used to manage color data, independent of draw class/platform.
Vectorial multi-channel capable meter control.
ISender is a utility class which can be used to defer data from the realtime audio processing and sen...
This file contains the base IControl implementation, along with some base classes for specific types ...
float R
Right side of the rectangle (X + W)
void Draw(IGraphics &g) override
Draw the control to the graphics context.
Manages a non-owned block of memory, for receiving arbitrary message byte streams.
Definition: IPlugStructs.h:267
bool IsDisabled() const
Definition: IControl.h:356
ISenderData is used to represent a typed data packet, that may contain values for multiple channels...
Definition: ISender.h:30
A base class for mult-strip/track controls, such as multi-sliders, meters Track refers to the channel...
Definition: IControl.h:1248
Vectorial multi-channel capable meter control with segmented LEDs.
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
LED Range comprises info for a range of LED segments.
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
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
BEGIN_IPLUG_NAMESPACE T Clip(T x, T lo, T hi)
Clips the value x between lo and hi.
void OnMsgFromDelegate(int msgTag, int dataSize, const void *pData) override
Implement to receive messages sent to the control, see IEditorDelegate:SendControlMsgFromDelegate() ...
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) ...
double GetValue(int valIdx=0) const
Get the control&#39;s value.
Definition: IControl.cpp:151
ISender is a utility class which can be used to defer data from the realtime audio processing and sen...
Definition: ISender.h:57
IRECT GetPadded(float padding) const
Get a copy of this IRECT with each value padded by padding N.B.
virtual void SetValue(double value, int valIdx=0)
Set one of the control&#39;s values.
Definition: IControl.cpp:145
void Draw(IGraphics &g) override
Draw the control to the graphics context.
static double AmpToDB(double amp)
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
float B
Bottom of the rectangle (Y + H)