From 0ba244e98f05ab36c46636c6c718f84af531d75e Mon Sep 17 00:00:00 2001 From: Andrew Belt Date: Tue, 13 Mar 2018 07:47:50 -0400 Subject: [PATCH] Reorganize Components, add LEDSlider with colors --- include/app.hpp | 27 +++---- include/componentlibrary.hpp | 60 ++++++++++++---- res/ComponentLibrary/LEDSlider.svg | 66 +++++++++++++++++ res/ComponentLibrary/LEDSliderBlueHandle.svg | 71 +++++++++++++++++++ res/ComponentLibrary/LEDSliderGreenHandle.svg | 71 +++++++++++++++++++ res/ComponentLibrary/LEDSliderRedHandle.svg | 71 +++++++++++++++++++ res/ComponentLibrary/LEDSliderWhiteHandle.svg | 71 +++++++++++++++++++ .../LEDSliderYellowHandle.svg | 71 +++++++++++++++++++ src/app/CircularShadow.cpp | 2 - src/app/Knob.cpp | 1 + src/app/SVGFader.cpp | 30 -------- src/app/SVGPort.cpp | 14 ++++ src/app/SVGSlider.cpp | 37 ++++++++++ 13 files changed, 533 insertions(+), 59 deletions(-) create mode 100644 res/ComponentLibrary/LEDSlider.svg create mode 100644 res/ComponentLibrary/LEDSliderBlueHandle.svg create mode 100644 res/ComponentLibrary/LEDSliderGreenHandle.svg create mode 100644 res/ComponentLibrary/LEDSliderRedHandle.svg create mode 100644 res/ComponentLibrary/LEDSliderWhiteHandle.svg create mode 100644 res/ComponentLibrary/LEDSliderYellowHandle.svg delete mode 100644 src/app/SVGFader.cpp create mode 100644 src/app/SVGSlider.cpp diff --git a/include/app.hpp b/include/app.hpp index 968036dd..ef0ba852 100644 --- a/include/app.hpp +++ b/include/app.hpp @@ -274,11 +274,11 @@ struct SpriteKnob : Knob, SpriteWidget { /** A knob which rotates an SVG and caches it in a framebuffer */ struct SVGKnob : Knob, FramebufferWidget { - /** Angles in radians */ - float minAngle, maxAngle; TransformWidget *tw; SVGWidget *sw; CircularShadow *shadow; + /** Angles in radians */ + float minAngle, maxAngle; SVGKnob(); void setSVG(std::shared_ptr svg); @@ -289,18 +289,22 @@ struct SVGKnob : Knob, FramebufferWidget { /** Behaves like a knob but linearly moves an SVGWidget between two points. Can be used for horizontal or vertical linear faders. */ -struct SVGFader : Knob, FramebufferWidget { - /** Intermediate positions will be interpolated between these positions */ - Vec minHandlePos, maxHandlePos; - /** Not owned */ +struct SVGSlider : Knob, FramebufferWidget { SVGWidget *background; SVGWidget *handle; + /** Intermediate positions will be interpolated between these positions */ + Vec minHandlePos, maxHandlePos; - SVGFader(); + SVGSlider(); + void setSVGs(std::shared_ptr backgroundSVG, std::shared_ptr handleSVG); void step() override; void onChange(EventChange &e) override; }; +/** Deprecated name for SVGSlider */ +typedef SVGSlider SVGFader; + +/** A Parameter with multiple frames corresponding to its value */ struct SVGSwitch : virtual Parameter, FramebufferWidget { std::vector> frames; SVGWidget *sw; @@ -446,13 +450,11 @@ struct ModuleLightWidget : MultiLightWidget { // ports //////////////////// -struct Port : OpaqueWidget { +struct Port : Component { enum PortType { INPUT, OUTPUT }; - - Module *module = NULL; PortType type = INPUT; int portId; MultiLightWidget *plugLight; @@ -470,9 +472,8 @@ struct Port : OpaqueWidget { template static T *create(Vec pos, PortType type, Module *module, int portId) { - T *o = Widget::create(pos); + T *o = Component::create(pos, module); o->type = type; - o->module = module; o->portId = portId; return o; } @@ -480,8 +481,10 @@ struct Port : OpaqueWidget { struct SVGPort : Port, FramebufferWidget { SVGWidget *background; + CircularShadow *shadow; SVGPort(); + void setSVG(std::shared_ptr svg); void draw(NVGcontext *vg) override; }; diff --git a/include/componentlibrary.hpp b/include/componentlibrary.hpp index a2b60456..ab51d576 100644 --- a/include/componentlibrary.hpp +++ b/include/componentlibrary.hpp @@ -322,45 +322,75 @@ struct BefacoTinyKnob : SVGKnob { } }; -struct BefacoSlidePot : SVGFader { +struct BefacoSlidePot : SVGSlider { BefacoSlidePot() { Vec margin = Vec(3.5, 3.5); maxHandlePos = Vec(-1, -2).plus(margin); minHandlePos = Vec(-1, 87).plus(margin); - background->svg = SVG::load(assetGlobal("res/ComponentLibrary/BefacoSlidePot.svg")); - background->wrap(); + setSVGs(SVG::load(assetGlobal("res/ComponentLibrary/BefacoSlidePot.svg")), SVG::load(assetGlobal("res/ComponentLibrary/BefacoSlidePotHandle.svg"))); background->box.pos = margin; box.size = background->box.size.plus(margin.mult(2)); - handle->svg = SVG::load(assetGlobal("res/ComponentLibrary/BefacoSlidePotHandle.svg")); - handle->wrap(); + } +}; + +struct LEDSlider : SVGSlider { + LEDSlider() { + maxHandlePos = mm2px(Vec(0.738, 0.738).plus(Vec(2, 0))); + minHandlePos = mm2px(Vec(0.738, 22.078).plus(Vec(2, 0))); + setSVGs(SVG::load(assetGlobal("res/ComponentLibrary/LEDSlider.svg")), NULL); + } +}; + +/** API is unstable for LEDSlider. Will add a LightWidget later. */ +struct LEDSliderGreen : LEDSlider { + LEDSliderGreen() { + handle->setSVG(SVG::load(assetGlobal("res/ComponentLibrary/LEDSliderGreenHandle.svg"))); + } +}; + +struct LEDSliderRed : LEDSlider { + LEDSliderRed() { + handle->setSVG(SVG::load(assetGlobal("res/ComponentLibrary/LEDSliderRedHandle.svg"))); + } +}; + +struct LEDSliderYellow : LEDSlider { + LEDSliderYellow() { + handle->setSVG(SVG::load(assetGlobal("res/ComponentLibrary/LEDSliderYellowHandle.svg"))); + } +}; + +struct LEDSliderBlue : LEDSlider { + LEDSliderBlue() { + handle->setSVG(SVG::load(assetGlobal("res/ComponentLibrary/LEDSliderBlueHandle.svg"))); + } +}; + +struct LEDSliderWhite : LEDSlider { + LEDSliderWhite() { + handle->setSVG(SVG::load(assetGlobal("res/ComponentLibrary/LEDSliderWhiteHandle.svg"))); } }; //////////////////// -// Jacks +// Ports //////////////////// struct PJ301MPort : SVGPort { PJ301MPort() { - background->svg = SVG::load(assetGlobal("res/ComponentLibrary/PJ301M.svg")); - background->wrap(); - box.size = background->box.size; + setSVG(SVG::load(assetGlobal("res/ComponentLibrary/PJ301M.svg"))); } }; struct PJ3410Port : SVGPort { PJ3410Port() { - background->svg = SVG::load(assetGlobal("res/ComponentLibrary/PJ3410.svg")); - background->wrap(); - box.size = background->box.size; + setSVG(SVG::load(assetGlobal("res/ComponentLibrary/PJ3410.svg"))); } }; struct CL1362Port : SVGPort { CL1362Port() { - background->svg = SVG::load(assetGlobal("res/ComponentLibrary/CL1362.svg")); - background->wrap(); - box.size = background->box.size; + setSVG(SVG::load(assetGlobal("res/ComponentLibrary/CL1362.svg"))); } }; diff --git a/res/ComponentLibrary/LEDSlider.svg b/res/ComponentLibrary/LEDSlider.svg new file mode 100644 index 00000000..272a9f19 --- /dev/null +++ b/res/ComponentLibrary/LEDSlider.svg @@ -0,0 +1,66 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/res/ComponentLibrary/LEDSliderBlueHandle.svg b/res/ComponentLibrary/LEDSliderBlueHandle.svg new file mode 100644 index 00000000..eabe2cbd --- /dev/null +++ b/res/ComponentLibrary/LEDSliderBlueHandle.svg @@ -0,0 +1,71 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/res/ComponentLibrary/LEDSliderGreenHandle.svg b/res/ComponentLibrary/LEDSliderGreenHandle.svg new file mode 100644 index 00000000..add9739f --- /dev/null +++ b/res/ComponentLibrary/LEDSliderGreenHandle.svg @@ -0,0 +1,71 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/res/ComponentLibrary/LEDSliderRedHandle.svg b/res/ComponentLibrary/LEDSliderRedHandle.svg new file mode 100644 index 00000000..b4b0baf9 --- /dev/null +++ b/res/ComponentLibrary/LEDSliderRedHandle.svg @@ -0,0 +1,71 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/res/ComponentLibrary/LEDSliderWhiteHandle.svg b/res/ComponentLibrary/LEDSliderWhiteHandle.svg new file mode 100644 index 00000000..e9933563 --- /dev/null +++ b/res/ComponentLibrary/LEDSliderWhiteHandle.svg @@ -0,0 +1,71 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/res/ComponentLibrary/LEDSliderYellowHandle.svg b/res/ComponentLibrary/LEDSliderYellowHandle.svg new file mode 100644 index 00000000..c6dab093 --- /dev/null +++ b/res/ComponentLibrary/LEDSliderYellowHandle.svg @@ -0,0 +1,71 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/src/app/CircularShadow.cpp b/src/app/CircularShadow.cpp index 2e00f08d..3df2b8a3 100644 --- a/src/app/CircularShadow.cpp +++ b/src/app/CircularShadow.cpp @@ -7,8 +7,6 @@ namespace rack { CircularShadow::CircularShadow() { blurRadius = 0; opacity = 0.15; - // blurRadius = 0; - // opacity = 0.15; } void CircularShadow::draw(NVGcontext *vg) { diff --git a/src/app/Knob.cpp b/src/app/Knob.cpp index 51d5288f..779415ff 100644 --- a/src/app/Knob.cpp +++ b/src/app/Knob.cpp @@ -30,6 +30,7 @@ void Knob::onDragMove(EventDragMove &e) { if (windowIsModPressed()) delta /= 16.0; dragValue += delta; + dragValue = clamp(dragValue, minValue, maxValue); if (snap) setValue(roundf(dragValue)); else diff --git a/src/app/SVGFader.cpp b/src/app/SVGFader.cpp deleted file mode 100644 index 088c401d..00000000 --- a/src/app/SVGFader.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include "app.hpp" - - -namespace rack { - - -SVGFader::SVGFader() { - background = new SVGWidget(); - addChild(background); - - handle = new SVGWidget(); - addChild(handle); -} - -void SVGFader::step() { - if (dirty) { - // Update handle position - Vec handlePos = Vec(rescale(value, minValue, maxValue, minHandlePos.x, maxHandlePos.x), rescale(value, minValue, maxValue, minHandlePos.y, maxHandlePos.y)); - handle->box.pos = handlePos; - } - FramebufferWidget::step(); -} - -void SVGFader::onChange(EventChange &e) { - dirty = true; - Knob::onChange(e); -} - - -} // namespace rack diff --git a/src/app/SVGPort.cpp b/src/app/SVGPort.cpp index 06343097..4b9651c1 100644 --- a/src/app/SVGPort.cpp +++ b/src/app/SVGPort.cpp @@ -5,10 +5,24 @@ namespace rack { SVGPort::SVGPort() { + shadow = new CircularShadow(); + addChild(shadow); + // Avoid breakage if plugins fail to call setSVG() + // In that case, just disable the shadow. + shadow->box.size = Vec(); + background = new SVGWidget(); addChild(background); } +void SVGPort::setSVG(std::shared_ptr svg) { + background->setSVG(svg); + box.size = background->box.size; + shadow->box.size = background->box.size; + shadow->box.pos = Vec(0, background->box.size.y * 0.1); + // shadow->box = shadow->box.grow(Vec(2, 2)); +} + void SVGPort::draw(NVGcontext *vg) { Port::draw(vg); FramebufferWidget::draw(vg); diff --git a/src/app/SVGSlider.cpp b/src/app/SVGSlider.cpp new file mode 100644 index 00000000..8931fa4b --- /dev/null +++ b/src/app/SVGSlider.cpp @@ -0,0 +1,37 @@ +#include "app.hpp" + + +namespace rack { + + +SVGSlider::SVGSlider() { + background = new SVGWidget(); + addChild(background); + + handle = new SVGWidget(); + addChild(handle); +} + +void SVGSlider::setSVGs(std::shared_ptr backgroundSVG, std::shared_ptr handleSVG) { + background->setSVG(backgroundSVG); + box.size = background->box.size; + if (handleSVG) { + handle->setSVG(handleSVG); + } +} + +void SVGSlider::step() { + if (dirty) { + // Interpolate handle position + handle->box.pos = Vec(rescale(value, minValue, maxValue, minHandlePos.x, maxHandlePos.x), rescale(value, minValue, maxValue, minHandlePos.y, maxHandlePos.y)); + } + FramebufferWidget::step(); +} + +void SVGSlider::onChange(EventChange &e) { + dirty = true; + Knob::onChange(e); +} + + +} // namespace rack