From bc619644ac62fdc4fb9b6d6be206789f749ba857 Mon Sep 17 00:00:00 2001 From: Andrew Belt Date: Thu, 26 Oct 2017 09:50:18 -0400 Subject: [PATCH] Throw away old lights, add new LightWidget as a final replacement --- include/app.hpp | 32 +++++++++++---- include/components.hpp | 76 +++++++++--------------------------- include/engine.hpp | 1 + include/rack.hpp | 36 +++++++---------- src/app/ColorLightWidget.cpp | 24 ++++++++++++ src/app/WireWidget.cpp | 10 +++-- src/core/MidiCCToCV.cpp | 11 +++--- src/core/MidiToCV.cpp | 17 ++++---- src/core/QuadMidiToCV.cpp | 17 ++++---- src/engine.cpp | 4 ++ 10 files changed, 112 insertions(+), 116 deletions(-) create mode 100644 src/app/ColorLightWidget.cpp diff --git a/include/app.hpp b/include/app.hpp index 8a53f1b6..9cb56c09 100644 --- a/include/app.hpp +++ b/include/app.hpp @@ -7,13 +7,13 @@ namespace rack { +struct Model; struct Module; struct Wire; struct RackWidget; struct ParamWidget; struct Port; -struct Scene; //////////////////// // module @@ -23,7 +23,6 @@ struct Scene; #define RACK_GRID_WIDTH 15 #define RACK_GRID_HEIGHT 380 -struct Model; struct ModuleWidget : OpaqueWidget { Model *model = NULL; /** Owns the module pointer */ @@ -168,12 +167,6 @@ struct CircularShadow : TransparentWidget { void draw(NVGcontext *vg) override; }; -struct LightWidget : TransparentWidget { - NVGcolor bgColor = nvgRGBf(0, 0, 0); - NVGcolor color = nvgRGBf(1, 1, 1); - void draw(NVGcontext *vg) override; -}; - struct ParamWidget : OpaqueWidget, QuantityWidget { Module *module = NULL; int paramId; @@ -309,6 +302,29 @@ struct SVGScrew : FramebufferWidget { SVGScrew(); }; +//////////////////// +// lights +//////////////////// + +struct LightWidget : TransparentWidget { + NVGcolor bgColor = nvgRGBf(0, 0, 0); + NVGcolor color = nvgRGBf(1, 1, 1); + void draw(NVGcontext *vg) override; +}; + +/** A LightWidget that points to a module's Light or a range of lights */ +struct ModuleLightWidget : LightWidget { + Module *module = NULL; + int lightId; +}; + +/** Mixes colors based on the brightness of the module light at lightId, lightId + 1, etc */ +struct ColorLightWidget : ModuleLightWidget { + std::vector colors; + void addColor(NVGcolor c); + void step() override; +}; + //////////////////// // scene //////////////////// diff --git a/include/components.hpp b/include/components.hpp index 1ccfa1af..5b1f4e1c 100644 --- a/include/components.hpp +++ b/include/components.hpp @@ -422,95 +422,55 @@ struct CL1362Port : SVGPort { // Lights //////////////////// -struct ValueLight : LightWidget { - float *value = NULL; - virtual void setValue(float v) {} - void step() override { - if (value) - setValue(*value); +struct RedLight : ColorLightWidget { + RedLight() { + addColor(COLOR_RED); } }; -struct ColorValueLight : ValueLight { - NVGcolor baseColor; - void setValue(float v) override { - v = sqrtBipolar(v); - color = baseColor; - color.a *= clampf(v, 0.0, 1.0); +struct GreenLight : ColorLightWidget { + GreenLight() { + addColor(COLOR_GREEN); } }; -struct RedValueLight : ColorValueLight { - RedValueLight() { - baseColor = COLOR_RED; +struct GreenRedLight : ColorLightWidget { + GreenRedLight() { + addColor(COLOR_GREEN); + addColor(COLOR_RED); } }; -struct YellowValueLight : ColorValueLight { - YellowValueLight() { - baseColor = COLOR_YELLOW; - } -}; - -struct GreenValueLight : ColorValueLight { - GreenValueLight() { - baseColor = COLOR_GREEN; - } -}; - -struct PolarityLight : ValueLight { - NVGcolor posColor; - NVGcolor negColor; - void setValue(float v) override { - v = sqrtBipolar(v); - color = (v >= 0.0) ? posColor : negColor; - color.a *= clampf(fabsf(v), 0.0, 1.0); - } -}; - -struct GreenRedPolarityLight : PolarityLight { - GreenRedPolarityLight() { - posColor = COLOR_GREEN; - negColor = COLOR_RED; - } -}; - -struct ModeValueLight : ValueLight { - std::vector colors; - void setValue(float v) override { - int mode = clampi((int)roundf(v), 0, colors.size()); - color = colors[mode]; - } - void addColor(NVGcolor color) { - colors.push_back(color); - } -}; +/** 5mm diameter */ template struct LargeLight : BASE { LargeLight() { - this->box.size = Vec(20, 20); + this->box.size = Vec(15, 15); } }; +/** 3mm diameter */ template struct MediumLight : BASE { MediumLight() { - this->box.size = Vec(12, 12); + this->box.size = Vec(9, 9); } }; +/** 2mm diameter */ template struct SmallLight : BASE { SmallLight() { - this->box.size = Vec(8, 8); + this->box.size = Vec(6, 6); } }; +/** 1mm diameter */ template struct TinyLight : BASE { TinyLight() { - this->box.size = Vec(5, 5); + this->box.size = Vec(3, 3); } }; diff --git a/include/engine.hpp b/include/engine.hpp index b4220e6a..c5a14354 100644 --- a/include/engine.hpp +++ b/include/engine.hpp @@ -32,6 +32,7 @@ struct Output { struct Light { /** The square of the brightness value */ float value = 0.0; + float getBrightness(); void setBrightness(float brightness) { value = brightness * brightness; } diff --git a/include/rack.hpp b/include/rack.hpp index 7a079bfe..aaa6c56e 100644 --- a/include/rack.hpp +++ b/include/rack.hpp @@ -34,9 +34,16 @@ Model *createModel(std::string manufacturerSlug, std::string manufacturerName, s return model; } -template +template +Widget *createScrew(Vec pos) { + Widget *screw = new TScrew(); + screw->box.pos = pos; + return screw; +} + +template ParamWidget *createParam(Vec pos, Module *module, int paramId, float minValue, float maxValue, float defaultValue) { - ParamWidget *param = new TParam(); + ParamWidget *param = new TParamWidget(); param->box.pos = pos; param->module = module; param->paramId = paramId; @@ -65,27 +72,12 @@ Port *createOutput(Vec pos, Module *module, int outputId) { return port; } -template -Widget *createScrew(Vec pos) { - Widget *screw = new TScrew(); - screw->box.pos = pos; - return screw; -} - -template -ValueLight *createValueLight(Vec pos, float *value) { - ValueLight *light = new TLight(); - light->box.pos = pos; - light->value = value; - return light; -} - -/** Polyfill for future LightWidget */ -template -ValueLight *createValueLight(Vec pos, Module *module, int lightId) { - ValueLight *light = new TLight(); +template +ModuleLightWidget *createLight(Vec pos, Module *module, int lightId) { + ModuleLightWidget *light = new TModuleLightWidget(); light->box.pos = pos; - light->value = &module->lights[lightId].value; + light->module = module; + light->lightId = lightId; return light; } diff --git a/src/app/ColorLightWidget.cpp b/src/app/ColorLightWidget.cpp new file mode 100644 index 00000000..c7dcd094 --- /dev/null +++ b/src/app/ColorLightWidget.cpp @@ -0,0 +1,24 @@ +#include "app.hpp" +#include "engine.hpp" + + +namespace rack { + + +void ColorLightWidget::addColor(NVGcolor c) { + colors.push_back(c); +} + +void ColorLightWidget::step() { + color = nvgRGBf(0, 0, 0); + for (int i = 0; i < (int)colors.size(); i++) { + NVGcolor c = colors[i]; + float brightness = module->lights[lightId + i].getBrightness(); + color.r += c.r * brightness; + color.g += c.g * brightness; + color.b += c.b * brightness; + } +} + + +} // namespace rack diff --git a/src/app/WireWidget.cpp b/src/app/WireWidget.cpp index be314394..1908f5ac 100644 --- a/src/app/WireWidget.cpp +++ b/src/app/WireWidget.cpp @@ -87,10 +87,10 @@ WireWidget::WireWidget() { lastWireColorId = (lastWireColorId + 1) % LENGTHOF(wireColors); color = wireColors[lastWireColorId]; - inputLight = construct(&PolarityLight::posColor, COLOR_GREEN, &PolarityLight::negColor, COLOR_RED); - outputLight = construct(&PolarityLight::posColor, COLOR_GREEN, &PolarityLight::negColor, COLOR_RED); - addChild(inputLight); - addChild(outputLight); + // inputLight = construct(&PolarityLight::posColor, COLOR_GREEN, &PolarityLight::negColor, COLOR_RED); + // outputLight = construct(&PolarityLight::posColor, COLOR_GREEN, &PolarityLight::negColor, COLOR_RED); + // addChild(inputLight); + // addChild(outputLight); } WireWidget::~WireWidget() { @@ -166,6 +166,7 @@ void WireWidget::drawPlugs(NVGcontext *vg) { drawPlug(vg, inputPos, color); // Draw plug light + /* if (gToolbar->plugLightButton->value > 0.0) { if (wire) { Output &output = wire->outputModule->outputs[wire->outputId]; @@ -188,6 +189,7 @@ void WireWidget::drawPlugs(NVGcontext *vg) { outputLight->visible = false; inputLight->visible = false; } + */ Widget::draw(vg); } diff --git a/src/core/MidiCCToCV.cpp b/src/core/MidiCCToCV.cpp index e6337c92..c227bf56 100644 --- a/src/core/MidiCCToCV.cpp +++ b/src/core/MidiCCToCV.cpp @@ -18,6 +18,9 @@ struct MIDICCToCVInterface : MidiIO, Module { enum OutputIds { NUM_OUTPUTS = 16 }; + enum LightIds { + NUM_LIGHTS = 16 + }; int cc[NUM_OUTPUTS]; int ccNum[NUM_OUTPUTS]; @@ -25,10 +28,9 @@ struct MIDICCToCVInterface : MidiIO, Module { bool ccSyncFirst[NUM_OUTPUTS]; bool ccNumInited[NUM_OUTPUTS]; bool onFocus[NUM_OUTPUTS]; - float lights[NUM_OUTPUTS]; - MIDICCToCVInterface() : MidiIO(), Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS) { + MIDICCToCVInterface() : MidiIO(), Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) { for (int i = 0; i < NUM_OUTPUTS; i++) { cc[i] = 0; ccNum[i] = i; @@ -97,7 +99,7 @@ void MIDICCToCVInterface::step() { for (int i = 0; i < NUM_OUTPUTS; i++) { - lights[i] = ccSync[i] / 127.0; + lights[i].setBrightness(ccSync[i] / 127.0); outputs[i].value = cc[i] / 127.0 * 10.0; } @@ -294,8 +296,7 @@ MIDICCToCVWidget::MIDICCToCVWidget() { yPos += labelHeight + margin; addOutput(createOutput(Vec((i % 4) * (63) + 10, yPos + 5), module, i)); - addChild(createValueLight>(Vec((i % 4) * (63) + 32, yPos + 5), - &module->lights[i])); + addChild(createLight>(Vec((i % 4) * (63) + 32, yPos + 5), module, i)); if ((i + 1) % 4 == 0) { yPos += 47 + margin; diff --git a/src/core/MidiToCV.cpp b/src/core/MidiToCV.cpp index 4e12a25a..b7fe9be7 100644 --- a/src/core/MidiToCV.cpp +++ b/src/core/MidiToCV.cpp @@ -26,6 +26,10 @@ struct MIDIToCVInterface : MidiIO, Module { CHANNEL_AFTERTOUCH_OUTPUT, NUM_OUTPUTS }; + enum LightIds { + RESET_LIGHT, + NUM_LIGHTS + }; std::list notes; bool pedal = false; @@ -38,9 +42,8 @@ struct MIDIToCVInterface : MidiIO, Module { bool retriggered = false; SchmittTrigger resetTrigger; - float resetLight = 0.0; - MIDIToCVInterface() : MidiIO(), Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS) { + MIDIToCVInterface() : MidiIO(), Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) { } @@ -78,14 +81,11 @@ void MIDIToCVInterface::resetMidi() { pitchWheel = 64; afterTouch = 0; vel = 0; - resetLight = 1.0; outputs[GATE_OUTPUT].value = 0.0; notes.clear(); } void MIDIToCVInterface::step() { - static float sampleRate = engineGetSampleRate(); - if (isPortOpen()) { std::vector message; @@ -109,10 +109,7 @@ void MIDIToCVInterface::step() { return; } - if (resetLight > 0) { - resetLight -= resetLight / 0.55 / sampleRate; // fade out light - } - + lights[RESET_LIGHT].value -= lights[RESET_LIGHT].value / 0.55 / engineGetSampleRate(); // fade out light outputs[GATE_OUTPUT].value = gate ? 10.0 : 0.0; outputs[MOD_OUTPUT].value = mod / 127.0 * 10.0; @@ -228,7 +225,7 @@ MidiToCVWidget::MidiToCVWidget() { } addParam(createParam(Vec(7 * 15, labelHeight), module, MIDIToCVInterface::RESET_PARAM, 0.0, 1.0, 0.0)); - addChild(createValueLight>(Vec(7 * 15 + 5, labelHeight + 5), &module->resetLight)); + addChild(createLight>(Vec(7 * 15 + 5, labelHeight + 5), module, MIDIToCVInterface::RESET_LIGHT)); { Label *label = new Label(); label->box.pos = Vec(margin, yPos); diff --git a/src/core/QuadMidiToCV.cpp b/src/core/QuadMidiToCV.cpp index 60e43a07..3d933889 100644 --- a/src/core/QuadMidiToCV.cpp +++ b/src/core/QuadMidiToCV.cpp @@ -28,6 +28,10 @@ struct QuadMIDIToCVInterface : MidiIO, Module { AT_OUTPUT = 12, NUM_OUTPUTS = 16 }; + enum LightIds { + RESET_LIGHT, + NUM_LIGHTS + }; enum Modes { ROTATE, @@ -47,9 +51,8 @@ struct QuadMIDIToCVInterface : MidiIO, Module { std::list open; SchmittTrigger resetTrigger; - float resetLight = 0.0; - QuadMIDIToCVInterface() : MidiIO(), Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS) { + QuadMIDIToCVInterface() : MidiIO(), Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) { } @@ -90,11 +93,10 @@ void QuadMIDIToCVInterface::resetMidi() { open.clear(); pedal = false; - resetLight = 1.0; + lights[RESET_LIGHT].value = 1.0; } void QuadMIDIToCVInterface::step() { - static float sampleRate = engineGetSampleRate(); static int msgsProcessed = 0; if (isPortOpen()) { @@ -125,10 +127,7 @@ void QuadMIDIToCVInterface::step() { return; } - if (resetLight > 0) { - resetLight -= resetLight / 0.55 / sampleRate; // fade out light - } - + lights[RESET_LIGHT].value -= lights[RESET_LIGHT].value / 0.55 / engineGetSampleRate(); // fade out light } @@ -307,7 +306,7 @@ QuadMidiToCVWidget::QuadMidiToCVWidget() { addParam(createParam(Vec(12 * 15, labelHeight), module, QuadMIDIToCVInterface::RESET_PARAM, 0.0, 1.0, 0.0)); - addChild(createValueLight>(Vec(12 * 15 + 5, labelHeight + 5), &module->resetLight)); + addChild(createLight>(Vec(12 * 15 + 5, labelHeight + 5), module, QuadMIDIToCVInterface::RESET_LIGHT)); { Label *label = new Label(); label->box.pos = Vec(margin, yPos); diff --git a/src/engine.cpp b/src/engine.cpp index 5e2b9f05..e064947b 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -33,6 +33,10 @@ static int smoothParamId; static float smoothValue; +float Light::getBrightness() { + return sqrtf(value); +} + void Light::setBrightnessSmooth(float brightness) { value += (brightness * brightness - value) / sampleRate * 60.0; }