Browse Source

Make LedDisplay draw on layer 1. Add translucent rectangle over ModuleContainer and draw lights on layer 1 instead of using nvgGlobalTint().

tags/v2.0.0
Andrew Belt 3 years ago
parent
commit
b28819a99d
4 changed files with 156 additions and 103 deletions
  1. +2
    -0
      include/app/LedDisplay.hpp
  2. +68
    -64
      src/app/CableWidget.cpp
  3. +44
    -28
      src/app/LedDisplay.cpp
  4. +42
    -11
      src/app/RackWidget.cpp

+ 2
- 0
include/app/LedDisplay.hpp View File

@@ -26,6 +26,7 @@ struct LedDisplayChoice : widget::OpaqueWidget {
NVGcolor bgColor;
LedDisplayChoice();
void draw(const DrawArgs& args) override;
void drawLayer(const DrawArgs& args, int layer) override;
void onButton(const ButtonEvent& e) override;
};

@@ -36,6 +37,7 @@ struct LedDisplayTextField : ui::TextField {
NVGcolor bgColor;
LedDisplayTextField();
void draw(const DrawArgs& args) override;
void drawLayer(const DrawArgs& args, int layer) override;
int getTextPosition(math::Vec mousePos) override;
};



+ 68
- 64
src/app/CableWidget.cpp View File

