| @@ -1,25 +0,0 @@ | |||
| #pragma once | |||
| #include <app/common.hpp> | |||
| #include <app/SvgSwitch.hpp> | |||
| namespace rack { | |||
| namespace app { | |||
| /** A ParamWidget that behaves like a Switch but draws SVG frames for mouse up/down state. | |||
| */ | |||
| struct SvgLatch : SvgSwitch { | |||
| struct Internal; | |||
| Internal* internal; | |||
| SvgLatch(); | |||
| ~SvgLatch(); | |||
| void onDragStart(const DragStartEvent& e) override; | |||
| void onDragEnd(const DragEndEvent& e) override; | |||
| void onChange(const ChangeEvent& e) override; | |||
| }; | |||
| } // namespace app | |||
| } // namespace rack | |||
| @@ -12,14 +12,26 @@ namespace app { | |||
| /** A ParamWidget with multiple frames corresponding to its value */ | |||
| struct SvgSwitch : Switch { | |||
| struct Internal; | |||
| Internal* internal; | |||
| widget::FramebufferWidget* fb; | |||
| CircularShadow* shadow; | |||
| widget::SvgWidget* sw; | |||
| std::vector<std::shared_ptr<window::Svg>> frames; | |||
| /** Use frames 0 and 1 when the mouse is pressed and released, instead of using the param value as the frame index. | |||
| TODO change name | |||
| */ | |||
| bool latch = false; | |||
| SvgSwitch(); | |||
| ~SvgSwitch(); | |||
| /** Adds an SVG file to represent the next switch position */ | |||
| void addFrame(std::shared_ptr<window::Svg> svg); | |||
| void onDragStart(const DragStartEvent& e) override; | |||
| void onDragEnd(const DragEndEvent& e) override; | |||
| void onChange(const ChangeEvent& e) override; | |||
| }; | |||
| @@ -6,7 +6,6 @@ | |||
| #include <app/SvgPort.hpp> | |||
| #include <app/ModuleLightWidget.hpp> | |||
| #include <app/SvgSwitch.hpp> | |||
| #include <app/SvgLatch.hpp> | |||
| #include <app/SvgScrew.hpp> | |||
| #include <app/AudioWidget.hpp> | |||
| #include <app/MidiWidget.hpp> | |||
| @@ -769,13 +768,6 @@ struct CL1362Port : app::SvgPort { | |||
| // Switches | |||
| //////////////////// | |||
| template <typename TSwitch> | |||
| struct LatchingSwitch : TSwitch { | |||
| LatchingSwitch() { | |||
| this->momentary = false; | |||
| } | |||
| }; | |||
| template <typename TSwitch> | |||
| struct MomentarySwitch : TSwitch { | |||
| MomentarySwitch() { | |||
| @@ -841,10 +833,10 @@ struct LEDButton : app::SvgSwitch { | |||
| } | |||
| }; | |||
| struct LEDLatch : app::SvgLatch { | |||
| struct LEDLatch : LEDButton { | |||
| LEDLatch() { | |||
| addFrame(Svg::load(asset::system("res/ComponentLibrary/LEDButton.svg"))); | |||
| addFrame(Svg::load(asset::system("res/ComponentLibrary/LEDButton_1.svg"))); | |||
| momentary = false; | |||
| latch = true; | |||
| } | |||
| }; | |||
| @@ -865,18 +857,10 @@ struct LEDLightButton : LEDButton { | |||
| }; | |||
| template <typename TLight> | |||
| struct LEDLightLatch : LEDLatch { | |||
| app::ModuleLightWidget* light; | |||
| struct LEDLightLatch : LEDLightButton<TLight> { | |||
| LEDLightLatch() { | |||
| light = new TLight; | |||
| // Move center of light to center of box | |||
| light->box.pos = box.size.div(2).minus(light->box.size.div(2)); | |||
| addChild(light); | |||
| } | |||
| app::ModuleLightWidget* getLight() { | |||
| return light; | |||
| this->momentary = false; | |||
| this->latch = true; | |||
| } | |||
| }; | |||
| @@ -91,7 +91,6 @@ Directly including Rack headers other than rack.hpp in your plugin is unsupporte | |||
| #include <app/ModuleWidget.hpp> | |||
| #include <app/SvgSlider.hpp> | |||
| #include <app/SvgButton.hpp> | |||
| #include <app/SvgLatch.hpp> | |||
| #include <engine/Param.hpp> | |||
| #include <engine/ParamHandle.hpp> | |||
| @@ -1,51 +0,0 @@ | |||
| #include <app/SvgLatch.hpp> | |||
| namespace rack { | |||
| namespace app { | |||
| SvgLatch::SvgLatch() { | |||
| } | |||
| SvgLatch::~SvgLatch() { | |||
| } | |||
| void SvgLatch::onDragStart(const DragStartEvent& e) { | |||
| // Use Switch behavior | |||
| Switch::onDragStart(e); | |||
| if (e.button != GLFW_MOUSE_BUTTON_LEFT) | |||
| return; | |||
| // Set down frame | |||
| if (frames.size() >= 2) { | |||
| sw->setSvg(frames[1]); | |||
| fb->setDirty(); | |||
| } | |||
| } | |||
| void SvgLatch::onDragEnd(const DragEndEvent& e) { | |||
| // Use Switch behavior | |||
| Switch::onDragEnd(e); | |||
| if (e.button != GLFW_MOUSE_BUTTON_LEFT) | |||
| return; | |||
| // Set up frame | |||
| if (frames.size() >= 1) { | |||
| sw->setSvg(frames[0]); | |||
| fb->setDirty(); | |||
| } | |||
| } | |||
| void SvgLatch::onChange(const ChangeEvent& e) { | |||
| // Bypass SvgSwitch behavior | |||
| Switch::onChange(e); | |||
| } | |||
| } // namespace app | |||
| } // namespace rack | |||
| @@ -17,6 +17,11 @@ SvgSwitch::SvgSwitch() { | |||
| fb->addChild(sw); | |||
| } | |||
| SvgSwitch::~SvgSwitch() { | |||
| } | |||
| void SvgSwitch::addFrame(std::shared_ptr<window::Svg> svg) { | |||
| frames.push_back(svg); | |||
| // If this is our first frame, automatically set SVG and size | |||
| @@ -30,13 +35,46 @@ void SvgSwitch::addFrame(std::shared_ptr<window::Svg> svg) { | |||
| } | |||
| } | |||
| void SvgSwitch::onDragStart(const DragStartEvent& e) { | |||
| Switch::onDragStart(e); | |||
| if (e.button != GLFW_MOUSE_BUTTON_LEFT) | |||
| return; | |||
| // Set down frame if latch | |||
| if (latch) { | |||
| if (frames.size() >= 2) { | |||
| sw->setSvg(frames[1]); | |||
| fb->setDirty(); | |||
| } | |||
| } | |||
| } | |||
| void SvgSwitch::onDragEnd(const DragEndEvent& e) { | |||
| Switch::onDragEnd(e); | |||
| if (e.button != GLFW_MOUSE_BUTTON_LEFT) | |||
| return; | |||
| // Set up frame if latch | |||
| if (latch) { | |||
| if (frames.size() >= 1) { | |||
| sw->setSvg(frames[0]); | |||
| fb->setDirty(); | |||
| } | |||
| } | |||
| } | |||
| void SvgSwitch::onChange(const ChangeEvent& e) { | |||
| engine::ParamQuantity* pq = getParamQuantity(); | |||
| if (!frames.empty() && pq) { | |||
| int index = (int) std::round(pq->getValue() - pq->getMinValue()); | |||
| index = math::clamp(index, 0, (int) frames.size() - 1); | |||
| sw->setSvg(frames[index]); | |||
| fb->setDirty(); | |||
| if (!latch) { | |||
| engine::ParamQuantity* pq = getParamQuantity(); | |||
| if (!frames.empty() && pq) { | |||
| int index = (int) std::round(pq->getValue() - pq->getMinValue()); | |||
| index = math::clamp(index, 0, (int) frames.size() - 1); | |||
| sw->setSvg(frames[index]); | |||
| fb->setDirty(); | |||
| } | |||
| } | |||
| ParamWidget::onChange(e); | |||
| } | |||