From 428f137d4556408b444c22db788a04911479b0fc Mon Sep 17 00:00:00 2001 From: Andrew Belt Date: Sat, 12 Jan 2019 22:56:24 -0500 Subject: [PATCH] Remove multiple inheritance from all widgets, remove virtual inheritance, merge MomentarySwitch and ToggleSwitch to Switch with a boolean. --- include/app/LedDisplay.hpp | 2 +- include/app/SVGKnob.hpp | 4 +- include/app/SVGPort.hpp | 6 +-- include/app/SVGSlider.hpp | 12 ++++-- include/app/SVGSwitch.hpp | 8 ++-- .../app/{MomentarySwitch.hpp => Switch.hpp} | 8 ++-- include/app/ToggleSwitch.hpp | 15 ------- include/componentlibrary.hpp | 41 +++++++++++-------- include/rack.hpp | 2 - include/ui/Label.hpp | 2 +- include/ui/ProgressBar.hpp | 2 +- include/ui/SequentialLayout.hpp | 2 +- include/ui/Tooltip.hpp | 2 +- include/widgets/FramebufferWidget.hpp | 2 +- include/widgets/ObstructWidget.hpp | 2 +- include/widgets/OpaqueWidget.hpp | 2 +- include/widgets/SVGWidget.hpp | 2 +- include/widgets/TransformWidget.hpp | 2 +- include/widgets/TransparentWidget.hpp | 2 +- include/widgets/Widget.hpp | 2 - include/widgets/ZoomWidget.hpp | 2 +- src/app/MomentarySwitch.cpp | 20 --------- src/app/PortWidget.cpp | 1 + src/app/SVGKnob.cpp | 18 ++++---- src/app/SVGPort.cpp | 25 +++++------ src/app/SVGSlider.cpp | 21 +++++----- src/app/SVGSwitch.cpp | 18 ++++---- src/app/{ToggleSwitch.cpp => Switch.cpp} | 28 ++++++++++--- 28 files changed, 122 insertions(+), 131 deletions(-) rename include/app/{MomentarySwitch.hpp => Switch.hpp} (50%) delete mode 100644 include/app/ToggleSwitch.hpp delete mode 100644 src/app/MomentarySwitch.cpp rename src/app/{ToggleSwitch.cpp => Switch.cpp} (57%) diff --git a/include/app/LedDisplay.hpp b/include/app/LedDisplay.hpp index 34a341d2..15c6177d 100644 --- a/include/app/LedDisplay.hpp +++ b/include/app/LedDisplay.hpp @@ -8,7 +8,7 @@ namespace rack { -struct LedDisplay : virtual Widget { +struct LedDisplay : Widget { void draw(NVGcontext *vg) override; }; diff --git a/include/app/SVGKnob.hpp b/include/app/SVGKnob.hpp index 117ff31e..1db7517c 100644 --- a/include/app/SVGKnob.hpp +++ b/include/app/SVGKnob.hpp @@ -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); - void step() override; void onChange(const event::Change &e) override; }; diff --git a/include/app/SVGPort.hpp b/include/app/SVGPort.hpp index 25763900..bff38e43 100644 --- a/include/app/SVGPort.hpp +++ b/include/app/SVGPort.hpp @@ -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); - void draw(NVGcontext *vg) override; }; diff --git a/include/app/SVGSlider.hpp b/include/app/SVGSlider.hpp index ebf916b2..26d13257 100644 --- a/include/app/SVGSlider.hpp +++ b/include/app/SVGSlider.hpp @@ -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 backgroundSVG, std::shared_ptr handleSVG); - void step() override; + void setBackgroundSVG(std::shared_ptr backgroundSVG); + void setHandleSVG(std::shared_ptr handleSVG); void onChange(const event::Change &e) override; + + DEPRECATED void setSVGs(std::shared_ptr backgroundSVG, std::shared_ptr handleSVG) { + setBackgroundSVG(backgroundSVG); + setHandleSVG(handleSVG); + } }; diff --git a/include/app/SVGSwitch.hpp b/include/app/SVGSwitch.hpp index a9b1d2b4..0699f717 100644 --- a/include/app/SVGSwitch.hpp +++ b/include/app/SVGSwitch.hpp @@ -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> frames; +struct SVGSwitch : Switch { + FramebufferWidget *fb; SVGWidget *sw; + std::vector> frames; SVGSwitch(); - void step() override; /** Adds an SVG file to represent the next switch position */ void addFrame(std::shared_ptr svg); void onChange(const event::Change &e) override; diff --git a/include/app/MomentarySwitch.hpp b/include/app/Switch.hpp similarity index 50% rename from include/app/MomentarySwitch.hpp rename to include/app/Switch.hpp index 7ae69b40..5d45a4c5 100644 --- a/include/app/MomentarySwitch.hpp +++ b/include/app/Switch.hpp @@ -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; }; diff --git a/include/app/ToggleSwitch.hpp b/include/app/ToggleSwitch.hpp deleted file mode 100644 index 51695a7e..00000000 --- a/include/app/ToggleSwitch.hpp +++ /dev/null @@ -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 diff --git a/include/componentlibrary.hpp b/include/componentlibrary.hpp index 571587ae..3868be16 100644 --- a/include/componentlibrary.hpp +++ b/include/componentlibrary.hpp @@ -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"))); } }; diff --git a/include/rack.hpp b/include/rack.hpp index 48439aa7..d35407a4 100644 --- a/include/rack.hpp +++ b/include/rack.hpp @@ -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" diff --git a/include/ui/Label.hpp b/include/ui/Label.hpp index ca855e4f..2860e357 100644 --- a/include/ui/Label.hpp +++ b/include/ui/Label.hpp @@ -6,7 +6,7 @@ namespace rack { -struct Label : virtual Widget { +struct Label : Widget { enum Alignment { LEFT_ALIGNMENT, CENTER_ALIGNMENT, diff --git a/include/ui/ProgressBar.hpp b/include/ui/ProgressBar.hpp index 2b1ccb7c..a56958e5 100644 --- a/include/ui/ProgressBar.hpp +++ b/include/ui/ProgressBar.hpp @@ -7,7 +7,7 @@ namespace rack { -struct ProgressBar : virtual Widget { +struct ProgressBar : Widget { Quantity *quantity = NULL; ProgressBar(); diff --git a/include/ui/SequentialLayout.hpp b/include/ui/SequentialLayout.hpp index 9e575252..38906f69 100644 --- a/include/ui/SequentialLayout.hpp +++ b/include/ui/SequentialLayout.hpp @@ -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, diff --git a/include/ui/Tooltip.hpp b/include/ui/Tooltip.hpp index 154342fb..462d9768 100644 --- a/include/ui/Tooltip.hpp +++ b/include/ui/Tooltip.hpp @@ -6,7 +6,7 @@ namespace rack { -struct Tooltip : virtual Widget { +struct Tooltip : Widget { std::string text; void step() override; diff --git a/include/widgets/FramebufferWidget.hpp b/include/widgets/FramebufferWidget.hpp index c170739c..403498ad 100644 --- a/include/widgets/FramebufferWidget.hpp +++ b/include/widgets/FramebufferWidget.hpp @@ -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 diff --git a/include/widgets/ObstructWidget.hpp b/include/widgets/ObstructWidget.hpp index eda33df9..a9790758 100644 --- a/include/widgets/ObstructWidget.hpp +++ b/include/widgets/ObstructWidget.hpp @@ -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); } diff --git a/include/widgets/OpaqueWidget.hpp b/include/widgets/OpaqueWidget.hpp index 14203c8f..26d65997 100644 --- a/include/widgets/OpaqueWidget.hpp +++ b/include/widgets/OpaqueWidget.hpp @@ -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()) diff --git a/include/widgets/SVGWidget.hpp b/include/widgets/SVGWidget.hpp index da8a65bb..be642042 100644 --- a/include/widgets/SVGWidget.hpp +++ b/include/widgets/SVGWidget.hpp @@ -7,7 +7,7 @@ namespace rack { /** Draws an SVG */ -struct SVGWidget : virtual Widget { +struct SVGWidget : Widget { std::shared_ptr svg; /** Sets the box size to the svg image size */ diff --git a/include/widgets/TransformWidget.hpp b/include/widgets/TransformWidget.hpp index 9c784935..1f065199 100644 --- a/include/widgets/TransformWidget.hpp +++ b/include/widgets/TransformWidget.hpp @@ -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]; diff --git a/include/widgets/TransparentWidget.hpp b/include/widgets/TransparentWidget.hpp index b522cb1b..026d7c25 100644 --- a/include/widgets/TransparentWidget.hpp +++ b/include/widgets/TransparentWidget.hpp @@ -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 {} diff --git a/include/widgets/Widget.hpp b/include/widgets/Widget.hpp index 08c229b2..0851119f 100644 --- a/include/widgets/Widget.hpp +++ b/include/widgets/Widget.hpp @@ -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 */ diff --git a/include/widgets/ZoomWidget.hpp b/include/widgets/ZoomWidget.hpp index 4ad0347f..d8158146 100644 --- a/include/widgets/ZoomWidget.hpp +++ b/include/widgets/ZoomWidget.hpp @@ -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 { diff --git a/src/app/MomentarySwitch.cpp b/src/app/MomentarySwitch.cpp deleted file mode 100644 index c3520678..00000000 --- a/src/app/MomentarySwitch.cpp +++ /dev/null @@ -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 diff --git a/src/app/PortWidget.cpp b/src/app/PortWidget.cpp index 8362ad02..05ccdfd0 100644 --- a/src/app/PortWidget.cpp +++ b/src/app/PortWidget.cpp @@ -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) { diff --git a/src/app/SVGKnob.cpp b/src/app/SVGKnob.cpp index 99cb98f3..e5a4b221 100644 --- a/src/app/SVGKnob.cpp +++ b/src/app/SVGKnob.cpp @@ -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) { 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); } diff --git a/src/app/SVGPort.cpp b/src/app/SVGPort.cpp index 39fe49be..71df35f4 100644 --- a/src/app/SVGPort.cpp +++ b/src/app/SVGPort.cpp @@ -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) { - 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; } diff --git a/src/app/SVGSlider.cpp b/src/app/SVGSlider.cpp index 973fcc90..6ee2e620 100644 --- a/src/app/SVGSlider.cpp +++ b/src/app/SVGSlider.cpp @@ -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 backgroundSVG, std::shared_ptr handleSVG) { +void SVGSlider::setBackgroundSVG(std::shared_ptr 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 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); } diff --git a/src/app/SVGSwitch.cpp b/src/app/SVGSwitch.cpp index 5eecca81..c18982df 100644 --- a/src/app/SVGSwitch.cpp +++ b/src/app/SVGSwitch.cpp @@ -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) { @@ -20,16 +18,16 @@ void SVGSwitch::addFrame(std::shared_ptr 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); } diff --git a/src/app/ToggleSwitch.cpp b/src/app/Switch.cpp similarity index 57% rename from src/app/ToggleSwitch.cpp rename to src/app/Switch.cpp index 8e040057..33683803 100644 --- a/src/app/ToggleSwitch.cpp +++ b/src/app/Switch.cpp @@ -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