#include "IPlugEffect.h" #include "IPlug_include_in_plug_src.h" #include "IControls.h" constexpr auto CN = 30; struct Cable { IVec2 pos1; IVec2 pos2; IColor color; Cable(float x, float y, const IColor& color) : pos1(x, y) , pos2(x + 1, y + 1) , color(color) { } }; class CableControl : public IControl { private: WDL_PtrList mCables; public: CableControl(const IRECT& bounds) : IControl(bounds) { mIgnoreMouse = true; } ~CableControl() { mCables.Empty(true); } void Draw(IGraphics& g) override { for (int i = 0; i < mCables.GetSize(); i++) { DrawCable(g, mCables.Get(i)); } } Cable* AddCable(float x, float y, const IColor& color) { Cable* pNewCable = mCables.Add(new Cable(x, y, color)); SetDirty(false); return pNewCable; } void RemoveCable(Cable* pCable) { mCables.DeletePtr(pCable, true); SetDirty(false); } private: void DrawCable(IGraphics& g, Cable* cable) { float d = (abs(cable->pos1.x - cable->pos2.x) + abs(cable->pos1.y - cable->pos2.y)) *0.25; g.PathMoveTo(cable->pos1.x, cable->pos1.y+5); g.PathCubicBezierTo(cable->pos1.x, cable->pos1.y + d+ 5, cable->pos2.x, cable->pos2.y + d+5, cable->pos2.x, cable->pos2.y+5); g.PathStroke(COLOR_BLACK_DROP_SHADOW.WithOpacity(0.2), 8.f); g.PathMoveTo(cable->pos1.x, cable->pos1.y); g.PathCubicBezierTo(cable->pos1.x, cable->pos1.y + d+5, cable->pos2.x, cable->pos2.y + d+5, cable->pos2.x, cable->pos2.y); g.PathStroke(cable->color, 6.f); g.FillCircle(cable->color, cable->pos1.x, cable->pos1.y, 5); g.FillCircle(cable->color, cable->pos2.x, cable->pos2.y, 5); } }; class PlugControl : public IControl { public: PlugControl(const IRECT& bounds, CableControl* pCableControl) : IControl(bounds) , mCableControl(pCableControl) {} void Draw(IGraphics& g) override { g.FillEllipse(COLOR_RED, mRECT); if (mMouseIsOver || mAboutToConnect) { g.DrawEllipse(COLOR_BLACK, mRECT, 0, 3); } } void OnMouseDown(float x, float y, const IMouseMod& mod) override { mLastCable = mCableControl->AddCable(mRECT.MW(), mRECT.MH(), COLOR_RED.GetRandomColor()); } void OnMouseUp(float x, float y, const IMouseMod& mod) override { bool valid = false; for (int i = 0; i < CN; i++) { PlugControl* pPlug = GetUI()->GetControlWithTag(i)->As(); if (pPlug != this) valid |= pPlug->GetRECT().Contains(x, y); } if (!valid) { mCableControl->RemoveCable(mLastCable); } mLastCable = nullptr; } void OnMouseDrag(float x, float y, float dX, float dY, const IMouseMod& mod) override { if (mLastCable) { mLastCable->pos2 = { x, y }; for (int i = 0; i < CN; i++) { PlugControl* pPlug = GetUI()->GetControlWithTag(i)->As(); pPlug->mAboutToConnect = pPlug->GetRECT().Contains(x, y); } mCableControl->SetDirty(false); } } bool mAboutToConnect = false; private: Cable* mLastCable = nullptr; CableControl* mCableControl = nullptr; }; IPlugEffect::IPlugEffect(const InstanceInfo& info) : Plugin(info, MakeConfig(kNumParams, kNumPresets)) { GetParam(kGain)->InitDouble("Gain", 0., 0., 100.0, 0.01, "%"); #if IPLUG_EDITOR // http://bit.ly/2S64BDd mMakeGraphicsFunc = [&]() { return MakeGraphics(*this, PLUG_WIDTH, PLUG_HEIGHT, PLUG_FPS, GetScaleForScreen(PLUG_HEIGHT)); }; mLayoutFunc = [&](IGraphics* pGraphics) { pGraphics->AttachCornerResizer(EUIResizerMode::Scale, false); pGraphics->AttachPanelBackground(COLOR_GRAY); pGraphics->EnableMouseOver(true); pGraphics->LoadFont("Roboto-Regular", ROBOTO_FN); const IRECT b = pGraphics->GetBounds(); CableControl* pCableControl = new CableControl(b); IRECT base = IRECT(0, 0, 20, 20).GetTranslated(200, 50); float off = b.H() / (CN / 2); for (size_t i = 0; i < CN / 2; i++) { pGraphics->AttachControl(new PlugControl(base.GetTranslated(50+(i*3), i * off), pCableControl), i); } for (size_t i = 0; i < CN / 2; i++) { pGraphics->AttachControl(new PlugControl(base.GetTranslated(200- (i * 3), i * off), pCableControl), CN/2+i); } pGraphics->AttachControl(pCableControl); }; #endif } #if IPLUG_DSP void IPlugEffect::ProcessBlock(sample** inputs, sample** outputs, int nFrames) { const double gain = GetParam(kGain)->Value() / 100.; const int nChans = NOutChansConnected(); for (int s = 0; s < nFrames; s++) { for (int c = 0; c < nChans; c++) { outputs[c][s] = inputs[c][s] * gain; } } } #endif