| @@ -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 | |||