@@ -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 */ | /** A ParamWidget with multiple frames corresponding to its value */ | ||||
struct SvgSwitch : Switch { | struct SvgSwitch : Switch { | ||||
struct Internal; | |||||
Internal* internal; | |||||
widget::FramebufferWidget* fb; | widget::FramebufferWidget* fb; | ||||
CircularShadow* shadow; | CircularShadow* shadow; | ||||
widget::SvgWidget* sw; | widget::SvgWidget* sw; | ||||
std::vector<std::shared_ptr<window::Svg>> frames; | 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(); | ||||
~SvgSwitch(); | |||||
/** Adds an SVG file to represent the next switch position */ | /** Adds an SVG file to represent the next switch position */ | ||||
void addFrame(std::shared_ptr<window::Svg> svg); | 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; | void onChange(const ChangeEvent& e) override; | ||||
}; | }; | ||||
@@ -6,7 +6,6 @@ | |||||
#include <app/SvgPort.hpp> | #include <app/SvgPort.hpp> | ||||
#include <app/ModuleLightWidget.hpp> | #include <app/ModuleLightWidget.hpp> | ||||
#include <app/SvgSwitch.hpp> | #include <app/SvgSwitch.hpp> | ||||
#include <app/SvgLatch.hpp> | |||||
#include <app/SvgScrew.hpp> | #include <app/SvgScrew.hpp> | ||||
#include <app/AudioWidget.hpp> | #include <app/AudioWidget.hpp> | ||||
#include <app/MidiWidget.hpp> | #include <app/MidiWidget.hpp> | ||||
@@ -769,13 +768,6 @@ struct CL1362Port : app::SvgPort { | |||||
// Switches | // Switches | ||||
//////////////////// | //////////////////// | ||||
template <typename TSwitch> | |||||
struct LatchingSwitch : TSwitch { | |||||
LatchingSwitch() { | |||||
this->momentary = false; | |||||
} | |||||
}; | |||||
template <typename TSwitch> | template <typename TSwitch> | ||||
struct MomentarySwitch : TSwitch { | struct MomentarySwitch : TSwitch { | ||||
MomentarySwitch() { | MomentarySwitch() { | ||||
@@ -841,10 +833,10 @@ struct LEDButton : app::SvgSwitch { | |||||
} | } | ||||
}; | }; | ||||
struct LEDLatch : app::SvgLatch { | |||||
struct LEDLatch : LEDButton { | |||||
LEDLatch() { | 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> | template <typename TLight> | ||||
struct LEDLightLatch : LEDLatch { | |||||
app::ModuleLightWidget* light; | |||||
struct LEDLightLatch : LEDLightButton<TLight> { | |||||
LEDLightLatch() { | 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/ModuleWidget.hpp> | ||||
#include <app/SvgSlider.hpp> | #include <app/SvgSlider.hpp> | ||||
#include <app/SvgButton.hpp> | #include <app/SvgButton.hpp> | ||||
#include <app/SvgLatch.hpp> | |||||
#include <engine/Param.hpp> | #include <engine/Param.hpp> | ||||
#include <engine/ParamHandle.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); | fb->addChild(sw); | ||||
} | } | ||||
SvgSwitch::~SvgSwitch() { | |||||
} | |||||
void SvgSwitch::addFrame(std::shared_ptr<window::Svg> svg) { | void SvgSwitch::addFrame(std::shared_ptr<window::Svg> svg) { | ||||
frames.push_back(svg); | frames.push_back(svg); | ||||
// If this is our first frame, automatically set SVG and size | // 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) { | 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); | ParamWidget::onChange(e); | ||||
} | } | ||||