23 BEGIN_IGRAPHICS_NAMESPACE
62 static const IColor DEFAULT_BK_COLOR;
63 static const IColor DEFAULT_WK_COLOR;
64 static const IColor DEFAULT_PK_COLOR;
65 static const IColor DEFAULT_FR_COLOR;
66 static const IColor DEFAULT_HK_COLOR;
69 const IColor& WK_COLOR = DEFAULT_WK_COLOR,
70 const IColor& BK_COLOR = DEFAULT_BK_COLOR,
71 const IColor& PK_COLOR = DEFAULT_PK_COLOR,
72 const IColor& FR_COLOR = DEFAULT_FR_COLOR,
73 const IColor& HK_COLOR = DEFAULT_HK_COLOR)
80 , mRoundedKeys(roundedKeys)
82 mText.mFGColor = FR_COLOR;
83 mDblAsSingleClick =
true;
84 bool keepWidth = !(bounds.
W() <= 0.0);
85 if (bounds.
W() <= 0.0)
87 mRECT.
R = mRECT.
L + mRECT.
H();
91 SetNoteRange(minNote, maxNote, keepWidth);
97 int prevKey = mLastTouchedKey;
98 mLastTouchedKey = GetKeyAtPoint(x, y);
100 SetKeyIsPressed(mLastTouchedKey,
true);
102 mMouseOverKey = mLastTouchedKey;
104 if(mLastTouchedKey != prevKey)
106 mLastVelocity = GetVelocity(y);
108 TriggerMidiMsgFromKeyPress(mLastTouchedKey, (
int) (mLastVelocity * 127.f));
116 if (mLastTouchedKey > -1)
118 SetKeyIsPressed(mLastTouchedKey,
false);
119 TriggerMidiMsgFromKeyPress(mLastTouchedKey, 0);
121 mLastTouchedKey = -1;
131 if (mLastTouchedKey > -1 || mShowNoteAndVel)
133 mLastTouchedKey = -1;
142 int prevKey = mLastTouchedKey;
143 mLastTouchedKey = GetKeyAtPoint(x, y);
145 SetKeyIsPressed(mLastTouchedKey,
true);
147 mMouseOverKey = mLastTouchedKey;
149 if(mLastTouchedKey != prevKey)
151 mLastVelocity = GetVelocity(y);
153 TriggerMidiMsgFromKeyPress(mLastTouchedKey, (
int) (mLastVelocity * 127.f));
155 TriggerMidiMsgFromKeyPress(prevKey, 0);
156 SetKeyIsPressed(prevKey,
false);
167 mMouseOverKey = GetKeyAtPoint(x, y);
174 if (mLastTouchedKey > -1)
176 SetKeyIsPressed(mLastTouchedKey,
false);
177 TriggerMidiMsgFromKeyPress(mLastTouchedKey, 0);
179 mLastTouchedKey = -1;
189 float r = mRECT.
W() / mTargetRECT.
W();
190 float dx = mRECT.
L - mTargetRECT.
L;
192 for (
int i = 0; i < NKeys(); ++i)
194 float* pKeyL = GetKeyXPos(i);
195 float d = *pKeyL - mRECT.
L;
196 *pKeyL = mRECT.
L + d * r + dx;
207 case IMidiMsg::kNoteOn:
210 case IMidiMsg::kNoteOff:
213 case IMidiMsg::kControlChange:
215 ClearNotesFromMidi();
227 g.
FillRoundRect(color, bounds, 0., 0., mRoundness, mRoundness);
237 float BKBottom = mRECT.
T + mRECT.
H() * mBKHeightRatio;
238 float BKWidth = GetBKWidth();
241 for (
int i = 0; i < NKeys(); ++i)
245 float kL = *GetKeyXPos(i);
246 IRECT keyBounds =
IRECT(kL, mRECT.
T, kL + mWKWidth, mRECT.
B);
248 DrawKey(g, keyBounds, i == mHighlight ? mHK_COLOR : mWK_COLOR);
250 if (GetKeyIsPressed(i))
253 DrawKey(g, keyBounds, mPK_COLOR);
257 IRECT shadowBounds = keyBounds;
258 shadowBounds.
R = shadowBounds.
L + 0.35f * shadowBounds.
W();
261 g.
FillRect(shadowColor, shadowBounds, &mBlend);
263 g.
FillRoundRect(shadowColor, shadowBounds, 0., 0., mRoundness, mRoundness, &mBlend);
267 if (mDrawFrame && i != 0)
269 g.
DrawLine(mFR_COLOR, kL, mRECT.
T, kL, mRECT.
B, &mBlend, mFrameThickness);
270 if (i == NKeys() - 2 && IsBlackKey(NKeys() - 1))
271 g.
DrawLine(mFR_COLOR, kL + mWKWidth, mRECT.
T, kL + mWKWidth, mRECT.
B, &mBlend, mFrameThickness);
277 for (
int i = 0; i < NKeys(); ++i)
281 float kL = *GetKeyXPos(i);
282 IRECT keyBounds =
IRECT(kL, mRECT.
T, kL + BKWidth, BKBottom);
284 if (mDrawShadows && !GetKeyIsPressed(i) && i < NKeys() - 1)
286 IRECT shadowBounds = keyBounds;
287 float w = shadowBounds.
W();
288 shadowBounds.
L += 0.6f * w;
289 if (GetKeyIsPressed(i + 1))
293 shadowBounds.
B = shadowBounds.
T + 1.05f * shadowBounds.
H();
295 shadowBounds.
R = shadowBounds.
L + w;
296 DrawKey(g, shadowBounds, shadowColor);
298 DrawKey(g, keyBounds, (i == mHighlight ? mHK_COLOR : mBK_COLOR.
WithContrast(
IsDisabled() ? GRAYED_ALPHA : 0.f)));
300 if (GetKeyIsPressed(i))
304 cBP.A = (int) mBKAlpha;
305 g.
FillRect(cBP, keyBounds, &mBlend);
311 if (mBKHeightRatio != 1.0)
312 g.
DrawLine(mFR_COLOR, kL, BKBottom, kL + BKWidth, BKBottom, &mBlend);
314 g.
DrawLine(mFR_COLOR, kL, mRECT.
T, kL, BKBottom, &mBlend);
315 if (i != NKeys() - 1)
316 g.
DrawLine(mFR_COLOR, kL + BKWidth, mRECT.
T, kL + BKWidth, BKBottom, &mBlend);
322 g.
DrawRect(mFR_COLOR, mRECT, &mBlend, mFrameThickness);
326 if (mMouseOverKey > -1)
328 IRECT r =
IRECT(*GetKeyXPos(mMouseOverKey), mRECT.
T, 0, 0);
329 r.
B = r.
T + 1.2f * mText.mSize;
332 GetNoteNameStr(mMinNote + mMouseOverKey,
false, t);
333 if (mLastTouchedKey > -1)
335 t.AppendFormatted(16,
", vel: %3.2f", mLastVelocity * 127.f);
338 float e = r.
R - mRECT.
R;
346 g.
DrawText(mText, t.Get(), r, &mBlend);
354 ti.SetFormatted(32,
"key: %d, vel: %3.2f", mLastTouchedKey, mLastVelocity * 127.f);
356 IText txt(20, COLOR_RED);
357 IRECT tr(mRECT.
L + 20, mRECT.
B - 20, mRECT.
L + 160, mRECT.
B);
358 g.
DrawText(txt, ti.Get(), tr, &mBlend);
364 void SetNoteRange(
int min,
int max,
bool keepWidth =
true)
366 if (min < 0 || max < 0)
return;
378 mPressedKeys.Resize(NKeys());
379 memset(mPressedKeys.Get(), 0, mPressedKeys.GetSize() *
sizeof(bool));
381 RecreateKeyBounds(keepWidth);
384 void SetNoteFromMidi(
int noteNum,
bool played)
386 if (noteNum < mMinNote || noteNum > mMaxNote)
return;
387 SetKeyIsPressed(noteNum - mMinNote, played);
390 void SetKeyIsPressed(
int key,
bool pressed)
392 mPressedKeys.Get()[key] = pressed;
396 void SetKeyHighlight(
int key)
402 void ClearNotesFromMidi()
404 memset(mPressedKeys.Get(), 0, mPressedKeys.GetSize() *
sizeof(bool));
408 void SetBlackToWhiteRatios(
float widthRatio,
float heightRatio = 0.6)
410 widthRatio =
Clip(widthRatio, 0.1f, 1.f);
411 heightRatio =
Clip(heightRatio, 0.1f, 1.f);
413 float halfW = 0.5f * mWKWidth * mBKWidthRatio;
414 float r = widthRatio / mBKWidthRatio;
415 mBKWidthRatio = widthRatio;
416 mBKHeightRatio = heightRatio;
418 for (
int i = 0; i < NKeys(); ++i)
422 float* pKeyL = GetKeyXPos(i);
423 float mid = *pKeyL + halfW;
424 *pKeyL = mid - halfW * r;
425 if (*pKeyL < mRECT.
L)
433 void SetHeight(
float h,
bool keepAspectRatio =
false)
435 if (h <= 0.0)
return;
436 float r = h / mRECT.
H();
437 mRECT.
B = mRECT.
T + mRECT.
H() * r;
442 SetWidth(mRECT.
W() * r);
446 void SetWidth(
float w,
bool keepAspectRatio =
false)
448 if (w <= 0.0)
return;
449 float r = w / mRECT.
W();
450 mRECT.
R = mRECT.
L + mRECT.
W() * r;
452 for (
int i = 0; i < NKeys(); ++i)
454 float* pKeyL = GetKeyXPos(i);
455 float d = *pKeyL - mRECT.
L;
456 *pKeyL = mRECT.
L + d * r;
462 SetHeight(mRECT.
H() * r);
467 void SetShowNotesAndVelocity(
bool show)
469 mShowNoteAndVel = show;
472 void SetColors(
const IColor BKColor,
const IColor& WKColor,
const IColor& PKColor = DEFAULT_PK_COLOR,
const IColor& FRColor = DEFAULT_FR_COLOR)
479 mBKAlpha = (float) PKColor.A;
481 if (mBKAlpha < 240.f)
483 const float lumWK = WKColor.
GetLuminosity() * WKColor.A / 255.f;
484 const float adjustment = PKColor.A / 255.f;
485 const float lumPK = PKColor.GetLuminosity() * adjustment;
486 const float lumRes = (1.f - adjustment) * lumWK + lumPK;
487 const float lumDW = lumRes - lumWK;
488 const float lumBK = BKColor.
GetLuminosity() * BKColor.A / 255.f;
490 if ((lumDW < 0 && lumBK < lumWK) || (lumDW > 0 && lumBK > lumWK))
492 float dbWB = lumWK - lumBK;
493 mBKAlpha += (255.f - mBKAlpha) * (1.f - dbWB * dbWB / 255.f / 255.f) + 0.5f;
496 mBKAlpha += lumDW + 0.5f;
498 mBKAlpha =
Clip(mBKAlpha, 15.f, 255.f);
505 int GetMidiNoteNumberForKey(
int key)
const 507 if (key > -1)
return mMinNote + key;
514 void RecreateKeyBounds(
bool keepWidth)
520 mIsBlackKeyList.Resize(NKeys());
521 mKeyXPos.Resize(NKeys());
523 float numWhites = 0.f;
524 for (
int n = mMinNote, i = 0; n <= mMaxNote; ++n, i++)
526 if (n % 12 == 1 || n % 12 == 3 || n % 12 == 6 || n % 12 == 8 || n % 12 == 10)
528 mIsBlackKeyList.Get()[i] =
true;
532 mIsBlackKeyList.Get()[i] =
false;
538 float WKPadStart = 0.f;
539 float WKPadEnd = 0.f;
541 auto GetShiftForPitchClass = [
this](
int pitch) {
544 if (pitch == 0)
return 0.f;
545 else if (pitch % 12 == 1)
return 7.f / 12.f;
546 else if (pitch % 12 == 3)
return 5.f / 12.f;
547 else if (pitch % 12 == 6)
return 2.f / 3.f;
548 else if (pitch % 12 == 8)
return 0.5f;
549 else if (pitch % 12 == 10)
return 1.f / 3.f;
553 WKPadStart = GetShiftForPitchClass(mMinNote);
555 if (mMinNote != mMaxNote && IsBlackKey(mIsBlackKeyList.GetSize() - 1))
556 WKPadEnd = 1.f - GetShiftForPitchClass(mMaxNote);
560 mWKWidth = 0.2f * mRECT.
H();
564 mWKWidth = mRECT.
W();
566 mWKWidth /= (numWhites + mBKWidthRatio * (WKPadStart + WKPadEnd));
569 float BKWidth = mWKWidth;
572 BKWidth *= mBKWidthRatio;
574 float prevWKLeft = mRECT.
L;
576 for (
int k = 0; k < mIsBlackKeyList.GetSize(); ++k)
580 float l = prevWKLeft;
583 l -= GetShiftForPitchClass(mMinNote + k) * BKWidth;
585 else prevWKLeft += WKPadStart * BKWidth;
586 mKeyXPos.Get()[k] = l;
590 mKeyXPos.Get()[k] = prevWKLeft;
591 prevWKLeft += mWKWidth;
599 int GetKeyAtPoint(
float x,
float y)
604 float BKBottom = mRECT.
T + mRECT.
H() * mBKHeightRatio;
605 float BKWidth = GetBKWidth();
609 for (
int i = 0; i < NKeys(); ++i)
613 float kL = *GetKeyXPos(i);
614 IRECT keyBounds =
IRECT(kL, mRECT.
T, kL + BKWidth, BKBottom);
625 for (
int i = 0; i < NKeys(); ++i)
629 float kL = *GetKeyXPos(i);
630 IRECT keyBounds =
IRECT(kL, mRECT.
T, kL + mWKWidth, mRECT.
B);
643 float GetVelocity(
float yPos)
647 if (mLastTouchedKey > -1)
651 if (IsBlackKey(mLastTouchedKey))
654 float fracPos = (yPos - mRECT.
T) / (0.95f * h);
656 velocity =
Clip(fracPos, 1.f / 127.f, 1.f);
662 void GetNoteNameStr(
int midiNoteNum,
bool addOctave, WDL_String& str)
664 int oct = midiNoteNum / 12;
665 midiNoteNum -= 12 * oct;
666 const char* notes[12] = {
"C",
"C#",
"D",
"D#",
"E",
"F",
"F#",
"G",
"G#",
"A",
"A#",
"B" };
667 const char* n = notes[midiNoteNum];
670 str.AppendFormatted(2,
"%d", --oct);
673 bool IsBlackKey(
int i)
const {
return *(mIsBlackKeyList.Get() + i); }
675 float* GetKeyXPos(
int i) {
return mKeyXPos.Get() + i; }
677 bool GetKeyIsPressed(
int i)
const {
return *(mPressedKeys.Get() + i); }
679 int NKeys()
const {
return mMaxNote - mMinNote + 1; }
681 float GetBKWidth()
const 689 void TriggerMidiMsgFromKeyPress(
int key,
int velocity)
693 const int nn = GetMidiNoteNumberForKey(key);
710 bool mRoundedKeys =
false;
711 float mRoundness = 5.f;
712 bool mDrawShadows =
false;
713 bool mDrawFrame =
true;
714 float mFrameThickness = 1.f;
715 bool mShowNoteAndVel =
false;
716 float mWKWidth = 0.f;
717 float mBKWidthRatio = 0.6f;
718 float mBKHeightRatio = 0.6f;
719 float mBKAlpha = 100.f;
720 int mLastTouchedKey = -1;
721 float mLastVelocity = 0.f;
722 int mMouseOverKey = -1;
723 int mMinNote, mMaxNote;
724 WDL_TypedBuf<bool> mIsBlackKeyList;
725 WDL_TypedBuf<bool> mPressedKeys;
726 WDL_TypedBuf<float> mKeyXPos;
734 static constexpr
int kSpringAnimationTime = 50;
735 static constexpr
int kNumRungs = 10;
737 static constexpr
int kMessageTagSetPitchBendRange = 0;
743 :
ISliderControlBase(bounds, kNoParameter, EDirection::Vertical, DEFAULT_GEARING, 40.f)
744 , mPitchBendRange(initBendRange)
747 mMenu.AddItem(
"1 semitone");
748 mMenu.AddItem(
"2 semitones");
749 mMenu.AddItem(
"Fifth");
750 mMenu.AddItem(
"Octave");
752 SetValue(cc == IMidiMsg::EControlChangeMsg::kNoCC ? 0.5 : 0.);
756 if(cc == IMidiMsg::EControlChangeMsg::kNoCC)
768 const float stepSize = handleBounds.
H() / (float) kNumRungs;
775 if(layerRect.
W() > 0 && layerRect.
H() > 0)
791 const float value =
static_cast<float>(
GetValue());
792 const float y = (handleBounds.
H() - (stepSize)) * value;
793 const float triangleRamp = std::fabs(value-0.5f) * 2.f;
795 g.
DrawBitmap(mLayer->GetBitmap(), handleBounds, 0, (int) y);
808 g.
DrawRect(COLOR_BLACK, handleBounds);
813 if(mCC == IMidiMsg::EControlChangeMsg::kNoCC)
815 if(msg.
StatusMsg() == IMidiMsg::kPitchWheel)
840 switch (pSelectedMenu->GetChosenItemIdx())
842 case 0: mPitchBendRange = 1;
break;
843 case 1: mPitchBendRange = 2;
break;
844 case 2: mPitchBendRange = 7;
break;
847 mPitchBendRange = 12;
break;
856 if(mod.R && mCC == IMidiMsg::EControlChangeMsg::kNoCC)
858 switch (mPitchBendRange)
860 case 1: mMenu.CheckItemAlone(0);
break;
861 case 2: mMenu.CheckItemAlone(1);
break;
862 case 7: mMenu.CheckItemAlone(2);
break;
863 case 12: mMenu.CheckItemAlone(3);
break;
876 if(mCC == IMidiMsg::EControlChangeMsg::kNoCC)
883 pCaller->OnEndAnimation();
886 }, kSpringAnimationTime);
899 END_IGRAPHICS_NAMESPACE
void PathRect(const IRECT &bounds)
Add a rectangle to the current path.
bool Contains(const IRECT &rhs) const
Returns true if this IRECT completely contains rhs.
void StartLayer(IControl *pOwner, const IRECT &r, bool cacheable=false)
Create an IGraphics layer.
void Draw(IGraphics &g) override
Draw the control to the graphics context.
The lowest level base class of an IGraphics control.
Used to manage a rectangular area, independent of draw class/platform.
IGEditorDelegate * GetDelegate()
Gets a pointer to the class implementing the IEditorDelegate interface that handles parameter changes...
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.
void OnTouchCancelled(float x, float y, const IMouseMod &mod) override
Implement this method to respond to a touch cancel event on this control.
virtual void DrawRect(const IColor &color, const IRECT &bounds, const IBlend *pBlend=0, float thickness=1.f)
Draw a rectangle to the graphics context.
int GetTag() const
Get the control's tag.
Encapsulates a MIDI message and provides helper functions.
Used to manage mouse modifiers i.e.
void OnMouseDown(float x, float y, const IMouseMod &mod) override
Implement this method to respond to a mouse down event on this control.
void OnMouseUp(float x, float y, const IMouseMod &mod) override
Implement this method to respond to a mouse up event on this control.
void OnMouseDown(float x, float y, const IMouseMod &mod) override
Implement this method to respond to a mouse down event on this control.
void MakePitchWheelMsg(double value, int channel=0, int offset=0)
Create a pitch wheel/bend message.
void OnMidi(const IMidiMsg &msg) override
Implement to receive MIDI messages sent to the control if mWantsMidi == true, see IEditorDelegate:Sen...
EControlChangeMsg
Constants for MIDI CC messages.
T Lerp(T a, T b, T f)
Linear interpolate between values a and b.
IControl * SetActionFunction(IActionFunction actionFunc)
Set an Action Function for this control.
IColor WithContrast(float c) const
Returns a new contrasted IColor based on this one.
void OnMouseWheel(float x, float y, const IMouseMod &mod, float d) override
Implement this method to respond to a mouse wheel event on this control.
Used to manage color data, independent of draw class/platform.
IRECT GetTranslated(float x, float y) const
Get a translated copy of this rectangle.
int NoteNumber() const
Gets the MIDI note number.
IRECT FracRectVertical(float frac, bool fromTop=false) const
Returns a new IRECT with a height that is multiplied by frac.
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.
virtual void SendArbitraryMsgFromUI(int msgTag, int ctrlTag=kNoTag, int dataSize=0, const void *pData=nullptr)
SendArbitraryMsgFromUI (Abbreviation: SAMFUI)
Vectorial "wheel" control for pitchbender/modwheel.
This file contains the base IControl implementation, along with some base classes for specific types ...
void OnPopupMenuSelection(IPopupMenu *pSelectedMenu, int) override
Implement this method to handle popup menu selection after IGraphics::CreatePopupMenu/IControl::Promp...
float R
Right side of the rectangle (X + W)
void OnMouseOver(float x, float y, const IMouseMod &mod) override
Implement this method to respond to a mouseover event on this control.
void OnMouseOut() override
Implement this method to respond to a mouseout event on this control.
double GetAnimationProgress() const
Get the progress in a control's animation, in the range 0-1.
void CreatePopupMenu(IControl &control, IPopupMenu &menu, const IRECT &bounds, int valIdx=0)
Shows a pop up/contextual menu in relation to a rectangular region of the graphics context...
IColor WithOpacity(float alpha) const
Returns a new IColor with a different opacity.
int Velocity() const
Get the velocity value of a NoteOn/NoteOff message.
void OnMidi(const IMidiMsg &msg) override
Implement to receive MIDI messages sent to the control if mWantsMidi == true, see IEditorDelegate:Sen...
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.
IText is used to manage font and text/text entry style for a piece of text on the UI...
bool CheckLayer(const ILayerPtr &layer)
Test to see if a layer needs drawing, for instance if the control's bounds were changed.
virtual void SendMidiMsgFromUI(const IMidiMsg &msg)
SendMidiMsgFromUI (Abbreviation: SMMFUI) This method should be used when sending a MIDI message from ...
IWheelControl(const IRECT &bounds, IMidiMsg::EControlChangeMsg cc=IMidiMsg::EControlChangeMsg::kNoCC, int initBendRange=12)
Create a WheelControl.
void OnMouseDown(float x, float y, const IMouseMod &mod) override
Implement this method to respond to a mouse down event on this control.
IControl(const IRECT &bounds, int paramIdx=kNoParameter, IActionFunction actionFunc=nullptr)
Constructor.
virtual void PathFill(const IPattern &pattern, const IFillOptions &options=IFillOptions(), const IBlend *pBlend=0)=0
Fill the current current path.
double PitchWheel() const
Get the value from a Pitchwheel message.
void MakeNoteOffMsg(int noteNumber, int offset, int channel=0)
Make a Note Off message.
The lowest level base class of an IGraphics context.
void SetAnimation(IAnimationFunction func)
Set the animation function.
void OnMouseUp(float x, float y, const IMouseMod &mod) override
Implement this method to respond to a mouse up event on this control.
Vectorial keyboard control.
virtual void FillRoundRect(const IColor &color, const IRECT &bounds, float cornerRadius=5.f, const IBlend *pBlend=0)
Fill a rounded rectangle with a color.
virtual void FillRect(const IColor &color, const IRECT &bounds, const IBlend *pBlend=0)
Fill a rectangular region of the graphics context with a color.
BEGIN_IPLUG_NAMESPACE T Clip(T x, T lo, T hi)
Clips the value x between lo and hi.
void Constrain(float &x, float &y) const
Ensure the point (x,y) is inside this IRECT.
virtual void DrawBitmap(const IBitmap &bitmap, const IRECT &bounds, int srcX, int srcY, const IBlend *pBlend=0)=0
Draw a bitmap (raster) image to the graphics context.
A base class for slider/fader controls, to handle mouse action and Sender.
EControlChangeMsg ControlChangeIdx() const
Gets the controller index of a CC message.
double GetValue(int valIdx=0) const
Get the control's value.
EStatusMsg StatusMsg() const
Gets the MIDI Status message.
float L
Left side of the rectangle (X)
ILayerPtr EndLayer()
End an IGraphics layer.
MIDI and sysex structs/utilites.
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.
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.
void SetWantsMidi(bool enable=true)
Specify whether this control wants to know about MIDI messages sent to the UI.
void OnResize() override
Called when IControl is constructed or resized using SetRect().
void MakeControlChangeMsg(EControlChangeMsg idx, double value, int channel=0, int offset=0)
Create a CC message.
void MakeNoteOnMsg(int noteNumber, int velocity, int offset, int channel=0)
Make a Note On message.
virtual void SetValue(double value, int valIdx=0)
Set one of the control's values.
int GetLuminosity() const
std::unique_ptr< ILayer > ILayerPtr
ILayerPtr is a managed pointer for transferring the ownership of layers.
virtual void DrawLine(const IColor &color, float x1, float y1, float x2, float y2, const IBlend *pBlend=0, float thickness=1.f)
Draw a line to the graphics context.
void OnMouseUp(float x, float y, const IMouseMod &mod) override
Implement this method to respond to a mouse up event on this control.
IRECT GetFromBottom(float amount) const
Get a subrect of this IRECT bounded in Y by 'amount' and the bottom edge.
float T
Top of the rectangle (Y)
double ControlChange(EControlChangeMsg idx) const
Get the value of a CC message.
virtual void SetDirty(bool triggerAction=true, int valIdx=kNoValIdx)
Mark the control as dirty, i.e.
float B
Bottom of the rectangle (Y + H)
void Draw(IGraphics &g) override
Draw the control to the graphics context.
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...