@@ -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); | |||
} | |||