Last active
April 7, 2022 21:50
-
-
Save olilarkin/3b461d27fd7a1c8b8882e1d561820b68 to your computer and use it in GitHub Desktop.
IPlug 2 XY Pad - control with 2 params
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "IPlugXY.h" | |
#include "IPlug_include_in_plug_src.h" | |
#include "IControls.h" | |
#if IPLUG_EDITOR | |
class IXYPad : public IControl | |
{ | |
private: | |
IPlugXY& mPlug; | |
ILayerPtr mLayer; | |
public: | |
IXYPad(IPlugXY& dlg, IRECT r) | |
: IControl(r) | |
, mPlug(dlg) | |
{ | |
} | |
void Draw(IGraphics& g) override | |
{ | |
float xpos = mX * mRECT.W(); | |
float ypos = mY * mRECT.H(); | |
g.DrawVerticalLine(mHandleColor, mRECT, mX); | |
g.DrawHorizontalLine(mHandleColor, mRECT, mY); | |
g.FillCircle(mHandleColor, xpos, ypos, mHandleRadius); | |
} | |
void OnMouseDown(float x, float y, const IMouseMod& mod) override | |
{ | |
mPlug.BeginParamGestureFromXY(GetTag()); | |
mHandleColor = COLOR_BLACK; | |
OnMouseDrag(x, y, 0., 0., mod); | |
} | |
void OnMouseUp(float x, float y, const IMouseMod& mod) override | |
{ | |
mPlug.EndParamGestureFromXY(GetTag()); | |
mHandleColor = COLOR_WHITE; | |
SetDirty(false); | |
} | |
void OnMouseDrag(float x, float y, float dX, float dY, const IMouseMod& mod) override | |
{ | |
mRECT.Constrain(x, y); | |
mX = (x - mRECT.L) / mRECT.W(); | |
mY = 1.f-((y - mRECT.T) / mRECT.H()); | |
SetDirty(true); | |
} | |
void SetDirty(bool triggerAction) override | |
{ | |
//mValue = Clip(mValue, mClampLo, mClampHi); | |
mDirty = true; | |
if (triggerAction) | |
mPlug.SetParamGestureFromXY(GetTag(), mX, mY); | |
} | |
void SetValsFromPlug(double x, double y) | |
{ | |
mX = x; | |
mY = y; | |
SetDirty(false); | |
} | |
private: | |
int mParamX = -1; | |
int mParamY = -1; | |
float mHandleRadius = 10.; | |
float mX = 0.f; | |
float mY = 0.f; | |
IColor mHandleColor = COLOR_BLACK; | |
}; | |
#endif | |
IPlugXY::IPlugXY(IPlugInstanceInfo instanceInfo) | |
: IPLUG_CTOR(kNumParams, kNumPrograms, instanceInfo) | |
{ | |
GetParam(kParamLeftX)->InitDouble("X1", 100., 0., 100.0, 0.01, "%"); | |
GetParam(kParamLeftY)->InitDouble("Y1", 100., 0., 100.0, 0.01, "%"); | |
GetParam(kParamRightX)->InitDouble("X2", 100., 0., 100.0, 0.01, "%"); | |
GetParam(kParamRightY)->InitDouble("Y2", 100., 0., 100.0, 0.01, "%"); | |
GetParam(kParamLink)->InitBool("link", false); | |
#if IPLUG_EDITOR // All UI methods and member variables should be within an IPLUG_EDITOR guard, should you want distributed UI | |
mMakeGraphicsFunc = [&]() { | |
return MakeGraphics(*this, PLUG_WIDTH, PLUG_HEIGHT, PLUG_FPS, 1.); | |
}; | |
mLayoutFunc = [&](IGraphics* pGraphics) { | |
pGraphics->AttachCornerResizer(kUIResizerScale, false); | |
pGraphics->AttachPanelBackground(COLOR_GRAY); | |
pGraphics->LoadFont(ROBOTTO_FN); | |
const IRECT b = pGraphics->GetBounds(); | |
pGraphics->AttachControl(new IXYPad(*this, b.GetGridCell(0, 2, 2)), kXYControl1Tag); | |
pGraphics->AttachControl(new IXYPad(*this, b.GetGridCell(1, 2, 2)), kXYControl2Tag); | |
pGraphics->AttachControl(new IVKnobControl(b.GetGridCell(2, 2, 2).FracRectHorizontal(0.5), kParamLeftX), kKnobX1); | |
pGraphics->AttachControl(new IVKnobControl(b.GetGridCell(2, 2, 2).FracRectHorizontal(0.5, true), kParamLeftY), kKnobY1); | |
pGraphics->AttachControl(new IVKnobControl(b.GetGridCell(3, 2, 2).FracRectHorizontal(0.5), kParamRightX), kKnobX2); | |
pGraphics->AttachControl(new IVKnobControl(b.GetGridCell(3, 2, 2).FracRectHorizontal(0.5, true), kParamRightY), kKnobY2); | |
pGraphics->AttachControl(new IVSwitchControl(b.GetCentredInside(30), kParamLink)); | |
pGraphics->GetControlWithTag(kKnobX1)->SetActionFunction(std::bind(&IPlugXY::UpdateXYs, this, std::placeholders::_1)); | |
pGraphics->GetControlWithTag(kKnobY1)->SetActionFunction(std::bind(&IPlugXY::UpdateXYs, this, std::placeholders::_1)); | |
pGraphics->GetControlWithTag(kKnobX2)->SetActionFunction(std::bind(&IPlugXY::UpdateXYs, this, std::placeholders::_1)); | |
pGraphics->GetControlWithTag(kKnobY2)->SetActionFunction(std::bind(&IPlugXY::UpdateXYs, this, std::placeholders::_1)); | |
}; | |
#endif | |
} | |
#if IPLUG_EDITOR | |
void IPlugXY::BeginParamGestureFromXY(int tag) | |
{ | |
if(GetParam(kParamLink)->Bool() || tag == kXYControl1Tag) | |
{ | |
BeginInformHostOfParamChangeFromUI(kParamLeftX); | |
BeginInformHostOfParamChangeFromUI(kParamLeftY); | |
} | |
if(GetParam(kParamLink)->Bool() || tag == kXYControl2Tag) | |
{ | |
BeginInformHostOfParamChangeFromUI(kParamRightX); | |
BeginInformHostOfParamChangeFromUI(kParamRightY); | |
} | |
} | |
void IPlugXY::SetParamGestureFromXY(int tag, double x, double y) | |
{ | |
if(GetParam(kParamLink)->Bool() || tag == kXYControl1Tag) | |
{ | |
SetParameterValue(kParamLeftX, x); | |
SetParameterValue(kParamLeftY, y); | |
} | |
if(GetParam(kParamLink)->Bool() || tag == kXYControl2Tag) | |
{ | |
SetParameterValue(kParamRightX, x); | |
SetParameterValue(kParamRightY, y); | |
} | |
if(GetParam(kParamLink)->Bool()) | |
{ | |
if(tag == kXYControl1Tag) | |
dynamic_cast<IXYPad*>(GetUI()->GetControlWithTag(kXYControl2Tag))->SetValsFromPlug(x, y); | |
else | |
dynamic_cast<IXYPad*>(GetUI()->GetControlWithTag(kXYControl1Tag))->SetValsFromPlug(x, y); | |
} | |
UpdateKnobs(); | |
} | |
void IPlugXY::EndParamGestureFromXY(int tag) | |
{ | |
if(GetParam(kParamLink)->Bool() || tag == kXYControl1Tag) | |
{ | |
EndInformHostOfParamChangeFromUI(kParamLeftX); | |
EndInformHostOfParamChangeFromUI(kParamLeftY); | |
} | |
if(GetParam(kParamLink)->Bool() || tag == kXYControl2Tag) | |
{ | |
EndInformHostOfParamChangeFromUI(kParamRightX); | |
EndInformHostOfParamChangeFromUI(kParamRightY); | |
} | |
} | |
void IPlugXY::UpdateKnobs() | |
{ | |
GetUI()->GetControlWithTag(kKnobX1)->SetValueFromDelegate(GetParam(kParamLeftX)->GetNormalized()); | |
GetUI()->GetControlWithTag(kKnobY1)->SetValueFromDelegate(GetParam(kParamLeftY)->GetNormalized()); | |
GetUI()->GetControlWithTag(kKnobX2)->SetValueFromDelegate(GetParam(kParamRightX)->GetNormalized()); | |
GetUI()->GetControlWithTag(kKnobY2)->SetValueFromDelegate(GetParam(kParamRightY)->GetNormalized()); | |
} | |
void IPlugXY::UpdateXYs(IControl* pCaller) | |
{ | |
if(pCaller->GetTag() == kKnobX1 || pCaller->GetTag() == kKnobY1) | |
{ | |
const double vx = GetParam(kParamLeftX)->GetNormalized(); | |
const double vy = GetParam(kParamLeftY)->GetNormalized(); | |
dynamic_cast<IXYPad*>(GetUI()->GetControlWithTag(kXYControl1Tag))->SetValsFromPlug(vx, vy); | |
if(GetParam(kParamLink)->Bool()) | |
{ | |
SetParameterValue(kParamRightX, vx); | |
SetParameterValue(kParamRightY, vy); | |
dynamic_cast<IXYPad*>(GetUI()->GetControlWithTag(kXYControl2Tag))->SetValsFromPlug(vx, vy); | |
GetUI()->GetControlWithTag(kKnobX2)->SetValueFromDelegate(vx); | |
GetUI()->GetControlWithTag(kKnobY2)->SetValueFromDelegate(vy); | |
} | |
} | |
if(pCaller->GetTag() == kKnobX2 || pCaller->GetTag() == kKnobY2) | |
{ | |
const double vx = GetParam(kParamRightX)->GetNormalized(); | |
const double vy = GetParam(kParamRightY)->GetNormalized(); | |
dynamic_cast<IXYPad*>(GetUI()->GetControlWithTag(kXYControl2Tag))->SetValsFromPlug(vx, vy); | |
if(GetParam(kParamLink)->Bool()) | |
{ | |
SetParameterValue(kParamLeftX, vx); | |
SetParameterValue(kParamLeftY, vy); | |
dynamic_cast<IXYPad*>(GetUI()->GetControlWithTag(kXYControl1Tag))->SetValsFromPlug(vx, vy); | |
GetUI()->GetControlWithTag(kKnobX1)->SetValueFromDelegate(vx); | |
GetUI()->GetControlWithTag(kKnobY1)->SetValueFromDelegate(vy); | |
} | |
} | |
} | |
void IPlugXY::OnParamChangeUI(int paramIdx, EParamSource src) | |
{ | |
if(GetUI() && src != kUI) | |
{ | |
switch (paramIdx) | |
{ | |
case kParamLeftX: | |
case kParamLeftY: | |
{ | |
const double vx = GetParam(kParamLeftX)->GetNormalized(); | |
const double vy = GetParam(kParamLeftY)->GetNormalized(); | |
if(GetParam(kParamLink)->Bool()) | |
{ | |
dynamic_cast<IXYPad*>(GetUI()->GetControlWithTag(kXYControl2Tag))->SetValsFromPlug(vx, vy); | |
GetUI()->GetControlWithTag(kKnobX2)->SetValueFromDelegate(vx); | |
GetUI()->GetControlWithTag(kKnobY2)->SetValueFromDelegate(vy); | |
} | |
dynamic_cast<IXYPad*>(GetUI()->GetControlWithTag(kXYControl1Tag))->SetValsFromPlug(vx, vy); | |
break; | |
} | |
case kParamRightX: | |
case kParamRightY: | |
{ | |
const double vx = GetParam(kParamRightX)->GetNormalized(); | |
const double vy = GetParam(kParamRightY)->GetNormalized(); | |
if(GetParam(kParamLink)->Bool()) | |
{ | |
dynamic_cast<IXYPad*>(GetUI()->GetControlWithTag(kXYControl1Tag))->SetValsFromPlug(vx, vy); | |
GetUI()->GetControlWithTag(kKnobX1)->SetValueFromDelegate(vx); | |
GetUI()->GetControlWithTag(kKnobY1)->SetValueFromDelegate(vy); | |
} | |
dynamic_cast<IXYPad*>(GetUI()->GetControlWithTag(kXYControl2Tag))->SetValsFromPlug(vx, vy); | |
break; | |
} | |
default: | |
break; | |
} | |
} | |
} | |
#endif | |
#if IPLUG_DSP | |
void IPlugXY::ProcessBlock(sample** inputs, sample** outputs, int nFrames) | |
{ | |
const double gainX = GetParam(kParamLeftX)->Value() / 100.; | |
const double gainY = GetParam(kParamLeftY)->Value() / 100.; | |
for (int s = 0; s < nFrames; s++) { | |
outputs[0][s] = inputs[0][s] * gainX; | |
outputs[1][s] = inputs[1][s] * gainY; | |
} | |
} | |
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include "IPlug_include_in_plug_hdr.h" | |
const int kNumPrograms = 1; | |
enum EParams | |
{ | |
kParamLeftX = 0, | |
kParamLeftY, | |
kParamRightX, | |
kParamRightY, | |
kParamLink, | |
kNumParams | |
}; | |
enum ECtrlTags | |
{ | |
kXYControl1Tag = 0, | |
kXYControl2Tag, | |
kKnobX1, | |
kKnobY1, | |
kKnobX2, | |
kKnobY2 | |
}; | |
class IPlugXY : public IPlug | |
{ | |
public: | |
IPlugXY(IPlugInstanceInfo instanceInfo); | |
#if IPLUG_EDITOR | |
void OnParamChangeUI(int paramIdx, EParamSource src) override; | |
void BeginParamGestureFromXY(int tag); | |
void SetParamGestureFromXY(int tag, double x, double y); | |
void EndParamGestureFromXY(int tag); | |
void UpdateKnobs(); | |
void UpdateXYs(IControl* pCaller); | |
#endif | |
#if IPLUG_DSP // All DSP methods and member variables should be within an IPLUG_DSP guard, should you want distributed UI | |
void ProcessBlock(sample** inputs, sample** outputs, int nFrames) override; | |
#endif | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment