@@ -8,7 +8,7 @@ | |||
namespace rack { | |||
struct LedDisplay : virtual Widget { | |||
struct LedDisplay : Widget { | |||
void draw(NVGcontext *vg) override; | |||
}; | |||
@@ -11,7 +11,8 @@ namespace rack { | |||
/** A knob which rotates an SVG and caches it in a framebuffer */ | |||
struct SVGKnob : Knob, FramebufferWidget { | |||
struct SVGKnob : Knob { | |||
FramebufferWidget *fb; | |||
TransformWidget *tw; | |||
SVGWidget *sw; | |||
CircularShadow *shadow; | |||
@@ -20,7 +21,6 @@ struct SVGKnob : Knob, FramebufferWidget { | |||
SVGKnob(); | |||
void setSVG(std::shared_ptr<SVG> svg); | |||
void step() override; | |||
void onChange(const event::Change &e) override; | |||
}; | |||
@@ -9,13 +9,13 @@ | |||
namespace rack { | |||
struct SVGPort : PortWidget, FramebufferWidget { | |||
SVGWidget *background; | |||
struct SVGPort : PortWidget { | |||
FramebufferWidget *fb; | |||
SVGWidget *sw; | |||
CircularShadow *shadow; | |||
SVGPort(); | |||
void setSVG(std::shared_ptr<SVG> svg); | |||
void draw(NVGcontext *vg) override; | |||
}; | |||
@@ -11,16 +11,22 @@ namespace rack { | |||
/** Behaves like a knob but linearly moves an SVGWidget between two points. | |||
Can be used for horizontal or vertical linear faders. | |||
*/ | |||
struct SVGSlider : Knob, FramebufferWidget { | |||
struct SVGSlider : Knob { | |||
FramebufferWidget *fb; | |||
SVGWidget *background; | |||
SVGWidget *handle; | |||
/** Intermediate positions will be interpolated between these positions */ | |||
math::Vec minHandlePos, maxHandlePos; | |||
SVGSlider(); | |||
void setSVGs(std::shared_ptr<SVG> backgroundSVG, std::shared_ptr<SVG> handleSVG); | |||
void step() override; | |||
void setBackgroundSVG(std::shared_ptr<SVG> backgroundSVG); | |||
void setHandleSVG(std::shared_ptr<SVG> handleSVG); | |||
void onChange(const event::Change &e) override; | |||
DEPRECATED void setSVGs(std::shared_ptr<SVG> backgroundSVG, std::shared_ptr<SVG> handleSVG) { | |||
setBackgroundSVG(backgroundSVG); | |||
setHandleSVG(handleSVG); | |||
} | |||
}; | |||
@@ -3,19 +3,19 @@ | |||
#include "widgets/Widget.hpp" | |||
#include "widgets/FramebufferWidget.hpp" | |||
#include "widgets/SVGWidget.hpp" | |||
#include "app/ParamWidget.hpp" | |||
#include "app/Switch.hpp" | |||
namespace rack { | |||
/** A ParamWidget with multiple frames corresponding to its value */ | |||
struct SVGSwitch : virtual ParamWidget, FramebufferWidget { | |||
std::vector<std::shared_ptr<SVG>> frames; | |||
struct SVGSwitch : Switch { | |||
FramebufferWidget *fb; | |||
SVGWidget *sw; | |||
std::vector<std::shared_ptr<SVG>> frames; | |||
SVGSwitch(); | |||
void step() override; | |||
/** Adds an SVG file to represent the next switch position */ | |||
void addFrame(std::shared_ptr<SVG> svg); | |||
void onChange(const event::Change &e) override; | |||
@@ -6,10 +6,10 @@ | |||
namespace rack { | |||
/** A switch that is turned on when held and turned off when released. | |||
Consider using SVGButton if the switch simply changes the state of your Module when clicked. | |||
*/ | |||
struct MomentarySwitch : virtual ParamWidget { | |||
/** A ParamWidget that controls */ | |||
struct Switch : ParamWidget { | |||
/** Return to original position when released */ | |||
bool momentary = false; | |||
void onDragStart(const event::DragStart &e) override; | |||
void onDragEnd(const event::DragEnd &e) override; | |||
}; |
@@ -1,15 +0,0 @@ | |||
#pragma once | |||
#include "app/common.hpp" | |||
#include "app/ParamWidget.hpp" | |||
namespace rack { | |||
/** A switch that cycles through each mechanical position */ | |||
struct ToggleSwitch : virtual ParamWidget { | |||
void onDragStart(const event::DragStart &e) override; | |||
}; | |||
} // namespace rack |
@@ -324,7 +324,8 @@ struct BefacoSlidePot : SVGSlider { | |||
math::Vec margin = math::Vec(3.5, 3.5); | |||
maxHandlePos = math::Vec(-1, -2).plus(margin); | |||
minHandlePos = math::Vec(-1, 87).plus(margin); | |||
setSVGs(SVG::load(asset::system("res/ComponentLibrary/BefacoSlidePot.svg")), SVG::load(asset::system("res/ComponentLibrary/BefacoSlidePotHandle.svg"))); | |||
setBackgroundSVG(SVG::load(asset::system("res/ComponentLibrary/BefacoSlidePot.svg"))); | |||
setHandleSVG(SVG::load(asset::system("res/ComponentLibrary/BefacoSlidePotHandle.svg"))); | |||
background->box.pos = margin; | |||
box.size = background->box.size.plus(margin.mult(2)); | |||
} | |||
@@ -334,38 +335,38 @@ struct LEDSlider : SVGSlider { | |||
LEDSlider() { | |||
maxHandlePos = mm2px(math::Vec(0.738, 0.738).plus(math::Vec(2, 0))); | |||
minHandlePos = mm2px(math::Vec(0.738, 22.078).plus(math::Vec(2, 0))); | |||
setSVGs(SVG::load(asset::system("res/ComponentLibrary/LEDSlider.svg")), NULL); | |||
setBackgroundSVG(SVG::load(asset::system("res/ComponentLibrary/LEDSlider.svg"))); | |||
} | |||
}; | |||
/** API is unstable for LEDSlider. Will add a LightWidget later. */ | |||
struct LEDSliderGreen : LEDSlider { | |||
LEDSliderGreen() { | |||
handle->setSVG(SVG::load(asset::system("res/ComponentLibrary/LEDSliderGreenHandle.svg"))); | |||
setHandleSVG(SVG::load(asset::system("res/ComponentLibrary/LEDSliderGreenHandle.svg"))); | |||
} | |||
}; | |||
struct LEDSliderRed : LEDSlider { | |||
LEDSliderRed() { | |||
handle->setSVG(SVG::load(asset::system("res/ComponentLibrary/LEDSliderRedHandle.svg"))); | |||
setHandleSVG(SVG::load(asset::system("res/ComponentLibrary/LEDSliderRedHandle.svg"))); | |||
} | |||
}; | |||
struct LEDSliderYellow : LEDSlider { | |||
LEDSliderYellow() { | |||
handle->setSVG(SVG::load(asset::system("res/ComponentLibrary/LEDSliderYellowHandle.svg"))); | |||
setHandleSVG(SVG::load(asset::system("res/ComponentLibrary/LEDSliderYellowHandle.svg"))); | |||
} | |||
}; | |||
struct LEDSliderBlue : LEDSlider { | |||
LEDSliderBlue() { | |||
handle->setSVG(SVG::load(asset::system("res/ComponentLibrary/LEDSliderBlueHandle.svg"))); | |||
setHandleSVG(SVG::load(asset::system("res/ComponentLibrary/LEDSliderBlueHandle.svg"))); | |||
} | |||
}; | |||
struct LEDSliderWhite : LEDSlider { | |||
LEDSliderWhite() { | |||
handle->setSVG(SVG::load(asset::system("res/ComponentLibrary/LEDSliderWhiteHandle.svg"))); | |||
setHandleSVG(SVG::load(asset::system("res/ComponentLibrary/LEDSliderWhiteHandle.svg"))); | |||
} | |||
}; | |||
@@ -508,7 +509,7 @@ struct PB61303Light : BASE { | |||
// Switches and Buttons | |||
//////////////////// | |||
struct NKK : SVGSwitch, ToggleSwitch { | |||
struct NKK : SVGSwitch { | |||
NKK() { | |||
addFrame(SVG::load(asset::system("res/ComponentLibrary/NKK_0.svg"))); | |||
addFrame(SVG::load(asset::system("res/ComponentLibrary/NKK_1.svg"))); | |||
@@ -516,14 +517,14 @@ struct NKK : SVGSwitch, ToggleSwitch { | |||
} | |||
}; | |||
struct CKSS : SVGSwitch, ToggleSwitch { | |||
struct CKSS : SVGSwitch { | |||
CKSS() { | |||
addFrame(SVG::load(asset::system("res/ComponentLibrary/CKSS_0.svg"))); | |||
addFrame(SVG::load(asset::system("res/ComponentLibrary/CKSS_1.svg"))); | |||
} | |||
}; | |||
struct CKSSThree : SVGSwitch, ToggleSwitch { | |||
struct CKSSThree : SVGSwitch { | |||
CKSSThree() { | |||
addFrame(SVG::load(asset::system("res/ComponentLibrary/CKSSThree_0.svg"))); | |||
addFrame(SVG::load(asset::system("res/ComponentLibrary/CKSSThree_1.svg"))); | |||
@@ -531,27 +532,30 @@ struct CKSSThree : SVGSwitch, ToggleSwitch { | |||
} | |||
}; | |||
struct CKD6 : SVGSwitch, MomentarySwitch { | |||
struct CKD6 : SVGSwitch { | |||
CKD6() { | |||
momentary = true; | |||
addFrame(SVG::load(asset::system("res/ComponentLibrary/CKD6_0.svg"))); | |||
addFrame(SVG::load(asset::system("res/ComponentLibrary/CKD6_1.svg"))); | |||
} | |||
}; | |||
struct TL1105 : SVGSwitch, MomentarySwitch { | |||
struct TL1105 : SVGSwitch { | |||
TL1105() { | |||
momentary = true; | |||
addFrame(SVG::load(asset::system("res/ComponentLibrary/TL1105_0.svg"))); | |||
addFrame(SVG::load(asset::system("res/ComponentLibrary/TL1105_1.svg"))); | |||
} | |||
}; | |||
struct LEDButton : SVGSwitch, MomentarySwitch { | |||
struct LEDButton : SVGSwitch { | |||
LEDButton() { | |||
momentary = true; | |||
addFrame(SVG::load(asset::system("res/ComponentLibrary/LEDButton.svg"))); | |||
} | |||
}; | |||
struct BefacoSwitch : SVGSwitch, ToggleSwitch { | |||
struct BefacoSwitch : SVGSwitch { | |||
BefacoSwitch() { | |||
addFrame(SVG::load(asset::system("res/ComponentLibrary/BefacoSwitch_0.svg"))); | |||
addFrame(SVG::load(asset::system("res/ComponentLibrary/BefacoSwitch_1.svg"))); | |||
@@ -559,21 +563,24 @@ struct BefacoSwitch : SVGSwitch, ToggleSwitch { | |||
} | |||
}; | |||
struct BefacoPush : SVGSwitch, MomentarySwitch { | |||
struct BefacoPush : SVGSwitch { | |||
BefacoPush() { | |||
momentary = true; | |||
addFrame(SVG::load(asset::system("res/ComponentLibrary/BefacoPush_0.svg"))); | |||
addFrame(SVG::load(asset::system("res/ComponentLibrary/BefacoPush_1.svg"))); | |||
} | |||
}; | |||
struct LEDBezel : SVGSwitch, MomentarySwitch { | |||
struct LEDBezel : SVGSwitch { | |||
LEDBezel() { | |||
momentary = true; | |||
addFrame(SVG::load(asset::system("res/ComponentLibrary/LEDBezel.svg"))); | |||
} | |||
}; | |||
struct PB61303 : SVGSwitch, MomentarySwitch { | |||
struct PB61303 : SVGSwitch { | |||
PB61303() { | |||
momentary = true; | |||
addFrame(SVG::load(asset::system("res/ComponentLibrary/PB61303.svg"))); | |||
} | |||
}; | |||
@@ -47,7 +47,6 @@ | |||
#include "app/MidiWidget.hpp" | |||
#include "app/ModuleLightWidget.hpp" | |||
#include "app/ModuleWidget.hpp" | |||
#include "app/MomentarySwitch.hpp" | |||
#include "app/MultiLightWidget.hpp" | |||
#include "app/ParamWidget.hpp" | |||
#include "app/PortWidget.hpp" | |||
@@ -62,7 +61,6 @@ | |||
#include "app/SVGScrew.hpp" | |||
#include "app/SVGSlider.hpp" | |||
#include "app/SVGSwitch.hpp" | |||
#include "app/ToggleSwitch.hpp" | |||
#include "app/Toolbar.hpp" | |||
#include "app/CableContainer.hpp" | |||
#include "app/CableWidget.hpp" | |||
@@ -6,7 +6,7 @@ | |||
namespace rack { | |||
struct Label : virtual Widget { | |||
struct Label : Widget { | |||
enum Alignment { | |||
LEFT_ALIGNMENT, | |||
CENTER_ALIGNMENT, | |||
@@ -7,7 +7,7 @@ | |||
namespace rack { | |||
struct ProgressBar : virtual Widget { | |||
struct ProgressBar : Widget { | |||
Quantity *quantity = NULL; | |||
ProgressBar(); | |||
@@ -7,7 +7,7 @@ namespace rack { | |||
/** Positions children in a row/column based on their widths/heights */ | |||
struct SequentialLayout : virtual Widget { | |||
struct SequentialLayout : Widget { | |||
enum Orientation { | |||
HORIZONTAL_ORIENTATION, | |||
VERTICAL_ORIENTATION, | |||
@@ -6,7 +6,7 @@ | |||
namespace rack { | |||
struct Tooltip : virtual Widget { | |||
struct Tooltip : Widget { | |||
std::string text; | |||
void step() override; | |||
@@ -9,7 +9,7 @@ namespace rack { | |||
When `dirty` is true, its children will be re-rendered on the next call to step() override. | |||
Events are not passed to the underlying scene. | |||
*/ | |||
struct FramebufferWidget : virtual Widget { | |||
struct FramebufferWidget : Widget { | |||
/** Set this to true to re-render the children to the framebuffer the next time it is drawn */ | |||
bool dirty = true; | |||
/** A margin in pixels around the children in the framebuffer | |||
@@ -7,7 +7,7 @@ namespace rack { | |||
/** Widget that consumes recursing events without giving a chance for children to consume. | |||
*/ | |||
struct ObstructWidget : virtual Widget { | |||
struct ObstructWidget : Widget { | |||
void onHover(const event::Hover &e) override { | |||
e.consume(this); | |||
} | |||
@@ -9,7 +9,7 @@ namespace rack { | |||
You can of course override the events. | |||
You may also call OpaqueWidget::on*() from the overridden method to continue recursing/consuming the event. | |||
*/ | |||
struct OpaqueWidget : virtual Widget { | |||
struct OpaqueWidget : Widget { | |||
void onHover(const event::Hover &e) override { | |||
Widget::onHover(e); | |||
if (!e.getConsumed()) | |||
@@ -7,7 +7,7 @@ namespace rack { | |||
/** Draws an SVG */ | |||
struct SVGWidget : virtual Widget { | |||
struct SVGWidget : Widget { | |||
std::shared_ptr<SVG> svg; | |||
/** Sets the box size to the svg image size */ | |||
@@ -6,7 +6,7 @@ namespace rack { | |||
/** Transforms appearance only, not positions of events */ | |||
struct TransformWidget : virtual Widget { | |||
struct TransformWidget : Widget { | |||
/** The transformation matrix */ | |||
float transform[6]; | |||
@@ -6,7 +6,7 @@ namespace rack { | |||
/** Widget that does not respond to events and does not pass events to children */ | |||
struct TransparentWidget : virtual Widget { | |||
struct TransparentWidget : Widget { | |||
/** Override behavior to do nothing instead. */ | |||
void onHover(const event::Hover &e) override {} | |||
void onButton(const event::Button &e) override {} | |||
@@ -11,8 +11,6 @@ namespace rack { | |||
/** A node in the 2D scene graph | |||
It is recommended to inherit virtually from Widget instead of directly. | |||
e.g. `struct MyWidget : virtual Widget {}` | |||
*/ | |||
struct Widget { | |||
/** Stores position and size */ | |||
@@ -5,7 +5,7 @@ | |||
namespace rack { | |||
struct ZoomWidget : virtual Widget { | |||
struct ZoomWidget : Widget { | |||
float zoom = 1.f; | |||
math::Vec getRelativeOffset(math::Vec v, Widget *relative) override { | |||
@@ -1,20 +0,0 @@ | |||
#include "app/MomentarySwitch.hpp" | |||
namespace rack { | |||
void MomentarySwitch::onDragStart(const event::DragStart &e) { | |||
if (paramQuantity) { | |||
paramQuantity->setMax(); | |||
} | |||
} | |||
void MomentarySwitch::onDragEnd(const event::DragEnd &e) { | |||
if (paramQuantity) { | |||
paramQuantity->setMin(); | |||
} | |||
} | |||
} // namespace rack |
@@ -54,6 +54,7 @@ void PortWidget::draw(NVGcontext *vg) { | |||
if (type == INPUT ? activeCable->inputPort : activeCable->outputPort) | |||
nvgGlobalAlpha(vg, 0.5); | |||
} | |||
Widget::draw(vg); | |||
} | |||
void PortWidget::onButton(const event::Button &e) { | |||
@@ -5,12 +5,15 @@ namespace rack { | |||
SVGKnob::SVGKnob() { | |||
fb = new FramebufferWidget; | |||
addChild(fb); | |||
shadow = new CircularShadow; | |||
addChild(shadow); | |||
fb->addChild(shadow); | |||
shadow->box.size = math::Vec(); | |||
tw = new TransformWidget; | |||
addChild(tw); | |||
fb->addChild(tw); | |||
sw = new SVGWidget; | |||
tw->addChild(sw); | |||
@@ -19,17 +22,14 @@ SVGKnob::SVGKnob() { | |||
void SVGKnob::setSVG(std::shared_ptr<SVG> svg) { | |||
sw->setSVG(svg); | |||
tw->box.size = sw->box.size; | |||
fb->box.size = sw->box.size; | |||
box.size = sw->box.size; | |||
shadow->box.size = sw->box.size; | |||
shadow->box.pos = math::Vec(0, sw->box.size.y * 0.1); | |||
// Move shadow downward by 10% | |||
shadow->box.pos = math::Vec(0, sw->box.size.y * 0.10); | |||
// shadow->box = shadow->box.grow(math::Vec(2, 2)); | |||
} | |||
void SVGKnob::step() { | |||
Knob::step(); | |||
FramebufferWidget::step(); | |||
} | |||
void SVGKnob::onChange(const event::Change &e) { | |||
// Re-transform the TransformWidget | |||
if (paramQuantity) { | |||
@@ -47,7 +47,7 @@ void SVGKnob::onChange(const event::Change &e) { | |||
tw->translate(center); | |||
tw->rotate(angle); | |||
tw->translate(center.neg()); | |||
dirty = true; | |||
fb->dirty = true; | |||
} | |||
Knob::onChange(e); | |||
} | |||
@@ -5,27 +5,28 @@ namespace rack { | |||
SVGPort::SVGPort() { | |||
fb = new FramebufferWidget; | |||
addChild(fb); | |||
shadow = new CircularShadow; | |||
addChild(shadow); | |||
fb->addChild(shadow); | |||
// Avoid breakage if plugins fail to call setSVG() | |||
// In that case, just disable the shadow. | |||
shadow->box.size = math::Vec(); | |||
background = new SVGWidget; | |||
addChild(background); | |||
sw = new SVGWidget; | |||
fb->addChild(sw); | |||
} | |||
void SVGPort::setSVG(std::shared_ptr<SVG> svg) { | |||
background->setSVG(svg); | |||
box.size = background->box.size; | |||
shadow->box.size = background->box.size; | |||
shadow->box.pos = math::Vec(0, background->box.size.y * 0.1); | |||
sw->setSVG(svg); | |||
fb->box.size = sw->box.size; | |||
box.size = sw->box.size; | |||
shadow->box.size = sw->box.size; | |||
// Move shadow downward by 10% | |||
shadow->box.pos = math::Vec(0, sw->box.size.y * 0.10); | |||
// shadow->box = shadow->box.grow(math::Vec(2, 2)); | |||
} | |||
void SVGPort::draw(NVGcontext *vg) { | |||
PortWidget::draw(vg); | |||
FramebufferWidget::draw(vg); | |||
fb->dirty = true; | |||
} | |||
@@ -5,26 +5,27 @@ namespace rack { | |||
SVGSlider::SVGSlider() { | |||
fb = new FramebufferWidget; | |||
addChild(fb); | |||
background = new SVGWidget; | |||
addChild(background); | |||
fb->addChild(background); | |||
handle = new SVGWidget; | |||
addChild(handle); | |||
fb->addChild(handle); | |||
speed = 2.0; | |||
} | |||
void SVGSlider::setSVGs(std::shared_ptr<SVG> backgroundSVG, std::shared_ptr<SVG> handleSVG) { | |||
void SVGSlider::setBackgroundSVG(std::shared_ptr<SVG> backgroundSVG) { | |||
background->setSVG(backgroundSVG); | |||
fb->box.size = background->box.size; | |||
box.size = background->box.size; | |||
if (handleSVG) { | |||
handle->setSVG(handleSVG); | |||
} | |||
} | |||
void SVGSlider::step() { | |||
Knob::step(); | |||
FramebufferWidget::step(); | |||
void SVGSlider::setHandleSVG(std::shared_ptr<SVG> handleSVG) { | |||
handle->setSVG(handleSVG); | |||
fb->dirty = true; | |||
} | |||
void SVGSlider::onChange(const event::Change &e) { | |||
@@ -34,7 +35,7 @@ void SVGSlider::onChange(const event::Change &e) { | |||
handle->box.pos = math::Vec( | |||
math::rescale(v, 0.f, 1.f, minHandlePos.x, maxHandlePos.x), | |||
math::rescale(v, 0.f, 1.f, minHandlePos.y, maxHandlePos.y)); | |||
dirty = true; | |||
fb->dirty = true; | |||
} | |||
ParamWidget::onChange(e); | |||
} | |||
@@ -5,13 +5,11 @@ namespace rack { | |||
SVGSwitch::SVGSwitch() { | |||
sw = new SVGWidget; | |||
addChild(sw); | |||
} | |||
fb = new FramebufferWidget; | |||
addChild(fb); | |||
void SVGSwitch::step() { | |||
ParamWidget::step(); | |||
FramebufferWidget::step(); | |||
sw = new SVGWidget; | |||
fb->addChild(sw); | |||
} | |||
void SVGSwitch::addFrame(std::shared_ptr<SVG> svg) { | |||
@@ -20,16 +18,16 @@ void SVGSwitch::addFrame(std::shared_ptr<SVG> svg) { | |||
if (!sw->svg) { | |||
sw->setSVG(svg); | |||
box.size = sw->box.size; | |||
fb->box.size = sw->box.size; | |||
} | |||
} | |||
void SVGSwitch::onChange(const event::Change &e) { | |||
assert(frames.size() > 0); | |||
if (paramQuantity) { | |||
int index = paramQuantity->getScaledValue() * (frames.size() - 1); | |||
if (!frames.empty() && paramQuantity) { | |||
int index = (int) paramQuantity->getValue(); | |||
index = math::clamp(index, 0, (int) frames.size() - 1); | |||
sw->setSVG(frames[index]); | |||
dirty = true; | |||
fb->dirty = true; | |||
} | |||
ParamWidget::onChange(e); | |||
} | |||
@@ -1,4 +1,4 @@ | |||
#include "app/ToggleSwitch.hpp" | |||
#include "app/Switch.hpp" | |||
#include "app.hpp" | |||
#include "app/Scene.hpp" | |||
#include "history.hpp" | |||
@@ -7,19 +7,26 @@ | |||
namespace rack { | |||
void ToggleSwitch::onDragStart(const event::DragStart &e) { | |||
void Switch::onDragStart(const event::DragStart &e) { | |||
// Cycle through values | |||
// e.g. a range of [0.0, 3.0] would have modes 0, 1, 2, and 3. | |||
if (paramQuantity) { | |||
float oldValue = paramQuantity->getValue(); | |||
if (paramQuantity->isMax()) { | |||
paramQuantity->setMin(); | |||
if (momentary) { | |||
// Set to maximum value | |||
paramQuantity->setMax(); | |||
} | |||
else { | |||
paramQuantity->setValue(std::floor(paramQuantity->getValue() + 1)); | |||
// Increment value by 1, or reset back to minimum | |||
if (paramQuantity->isMax()) { | |||
paramQuantity->setMin(); | |||
} | |||
else { | |||
paramQuantity->setValue(std::floor(paramQuantity->getValue() + 1)); | |||
} | |||
} | |||
float newValue = paramQuantity->getValue(); | |||
float newValue = paramQuantity->getValue(); | |||
if (oldValue != newValue) { | |||
// Push ParamChange history action | |||
history::ParamChange *h = new history::ParamChange; | |||
@@ -32,5 +39,14 @@ void ToggleSwitch::onDragStart(const event::DragStart &e) { | |||
} | |||
} | |||
void Switch::onDragEnd(const event::DragEnd &e) { | |||
if (paramQuantity) { | |||
if (momentary) { | |||
// Set to minimum value | |||
paramQuantity->setMin(); | |||
} | |||
} | |||
} | |||
} // namespace rack |