Browse Source

Add plug lights, remove plug light toggling

tags/v0.5.0
Andrew Belt 7 years ago
parent
commit
70bb8c7759
12 changed files with 171 additions and 123 deletions
  1. +30
    -24
      include/app.hpp
  2. +15
    -15
      include/components.hpp
  3. +13
    -11
      include/engine.hpp
  4. +2
    -2
      include/rack.hpp
  5. +0
    -27
      src/app/ColorLightWidget.cpp
  6. +22
    -0
      src/app/ModuleLightWidget.cpp
  7. +24
    -0
      src/app/MultiLightWidget.cpp
  8. +32
    -0
      src/app/Port.cpp
  9. +0
    -10
      src/app/Toolbar.cpp
  10. +15
    -24
      src/app/WireWidget.cpp
  11. +18
    -1
      src/engine.cpp
  12. +0
    -9
      src/settings.cpp

+ 30
- 24
include/app.hpp View File

@@ -277,6 +277,33 @@ struct MomentarySwitch : virtual Switch {
}
};

////////////////////
// lights
////////////////////

struct LightWidget : TransparentWidget {
NVGcolor bgColor = nvgRGBf(0, 0, 0);
NVGcolor color = nvgRGBf(1, 1, 1);
void draw(NVGcontext *vg) override;
};

/** Mixes a list of colors based on a list of brightness values */
struct MultiLightWidget : LightWidget {
std::vector<NVGcolor> baseColors;
void addBaseColor(NVGcolor baseColor);
/** Sets the color to a linear combination of the baseColors with the given weights */
void setValues(const std::vector<float> &values);
};

/** A MultiLightWidget that points to a module's Light or a range of lights
Will access firstLightId, firstLightId + 1, etc. for each added color
*/
struct ModuleLightWidget : MultiLightWidget {
Module *module = NULL;
int firstLightId;
void step() override;
};

////////////////////
// ports
////////////////////
@@ -290,8 +317,11 @@ struct Port : OpaqueWidget {
Module *module = NULL;
PortType type = INPUT;
int portId;
MultiLightWidget *plugLight;

Port();
~Port();
void step() override;
void draw(NVGcontext *vg) override;
void onMouseDown(EventMouseDown &e) override;
void onDragStart(EventDragStart &e) override;
@@ -315,29 +345,6 @@ 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<NVGcolor> colors;
void addColor(NVGcolor c);
void step() override;
};

