diff --git a/include/app/Knob.hpp b/include/app/Knob.hpp index a56e4122..5e2f3746 100644 --- a/include/app/Knob.hpp +++ b/include/app/Knob.hpp @@ -15,6 +15,7 @@ struct Knob : ParamWidget { /** Multiplier for mouse movement to adjust knob value */ float speed = 1.0; + void onButton(event::Button &e) override; void onDragStart(event::DragStart &e) override; void onDragEnd(event::DragEnd &e) override; void onDragMove(event::DragMove &e) override; diff --git a/include/app/ParamWidget.hpp b/include/app/ParamWidget.hpp index b9a6138f..382c6d04 100644 --- a/include/app/ParamWidget.hpp +++ b/include/app/ParamWidget.hpp @@ -9,12 +9,14 @@ namespace rack { struct ParamWidget : OpaqueWidget { Quantity *quantity = NULL; + float dirtyValue = NAN; ~ParamWidget() { if (quantity) delete quantity; } + void step() override; /** For legacy patch loading */ void fromJson(json_t *rootJ); void onButton(event::Button &e) override; diff --git a/include/app/SVGSwitch.hpp b/include/app/SVGSwitch.hpp index d87fdd10..8252b14f 100644 --- a/include/app/SVGSwitch.hpp +++ b/include/app/SVGSwitch.hpp @@ -15,6 +15,7 @@ struct SVGSwitch : virtual ParamWidget, FramebufferWidget { SVGWidget *sw; SVGSwitch(); + void step() override; /** Adds an SVG file to represent the next switch position */ void addFrame(std::shared_ptr svg); void onChange(event::Change &e) override; diff --git a/src/app/Knob.cpp b/src/app/Knob.cpp index 030c772a..7f9fcff3 100644 --- a/src/app/Knob.cpp +++ b/src/app/Knob.cpp @@ -4,6 +4,15 @@ namespace rack { +void Knob::onButton(event::Button &e) { + float r = box.size.x / 2; + math::Vec c = box.size.div(2); + float dist = e.pos.minus(c).norm(); + if (dist <= r) { + ParamWidget::onButton(e); + } +} + void Knob::onDragStart(event::DragStart &e) { context()->window->cursorLock(); } @@ -28,9 +37,6 @@ void Knob::onDragMove(event::DragMove &e) { if (context()->window->isModPressed()) delta /= 16.f; quantity->moveValue(delta); - - event::Change eChange; - onChange(eChange); } } diff --git a/src/app/ParamWidget.cpp b/src/app/ParamWidget.cpp index 2b59175f..cf1dbb04 100644 --- a/src/app/ParamWidget.cpp +++ b/src/app/ParamWidget.cpp @@ -5,6 +5,20 @@ namespace rack { +void ParamWidget::step() { + if (quantity) { + float value = quantity->getValue(); + // Trigger change event when quantity value changes + if (value != dirtyValue) { + dirtyValue = value; + event::Change eChange; + onChange(eChange); + } + } + + OpaqueWidget::step(); +} + void ParamWidget::fromJson(json_t *rootJ) { json_t *valueJ = json_object_get(rootJ, "value"); if (valueJ) { @@ -20,7 +34,6 @@ void ParamWidget::onButton(event::Button &e) { quantity->reset(); // Here's another way of doing it, but either works. // dynamic_cast(quantity)->getParam()->reset(); - return; } OpaqueWidget::onButton(e); diff --git a/src/app/SVGKnob.cpp b/src/app/SVGKnob.cpp index 04655a41..cd63f951 100644 --- a/src/app/SVGKnob.cpp +++ b/src/app/SVGKnob.cpp @@ -26,8 +26,13 @@ void SVGKnob::setSVG(std::shared_ptr svg) { } void SVGKnob::step() { - // Re-transform TransformWidget if dirty - if (dirty && quantity) { + Knob::step(); + FramebufferWidget::step(); +} + +void SVGKnob::onChange(event::Change &e) { + // Re-transform the TransformWidget + if (quantity) { float angle; if (quantity->isBounded()) { angle = math::rescale(quantity->getScaledValue(), 0.f, 1.f, minAngle, maxAngle); @@ -42,12 +47,8 @@ void SVGKnob::step() { tw->translate(center); tw->rotate(angle); tw->translate(center.neg()); + dirty = true; } - FramebufferWidget::step(); -} - -void SVGKnob::onChange(event::Change &e) { - dirty = true; Knob::onChange(e); } diff --git a/src/app/SVGSlider.cpp b/src/app/SVGSlider.cpp index c5210aa7..e135b319 100644 --- a/src/app/SVGSlider.cpp +++ b/src/app/SVGSlider.cpp @@ -23,18 +23,19 @@ void SVGSlider::setSVGs(std::shared_ptr backgroundSVG, std::shared_ptr } void SVGSlider::step() { - if (dirty && quantity) { + Knob::step(); + FramebufferWidget::step(); +} + +void SVGSlider::onChange(event::Change &e) { + if (quantity) { // Interpolate handle position float v = quantity->getScaledValue(); 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; } - FramebufferWidget::step(); -} - -void SVGSlider::onChange(event::Change &e) { - dirty = true; ParamWidget::onChange(e); } diff --git a/src/app/SVGSwitch.cpp b/src/app/SVGSwitch.cpp index e682dfd5..549bca95 100644 --- a/src/app/SVGSwitch.cpp +++ b/src/app/SVGSwitch.cpp @@ -9,6 +9,11 @@ SVGSwitch::SVGSwitch() { addChild(sw); } +void SVGSwitch::step() { + ParamWidget::step(); + FramebufferWidget::step(); +} + void SVGSwitch::addFrame(std::shared_ptr svg) { frames.push_back(svg); // If this is our first frame, automatically set SVG and size diff --git a/src/app/WireWidget.cpp b/src/app/WireWidget.cpp index d04cd560..c279a87a 100644 --- a/src/app/WireWidget.cpp +++ b/src/app/WireWidget.cpp @@ -31,7 +31,7 @@ static void drawPlug(NVGcontext *vg, math::Vec pos, NVGcolor color) { nvgFill(vg); } -static void drawWire(NVGcontext *vg, math::Vec pos1, math::Vec pos2, NVGcolor color, float width, float tension, float opacity) { +static void drawWire(NVGcontext *vg, math::Vec pos1, math::Vec pos2, NVGcolor color, float thickness, float tension, float opacity) { NVGcolor colorShadow = nvgRGBAf(0, 0, 0, 0.10); NVGcolor colorOutline = nvgLerpRGBA(color, nvgRGBf(0.0, 0.0, 0.0), 0.5); @@ -54,7 +54,7 @@ static void drawWire(NVGcontext *vg, math::Vec pos1, math::Vec pos2, NVGcolor co nvgMoveTo(vg, pos1.x, pos1.y); nvgQuadTo(vg, pos4.x, pos4.y, pos2.x, pos2.y); nvgStrokeColor(vg, colorShadow); - nvgStrokeWidth(vg, width); + nvgStrokeWidth(vg, thickness); nvgStroke(vg); // Wire outline @@ -62,12 +62,12 @@ static void drawWire(NVGcontext *vg, math::Vec pos1, math::Vec pos2, NVGcolor co nvgMoveTo(vg, pos1.x, pos1.y); nvgQuadTo(vg, pos3.x, pos3.y, pos2.x, pos2.y); nvgStrokeColor(vg, colorOutline); - nvgStrokeWidth(vg, width); + nvgStrokeWidth(vg, thickness); nvgStroke(vg); // Wire solid nvgStrokeColor(vg, color); - nvgStrokeWidth(vg, width - 2); + nvgStrokeWidth(vg, thickness - 2); nvgStroke(vg); nvgRestore(vg); @@ -179,17 +179,17 @@ void WireWidget::draw(NVGcontext *vg) { opacity = 1.0; } - float width = 5; + float thickness = 5; if (wire && wire->outputModule) { Output *output = &wire->outputModule->outputs[wire->outputId]; if (output->numChannels != 1) { - width = 8; + thickness = 8; } } math::Vec outputPos = getOutputPos(); math::Vec inputPos = getInputPos(); - drawWire(vg, outputPos, inputPos, color, width, tension, opacity); + drawWire(vg, outputPos, inputPos, color, thickness, tension, opacity); } void WireWidget::drawPlugs(NVGcontext *vg) { diff --git a/src/engine/Module.cpp b/src/engine/Module.cpp index 3f705aef..80004d84 100644 --- a/src/engine/Module.cpp +++ b/src/engine/Module.cpp @@ -21,9 +21,6 @@ void Module::setup(int numParams, int numInputs, int numOutputs, int numLights) json_t *Module::toJson() { json_t *rootJ = json_object(); - // id - json_object_set_new(rootJ, "id", json_integer(id)); - // params json_t *paramsJ = json_array(); for (Param ¶m : params) { @@ -42,11 +39,6 @@ json_t *Module::toJson() { } void Module::fromJson(json_t *rootJ) { - // id - json_t *idJ = json_object_get(rootJ, "id"); - if (idJ) - id = json_integer_value(idJ); - // params json_t *paramsJ = json_object_get(rootJ, "params"); size_t i;