@@ -276,79 +276,83 @@ void CableWidget::step() {


void CableWidget::draw(const DrawArgs& args) {
// Draw plugs
Widget::draw(args);
}


void CableWidget::drawLayer(const DrawArgs& args, int layer) {
float opacity = settings::cableOpacity;
bool thick = false;

if (isComplete()) {
engine::Output* output = &cable->outputModule->outputs[cable->outputId];
// Increase thickness if output port is polyphonic
if (output->isPolyphonic()) {
thick = true;
}
// Cable shadow and cable
if (layer == 2 || layer == 3) {
float opacity = settings::cableOpacity;
bool thick = false;

if (isComplete()) {
engine::Output* output = &cable->outputModule->outputs[cable->outputId];
// Increase thickness if output port is polyphonic
if (output->isPolyphonic()) {
thick = true;
}

// Draw opaque if mouse is hovering over a connected port
Widget* hoveredWidget = APP->event->hoveredWidget;
if (outputPort == hoveredWidget || inputPort == hoveredWidget) {
opacity = 1.0;
// Draw opaque if mouse is hovering over a connected port
Widget* hoveredWidget = APP->event->hoveredWidget;
if (outputPort == hoveredWidget || inputPort == hoveredWidget) {
opacity = 1.0;
}
// Draw translucent cable if not active (i.e. 0 channels)
else if (output->getChannels() == 0) {
opacity *= 0.5;
}
}
// Draw translucent cable if not active (i.e. 0 channels)
else if (output->getChannels() == 0) {
opacity *= 0.5;
else {
// Draw opaque if the cable is incomplete
opacity = 1.0;
}
}
else {
// Draw opaque if the cable is incomplete
opacity = 1.0;
}

if (opacity <= 0.0)
return;
nvgAlpha(args.vg, std::pow(opacity, 1.5));

math::Vec outputPos = getOutputPos();
math::Vec inputPos = getInputPos();

float thickness = thick ? 9.0 : 6.0;

// The endpoints are off-center
math::Vec slump = getSlumpPos(outputPos, inputPos);
outputPos = outputPos.plus(slump.minus(outputPos).normalize().mult(13.0));
inputPos = inputPos.plus(slump.minus(inputPos).normalize().mult(13.0));

nvgLineCap(args.vg, NVG_ROUND);
// Avoids glitches when cable is bent
nvgLineJoin(args.vg, NVG_ROUND);

if (layer == 1) {
// Draw cable shadow
math::Vec shadowSlump = slump.plus(math::Vec(0, 30));
nvgBeginPath(args.vg);
nvgMoveTo(args.vg, VEC_ARGS(outputPos));
nvgQuadTo(args.vg, VEC_ARGS(shadowSlump), VEC_ARGS(inputPos));
NVGcolor shadowColor = nvgRGBAf(0, 0, 0, 0.10);
nvgStrokeColor(args.vg, shadowColor);
nvgStrokeWidth(args.vg, thickness - 1.0);
nvgStroke(args.vg);
}
else if (layer == 2) {
// Draw cable outline
nvgBeginPath(args.vg);
nvgMoveTo(args.vg, VEC_ARGS(outputPos));
nvgQuadTo(args.vg, VEC_ARGS(slump), VEC_ARGS(inputPos));
// nvgStrokePaint(args.vg, nvgLinearGradient(args.vg, VEC_ARGS(outputPos), VEC_ARGS(inputPos), color::mult(color, 0.5), color));
nvgStrokeColor(args.vg, color::mult(color, 0.8));
nvgStrokeWidth(args.vg, thickness);
nvgStroke(args.vg);

// Draw cable
nvgStrokeColor(args.vg, color::mult(color, 0.95));
nvgStrokeWidth(args.vg, thickness - 1.0);
nvgStroke(args.vg);
if (opacity <= 0.0)
return;
nvgAlpha(args.vg, std::pow(opacity, 1.5));

math::Vec outputPos = getOutputPos();
math::Vec inputPos = getInputPos();

float thickness = thick ? 9.0 : 6.0;

// The endpoints are off-center
math::Vec slump = getSlumpPos(outputPos, inputPos);
outputPos = outputPos.plus(slump.minus(outputPos).normalize().mult(13.0));
inputPos = inputPos.plus(slump.minus(inputPos).normalize().mult(13.0));

nvgLineCap(args.vg, NVG_ROUND);
// Avoids glitches when cable is bent
nvgLineJoin(args.vg, NVG_ROUND);

if (layer == 2) {
// Draw cable shadow
math::Vec shadowSlump = slump.plus(math::Vec(0, 30));
nvgBeginPath(args.vg);
nvgMoveTo(args.vg, VEC_ARGS(outputPos));
nvgQuadTo(args.vg, VEC_ARGS(shadowSlump), VEC_ARGS(inputPos));
NVGcolor shadowColor = nvgRGBAf(0, 0, 0, 0.10);
nvgStrokeColor(args.vg, shadowColor);
nvgStrokeWidth(args.vg, thickness - 1.0);
nvgStroke(args.vg);
}
else if (layer == 3) {
// Draw cable outline
nvgBeginPath(args.vg);
nvgMoveTo(args.vg, VEC_ARGS(outputPos));
nvgQuadTo(args.vg, VEC_ARGS(slump), VEC_ARGS(inputPos));
// nvgStrokePaint(args.vg, nvgLinearGradient(args.vg, VEC_ARGS(outputPos), VEC_ARGS(inputPos), color::mult(color, 0.5), color));
nvgStrokeColor(args.vg, color::mult(color, 0.8));
nvgStrokeWidth(args.vg, thickness);
nvgStroke(args.vg);

// Draw cable
nvgStrokeColor(args.vg, color::mult(color, 0.95));
nvgStrokeWidth(args.vg, thickness - 1.0);
nvgStroke(args.vg);
}
}

Widget::drawLayer(args, layer);


+ 44
- 28
src/app/LedDisplay.cpp View File

@@ -45,7 +45,6 @@ LedDisplayChoice::LedDisplayChoice() {


void LedDisplayChoice::draw(const DrawArgs& args) {
nvgScissor(args.vg, RECT_ARGS(args.clipBox));
if (bgColor.a > 0.0) {
nvgBeginPath(args.vg);
nvgRect(args.vg, 0, 0, box.size.x, box.size.y);
@@ -53,16 +52,26 @@ void LedDisplayChoice::draw(const DrawArgs& args) {
nvgFill(args.vg);
}

std::shared_ptr<window::Font> font = APP->window->loadFont(fontPath);
nvgGlobalTint(args.vg, color::WHITE);
if (font && font->handle >= 0) {
nvgFillColor(args.vg, color);
nvgFontFaceId(args.vg, font->handle);
nvgTextLetterSpacing(args.vg, 0.0);

nvgFontSize(args.vg, 12);
nvgText(args.vg, textOffset.x, textOffset.y, text.c_str(), NULL);
Widget::draw(args);
}


void LedDisplayChoice::drawLayer(const DrawArgs& args, int layer) {
nvgScissor(args.vg, RECT_ARGS(args.clipBox));

if (layer == 1) {
std::shared_ptr<window::Font> font = APP->window->loadFont(fontPath);
if (font && font->handle >= 0) {
nvgFillColor(args.vg, color);
nvgFontFaceId(args.vg, font->handle);
nvgTextLetterSpacing(args.vg, 0.0);

nvgFontSize(args.vg, 12);
nvgText(args.vg, textOffset.x, textOffset.y, text.c_str(), NULL);
}
}

Widget::drawLayer(args, layer);
nvgResetScissor(args.vg);
}

@@ -87,8 +96,6 @@ LedDisplayTextField::LedDisplayTextField() {


void LedDisplayTextField::draw(const DrawArgs& args) {
nvgScissor(args.vg, RECT_ARGS(args.clipBox));

// Background
if (bgColor.a > 0.0) {
nvgBeginPath(args.vg);
@@ -97,24 +104,33 @@ void LedDisplayTextField::draw(const DrawArgs& args) {
nvgFill(args.vg);
}

// Text
std::shared_ptr<window::Font> font = APP->window->loadFont(fontPath);
nvgGlobalTint(args.vg, color::WHITE);
if (font && font->handle >= 0) {
bndSetFont(font->handle);

NVGcolor highlightColor = color;
highlightColor.a = 0.5;
int begin = std::min(cursor, selection);
int end = (this == APP->event->selectedWidget) ? std::max(cursor, selection) : -1;
bndIconLabelCaret(args.vg,
textOffset.x, textOffset.y,
box.size.x - 2 * textOffset.x, box.size.y - 2 * textOffset.y,
-1, color, 12, text.c_str(), highlightColor, begin, end);

bndSetFont(APP->window->uiFont->handle);
Widget::draw(args);
}


void LedDisplayTextField::drawLayer(const DrawArgs& args, int layer) {
nvgScissor(args.vg, RECT_ARGS(args.clipBox));

if (layer == 1) {
// Text
std::shared_ptr<window::Font> font = APP->window->loadFont(fontPath);
if (font && font->handle >= 0) {
bndSetFont(font->handle);

NVGcolor highlightColor = color;
highlightColor.a = 0.5;
int begin = std::min(cursor, selection);
int end = (this == APP->event->selectedWidget) ? std::max(cursor, selection) : -1;
bndIconLabelCaret(args.vg,
textOffset.x, textOffset.y,
box.size.x - 2 * textOffset.x, box.size.y - 2 * textOffset.y,
-1, color, 12, text.c_str(), highlightColor, begin, end);

bndSetFont(APP->window->uiFont->handle);
}
}

Widget::drawLayer(args, layer);
nvgResetScissor(args.vg);
}



+ 42
- 11
src/app/RackWidget.cpp View File

@@ -44,24 +44,39 @@ struct ModuleContainer : widget::Widget {
Widget::drawLayer(args, -1);

Widget::draw(args);
}

// Draw lights and light halos
nvgGlobalTint(args.vg, color::WHITE);
Widget::drawLayer(args, 1);
void drawLayer(const DrawArgs& args, int layer) override {
// Draw lights after translucent rectangle
if (layer == 1) {
Widget::drawLayer(args, 1);
}
}
};


struct CableContainer : widget::TransparentWidget {
void draw(const DrawArgs& args) override {
// Draw Plugs
Widget::draw(args);
// Don't draw on layer 0
}

// Draw cable shadows
Widget::drawLayer(args, 1);
void drawLayer(const DrawArgs& args, int layer) override {
if (layer == 2) {
// Draw Plugs
Widget::draw(args);

// Draw cables
Widget::drawLayer(args, 2);
// Draw cable lights
nvgSave(args.vg);
nvgGlobalTint(args.vg, color::WHITE);
Widget::drawLayer(args, 1);
nvgRestore(args.vg);

// Draw cable shadows
Widget::drawLayer(args, 2);

// Draw cables
Widget::drawLayer(args, 3);
}
}
};

@@ -103,12 +118,28 @@ void RackWidget::step() {
}

void RackWidget::draw(const DrawArgs& args) {
// Darken all children by user setting
float b = settings::rackBrightness;
nvgGlobalTint(args.vg, nvgRGBAf(b, b, b, 1));

// Draw rack rails and modules
Widget::draw(args);

// Draw translucent dark rectangle
if (b < 1.f) {
nvgBeginPath(args.vg);
nvgRect(args.vg, 0.0, 0.0, VEC_ARGS(box.size));
nvgFillColor(args.vg, nvgRGBAf(0, 0, 0, 1.f - b));
nvgFill(args.vg);
}

// Draw lights and halos
Widget::drawLayer(args, 1);

// Tint all draws after this point
nvgGlobalTint(args.vg, nvgRGBAf(b, b, b, 1));

// Draw cables
Widget::drawLayer(args, 2);

// Draw selection rectangle
if (internal->selecting) {
nvgBeginPath(args.vg);


Loading…
Cancel
Save