Browse Source

Add Widget::drawLayer().

tags/v2.0.0
Andrew Belt 3 years ago
parent
commit
cf2ca17156
5 changed files with 56 additions and 21 deletions
  1. +1
    -0
      include/app/CableWidget.hpp
  2. +9
    -3
      include/widget/Widget.hpp
  3. +20
    -7
      src/app/CableWidget.cpp
  4. +2
    -6
      src/app/RackWidget.cpp
  5. +24
    -5
      src/widget/Widget.cpp

+ 1
- 0
include/app/CableWidget.hpp View File

@@ -46,6 +46,7 @@ struct CableWidget : widget::Widget {
void fromJson(json_t* rootJ);
void step() override;
void draw(const DrawArgs& args) override;
void drawLayer(const DrawArgs& args, int layer) override;
engine::Cable* releaseCable();
};



+ 9
- 3
include/widget/Widget.hpp View File

@@ -126,8 +126,6 @@ struct Widget : WeakBase {
/** Local box representing the visible viewport. */
math::Rect clipBox;
NVGLUframebuffer* fb = NULL;
/** Custom widgets may draw children multiple times, passing a different layer number each time. */
int layer = 0;
};

/** Draws the widget to the NanoVG context */
@@ -135,8 +133,16 @@ struct Widget : WeakBase {
/** Override draw(const DrawArgs &args) instead */
DEPRECATED virtual void draw(NVGcontext* vg) {}

/** Draw additional layers.

Custom widgets may draw its children multiple times on different layers, passing an arbitrary layer number each time.
Layer 0 calls children's draw().
When overriding, always wrap draw commands in `if (layer == ...) {}` to avoid drawing on all layers.
*/
virtual void drawLayer(const DrawArgs& args, int layer);

/** Draws a particular child. */
void drawChild(Widget* child, const DrawArgs& args);
void drawChild(Widget* child, const DrawArgs& args, int layer = 0);

// Events



+ 20
- 7
src/app/CableWidget.cpp View File

@@ -131,11 +131,13 @@ CableWidget::CableWidget() {
addChild(outputPlug);
}


CableWidget::~CableWidget() {
setCable(NULL);
delete internal;
}


void CableWidget::setNextCableColor() {
if (!settings::cableColors.empty()) {
int id = APP->scene->rack->nextCableColorId++;
@@ -144,10 +146,12 @@ void CableWidget::setNextCableColor() {
}
}


bool CableWidget::isComplete() {
return outputPort && inputPort;
}


void CableWidget::updateCable() {
if (cable) {
APP->engine->removeCable(cable);
@@ -164,6 +168,7 @@ void CableWidget::updateCable() {
}
}


void CableWidget::setCable(engine::Cable* cable) {
if (this->cable) {
APP->engine->removeCable(this->cable);
@@ -188,10 +193,12 @@ void CableWidget::setCable(engine::Cable* cable) {
}
}


engine::Cable* CableWidget::getCable() {
return cable;
}


math::Vec CableWidget::getInputPos() {
if (inputPort) {
return inputPort->getRelativeOffset(inputPort->box.zeroPos().getCenter(), APP->scene->rack);
@@ -204,6 +211,7 @@ math::Vec CableWidget::getInputPos() {
}
}


math::Vec CableWidget::getOutputPos() {
if (outputPort) {
return outputPort->getRelativeOffset(outputPort->box.zeroPos().getCenter(), APP->scene->rack);
@@ -216,11 +224,13 @@ math::Vec CableWidget::getOutputPos() {
}
}


void CableWidget::mergeJson(json_t* rootJ) {
std::string s = color::toHexString(color);
json_object_set_new(rootJ, "color", json_string(s.c_str()));
}


void CableWidget::fromJson(json_t* rootJ) {
json_t* colorJ = json_object_get(rootJ, "color");
if (colorJ) {
@@ -230,6 +240,7 @@ void CableWidget::fromJson(json_t* rootJ) {
}
}


static math::Vec getSlumpPos(math::Vec pos1, math::Vec pos2) {
float dist = pos1.minus(pos2).norm();
math::Vec avg = pos1.plus(pos2).div(2);
@@ -238,6 +249,7 @@ static math::Vec getSlumpPos(math::Vec pos1, math::Vec pos2) {
return avg;
}


void CableWidget::step() {
math::Vec outputPos = getOutputPos();
math::Vec inputPos = getInputPos();
@@ -262,13 +274,13 @@ void CableWidget::step() {
Widget::step();
}


void CableWidget::draw(const DrawArgs& args) {
if (args.layer == 0) {
// Draw PlugWidgets
Widget::draw(args);
return;
}
Widget::draw(args);
}


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

@@ -312,7 +324,7 @@ void CableWidget::draw(const DrawArgs& args) {
// Avoids glitches when cable is bent
nvgLineJoin(args.vg, NVG_ROUND);

if (args.layer == 1) {
if (layer == 1) {
// Draw cable shadow
math::Vec shadowSlump = slump.plus(math::Vec(0, 30));
nvgBeginPath(args.vg);
@@ -323,7 +335,7 @@ void CableWidget::draw(const DrawArgs& args) {
nvgStrokeWidth(args.vg, thickness - 1.0);
nvgStroke(args.vg);
}
else if (args.layer == 2) {
else if (layer == 2) {
// Draw cable outline
nvgBeginPath(args.vg);
nvgMoveTo(args.vg, VEC_ARGS(outputPos));
@@ -340,6 +352,7 @@ void CableWidget::draw(const DrawArgs& args) {
}
}


engine::Cable* CableWidget::releaseCable() {
engine::Cable* cable = this->cable;
this->cable = NULL;


+ 2
- 6
src/app/RackWidget.cpp View File

@@ -62,14 +62,10 @@ struct CableContainer : widget::TransparentWidget {
Widget::draw(args);

// Draw cable shadows
DrawArgs args1 = args;
args1.layer = 1;
Widget::draw(args1);
Widget::drawLayer(args, 1);

// Draw cables
DrawArgs args2 = args;
args2.layer = 2;
Widget::draw(args2);
Widget::drawLayer(args, 2);
}
};



+ 24
- 5
src/widget/Widget.cpp View File

@@ -273,7 +273,22 @@ void Widget::draw(const DrawArgs& args) {
}


void Widget::drawChild(Widget* child, const DrawArgs& args) {
void Widget::drawLayer(const DrawArgs& args, int layer) {
// Iterate children
for (Widget* child : children) {
// Don't draw if invisible
if (!child->isVisible())
continue;
// Don't draw if child is outside clip box
if (!args.clipBox.intersects(child->box))
continue;

drawChild(child, args, layer);
}
}


void Widget::drawChild(Widget* child, const DrawArgs& args, int layer) {
DrawArgs childArgs = args;
// Intersect child clip box with self
childArgs.clipBox = childArgs.clipBox.intersect(child->box);
@@ -283,13 +298,17 @@ void Widget::drawChild(Widget* child, const DrawArgs& args) {
nvgSave(args.vg);
nvgTranslate(args.vg, child->box.pos.x, child->box.pos.y);

child->draw(childArgs);
if (layer == 0) {
child->draw(childArgs);
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
// Call deprecated draw function, which does nothing by default
child->draw(args.vg);
// Call deprecated draw function, which does nothing by default
child->draw(args.vg);
#pragma GCC diagnostic pop
}
else {
child->drawLayer(childArgs, layer);
}

nvgRestore(args.vg);
}


Loading…
Cancel
Save