////////////////////
// scene
////////////////////
@@ -347,7 +354,6 @@ struct Toolbar : OpaqueWidget {
Slider *wireTensionSlider;
Slider *zoomSlider;
RadioButton *cpuUsageButton;
RadioButton *plugLightButton;

Toolbar();
void draw(NVGcontext *vg) override;


+ 15
- 15
include/components.hpp View File

@@ -368,43 +368,43 @@ struct CL1362Port : SVGPort {
// Lights
////////////////////

struct RedLight : ColorLightWidget {
struct RedLight : ModuleLightWidget {
RedLight() {
addColor(COLOR_RED);
addBaseColor(COLOR_RED);
}
};

struct GreenLight : ColorLightWidget {
struct GreenLight : ModuleLightWidget {
GreenLight() {
addColor(COLOR_GREEN);
addBaseColor(COLOR_GREEN);
}
};

struct YellowLight : ColorLightWidget {
struct YellowLight : ModuleLightWidget {
YellowLight() {
addColor(COLOR_YELLOW);
addBaseColor(COLOR_YELLOW);
}
};

struct BlueLight : ColorLightWidget {
struct BlueLight : ModuleLightWidget {
BlueLight() {
addColor(COLOR_BLUE);
addBaseColor(COLOR_BLUE);
}
};

/** Reads two adjacent lightIds, so `lightId` and `lightId + 1` must be defined */
struct GreenRedLight : ColorLightWidget {
struct GreenRedLight : ModuleLightWidget {
GreenRedLight() {
addColor(COLOR_GREEN);
addColor(COLOR_RED);
addBaseColor(COLOR_GREEN);
addBaseColor(COLOR_RED);
}
};

struct RedGreenBlueLight : ColorLightWidget {
struct RedGreenBlueLight : ModuleLightWidget {
RedGreenBlueLight() {
addColor(COLOR_RED);
addColor(COLOR_GREEN);
addColor(COLOR_BLUE);
addBaseColor(COLOR_RED);
addBaseColor(COLOR_GREEN);
addBaseColor(COLOR_BLUE);
}
};



+ 13
- 11
include/engine.hpp View File

@@ -11,11 +11,22 @@ struct Param {
float value = 0.0;
};

struct Light {
/** The square of the brightness value */
float value = 0.0;
float getBrightness();
void setBrightness(float brightness) {
value = brightness * brightness;
}
void setBrightnessSmooth(float brightness);
};

struct Input {
/** Voltage of the port, zero if not plugged in. Read-only by Module */
float value = 0.0;
/** Whether a wire is plugged in */
bool active = false;
Light plugLights[2];
/** Returns the value if a wire is plugged in, otherwise returns the given default value */
float normalize(float normalValue) {
return active ? value : normalValue;
@@ -27,16 +38,7 @@ struct Output {
float value = 0.0;
/** Whether a wire is plugged in */
bool active = false;
};

struct Light {
/** The square of the brightness value */
float value = 0.0;
float getBrightness();
void setBrightness(float brightness) {
value = brightness * brightness;
}
void setBrightnessSmooth(float brightness);
Light plugLights[2];
};


@@ -49,7 +51,7 @@ struct Module {
float cpuTime = 0.0;

/** Deprecated, use constructor below this one */
Module() {}
Module() DEPRECATED {}
/** Constructs Module with a fixed number of params, inputs, and outputs */
Module(int numParams, int numInputs, int numOutputs, int numLights = 0) {
params.resize(numParams);


+ 2
- 2
include/rack.hpp View File

@@ -74,11 +74,11 @@ Port *createOutput(Vec pos, Module *module, int outputId) {
}

template<class TModuleLightWidget>
ModuleLightWidget *createLight(Vec pos, Module *module, int lightId) {
ModuleLightWidget *createLight(Vec pos, Module *module, int firstLightId) {
ModuleLightWidget *light = new TModuleLightWidget();
light->box.pos = pos;
light->module = module;
light->lightId = lightId;
light->firstLightId = firstLightId;
return light;
}



+ 0
- 27
src/app/ColorLightWidget.cpp View File

@@ -1,27 +0,0 @@
#include "app.hpp"
#include "engine.hpp"


namespace rack {


void ColorLightWidget::addColor(NVGcolor c) {
colors.push_back(c);
}

void ColorLightWidget::step() {
assert(module);
assert(module->lights.size() >= lightId + colors.size());
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();
brightness = clampf(brightness, 0.0, 1.0);
color.r += c.r * brightness;
color.g += c.g * brightness;
color.b += c.b * brightness;
}
}


} // namespace rack

+ 22
- 0
src/app/ModuleLightWidget.cpp View File

@@ -0,0 +1,22 @@
#include "app.hpp"
#include "engine.hpp"


namespace rack {


void ModuleLightWidget::step() {
assert(module);
assert(module->lights.size() >= firstLightId + baseColors.size());
std::vector<float> values(baseColors.size());

for (size_t i = 0; i < baseColors.size(); i++) {
float value = module->lights[firstLightId + i].getBrightness();
value = clampf(value, 0.0, 1.0);
values[i] = value;
}
setValues(values);
}


} // namespace rack

+ 24
- 0
src/app/MultiLightWidget.cpp View File

@@ -0,0 +1,24 @@
#include "app.hpp"


namespace rack {


void MultiLightWidget::addBaseColor(NVGcolor baseColor) {
baseColors.push_back(baseColor);
}

void MultiLightWidget::setValues(const std::vector<float> &values) {
assert(values.size() == baseColors.size());
color = nvgRGBf(0, 0, 0);
for (size_t i = 0; i < baseColors.size(); i++) {
NVGcolor c = baseColors[i];
float value = values[i];
color.r += c.r * value;
color.g += c.g * value;
color.b += c.b * value;
}
}


} // namespace rack

+ 32
- 0
src/app/Port.cpp View File

@@ -1,13 +1,45 @@
#include "app.hpp"
#include "gui.hpp"
#include "components.hpp"
#include "engine.hpp"


namespace rack {


struct PlugLight : MultiLightWidget {
PlugLight() {
addBaseColor(COLOR_GREEN);
addBaseColor(COLOR_RED);
box.size = Vec(8, 8);
bgColor = COLOR_BLACK_TRANSPARENT;
}
};


Port::Port() {
plugLight = new PlugLight();
}

Port::~Port() {
// plugLight is not a child and is thus owned by the Port, so we need to delete it here
delete plugLight;
gRackWidget->wireContainer->removeAllWires(this);
}

void Port::step() {
std::vector<float> values(2);
if (type == INPUT) {
values[0] = module->inputs[portId].plugLights[0].getBrightness();
values[1] = module->inputs[portId].plugLights[1].getBrightness();
}
else {
values[0] = module->outputs[portId].plugLights[0].getBrightness();
values[1] = module->outputs[portId].plugLights[1].getBrightness();
}
plugLight->setValues(values);
}

void Port::draw(NVGcontext *vg) {
WireWidget *activeWire = gRackWidget->wireContainer->activeWire;
if (activeWire) {


+ 0
- 10
src/app/Toolbar.cpp View File

@@ -166,16 +166,6 @@ Toolbar::Toolbar() {
}
xPos += margin;

{
plugLightButton = new RadioButton();
plugLightButton->box.pos = Vec(xPos, margin);
plugLightButton->box.size.x = 100;
plugLightButton->label = "Plug lights";
addChild(plugLightButton);
xPos += plugLightButton->box.size.x;
}
xPos += margin;

/*
{
cpuUsageButton = new RadioButton();


+ 15
- 24
src/app/WireWidget.cpp View File

@@ -155,7 +155,9 @@ void WireWidget::draw(NVGcontext *vg) {
if (!(inputPort && outputPort))
opacity = 1.0;

drawWire(vg, getOutputPos(), getInputPos(), color, tension, opacity);
Vec outputPos = getOutputPos();
Vec inputPos = getInputPos();
drawWire(vg, outputPos, inputPos, color, tension, opacity);
}

void WireWidget::drawPlugs(NVGcontext *vg) {
@@ -166,31 +168,20 @@ 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];
float value = output.value / 8.0;
outputLight->box.size = Vec(10, 10);
inputLight->box.size = Vec(10, 10);
outputLight->box.pos = outputPos.minus(Vec(5, 5));
inputLight->box.pos = inputPos.minus(Vec(5, 5));
outputLight->setValue(value);
inputLight->setValue(value);
}
else {
outputLight->setValue(0.0);
inputLight->setValue(0.0);
}
outputLight->visible = true;
inputLight->visible = true;
// TODO
// Only draw this when light is on top of the plug stack
if (outputPort) {
nvgSave(vg);
nvgTranslate(vg, outputPos.x - 4, outputPos.y - 4);
outputPort->plugLight->draw(vg);
nvgRestore(vg);
}
else {
outputLight->visible = false;
inputLight->visible = false;
if (inputPort) {
nvgSave(vg);
nvgTranslate(vg, inputPos.x - 4, inputPos.y - 4);
inputPort->plugLight->draw(vg);
nvgRestore(vg);
}
*/
Widget::draw(vg);
}




+ 18
- 1
src/engine.cpp View File

@@ -39,7 +39,7 @@ float Light::getBrightness() {
}

void Light::setBrightnessSmooth(float brightness) {
float v = brightness * brightness;
float v = (brightness > 0.0) ? brightness * brightness : 0.0;
if (v < value) {
// Fade out light with lambda = 2 * framerate
value += (v - value) * sampleTime * (60.0 * 2.0);
@@ -87,6 +87,23 @@ static void engineStep() {
// Step modules
for (Module *module : modules) {
module->step();

// TODO skip this step when plug lights are disabled
// Step ports
for (Input &input : module->inputs) {
if (input.active) {
float value = input.value / 10.0;
input.plugLights[0].setBrightnessSmooth(value);
input.plugLights[1].setBrightnessSmooth(-value);
}
}
for (Output &output : module->outputs) {
if (output.active) {
float value = output.value / 10.0;
output.plugLights[0].setBrightnessSmooth(value);
output.plugLights[1].setBrightnessSmooth(-value);
}
}
}

// Step cables by moving their output values to inputs


+ 0
- 9
src/settings.cpp View File

@@ -52,10 +52,6 @@ static json_t *settingsToJson() {
json_t *sampleRateJ = json_real(engineGetSampleRate());
json_object_set_new(rootJ, "sampleRate", sampleRateJ);

// plugLight
json_t *plugLightJ = json_boolean(gToolbar->plugLightButton->value > 0.0);
json_object_set_new(rootJ, "plugLight", plugLightJ);

// lastPath
json_t *lastPathJ = json_string(gRackWidget->lastPath.c_str());
json_object_set_new(rootJ, "lastPath", lastPathJ);
@@ -114,11 +110,6 @@ static void settingsFromJson(json_t *rootJ) {
engineSetSampleRate(sampleRate);
}

// plugLight
json_t *plugLightJ = json_object_get(rootJ, "plugLight");
if (plugLightJ)
gToolbar->plugLightButton->setValue(json_is_true(plugLightJ) ? 1.0 : 0.0);

// lastPath
json_t *lastPathJ = json_object_get(rootJ, "lastPath");
if (lastPathJ)


Loading…
Cancel
Save