23BEGIN_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;
200 RecreateKeyBounds(
true);
208 case IMidiMsg::kNoteOn:
211 case IMidiMsg::kNoteOff:
214 case IMidiMsg::kControlChange:
216 ClearNotesFromMidi();
228 g.
FillRoundRect(color, bounds, 0., 0., mRoundness, mRoundness);
238 float BKBottom = mRECT.T + mRECT.
H() * mBKHeightRatio;
239 float BKWidth = GetBKWidth();
242 for (
int i = 0; i < NKeys(); ++i)
246 float kL = *GetKeyXPos(i);
247 IRECT keyBounds =
IRECT(kL, mRECT.T, kL + mWKWidth, mRECT.B);
249 DrawKey(g, keyBounds, i == mHighlight ? mHK_COLOR : mWK_COLOR);
251 if (GetKeyIsPressed(i))
254 DrawKey(g, keyBounds, mPK_COLOR);
258 IRECT shadowBounds = keyBounds;
259 shadowBounds.R = shadowBounds.L + 0.35f * shadowBounds.
W();
262 g.
FillRect(shadowColor, shadowBounds, &mBlend);
264 g.
FillRoundRect(shadowColor, shadowBounds, 0., 0., mRoundness, mRoundness, &mBlend);
268 if (mDrawFrame && i != 0)
270 g.
DrawLine(mFR_COLOR, kL, mRECT.T, kL, mRECT.B, &mBlend, mFrameThickness);
271 if (i == NKeys() - 2 && IsBlackKey(NKeys() - 1))
272 g.
DrawLine(mFR_COLOR, kL + mWKWidth, mRECT.T, kL + mWKWidth, mRECT.B, &mBlend, mFrameThickness);
278 for (
int i = 0; i < NKeys(); ++i)
282 float kL = *GetKeyXPos(i);
283 IRECT keyBounds =
IRECT(kL, mRECT.T, kL + BKWidth, BKBottom);
285 if (mDrawShadows && !GetKeyIsPressed(i) && i < NKeys() - 1)
287 IRECT shadowBounds = keyBounds;
288 float w = shadowBounds.
W();
289 shadowBounds.L += 0.6f * w;
290 if (GetKeyIsPressed(i + 1))
294 shadowBounds.B = shadowBounds.T + 1.05f * shadowBounds.
H();
296 shadowBounds.R = shadowBounds.L + w;
297 DrawKey(g, shadowBounds, shadowColor);
299 DrawKey(g, keyBounds, (i == mHighlight ? mHK_COLOR : mBK_COLOR.
WithContrast(
IsDisabled() ? GRAYED_ALPHA : 0.f)));
301 if (GetKeyIsPressed(i))
305 cBP.A = (int) mBKAlpha;
306 g.
FillRect(cBP, keyBounds, &mBlend);
312 if (mBKHeightRatio != 1.0)
313 g.
DrawLine(mFR_COLOR, kL, BKBottom, kL + BKWidth, BKBottom, &mBlend);
315 g.
DrawLine(mFR_COLOR, kL, mRECT.T, kL, BKBottom, &mBlend);
316 if (i != NKeys() - 1)
317 g.
DrawLine(mFR_COLOR, kL + BKWidth, mRECT.T, kL + BKWidth, BKBottom, &mBlend);
323 g.
DrawRect(mFR_COLOR, mRECT, &mBlend, mFrameThickness);
327 if (mMouseOverKey > -1)
329 IRECT r =
IRECT(*GetKeyXPos(mMouseOverKey), mRECT.T, 0, 0);
330 r.B = r.T + 1.2f * mText.mSize;
333 GetNoteNameStr(mMinNote + mMouseOverKey,
false, t);
334 if (mLastTouchedKey > -1)
336 t.AppendFormatted(16,
", vel: %3.2f", mLastVelocity * 127.f);
339 float e = r.R - mRECT.R;
347 g.
DrawText(mText, t.Get(), r, &mBlend);
355 ti.SetFormatted(32,
"key: %d, vel: %3.2f", mLastTouchedKey, mLastVelocity * 127.f);
357 IText txt(20, COLOR_RED);
358 IRECT tr(mRECT.L + 20, mRECT.B - 20, mRECT.L + 160, mRECT.B);
359 g.
DrawText(txt, ti.Get(), tr, &mBlend);
365 void SetNoteRange(
int min,
int max,
bool keepWidth =
true)
367 if (min < 0 || max < 0)
return;
379 mPressedKeys.Resize(NKeys());
380 memset(mPressedKeys.Get(), 0, mPressedKeys.GetSize() *
sizeof(
bool));
382 RecreateKeyBounds(keepWidth);
385 void SetNoteFromMidi(
int noteNum,
bool played)
387 if (noteNum < mMinNote || noteNum > mMaxNote)
return;
388 SetKeyIsPressed(noteNum - mMinNote, played);
391 void SetKeyIsPressed(
int key,
bool pressed)
393 mPressedKeys.Get()[key] = pressed;
397 void SetKeyHighlight(
int key)
403 void ClearNotesFromMidi()
405 memset(mPressedKeys.Get(), 0, mPressedKeys.GetSize() *
sizeof(
bool));
409 void SetBlackToWhiteRatios(
float widthRatio,
float heightRatio = 0.6)
411 widthRatio =
Clip(widthRatio, 0.1f, 1.f);
412 heightRatio =
Clip(heightRatio, 0.1f, 1.f);
414 float halfW = 0.5f * mWKWidth * mBKWidthRatio;
415 float r = widthRatio / mBKWidthRatio;
416 mBKWidthRatio = widthRatio;
417 mBKHeightRatio = heightRatio;
419 for (
int i = 0; i < NKeys(); ++i)
423 float* pKeyL = GetKeyXPos(i);
424 float mid = *pKeyL + halfW;
425 *pKeyL = mid - halfW * r;
426 if (*pKeyL < mRECT.L)
434 void SetHeight(
float h,
bool keepAspectRatio =
false)
436 if (h <= 0.0)
return;
437 float r = h / mRECT.
H();
438 mRECT.B = mRECT.T + mRECT.
H() * r;
443 SetWidth(mRECT.
W() * r);
447 void SetWidth(
float w,
bool keepAspectRatio =
false)
449 if (w <= 0.0)
return;
450 float r = w / mRECT.
W();
451 mRECT.R = mRECT.L + mRECT.
W() * r;
453 for (
int i = 0; i < NKeys(); ++i)
455 float* pKeyL = GetKeyXPos(i);
456 float d = *pKeyL - mRECT.L;
457 *pKeyL = mRECT.L + d * r;
463 SetHeight(mRECT.
H() * r);
468 void SetShowNotesAndVelocity(
bool show)
470 mShowNoteAndVel = show;
473 void SetColors(
const IColor BKColor,
const IColor& WKColor,
const IColor& PKColor = DEFAULT_PK_COLOR,
const IColor& FRColor = DEFAULT_FR_COLOR)
480 mBKAlpha = (float) PKColor.A;
482 if (mBKAlpha < 240.f)
484 const float lumWK = WKColor.
GetLuminosity() * WKColor.A / 255.f;
485 const float adjustment = PKColor.A / 255.f;
486 const float lumPK = PKColor.GetLuminosity() * adjustment;
487 const float lumRes = (1.f - adjustment) * lumWK + lumPK;
488 const float lumDW = lumRes - lumWK;
489 const float lumBK = BKColor.
GetLuminosity() * BKColor.A / 255.f;
491 if ((lumDW < 0 && lumBK < lumWK) || (lumDW > 0 && lumBK > lumWK))
493 float dbWB = lumWK - lumBK;
494 mBKAlpha += (255.f - mBKAlpha) * (1.f - dbWB * dbWB / 255.f / 255.f) + 0.5f;
497 mBKAlpha += lumDW + 0.5f;
499 mBKAlpha =
Clip(mBKAlpha, 15.f, 255.f);
506 int GetMidiNoteNumberForKey(
int key)
const
508 if (key > -1)
return mMinNote + key;
515 void RecreateKeyBounds(
bool keepWidth)
521 mIsBlackKeyList.Resize(NKeys());
522 mKeyXPos.Resize(NKeys());
524 float numWhites = 0.f;
525 for (
int n = mMinNote, i = 0; n <= mMaxNote; ++n, i++)
527 if (n % 12 == 1 || n % 12 == 3 || n % 12 == 6 || n % 12 == 8 || n % 12 == 10)
529 mIsBlackKeyList.Get()[i] =
true;
533 mIsBlackKeyList.Get()[i] =
false;
539 float WKPadStart = 0.f;
540 float WKPadEnd = 0.f;
542 auto GetShiftForPitchClass = [
this](
int pitch) {
545 if (pitch == 0)
return 0.f;
546 else if (pitch % 12 == 1)
return 7.f / 12.f;
547 else if (pitch % 12 == 3)
return 5.f / 12.f;
548 else if (pitch % 12 == 6)
return 2.f / 3.f;
549 else if (pitch % 12 == 8)
return 0.5f;
550 else if (pitch % 12 == 10)
return 1.f / 3.f;
554 WKPadStart = GetShiftForPitchClass(mMinNote);
556 if (mMinNote != mMaxNote && IsBlackKey(mIsBlackKeyList.GetSize() - 1))
557 WKPadEnd = 1.f - GetShiftForPitchClass(mMaxNote);
561 mWKWidth = 0.2f * mRECT.
H();
565 mWKWidth = mRECT.
W();
567 mWKWidth /= (numWhites + mBKWidthRatio * (WKPadStart + WKPadEnd));
570 float BKWidth = mWKWidth;
573 BKWidth *= mBKWidthRatio;
575 float prevWKLeft = mRECT.L;
577 for (
int k = 0; k < mIsBlackKeyList.GetSize(); ++k)
581 float l = prevWKLeft;
584 l -= GetShiftForPitchClass(mMinNote + k) * BKWidth;
586 else prevWKLeft += WKPadStart * BKWidth;
587 mKeyXPos.Get()[k] = l;
591 mKeyXPos.Get()[k] = prevWKLeft;
592 prevWKLeft += mWKWidth;
600 int GetKeyAtPoint(
float x,
float y)
605 float BKBottom = mRECT.T + mRECT.
H() * mBKHeightRatio;
606 float BKWidth = GetBKWidth();
610 for (
int i = 0; i < NKeys(); ++i)
614 float kL = *GetKeyXPos(i);
615 IRECT keyBounds =
IRECT(kL, mRECT.T, kL + BKWidth, BKBottom);
626 for (
int i = 0; i < NKeys(); ++i)
630 float kL = *GetKeyXPos(i);
631 IRECT keyBounds =
IRECT(kL, mRECT.T, kL + mWKWidth, mRECT.B);
644 float GetVelocity(
float yPos)
648 if (mLastTouchedKey > -1)
652 if (IsBlackKey(mLastTouchedKey))
655 float fracPos = (yPos - mRECT.T) / (0.95f * h);
657 velocity =
Clip(fracPos, 1.f / 127.f, 1.f);
663 void GetNoteNameStr(
int midiNoteNum,
bool addOctave, WDL_String& str)
665 int oct = midiNoteNum / 12;
666 midiNoteNum -= 12 * oct;
667 const char* notes[12] = {
"C",
"C#",
"D",
"D#",
"E",
"F",
"F#",
"G",
"G#",
"A",
"A#",
"B" };
668 const char* n = notes[midiNoteNum];
671 str.AppendFormatted(2,
"%d", --oct);
674 bool IsBlackKey(
int i)
const {
return *(mIsBlackKeyList.Get() + i); }
676 float* GetKeyXPos(
int i) {
return mKeyXPos.Get() + i; }
678 bool GetKeyIsPressed(
int i)
const {
return *(mPressedKeys.Get() + i); }
680 int NKeys()
const {
return mMaxNote - mMinNote + 1; }
682 float GetBKWidth()
const
690 void TriggerMidiMsgFromKeyPress(
int key,
int velocity)
694 const int nn = GetMidiNoteNumberForKey(key);
711 bool mRoundedKeys =
false;
712 float mRoundness = 5.f;
713 bool mDrawShadows =
false;
714 bool mDrawFrame =
true;
715 float mFrameThickness = 1.f;
716 bool mShowNoteAndVel =
false;
717 float mWKWidth = 0.f;
718 float mBKWidthRatio = 0.6f;
719 float mBKHeightRatio = 0.6f;
720 float mBKAlpha = 100.f;
721 int mLastTouchedKey = -1;
722 float mLastVelocity = 0.f;
723 int mMouseOverKey = -1;
724 int mMinNote, mMaxNote;
725 WDL_TypedBuf<bool> mIsBlackKeyList;
726 WDL_TypedBuf<bool> mPressedKeys;
727 WDL_TypedBuf<float> mKeyXPos;
735 static constexpr int kSpringAnimationTime = 50;
736 static constexpr int kNumRungs = 10;
738 static constexpr int kMessageTagSetPitchBendRange = 0;
744 :
ISliderControlBase(bounds, kNoParameter, EDirection::Vertical, DEFAULT_GEARING, 40.f)
745 , mPitchBendRange(initBendRange)
748 mMenu.AddItem(
"1 semitone");
749 mMenu.AddItem(
"2 semitones");
750 mMenu.AddItem(
"Fifth");
751 mMenu.AddItem(
"Octave");
753 SetValue(cc == IMidiMsg::EControlChangeMsg::kNoCC ? 0.5 : 0.);
757 if(cc == IMidiMsg::EControlChangeMsg::kNoCC)
769 const float stepSize = handleBounds.
H() / (float) kNumRungs;
776 if(layerRect.
W() > 0 && layerRect.
H() > 0)
792 const float value =
static_cast<float>(
GetValue());
793 const float y = (handleBounds.
H() - (stepSize)) * value;
794 const float triangleRamp = std::fabs(value-0.5f) * 2.f;
796 g.
DrawBitmap(mLayer->GetBitmap(), handleBounds, 0, (
int) y);
803 {COLOR_BLACK.
WithContrast(iplug::Lerp(0.f, 0.5f, triangleRamp)), 0.f},
804 {COLOR_BLACK.
WithContrast(iplug::Lerp(0.5f, 0.f, triangleRamp)), 1.f}
809 g.
DrawRect(COLOR_BLACK, handleBounds);
814 if(mCC == IMidiMsg::EControlChangeMsg::kNoCC)
816 if(msg.
StatusMsg() == IMidiMsg::kPitchWheel)
841 switch (pSelectedMenu->GetChosenItemIdx())
843 case 0: mPitchBendRange = 1;
break;
844 case 1: mPitchBendRange = 2;
break;
845 case 2: mPitchBendRange = 7;
break;
848 mPitchBendRange = 12;
break;
857 if(mod.R && mCC == IMidiMsg::EControlChangeMsg::kNoCC)
859 switch (mPitchBendRange)
861 case 1: mMenu.CheckItemAlone(0);
break;
862 case 2: mMenu.CheckItemAlone(1);
break;
863 case 7: mMenu.CheckItemAlone(2);
break;
864 case 12: mMenu.CheckItemAlone(3);
break;
877 if(mCC == IMidiMsg::EControlChangeMsg::kNoCC)
883 pCaller->SetDirty(true);
884 pCaller->OnEndAnimation();
887 }, kSpringAnimationTime);
900END_IGRAPHICS_NAMESPACE
This file contains the base IControl implementation, along with some base classes for specific types ...
MIDI and sysex structs/utilites.
The lowest level base class of an IGraphics control.
void SetWantsMidi(bool enable=true)
Specify whether this control wants to know about MIDI messages sent to the UI.
IGEditorDelegate * GetDelegate()
Gets a pointer to the class implementing the IEditorDelegate interface that handles parameter changes...
double GetAnimationProgress() const
Get the progress in a control's animation, in the range 0-1.
int GetTag() const
Get the control's tag.
virtual void SetValue(double value, int valIdx=0)
Set one of the control's values.
double GetValue(int valIdx=0) const
Get the control's value.
virtual void SetDirty(bool triggerAction=true, int valIdx=kNoValIdx)
Mark the control as dirty, i.e.
IControl * SetActionFunction(IActionFunction actionFunc)
Set an Action Function for this control.
void SetAnimation(IAnimationFunction func)
Set the animation function.
virtual void SendMidiMsgFromUI(const IMidiMsg &msg)
SendMidiMsgFromUI (Abbreviation: SMMFUI) This method should be used when sending a MIDI message from ...
virtual void SendArbitraryMsgFromUI(int msgTag, int ctrlTag=kNoTag, int dataSize=0, const void *pData=nullptr)
SendArbitraryMsgFromUI (Abbreviation: SAMFUI)
The lowest level base class of an IGraphics 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.
virtual void PathFill(const IPattern &pattern, const IFillOptions &options=IFillOptions(), const IBlend *pBlend=0)=0
Fill the current current path.
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.
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.
void PathRect(const IRECT &bounds)
Add a rectangle to the current path.
bool CheckLayer(const ILayerPtr &layer)
Test to see if a layer needs drawing, for instance if the control's bounds were changed.
virtual void FillRect(const IColor &color, const IRECT &bounds, const IBlend *pBlend=0)
Fill a rectangular region of the graphics context with a color.
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.
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 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 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.
void StartLayer(IControl *pOwner, const IRECT &r, bool cacheable=false)
Create an IGraphics layer.
ILayerPtr EndLayer()
End an IGraphics layer.
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.
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.
Vectorial keyboard control.
void OnMouseOut() override
Implement this method to respond to a mouseout 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 OnMouseOver(float x, float y, const IMouseMod &mod) override
Implement this method to respond to a mouseover event on this control.
void OnResize() override
Called when IControl is constructed or resized using SetRect().
void OnMidi(const IMidiMsg &msg) override
Implement to receive MIDI messages sent to the control if mWantsMidi == true, see IEditorDelegate:Sen...
void OnTouchCancelled(float x, float y, const IMouseMod &mod) override
Implement this method to respond to a touch cancel 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 Draw(IGraphics &g) override
Draw the control to the graphics context.
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.
Vectorial "wheel" control for pitchbender/modwheel.
void OnMidi(const IMidiMsg &msg) override
Implement to receive MIDI messages sent to the control if mWantsMidi == true, see IEditorDelegate:Sen...
void OnPopupMenuSelection(IPopupMenu *pSelectedMenu, int) override
Implement this method to handle popup menu selection after IGraphics::CreatePopupMenu/IControlPromptU...
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.
void OnMouseUp(float x, float y, const IMouseMod &mod) override
Implement this method to respond to a mouse up event on this control.
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.
IWheelControl(const IRECT &bounds, IMidiMsg::EControlChangeMsg cc=IMidiMsg::EControlChangeMsg::kNoCC, int initBendRange=12)
Create a WheelControl.
std::unique_ptr< ILayer > ILayerPtr
ILayerPtr is a managed pointer for transferring the ownership of layers.
BEGIN_IPLUG_NAMESPACE T Clip(T x, T lo, T hi)
Clips the value x between lo and hi.
Used to manage color data, independent of draw class/platform.
IColor WithContrast(float c) const
Returns a new contrasted IColor based on this one.
IColor WithOpacity(float alpha) const
Returns a new IColor with a different opacity.
int GetLuminosity() const
Encapsulates a MIDI message and provides helper functions.
void MakeNoteOnMsg(int noteNumber, int velocity, int offset, int channel=0)
Make a Note On message.
double ControlChange(EControlChangeMsg idx) const
Get the value of a CC message.
void MakeNoteOffMsg(int noteNumber, int offset, int channel=0)
Make a Note Off message.
void MakePitchWheelMsg(double value, int channel=0, int offset=0)
Create a pitch wheel/bend message.
int Velocity() const
Get the velocity value of a NoteOn/NoteOff message.
void MakeControlChangeMsg(EControlChangeMsg idx, double value, int channel=0, int offset=0)
Create a CC message.
EControlChangeMsg
Constants for MIDI CC messages.
EControlChangeMsg ControlChangeIdx() const
Gets the controller index of a CC message.
double PitchWheel() const
Get the value from a Pitchwheel message.
int NoteNumber() const
Gets the MIDI note number.
EStatusMsg StatusMsg() const
Gets the MIDI Status message.
Used to manage mouse modifiers i.e.
static IPattern CreateLinearGradient(float x1, float y1, float x2, float y2, const std::initializer_list< IColorStop > &stops={})
Create a linear gradient IPattern.
Used to manage a rectangular area, independent of draw class/platform.
IRECT GetFromBottom(float amount) const
Get a subrect of this IRECT bounded in Y by 'amount' and the bottom edge.
IRECT GetTranslated(float x, float y) const
Get a translated copy of this rectangle.
IRECT FracRectVertical(float frac, bool fromTop=false) const
Returns a new IRECT with a height that is multiplied by frac.
void Constrain(float &x, float &y) const
Ensure the point (x,y) is inside this IRECT.
bool Contains(const IRECT &rhs) const
Returns true if this IRECT completely contains rhs.
IRECT GetPadded(float padding) const
Get a copy of this IRECT with each value padded by padding N.B.
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...
IText is used to manage font and text/text entry style for a piece of text on the UI,...