iPlug2 - C++ Audio Plug-in Framework
IVDisplayControl.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 
22 BEGIN_IPLUG_NAMESPACE
23 BEGIN_IGRAPHICS_NAMESPACE
24 
26 class IVDisplayControl : public IControl
27  , public IVectorBase
28 {
29 public:
30  static constexpr int MAX_BUFFER_SIZE = 2048;
31 
32  IVDisplayControl(const IRECT& bounds, const char* label = "", const IVStyle& style = DEFAULT_STYLE, EDirection dir = EDirection::Horizontal, float lo = 0., float hi = 1.f, float defaultVal = 0., uint32_t bufferSize = 100, float strokeThickness = 2.f)
33  : IControl(bounds)
34  , IVectorBase(style)
35  , mBuffer(bufferSize, defaultVal)
36  , mLoValue(lo)
37  , mHiValue(hi)
38  , mStrokeThickness(strokeThickness)
39  , mDirection(dir)
40  {
41  assert(bufferSize > 0 && bufferSize < MAX_BUFFER_SIZE);
42 
43  AttachIControl(this, label);
44  }
45 
46  void Update(float v)
47  {
48  mBuffer[mReadPos] = v;
49  mReadPos = (mReadPos+1) % mBuffer.size();
50  SetDirty(false);
51  }
52 
53  void OnResize() override
54  {
55  SetTargetRECT(MakeRects(mRECT));
56 
57  mPlotBounds = mWidgetBounds.GetPadded(mDirection == EDirection::Horizontal ? 0.f : -mStrokeThickness,
58  mDirection == EDirection::Horizontal ? -mStrokeThickness : 0.f,
59  mDirection == EDirection::Horizontal ? 0.f : -mStrokeThickness,
60  mDirection == EDirection::Horizontal ? -mStrokeThickness : 0.f);
61 
62  SetDirty(false);
63  }
64 
65  void Draw(IGraphics& g) override
66  {
67  DrawBackground(g, mRECT);
68  DrawWidget(g);
69  DrawLabel(g);
70 
71  if(mStyle.drawFrame)
72  g.DrawRect(GetColor(kFR), mWidgetBounds, &mBlend, mStyle.frameThickness);
73  }
74 
75  void DrawWidget(IGraphics& g) override
76  {
77  float x = mPlotBounds.L;
78  float y = mPlotBounds.T;
79  float w = mPlotBounds.W();
80  float h = mPlotBounds.H();
81 
82  const int sz = static_cast<int>(mBuffer.size());
83 
84  auto getPlotPos = [&](int pos, float axis, float extrem) {
85  float v = mBuffer[(mReadPos+pos) % sz];
86  v = (v - mLoValue) / (mHiValue - mLoValue);
87  return axis + extrem - (v * extrem);
88  };
89 
90  if(mDirection == EDirection::Horizontal)
91  {
92  g.PathMoveTo(x, getPlotPos(0, y, h));
93 
94  for (int i = 0; i < sz; i++)
95  {
96  float vx = x + ((float)i/(sz-1)) * w;
97  float vy = getPlotPos(i, y, h);
98  g.PathLineTo(vx, vy);
99  }
100  }
101  else
102  {
103  g.PathMoveTo(getPlotPos(0, x, w), y);
104 
105  for (int i = 0; i < sz; i++)
106  {
107  float vx = getPlotPos(i, x, w);
108  float vy = y + ((float)i/(sz-1)) * h;
109  g.PathLineTo(vx, vy);
110  }
111  }
112 
113  g.PathStroke(IPattern::CreateLinearGradient(mPlotBounds, mDirection, {{COLOR_TRANSPARENT, 0.f}, {GetColor(kX1), 1.f}}), mStrokeThickness, IStrokeOptions(), &mBlend);
114  }
115 
116  void OnMsgFromDelegate(int msgTag, int dataSize, const void* pData) override
117  {
118  if (!IsDisabled() && msgTag == ISender<>::kUpdateMessage)
119  {
120  IByteStream stream(pData, dataSize);
121 
122  int pos = 0;
123  ISenderData<1> d;
124  pos = stream.Get(&d, pos);
125  Update(d.vals[0]);
126  SetDirty(false);
127  }
128  }
129 
130 private:
131  std::vector<float> mBuffer;
132  float mLoValue = 0.f;
133  float mHiValue = 1.f;
134  int mReadPos = 0;
135  float mStrokeThickness = 2.f;
136  EDirection mDirection;
137  IRECT mPlotBounds;
138 };
139 
140 END_IGRAPHICS_NAMESPACE
141 END_IPLUG_NAMESPACE
int Get(T *pDst, int startPos) const
Get arbitary typed data from the stream.
Definition: IPlugStructs.h:289
virtual void PathMoveTo(float x, float y)=0
Move the current point in the current path.
The lowest level base class of an IGraphics control.
Definition: IControl.h:42
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
virtual void DrawBackground(IGraphics &g, const IRECT &rect)
Draw the IVControl background (usually transparent)
Definition: IControl.h:733
virtual void PathLineTo(float x, float y)=0
Add a line to the current path from the current point to the specified location.
virtual void PathStroke(const IPattern &pattern, float thickness, const IStrokeOptions &options=IStrokeOptions(), const IBlend *pBlend=0)=0
Stroke the current current path.
Used to manage stroke behaviour for path based drawing back ends.
ISender is a utility class which can be used to defer data from the realtime audio processing and sen...
void AttachIControl(IControl *pControl, const char *label)
Call in the constructor of your IVControl to link the IVectorBase and IControl.
Definition: IControl.h:641
void OnResize() override
Called when IControl is constructed or resized using SetRect().
This file contains the base IControl implementation, along with some base classes for specific types ...
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
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
float W() const
void Draw(IGraphics &g) override
Draw the control to the graphics context.
const IColor & GetColor(EVColor color) const
Get value of a specific EVColor in the IVControl.
Definition: IControl.h:664
IControl(const IRECT &bounds, int paramIdx=kNoParameter, IActionFunction actionFunc=nullptr)
Constructor.
Definition: IControl.cpp:81
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
virtual void DrawLabel(IGraphics &g)
Draw the IVControl label text.
Definition: IControl.h:746
void OnMsgFromDelegate(int msgTag, int dataSize, const void *pData) override
Implement to receive messages sent to the control, see IEditorDelegate:SendControlMsgFromDelegate() ...
void DrawWidget(IGraphics &g) override
Draw the IVControl main widget (override)
void SetTargetRECT(const IRECT &bounds)
Set the rectangular mouse tracking target area, within the graphics context for this control...
Definition: IControl.h:317
float L
Left side of the rectangle (X)
ISender is a utility class which can be used to defer data from the realtime audio processing and sen...
Definition: ISender.h:57
static IPattern CreateLinearGradient(float x1, float y1, float x2, float y2, const std::initializer_list< IColorStop > &stops={})
Create a linear gradient IPattern.
IRECT GetPadded(float padding) const
Get a copy of this IRECT with each value padded by padding N.B.
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
A control to display a rolling graphics of historical values.
float T
Top of the rectangle (Y)
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