Browse Source

Add new Widget::draw() method. Deprecate old method.

tags/v1.0.0
Andrew Belt 6 years ago
parent
commit
6d1142b449
68 changed files with 364 additions and 348 deletions
  1. +2
    -2
      include/app/CableWidget.hpp
  2. +1
    -1
      include/app/CircularShadow.hpp
  3. +4
    -4
      include/app/LedDisplay.hpp
  4. +3
    -3
      include/app/LightWidget.hpp
  5. +1
    -1
      include/app/ModuleBrowser.hpp
  6. +2
    -2
      include/app/ModuleWidget.hpp
  7. +1
    -1
      include/app/ParamWidget.hpp
  8. +1
    -1
      include/app/PortWidget.hpp
  9. +1
    -1
      include/app/RackRail.hpp
  10. +1
    -1
      include/app/RackScrollWidget.hpp
  11. +1
    -1
      include/app/RackWidget.hpp
  12. +1
    -1
      include/app/SVGPanel.hpp
  13. +1
    -1
      include/app/Scene.hpp
  14. +1
    -1
      include/app/Toolbar.hpp
  15. +1
    -1
      include/ui/Button.hpp
  16. +1
    -1
      include/ui/ChoiceButton.hpp
  17. +1
    -1
      include/ui/Label.hpp
  18. +1
    -1
      include/ui/Menu.hpp
  19. +1
    -1
      include/ui/MenuItem.hpp
  20. +1
    -1
      include/ui/MenuLabel.hpp
  21. +1
    -1
      include/ui/MenuSeparator.hpp
  22. +1
    -1
      include/ui/PasswordField.hpp
  23. +1
    -1
      include/ui/ProgressBar.hpp
  24. +1
    -1
      include/ui/RadioButton.hpp
  25. +1
    -1
      include/ui/ScrollBar.hpp
  26. +1
    -1
      include/ui/ScrollWidget.hpp
  27. +1
    -1
      include/ui/Slider.hpp
  28. +1
    -1
      include/ui/TextField.hpp
  29. +1
    -1
      include/ui/Tooltip.hpp
  30. +1
    -1
      include/widgets/FramebufferWidget.hpp
  31. +2
    -2
      include/widgets/SVGWidget.hpp
  32. +3
    -3
      include/widgets/TransformWidget.hpp
  33. +9
    -2
      include/widgets/Widget.hpp
  34. +1
    -1
      include/widgets/ZoomWidget.hpp
  35. +13
    -13
      src/Core/Blank.cpp
  36. +45
    -45
      src/app/CableWidget.cpp
  37. +6
    -6
      src/app/CircularShadow.cpp
  38. +29
    -29
      src/app/LedDisplay.cpp
  39. +20
    -20
      src/app/LightWidget.cpp
  40. +9
    -11
      src/app/ModuleBrowser.cpp
  41. +24
    -24
      src/app/ModuleWidget.cpp
  42. +7
    -7
      src/app/ParamWidget.cpp
  43. +3
    -3
      src/app/PortWidget.cpp
  44. +30
    -30
      src/app/RackRail.cpp
  45. +4
    -4
      src/app/RackScrollWidget.cpp
  46. +11
    -11
      src/app/RackWidget.cpp
  47. +6
    -6
      src/app/SVGPanel.cpp
  48. +2
    -2
      src/app/Scene.cpp
  49. +14
    -14
      src/app/Toolbar.cpp
  50. +2
    -2
      src/ui/Button.cpp
  51. +2
    -2
      src/ui/ChoiceButton.cpp
  52. +4
    -4
      src/ui/Label.cpp
  53. +3
    -3
      src/ui/Menu.cpp
  54. +5
    -5
      src/ui/MenuItem.cpp
  55. +2
    -2
      src/ui/MenuLabel.cpp
  56. +7
    -7
      src/ui/MenuSeparator.cpp
  57. +2
    -2
      src/ui/PasswordField.cpp
  58. +2
    -2
      src/ui/ProgressBar.cpp
  59. +2
    -2
      src/ui/RadioButton.cpp
  60. +2
    -2
      src/ui/ScrollBar.cpp
  61. +4
    -4
      src/ui/ScrollWidget.cpp
  62. +2
    -2
      src/ui/Slider.cpp
  63. +5
    -5
      src/ui/TextField.cpp
  64. +4
    -4
      src/ui/Tooltip.cpp
  65. +19
    -17
      src/widgets/FramebufferWidget.cpp
  66. +16
    -9
      src/widgets/Widget.cpp
  67. +3
    -3
      src/widgets/ZoomWidget.cpp
  68. +3
    -1
      src/window.cpp

+ 2
- 2
include/app/CableWidget.hpp View File

@@ -27,8 +27,8 @@ struct CableWidget : OpaqueWidget {
math::Vec getInputPos();
json_t *toJson();
void fromJson(json_t *rootJ, const std::map<int, ModuleWidget*> &moduleWidgets);
void draw(NVGcontext *vg) override;
void drawPlugs(NVGcontext *vg);
void draw(const DrawContext &ctx) override;
void drawPlugs(const DrawContext &ctx);
};




+ 1
- 1
include/app/CircularShadow.hpp View File

@@ -10,7 +10,7 @@ struct CircularShadow : TransparentWidget {
float blurRadius;
float opacity;
CircularShadow();
void draw(NVGcontext *vg) override;
void draw(const DrawContext &ctx) override;
};




+ 4
- 4
include/app/LedDisplay.hpp View File

@@ -9,12 +9,12 @@ namespace rack {


struct LedDisplay : Widget {
void draw(NVGcontext *vg) override;
void draw(const DrawContext &ctx) override;
};

struct LedDisplaySeparator : TransparentWidget {
LedDisplaySeparator();
void draw(NVGcontext *vg) override;
void draw(const DrawContext &ctx) override;
};

struct LedDisplayChoice : TransparentWidget {
@@ -23,7 +23,7 @@ struct LedDisplayChoice : TransparentWidget {
math::Vec textOffset;
NVGcolor color;
LedDisplayChoice();
void draw(NVGcontext *vg) override;
void draw(const DrawContext &ctx) override;
void onButton(const event::Button &e) override;
};

@@ -32,7 +32,7 @@ struct LedDisplayTextField : TextField {
math::Vec textOffset;
NVGcolor color;
LedDisplayTextField();
void draw(NVGcontext *vg) override;
void draw(const DrawContext &ctx) override;
int getTextPosition(math::Vec mousePos) override;
};



+ 3
- 3
include/app/LightWidget.hpp View File

@@ -10,9 +10,9 @@ struct LightWidget : TransparentWidget {
NVGcolor bgColor = nvgRGBA(0, 0, 0, 0);
NVGcolor color = nvgRGBA(0, 0, 0, 0);
NVGcolor borderColor = nvgRGBA(0, 0, 0, 0);
void draw(NVGcontext *vg) override;
virtual void drawLight(NVGcontext *vg);
virtual void drawHalo(NVGcontext *vg);
void draw(const DrawContext &ctx) override;
virtual void drawLight(const DrawContext &ctx);
virtual void drawHalo(const DrawContext &ctx);
};




+ 1
- 1
include/app/ModuleBrowser.hpp View File

@@ -13,7 +13,7 @@ struct ModuleBrowser : OpaqueWidget {

ModuleBrowser();
void step() override;
void draw(NVGcontext *vg) override;
void draw(const DrawContext &ctx) override;
void onHoverKey(const event::HoverKey &e) override;
};



+ 2
- 2
include/app/ModuleWidget.hpp View File

@@ -30,8 +30,8 @@ struct ModuleWidget : OpaqueWidget {
}
~ModuleWidget();

void draw(NVGcontext *vg) override;
void drawShadow(NVGcontext *vg);
void draw(const DrawContext &ctx) override;
void drawShadow(const DrawContext &ctx);

void onHover(const event::Hover &e) override;
void onButton(const event::Button &e) override;


+ 1
- 1
include/app/ParamWidget.hpp View File

@@ -16,7 +16,7 @@ struct ParamWidget : OpaqueWidget {

~ParamWidget();
void step() override;
void draw(NVGcontext *vg) override;
void draw(const DrawContext &ctx) override;
void onButton(const event::Button &e) override;
void onEnter(const event::Enter &e) override;
void onLeave(const event::Leave &e) override;


+ 1
- 1
include/app/PortWidget.hpp View File

@@ -23,7 +23,7 @@ struct PortWidget : OpaqueWidget {
~PortWidget();

void step() override;
void draw(NVGcontext *vg) override;
void draw(const DrawContext &ctx) override;

void onButton(const event::Button &e) override;
void onDragStart(const event::DragStart &e) override;


+ 1
- 1
include/app/RackRail.hpp View File

@@ -7,7 +7,7 @@ namespace rack {


struct RackRail : TransparentWidget {
void draw(NVGcontext *vg) override;
void draw(const DrawContext &ctx) override;
};




+ 1
- 1
include/app/RackScrollWidget.hpp View File

@@ -8,7 +8,7 @@ namespace rack {

struct RackScrollWidget : ScrollWidget {
void step() override;
void draw(NVGcontext *vg) override;
void draw(const DrawContext &ctx) override;
};




+ 1
- 1
include/app/RackWidget.hpp View File

@@ -22,7 +22,7 @@ struct RackWidget : OpaqueWidget {
~RackWidget();

void step() override;
void draw(NVGcontext *vg) override;
void draw(const DrawContext &ctx) override;

void onHover(const event::Hover &e) override;
void onHoverKey(const event::HoverKey &e) override;


+ 1
- 1
include/app/SVGPanel.hpp View File

@@ -10,7 +10,7 @@ namespace rack {


struct PanelBorder : TransparentWidget {
void draw(NVGcontext *vg) override;
void draw(const DrawContext &ctx) override;
};




+ 1
- 1
include/app/Scene.hpp View File

@@ -28,7 +28,7 @@ struct Scene : OpaqueWidget {
Scene();
~Scene();
void step() override;
void draw(NVGcontext *vg) override;
void draw(const DrawContext &ctx) override;
void onHoverKey(const event::HoverKey &e) override;
void onPathDrop(const event::PathDrop &e) override;



+ 1
- 1
include/app/Toolbar.hpp View File

@@ -12,7 +12,7 @@ struct Toolbar : OpaqueWidget {
float cableTension = 0.5;

Toolbar();
void draw(NVGcontext *vg) override;
void draw(const DrawContext &ctx) override;
};




+ 1
- 1
include/ui/Button.hpp View File

@@ -15,7 +15,7 @@ struct Button : OpaqueWidget {

Button();
~Button();
void draw(NVGcontext *vg) override;
void draw(const DrawContext &ctx) override;
void onEnter(const event::Enter &e) override;
void onLeave(const event::Leave &e) override;
void onDragStart(const event::DragStart &e) override;


+ 1
- 1
include/ui/ChoiceButton.hpp View File

@@ -7,7 +7,7 @@ namespace rack {


struct ChoiceButton : Button {
void draw(NVGcontext *vg) override;
void draw(const DrawContext &ctx) override;
};




+ 1
- 1
include/ui/Label.hpp View File

@@ -19,7 +19,7 @@ struct Label : Widget {
Alignment alignment = LEFT_ALIGNMENT;

Label();
void draw(NVGcontext *vg) override;
void draw(const DrawContext &ctx) override;
};




+ 1
- 1
include/ui/Menu.hpp View File

@@ -17,7 +17,7 @@ struct Menu : OpaqueWidget {
~Menu();
void setChildMenu(Menu *menu);
void step() override;
void draw(NVGcontext *vg) override;
void draw(const DrawContext &ctx) override;
void onHoverScroll(const event::HoverScroll &e) override;
};



+ 1
- 1
include/ui/MenuItem.hpp View File

@@ -17,7 +17,7 @@ struct MenuItem : MenuEntry {
std::string rightText;
bool disabled = false;

void draw(NVGcontext *vg) override;
void draw(const DrawContext &ctx) override;
void step() override;
void onEnter(const event::Enter &e) override;
void onDragDrop(const event::DragDrop &e) override;


+ 1
- 1
include/ui/MenuLabel.hpp View File

@@ -9,7 +9,7 @@ namespace rack {
struct MenuLabel : MenuEntry {
std::string text;

void draw(NVGcontext *vg) override;
void draw(const DrawContext &ctx) override;
void step() override;
};



+ 1
- 1
include/ui/MenuSeparator.hpp View File

@@ -8,7 +8,7 @@ namespace rack {

struct MenuSeparator : MenuEntry {
MenuSeparator();
void draw(NVGcontext *vg) override;
void draw(const DrawContext &ctx) override;
};




+ 1
- 1
include/ui/PasswordField.hpp View File

@@ -7,7 +7,7 @@ namespace rack {


struct PasswordField : TextField {
void draw(NVGcontext *vg) override;
void draw(const DrawContext &ctx) override;
};




+ 1
- 1
include/ui/ProgressBar.hpp View File

@@ -12,7 +12,7 @@ struct ProgressBar : Widget {

ProgressBar();
~ProgressBar();
void draw(NVGcontext *vg) override;
void draw(const DrawContext &ctx) override;
};




+ 1
- 1
include/ui/RadioButton.hpp View File

@@ -13,7 +13,7 @@ struct RadioButton : OpaqueWidget {

RadioButton();
~RadioButton();
void draw(NVGcontext *vg) override;
void draw(const DrawContext &ctx) override;
void onEnter(const event::Enter &e) override;
void onLeave(const event::Leave &e) override;
void onDragDrop(const event::DragDrop &e) override;


+ 1
- 1
include/ui/ScrollBar.hpp View File

@@ -18,7 +18,7 @@ struct ScrollBar : OpaqueWidget {
float size = 0.0;

ScrollBar();
void draw(NVGcontext *vg) override;
void draw(const DrawContext &ctx) override;
void onDragStart(const event::DragStart &e) override;
void onDragMove(const event::DragMove &e) override;
void onDragEnd(const event::DragEnd &e) override;


+ 1
- 1
include/ui/ScrollWidget.hpp View File

@@ -16,7 +16,7 @@ struct ScrollWidget : OpaqueWidget {

ScrollWidget();
void scrollTo(math::Rect r);
void draw(NVGcontext *vg) override;
void draw(const DrawContext &ctx) override;
void step() override;
void onHover(const event::Hover &e) override;
void onHoverScroll(const event::HoverScroll &e) override;


+ 1
- 1
include/ui/Slider.hpp View File

@@ -14,7 +14,7 @@ struct Slider : OpaqueWidget {

Slider();
~Slider();
void draw(NVGcontext *vg) override;
void draw(const DrawContext &ctx) override;
void onDragStart(const event::DragStart &e) override;
void onDragMove(const event::DragMove &e) override;
void onDragEnd(const event::DragEnd &e) override;


+ 1
- 1
include/ui/TextField.hpp View File

@@ -20,7 +20,7 @@ struct TextField : OpaqueWidget {
int selection = 0;

TextField();
void draw(NVGcontext *vg) override;
void draw(const DrawContext &ctx) override;
void onButton(const event::Button &e) override;
void onHover(const event::Hover &e) override;
void onEnter(const event::Enter &e) override;


+ 1
- 1
include/ui/Tooltip.hpp View File

@@ -10,7 +10,7 @@ struct Tooltip : Widget {
std::string text;

void step() override;
void draw(NVGcontext *vg) override;
void draw(const DrawContext &ctx) override;
};




+ 1
- 1
include/widgets/FramebufferWidget.hpp View File

@@ -27,7 +27,7 @@ struct FramebufferWidget : Widget {

FramebufferWidget();
~FramebufferWidget();
void draw(NVGcontext *vg) override;
void draw(const DrawContext &ctx) override;
virtual void drawFramebuffer();
int getImageHandle();



+ 2
- 2
include/widgets/SVGWidget.hpp View File

@@ -26,9 +26,9 @@ struct SVGWidget : Widget {
wrap();
}

void draw(NVGcontext *vg) override {
void draw(const DrawContext &ctx) override {
if (svg && svg->handle) {
svgDraw(vg, svg->handle);
svgDraw(ctx.vg, svg->handle);
}
}
};


+ 3
- 3
include/widgets/TransformWidget.hpp View File

@@ -36,10 +36,10 @@ struct TransformWidget : Widget {
nvgTransformPremultiply(transform, t);
}

void draw(NVGcontext *vg) override {
void draw(const DrawContext &ctx) override {
// No need to save the state because that is done in the parent
nvgTransform(vg, transform[0], transform[1], transform[2], transform[3], transform[4], transform[5]);
Widget::draw(vg);
nvgTransform(ctx.vg, transform[0], transform[1], transform[2], transform[3], transform[4], transform[5]);
Widget::draw(ctx);
}
};



+ 9
- 2
include/widgets/Widget.hpp View File

@@ -10,6 +10,11 @@
namespace rack {


struct DrawContext {
mutable NVGcontext *vg;
};


/** A node in the 2D scene graph
*/
struct Widget {
@@ -67,8 +72,10 @@ struct Widget {

/** Advances the module by one frame */
virtual void step();
/** Draws to NanoVG context */
virtual void draw(NVGcontext *vg);
/** Draws the widget to the NanoVG context */
virtual void draw(const DrawContext &ctx);
/** Override `draw(const DrawContext &ctx)` instead */
DEPRECATED virtual void draw(NVGcontext *vg) {}

// Events



+ 1
- 1
include/widgets/ZoomWidget.hpp View File

@@ -11,7 +11,7 @@ struct ZoomWidget : Widget {
math::Vec getRelativeOffset(math::Vec v, Widget *relative) override;
math::Rect getViewport(math::Rect r) override;
void setZoom(float zoom);
void draw(NVGcontext *vg) override;
void draw(const DrawContext &ctx) override;

void onHover(const event::Hover &e) override {
event::Hover e2 = e;


+ 13
- 13
src/Core/Blank.cpp View File

@@ -16,12 +16,12 @@ struct BlankPanel : Widget {
panelBorder->box.size = box.size;
}

void draw(NVGcontext *vg) override {
nvgBeginPath(vg);
nvgRect(vg, 0.0, 0.0, box.size.x, box.size.y);
nvgFillColor(vg, nvgRGB(0xe6, 0xe6, 0xe6));
nvgFill(vg);
Widget::draw(vg);
void draw(const DrawContext &ctx) override {
nvgBeginPath(ctx.vg);
nvgRect(ctx.vg, 0.0, 0.0, box.size.x, box.size.y);
nvgFillColor(ctx.vg, nvgRGB(0xe6, 0xe6, 0xe6));
nvgFill(ctx.vg);
Widget::draw(ctx);
}
};

@@ -64,15 +64,15 @@ struct ModuleResizeHandle : Widget {
}
app()->scene->rackWidget->requestModuleBox(m, newBox);
}
void draw(NVGcontext *vg) override {
void draw(const DrawContext &ctx) override {
for (float x = 5.0; x <= 10.0; x += 5.0) {
nvgBeginPath(vg);
nvgBeginPath(ctx.vg);
const float margin = 5.0;
nvgMoveTo(vg, x + 0.5, margin + 0.5);
nvgLineTo(vg, x + 0.5, box.size.y - margin + 0.5);
nvgStrokeWidth(vg, 1.0);
nvgStrokeColor(vg, nvgRGBAf(0.5, 0.5, 0.5, 0.5));
nvgStroke(vg);
nvgMoveTo(ctx.vg, x + 0.5, margin + 0.5);
nvgLineTo(ctx.vg, x + 0.5, box.size.y - margin + 0.5);
nvgStrokeWidth(ctx.vg, 1.0);
nvgStrokeColor(ctx.vg, nvgRGBAf(0.5, 0.5, 0.5, 0.5));
nvgStroke(ctx.vg);
}
}
};


+ 45
- 45
src/app/CableWidget.cpp View File

@@ -10,67 +10,67 @@

namespace rack {

static void drawPlug(NVGcontext *vg, math::Vec pos, NVGcolor color) {
static void drawPlug(const DrawContext &ctx, math::Vec pos, NVGcolor color) {
NVGcolor colorOutline = nvgLerpRGBA(color, nvgRGBf(0.0, 0.0, 0.0), 0.5);

// Plug solid
nvgBeginPath(vg);
nvgCircle(vg, pos.x, pos.y, 9);
nvgFillColor(vg, color);
nvgFill(vg);
nvgBeginPath(ctx.vg);
nvgCircle(ctx.vg, pos.x, pos.y, 9);
nvgFillColor(ctx.vg, color);
nvgFill(ctx.vg);

// Border
nvgStrokeWidth(vg, 1.0);
nvgStrokeColor(vg, colorOutline);
nvgStroke(vg);
nvgStrokeWidth(ctx.vg, 1.0);
nvgStrokeColor(ctx.vg, colorOutline);
nvgStroke(ctx.vg);

// Hole
nvgBeginPath(vg);
nvgCircle(vg, pos.x, pos.y, 5);
nvgFillColor(vg, nvgRGBf(0.0, 0.0, 0.0));
nvgFill(vg);
nvgBeginPath(ctx.vg);
nvgCircle(ctx.vg, pos.x, pos.y, 5);
nvgFillColor(ctx.vg, nvgRGBf(0.0, 0.0, 0.0));
nvgFill(ctx.vg);
}

static void drawCable(NVGcontext *vg, math::Vec pos1, math::Vec pos2, NVGcolor color, float thickness, float tension, float opacity) {
static void drawCable(const DrawContext &ctx, 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);

// Cable
if (opacity > 0.0) {
nvgSave(vg);
nvgSave(ctx.vg);
// This power scaling looks more linear than actual linear scaling
nvgGlobalAlpha(vg, std::pow(opacity, 1.5));
nvgGlobalAlpha(ctx.vg, std::pow(opacity, 1.5));

float dist = pos1.minus(pos2).norm();
math::Vec slump;
slump.y = (1.0 - tension) * (150.0 + 1.0*dist);
math::Vec pos3 = pos1.plus(pos2).div(2).plus(slump);

nvgLineJoin(vg, NVG_ROUND);
nvgLineJoin(ctx.vg, NVG_ROUND);

// Shadow
math::Vec pos4 = pos3.plus(slump.mult(0.08));
nvgBeginPath(vg);
nvgMoveTo(vg, pos1.x, pos1.y);
nvgQuadTo(vg, pos4.x, pos4.y, pos2.x, pos2.y);
nvgStrokeColor(vg, colorShadow);
nvgStrokeWidth(vg, thickness);
nvgStroke(vg);
nvgBeginPath(ctx.vg);
nvgMoveTo(ctx.vg, pos1.x, pos1.y);
nvgQuadTo(ctx.vg, pos4.x, pos4.y, pos2.x, pos2.y);
nvgStrokeColor(ctx.vg, colorShadow);
nvgStrokeWidth(ctx.vg, thickness);
nvgStroke(ctx.vg);

// Cable outline
nvgBeginPath(vg);
nvgMoveTo(vg, pos1.x, pos1.y);
nvgQuadTo(vg, pos3.x, pos3.y, pos2.x, pos2.y);
nvgStrokeColor(vg, colorOutline);
nvgStrokeWidth(vg, thickness);
nvgStroke(vg);
nvgBeginPath(ctx.vg);
nvgMoveTo(ctx.vg, pos1.x, pos1.y);
nvgQuadTo(ctx.vg, pos3.x, pos3.y, pos2.x, pos2.y);
nvgStrokeColor(ctx.vg, colorOutline);
nvgStrokeWidth(ctx.vg, thickness);
nvgStroke(ctx.vg);

// Cable solid
nvgStrokeColor(vg, color);
nvgStrokeWidth(vg, thickness - 2);
nvgStroke(vg);
nvgStrokeColor(ctx.vg, color);
nvgStrokeWidth(ctx.vg, thickness - 2);
nvgStroke(ctx.vg);

nvgRestore(vg);
nvgRestore(ctx.vg);
}
}

@@ -205,7 +205,7 @@ void CableWidget::fromJson(json_t *rootJ, const std::map<int, ModuleWidget*> &mo
}
}

void CableWidget::draw(NVGcontext *vg) {
void CableWidget::draw(const DrawContext &ctx) {
float opacity = settings::cableOpacity;
float tension = settings::cableTension;

@@ -235,33 +235,33 @@ void CableWidget::draw(NVGcontext *vg) {

math::Vec outputPos = getOutputPos();
math::Vec inputPos = getInputPos();
drawCable(vg, outputPos, inputPos, color, thickness, tension, opacity);
drawCable(ctx, outputPos, inputPos, color, thickness, tension, opacity);
}

void CableWidget::drawPlugs(NVGcontext *vg) {
void CableWidget::drawPlugs(const DrawContext &ctx) {
// TODO Figure out a way to draw plugs first and cables last, and cut the plug portion of the cable off.
math::Vec outputPos = getOutputPos();
math::Vec inputPos = getInputPos();

// Draw plug if the cable is on top, or if the cable is incomplete
if (!isComplete() || app()->scene->rackWidget->getTopCable(outputPort) == this) {
drawPlug(vg, outputPos, color);
drawPlug(ctx, outputPos, color);
if (isComplete()) {
// Draw plug light
nvgSave(vg);
nvgTranslate(vg, outputPos.x - 4, outputPos.y - 4);
outputPort->plugLight->draw(vg);
nvgRestore(vg);
nvgSave(ctx.vg);
nvgTranslate(ctx.vg, outputPos.x - 4, outputPos.y - 4);
outputPort->plugLight->draw(ctx);
nvgRestore(ctx.vg);
}
}

if (!isComplete() || app()->scene->rackWidget->getTopCable(inputPort) == this) {
drawPlug(vg, inputPos, color);
drawPlug(ctx, inputPos, color);
if (isComplete()) {
nvgSave(vg);
nvgTranslate(vg, inputPos.x - 4, inputPos.y - 4);
inputPort->plugLight->draw(vg);
nvgRestore(vg);
nvgSave(ctx.vg);
nvgTranslate(ctx.vg, inputPos.x - 4, inputPos.y - 4);
inputPort->plugLight->draw(ctx);
nvgRestore(ctx.vg);
}
}
}


+ 6
- 6
src/app/CircularShadow.cpp View File

@@ -9,19 +9,19 @@ CircularShadow::CircularShadow() {
opacity = 0.15;
}

void CircularShadow::draw(NVGcontext *vg) {
void CircularShadow::draw(const DrawContext &ctx) {
if (opacity <= 0.0)
return;

nvgBeginPath(vg);
nvgRect(vg, -blurRadius, -blurRadius, box.size.x + 2*blurRadius, box.size.y + 2*blurRadius);
nvgBeginPath(ctx.vg);
nvgRect(ctx.vg, -blurRadius, -blurRadius, box.size.x + 2*blurRadius, box.size.y + 2*blurRadius);
math::Vec center = box.size.div(2.0);
float radius = center.x;
NVGcolor icol = nvgRGBAf(0.0, 0.0, 0.0, opacity);
NVGcolor ocol = nvgRGBAf(0.0, 0.0, 0.0, 0.0);
NVGpaint paint = nvgRadialGradient(vg, center.x, center.y, radius - blurRadius, radius, icol, ocol);
nvgFillPaint(vg, paint);
nvgFill(vg);
NVGpaint paint = nvgRadialGradient(ctx.vg, center.x, center.y, radius - blurRadius, radius, icol, ocol);
nvgFillPaint(ctx.vg, paint);
nvgFill(ctx.vg);
}




+ 29
- 29
src/app/LedDisplay.cpp View File

@@ -8,13 +8,13 @@
namespace rack {


void LedDisplay::draw(NVGcontext *vg) {
nvgBeginPath(vg);
nvgRoundedRect(vg, 0, 0, box.size.x, box.size.y, 5.0);
nvgFillColor(vg, nvgRGB(0x00, 0x00, 0x00));
nvgFill(vg);
void LedDisplay::draw(const DrawContext &ctx) {
nvgBeginPath(ctx.vg);
nvgRoundedRect(ctx.vg, 0, 0, box.size.x, box.size.y, 5.0);
nvgFillColor(ctx.vg, nvgRGB(0x00, 0x00, 0x00));
nvgFill(ctx.vg);

Widget::draw(vg);
Widget::draw(ctx);
}


@@ -22,13 +22,13 @@ LedDisplaySeparator::LedDisplaySeparator() {
box.size = math::Vec();
}

void LedDisplaySeparator::draw(NVGcontext *vg) {
nvgBeginPath(vg);
nvgMoveTo(vg, 0, 0);
nvgLineTo(vg, box.size.x, box.size.y);
nvgStrokeWidth(vg, 1.0);
nvgStrokeColor(vg, nvgRGB(0x33, 0x33, 0x33));
nvgStroke(vg);
void LedDisplaySeparator::draw(const DrawContext &ctx) {
nvgBeginPath(ctx.vg);
nvgMoveTo(ctx.vg, 0, 0);
nvgLineTo(ctx.vg, box.size.x, box.size.y);
nvgStrokeWidth(ctx.vg, 1.0);
nvgStrokeColor(ctx.vg, nvgRGB(0x33, 0x33, 0x33));
nvgStroke(ctx.vg);
}


@@ -39,19 +39,19 @@ LedDisplayChoice::LedDisplayChoice() {
textOffset = math::Vec(10, 18);
}

void LedDisplayChoice::draw(NVGcontext *vg) {
nvgScissor(vg, 0, 0, box.size.x, box.size.y);
void LedDisplayChoice::draw(const DrawContext &ctx) {
nvgScissor(ctx.vg, 0, 0, box.size.x, box.size.y);

if (font->handle >= 0) {
nvgFillColor(vg, color);
nvgFontFaceId(vg, font->handle);
nvgTextLetterSpacing(vg, 0.0);
nvgFillColor(ctx.vg, color);
nvgFontFaceId(ctx.vg, font->handle);
nvgTextLetterSpacing(ctx.vg, 0.0);

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

nvgResetScissor(vg);
nvgResetScissor(ctx.vg);
}

void LedDisplayChoice::onButton(const event::Button &e) {
@@ -70,14 +70,14 @@ LedDisplayTextField::LedDisplayTextField() {
}


void LedDisplayTextField::draw(NVGcontext *vg) {
nvgScissor(vg, 0, 0, box.size.x, box.size.y);
void LedDisplayTextField::draw(const DrawContext &ctx) {
nvgScissor(ctx.vg, 0, 0, box.size.x, box.size.y);

// Background
nvgBeginPath(vg);
nvgRoundedRect(vg, 0, 0, box.size.x, box.size.y, 5.0);
nvgFillColor(vg, nvgRGB(0x00, 0x00, 0x00));
nvgFill(vg);
nvgBeginPath(ctx.vg);
nvgRoundedRect(ctx.vg, 0, 0, box.size.x, box.size.y, 5.0);
nvgFillColor(ctx.vg, nvgRGB(0x00, 0x00, 0x00));
nvgFill(ctx.vg);

// Text
if (font->handle >= 0) {
@@ -87,14 +87,14 @@ void LedDisplayTextField::draw(NVGcontext *vg) {
highlightColor.a = 0.5;
int begin = std::min(cursor, selection);
int end = (this == app()->event->selectedWidget) ? std::max(cursor, selection) : -1;
bndIconLabelCaret(vg, textOffset.x, textOffset.y,
bndIconLabelCaret(ctx.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);
}

nvgResetScissor(vg);
nvgResetScissor(ctx.vg);
}

int LedDisplayTextField::getTextPosition(math::Vec mousePos) {


+ 20
- 20
src/app/LightWidget.cpp View File

@@ -5,45 +5,45 @@
namespace rack {


void LightWidget::draw(NVGcontext *vg) {
drawLight(vg);
drawHalo(vg);
void LightWidget::draw(const DrawContext &ctx) {
drawLight(ctx);
drawHalo(ctx);
}

void LightWidget::drawLight(NVGcontext *vg) {
void LightWidget::drawLight(const DrawContext &ctx) {
float radius = box.size.x / 2.0;

nvgBeginPath(vg);
nvgCircle(vg, radius, radius, radius);
nvgBeginPath(ctx.vg);
nvgCircle(ctx.vg, radius, radius, radius);

// Background
nvgFillColor(vg, bgColor);
nvgFill(vg);
nvgFillColor(ctx.vg, bgColor);
nvgFill(ctx.vg);

// Foreground
nvgFillColor(vg, color);
nvgFill(vg);
nvgFillColor(ctx.vg, color);
nvgFill(ctx.vg);

// Border
nvgStrokeWidth(vg, 0.5);
nvgStrokeColor(vg, borderColor);
nvgStroke(vg);
nvgStrokeWidth(ctx.vg, 0.5);
nvgStrokeColor(ctx.vg, borderColor);
nvgStroke(ctx.vg);
}

void LightWidget::drawHalo(NVGcontext *vg) {
void LightWidget::drawHalo(const DrawContext &ctx) {
float radius = box.size.x / 2.0;
float oradius = radius + 15.0;

nvgBeginPath(vg);
nvgRect(vg, radius - oradius, radius - oradius, 2*oradius, 2*oradius);
nvgBeginPath(ctx.vg);
nvgRect(ctx.vg, radius - oradius, radius - oradius, 2*oradius, 2*oradius);

NVGpaint paint;
NVGcolor icol = color::mult(color, 0.08);
NVGcolor ocol = nvgRGB(0, 0, 0);
paint = nvgRadialGradient(vg, radius, radius, radius, oradius, icol, ocol);
nvgFillPaint(vg, paint);
nvgGlobalCompositeOperation(vg, NVG_LIGHTER);
nvgFill(vg);
paint = nvgRadialGradient(ctx.vg, radius, radius, radius, oradius, icol, ocol);
nvgFillPaint(ctx.vg, paint);
nvgGlobalCompositeOperation(ctx.vg, NVG_LIGHTER);
nvgFill(ctx.vg);
}




+ 9
- 11
src/app/ModuleBrowser.cpp View File

@@ -47,9 +47,7 @@ struct ModuleBox : OpaqueWidget {
addChild(pluginLabel);
}

void draw(NVGcontext *vg) override {
DEBUG("%p model", model);

void draw(const DrawContext &ctx) override {
// Lazily create ModuleWidget when drawn
if (!initialized) {
Widget *transparentWidget = new TransparentWidget;
@@ -76,12 +74,12 @@ struct ModuleBox : OpaqueWidget {
initialized = true;
}

OpaqueWidget::draw(vg);
OpaqueWidget::draw(ctx);
if (app()->event->hoveredWidget == this) {
nvgBeginPath(vg);
nvgRect(vg, 0.0, 0.0, box.size.x, box.size.y);
nvgFillColor(vg, nvgRGBAf(1, 1, 1, 0.25));
nvgFill(vg);
nvgBeginPath(ctx.vg);
nvgRect(ctx.vg, 0.0, 0.0, box.size.x, box.size.y);
nvgFillColor(ctx.vg, nvgRGBAf(1, 1, 1, 0.25));
nvgFill(ctx.vg);
}
}

@@ -137,9 +135,9 @@ void ModuleBrowser::step() {
OpaqueWidget::step();
}

void ModuleBrowser::draw(NVGcontext *vg) {
bndMenuBackground(vg, 0.0, 0.0, box.size.x, box.size.y, 0);
Widget::draw(vg);
void ModuleBrowser::draw(const DrawContext &ctx) {
bndMenuBackground(ctx.vg, 0.0, 0.0, box.size.x, box.size.y, 0);
Widget::draw(ctx);
}

void ModuleBrowser::onHoverKey(const event::HoverKey &e) {


+ 24
- 24
src/app/ModuleWidget.cpp View File

@@ -136,57 +136,57 @@ ModuleWidget::~ModuleWidget() {
setModule(NULL);
}

void ModuleWidget::draw(NVGcontext *vg) {
void ModuleWidget::draw(const DrawContext &ctx) {
if (module && module->bypass) {
nvgGlobalAlpha(vg, 0.5);
nvgGlobalAlpha(ctx.vg, 0.5);
}
// nvgScissor(vg, 0, 0, box.size.x, box.size.y);
Widget::draw(vg);
// nvgScissor(ctx.vg, 0, 0, box.size.x, box.size.y);
Widget::draw(ctx);

// Power meter
if (module && settings::powerMeter) {
nvgBeginPath(vg);
nvgRect(vg,
nvgBeginPath(ctx.vg);
nvgRect(ctx.vg,
0, box.size.y - 20,
65, 20);
nvgFillColor(vg, nvgRGBAf(0, 0, 0, 0.75));
nvgFill(vg);
nvgFillColor(ctx.vg, nvgRGBAf(0, 0, 0, 0.75));
nvgFill(ctx.vg);

std::string cpuText = string::f("%.2f ÎĽs", module->cpuTime * 1e6f);
bndLabel(vg, 2.0, box.size.y - 20.0, INFINITY, INFINITY, -1, cpuText.c_str());
bndLabel(ctx.vg, 2.0, box.size.y - 20.0, INFINITY, INFINITY, -1, cpuText.c_str());

float p = math::clamp(module->cpuTime / app()->engine->getSampleTime(), 0.f, 1.f);
nvgBeginPath(vg);
nvgRect(vg,
nvgBeginPath(ctx.vg);
nvgRect(ctx.vg,
0, (1.f - p) * box.size.y,
5, p * box.size.y);
nvgFillColor(vg, nvgRGBAf(1, 0, 0, 1.0));
nvgFill(vg);
nvgFillColor(ctx.vg, nvgRGBAf(1, 0, 0, 1.0));
nvgFill(ctx.vg);
}

// if (module) {
// nvgBeginPath(vg);
// nvgRect(vg, 0, 0, 20, 20);
// nvgFillColor(vg, nvgRGBAf(0, 0, 0, 0.75));
// nvgFill(vg);
// nvgBeginPath(ctx.vg);
// nvgRect(ctx.vg, 0, 0, 20, 20);
// nvgFillColor(ctx.vg, nvgRGBAf(0, 0, 0, 0.75));
// nvgFill(ctx.vg);

// std::string debugText = string::f("%d", module->id);
// bndLabel(vg, 0, 0, INFINITY, INFINITY, -1, debugText.c_str());
// bndLabel(ctx.vg, 0, 0, INFINITY, INFINITY, -1, debugText.c_str());
// }

// nvgResetScissor(vg);
// nvgResetScissor(ctx.vg);
}

void ModuleWidget::drawShadow(NVGcontext *vg) {
nvgBeginPath(vg);
void ModuleWidget::drawShadow(const DrawContext &ctx) {
nvgBeginPath(ctx.vg);
float r = 20; // Blur radius
float c = 20; // Corner radius
math::Vec b = math::Vec(-10, 30); // Offset from each corner
nvgRect(vg, b.x - r, b.y - r, box.size.x - 2*b.x + 2*r, box.size.y - 2*b.y + 2*r);
nvgRect(ctx.vg, b.x - r, b.y - r, box.size.x - 2*b.x + 2*r, box.size.y - 2*b.y + 2*r);
NVGcolor shadowColor = nvgRGBAf(0, 0, 0, 0.2);
NVGcolor transparentColor = nvgRGBAf(0, 0, 0, 0);
nvgFillPaint(vg, nvgBoxGradient(vg, b.x, b.y, box.size.x - 2*b.x, box.size.y - 2*b.y, c, r, shadowColor, transparentColor));
nvgFill(vg);
nvgFillPaint(ctx.vg, nvgBoxGradient(ctx.vg, b.x, b.y, box.size.x - 2*b.x, box.size.y - 2*b.y, c, r, shadowColor, transparentColor));
nvgFill(ctx.vg);
}

void ModuleWidget::onHover(const event::Hover &e) {


+ 7
- 7
src/app/ParamWidget.cpp View File

@@ -125,19 +125,19 @@ void ParamWidget::step() {
OpaqueWidget::step();
}

void ParamWidget::draw(NVGcontext *vg) {
Widget::draw(vg);
void ParamWidget::draw(const DrawContext &ctx) {
Widget::draw(ctx);

// if (paramQuantity) {
// nvgBeginPath(vg);
// nvgRect(vg,
// nvgBeginPath(ctx.vg);
// nvgRect(ctx.vg,
// box.size.x - 12, box.size.y - 12,
// 12, 12);
// nvgFillColor(vg, nvgRGBAf(1, 0, 1, 0.9));
// nvgFill(vg);
// nvgFillColor(ctx.vg, nvgRGBAf(1, 0, 1, 0.9));
// nvgFill(ctx.vg);

// std::string mapText = string::f("%d", paramQuantity->paramId);
// bndLabel(vg, box.size.x - 17.0, box.size.y - 16.0, INFINITY, INFINITY, -1, mapText.c_str());
// bndLabel(ctx.vg, box.size.x - 17.0, box.size.y - 16.0, INFINITY, INFINITY, -1, mapText.c_str());
// }
}



+ 3
- 3
src/app/PortWidget.cpp View File

@@ -51,14 +51,14 @@ void PortWidget::step() {
plugLight->setBrightnesses(values);
}

void PortWidget::draw(NVGcontext *vg) {
void PortWidget::draw(const DrawContext &ctx) {
CableWidget *cw = app()->scene->rackWidget->incompleteCable;
if (cw) {
// Dim the PortWidget if the active cable cannot plug into this PortWidget
if (type == OUTPUT ? cw->outputPort : cw->inputPort)
nvgGlobalAlpha(vg, 0.5);
nvgGlobalAlpha(ctx.vg, 0.5);
}
Widget::draw(vg);
Widget::draw(ctx);
}

void PortWidget::onButton(const event::Button &e) {


+ 30
- 30
src/app/RackRail.cpp View File

@@ -3,57 +3,57 @@

namespace rack {

void RackRail::draw(NVGcontext *vg) {
void RackRail::draw(const DrawContext &ctx) {
const float railHeight = RACK_GRID_WIDTH;

// Background color
nvgBeginPath(vg);
nvgRect(vg, 0.0, 0.0, box.size.x, box.size.y);
nvgFillColor(vg, nvgRGBf(0.2, 0.2, 0.2));
nvgFill(vg);
nvgBeginPath(ctx.vg);
nvgRect(ctx.vg, 0.0, 0.0, box.size.x, box.size.y);
nvgFillColor(ctx.vg, nvgRGBf(0.2, 0.2, 0.2));
nvgFill(ctx.vg);

// Rails
nvgFillColor(vg, nvgRGBf(0.85, 0.85, 0.85));
nvgStrokeWidth(vg, 1.0);
nvgStrokeColor(vg, nvgRGBf(0.7, 0.7, 0.7));
nvgFillColor(ctx.vg, nvgRGBf(0.85, 0.85, 0.85));
nvgStrokeWidth(ctx.vg, 1.0);
nvgStrokeColor(ctx.vg, nvgRGBf(0.7, 0.7, 0.7));
float holeRadius = 3.5;
for (float railY = 0; railY < box.size.y; railY += RACK_GRID_HEIGHT) {
// Top rail
nvgBeginPath(vg);
nvgRect(vg, 0, railY, box.size.x, railHeight);
nvgBeginPath(ctx.vg);
nvgRect(ctx.vg, 0, railY, box.size.x, railHeight);
for (float railX = 0; railX < box.size.x; railX += RACK_GRID_WIDTH) {
nvgCircle(vg, railX + RACK_GRID_WIDTH / 2, railY + railHeight / 2, holeRadius);
nvgPathWinding(vg, NVG_HOLE);
nvgCircle(ctx.vg, railX + RACK_GRID_WIDTH / 2, railY + railHeight / 2, holeRadius);
nvgPathWinding(ctx.vg, NVG_HOLE);
}
nvgFill(vg);
nvgFill(ctx.vg);

nvgBeginPath(vg);
nvgMoveTo(vg, 0, railY + railHeight - 0.5);
nvgLineTo(vg, box.size.x, railY + railHeight - 0.5);
nvgStroke(vg);
nvgBeginPath(ctx.vg);
nvgMoveTo(ctx.vg, 0, railY + railHeight - 0.5);
nvgLineTo(ctx.vg, box.size.x, railY + railHeight - 0.5);
nvgStroke(ctx.vg);

// Bottom rail
nvgBeginPath(vg);
nvgRect(vg, 0, railY + RACK_GRID_HEIGHT - railHeight, box.size.x, railHeight);
nvgBeginPath(ctx.vg);
nvgRect(ctx.vg, 0, railY + RACK_GRID_HEIGHT - railHeight, box.size.x, railHeight);
for (float railX = 0; railX < box.size.x; railX += RACK_GRID_WIDTH) {
nvgCircle(vg, railX + RACK_GRID_WIDTH / 2, railY + RACK_GRID_HEIGHT - railHeight + railHeight / 2, holeRadius);
nvgPathWinding(vg, NVG_HOLE);
nvgCircle(ctx.vg, railX + RACK_GRID_WIDTH / 2, railY + RACK_GRID_HEIGHT - railHeight + railHeight / 2, holeRadius);
nvgPathWinding(ctx.vg, NVG_HOLE);
}
nvgFill(vg);
nvgFill(ctx.vg);

nvgBeginPath(vg);
nvgMoveTo(vg, 0, railY + RACK_GRID_HEIGHT - 0.5);
nvgLineTo(vg, box.size.x, railY + RACK_GRID_HEIGHT - 0.5);
nvgStroke(vg);
nvgBeginPath(ctx.vg);
nvgMoveTo(ctx.vg, 0, railY + RACK_GRID_HEIGHT - 0.5);
nvgLineTo(ctx.vg, box.size.x, railY + RACK_GRID_HEIGHT - 0.5);
nvgStroke(ctx.vg);
}


// Useful for screenshots
if (0) {
nvgBeginPath(vg);
nvgRect(vg, 0.0, 0.0, box.size.x, box.size.y);
nvgFillColor(vg, nvgRGBf(1.0, 1.0, 1.0));
nvgFill(vg);
nvgBeginPath(ctx.vg);
nvgRect(ctx.vg, 0.0, 0.0, box.size.x, box.size.y);
nvgFillColor(ctx.vg, nvgRGBf(1.0, 1.0, 1.0));
nvgFill(ctx.vg);
}
}



+ 4
- 4
src/app/RackScrollWidget.cpp View File

@@ -27,20 +27,20 @@ void RackScrollWidget::step() {
}


void RackScrollWidget::draw(NVGcontext *vg) {
ScrollWidget::draw(vg);
void RackScrollWidget::draw(const DrawContext &ctx) {
ScrollWidget::draw(ctx);

if (app()->scene->rackWidget->isEmpty()) {
math::Rect b;
b.size = math::Vec(600, 300);
b.pos = box.size.minus(b.size).div(2);
NVGcolor bg = nvgRGBAf(0, 0, 0, 0.4);
bndInnerBox(vg, b.pos.x, b.pos.y, b.size.x, b.size.y,
bndInnerBox(ctx.vg, b.pos.x, b.pos.y, b.size.x, b.size.y,
0, 0, 0, 0, bg, bg);

NVGcolor fg = nvgRGBAf(1, 1, 1, 0.25);
std::string text = "Right-click or press Enter to add modules";
bndIconLabelValue(vg, b.pos.x, b.pos.y + 80, b.size.x, b.size.y, -1, fg, BND_CENTER, 80, text.c_str(), NULL);
bndIconLabelValue(ctx.vg, b.pos.x, b.pos.y + 80, b.size.x, b.size.y, -1, fg, BND_CENTER, 80, text.c_str(), NULL);
}
}



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

@@ -42,32 +42,32 @@ static ModuleWidget *moduleFromJson(json_t *moduleJ) {


struct ModuleContainer : Widget {
void draw(NVGcontext *vg) override {
void draw(const DrawContext &ctx) override {
// Draw shadows behind each ModuleWidget first, so the shadow doesn't overlap the front of other ModuleWidgets.
for (Widget *child : children) {
ModuleWidget *w = dynamic_cast<ModuleWidget*>(child);
assert(w);

nvgSave(vg);
nvgTranslate(vg, child->box.pos.x, child->box.pos.y);
w->drawShadow(vg);
nvgRestore(vg);
nvgSave(ctx.vg);
nvgTranslate(ctx.vg, child->box.pos.x, child->box.pos.y);
w->drawShadow(ctx);
nvgRestore(ctx.vg);
}

Widget::draw(vg);
Widget::draw(ctx);
}
};


struct CableContainer : TransparentWidget {
void draw(NVGcontext *vg) override {
Widget::draw(vg);
void draw(const DrawContext &ctx) override {
Widget::draw(ctx);

// Draw cable plugs
for (Widget *w : children) {
CableWidget *cw = dynamic_cast<CableWidget*>(w);
assert(cw);
cw->drawPlugs(vg);
cw->drawPlugs(ctx);
}
}
};
@@ -116,8 +116,8 @@ void RackWidget::step() {
Widget::step();
}

void RackWidget::draw(NVGcontext *vg) {
Widget::draw(vg);
void RackWidget::draw(const DrawContext &ctx) {
Widget::draw(ctx);
}

void RackWidget::onHover(const event::Hover &e) {


+ 6
- 6
src/app/SVGPanel.cpp View File

@@ -4,13 +4,13 @@
namespace rack {


void PanelBorder::draw(NVGcontext *vg) {
void PanelBorder::draw(const DrawContext &ctx) {
NVGcolor borderColor = nvgRGBAf(0.5, 0.5, 0.5, 0.5);
nvgBeginPath(vg);
nvgRect(vg, 0.5, 0.5, box.size.x - 1.0, box.size.y - 1.0);
nvgStrokeColor(vg, borderColor);
nvgStrokeWidth(vg, 1.0);
nvgStroke(vg);
nvgBeginPath(ctx.vg);
nvgRect(ctx.vg, 0.5, 0.5, box.size.x - 1.0, box.size.y - 1.0);
nvgStrokeColor(ctx.vg, borderColor);
nvgStrokeWidth(ctx.vg, 1.0);
nvgStroke(ctx.vg);
}




+ 2
- 2
src/app/Scene.cpp View File

@@ -85,8 +85,8 @@ void Scene::step() {
}
}

void Scene::draw(NVGcontext *vg) {
OpaqueWidget::draw(vg);
void Scene::draw(const DrawContext &ctx) {
OpaqueWidget::draw(ctx);
}

void Scene::onHoverKey(const event::HoverKey &e) {


+ 14
- 14
src/app/Toolbar.cpp View File

@@ -26,8 +26,8 @@ struct MenuButton : Button {
box.size.x = bndLabelWidth(app()->window->vg, -1, text.c_str());
Widget::step();
}
void draw(NVGcontext *vg) override {
bndMenuItem(vg, 0.0, 0.0, box.size.x, box.size.y, state, -1, text.c_str());
void draw(const DrawContext &ctx) override {
bndMenuItem(ctx.vg, 0.0, 0.0, box.size.x, box.size.y, state, -1, text.c_str());
}
};

@@ -570,16 +570,16 @@ struct PluginsButton : MenuButton {
}
}

void draw(NVGcontext *vg) override {
MenuButton::draw(vg);
void draw(const DrawContext &ctx) override {
MenuButton::draw(ctx);
// if (1) {
// // Notification circle
// nvgBeginPath(vg);
// nvgCircle(vg, box.size.x - 3, 3, 4.0);
// nvgFillColor(vg, nvgRGBf(1.0, 0.0, 0.0));
// nvgFill(vg);
// nvgStrokeColor(vg, nvgRGBf(0.5, 0.0, 0.0));
// nvgStroke(vg);
// nvgBeginPath(ctx.vg);
// nvgCircle(ctx.vg, box.size.x - 3, 3, 4.0);
// nvgFillColor(ctx.vg, nvgRGBf(1.0, 0.0, 0.0));
// nvgFill(ctx.vg);
// nvgStrokeColor(ctx.vg, nvgRGBf(0.5, 0.0, 0.0));
// nvgStroke(ctx.vg);
// }
}
};
@@ -664,11 +664,11 @@ Toolbar::Toolbar() {
layout->addChild(helpButton);
}

void Toolbar::draw(NVGcontext *vg) {
bndMenuBackground(vg, 0.0, 0.0, box.size.x, box.size.y, BND_CORNER_ALL);
bndBevel(vg, 0.0, 0.0, box.size.x, box.size.y);
void Toolbar::draw(const DrawContext &ctx) {
bndMenuBackground(ctx.vg, 0.0, 0.0, box.size.x, box.size.y, BND_CORNER_ALL);
bndBevel(ctx.vg, 0.0, 0.0, box.size.x, box.size.y);

Widget::draw(vg);
Widget::draw(ctx);
}




+ 2
- 2
src/ui/Button.cpp View File

@@ -13,8 +13,8 @@ Button::~Button() {
delete quantity;
}

void Button::draw(NVGcontext *vg) {
bndToolButton(vg, 0.0, 0.0, box.size.x, box.size.y, BND_CORNER_NONE, state, -1, text.c_str());
void Button::draw(const DrawContext &ctx) {
bndToolButton(ctx.vg, 0.0, 0.0, box.size.x, box.size.y, BND_CORNER_NONE, state, -1, text.c_str());
}

void Button::onEnter(const event::Enter &e) {


+ 2
- 2
src/ui/ChoiceButton.cpp View File

@@ -4,8 +4,8 @@
namespace rack {


void ChoiceButton::draw(NVGcontext *vg) {
bndChoiceButton(vg, 0.0, 0.0, box.size.x, box.size.y, BND_CORNER_NONE, state, -1, text.c_str());
void ChoiceButton::draw(const DrawContext &ctx) {
bndChoiceButton(ctx.vg, 0.0, 0.0, box.size.x, box.size.y, BND_CORNER_NONE, state, -1, text.c_str());
}




+ 4
- 4
src/ui/Label.cpp View File

@@ -10,7 +10,7 @@ Label::Label() {
color = bndGetTheme()->regularTheme.textColor;
}

void Label::draw(NVGcontext *vg) {
void Label::draw(const DrawContext &ctx) {
// TODO
// Custom font sizes do not work with right or center alignment
float x;
@@ -20,14 +20,14 @@ void Label::draw(NVGcontext *vg) {
x = 0.0;
} break;
case RIGHT_ALIGNMENT: {
x = box.size.x - bndLabelWidth(vg, -1, text.c_str());
x = box.size.x - bndLabelWidth(ctx.vg, -1, text.c_str());
} break;
case CENTER_ALIGNMENT: {
x = (box.size.x - bndLabelWidth(vg, -1, text.c_str())) / 2.0;
x = (box.size.x - bndLabelWidth(ctx.vg, -1, text.c_str())) / 2.0;
} break;
}

bndIconLabelValue(vg, x, 0.0, box.size.x, box.size.y, -1, color, BND_LEFT, fontSize, text.c_str(), NULL);
bndIconLabelValue(ctx.vg, x, 0.0, box.size.x, box.size.y, -1, color, BND_LEFT, fontSize, text.c_str(), NULL);
}




+ 3
- 3
src/ui/Menu.cpp View File

@@ -48,9 +48,9 @@ void Menu::step() {
}
}

void Menu::draw(NVGcontext *vg) {
bndMenuBackground(vg, 0.0, 0.0, box.size.x, box.size.y, BND_CORNER_NONE);
Widget::draw(vg);
void Menu::draw(const DrawContext &ctx) {
bndMenuBackground(ctx.vg, 0.0, 0.0, box.size.x, box.size.y, BND_CORNER_NONE);
Widget::draw(ctx);
}

void Menu::onHoverScroll(const event::HoverScroll &e) {


+ 5
- 5
src/ui/MenuItem.cpp View File

@@ -4,7 +4,7 @@
namespace rack {


void MenuItem::draw(NVGcontext *vg) {
void MenuItem::draw(const DrawContext &ctx) {
BNDwidgetState state = BND_DEFAULT;

if (app()->event->hoveredWidget == this)
@@ -17,14 +17,14 @@ void MenuItem::draw(NVGcontext *vg) {

// Main text and background
if (!disabled)
bndMenuItem(vg, 0.0, 0.0, box.size.x, box.size.y, state, -1, text.c_str());
bndMenuItem(ctx.vg, 0.0, 0.0, box.size.x, box.size.y, state, -1, text.c_str());
else
bndMenuLabel(vg, 0.0, 0.0, box.size.x, box.size.y, -1, text.c_str());
bndMenuLabel(ctx.vg, 0.0, 0.0, box.size.x, box.size.y, -1, text.c_str());

// Right text
float x = box.size.x - bndLabelWidth(vg, -1, rightText.c_str());
float x = box.size.x - bndLabelWidth(ctx.vg, -1, rightText.c_str());
NVGcolor rightColor = (state == BND_DEFAULT && !disabled) ? bndGetTheme()->menuTheme.textColor : bndGetTheme()->menuTheme.textSelectedColor;
bndIconLabelValue(vg, x, 0.0, box.size.x, box.size.y, -1, rightColor, BND_LEFT, BND_LABEL_FONT_SIZE, rightText.c_str(), NULL);
bndIconLabelValue(ctx.vg, x, 0.0, box.size.x, box.size.y, -1, rightColor, BND_LEFT, BND_LABEL_FONT_SIZE, rightText.c_str(), NULL);
}

void MenuItem::step() {


+ 2
- 2
src/ui/MenuLabel.cpp View File

@@ -5,8 +5,8 @@
namespace rack {


void MenuLabel::draw(NVGcontext *vg) {
bndMenuLabel(vg, 0.0, 0.0, box.size.x, box.size.y, -1, text.c_str());
void MenuLabel::draw(const DrawContext &ctx) {
bndMenuLabel(ctx.vg, 0.0, 0.0, box.size.x, box.size.y, -1, text.c_str());
}

void MenuLabel::step() {


+ 7
- 7
src/ui/MenuSeparator.cpp View File

@@ -8,14 +8,14 @@ MenuSeparator::MenuSeparator() {
box.size.y = BND_WIDGET_HEIGHT / 2;
}

void MenuSeparator::draw(NVGcontext *vg) {
nvgBeginPath(vg);
void MenuSeparator::draw(const DrawContext &ctx) {
nvgBeginPath(ctx.vg);
const float margin = 8.0;
nvgMoveTo(vg, margin, box.size.y / 2.0);
nvgLineTo(vg, box.size.x - margin, box.size.y / 2.0);
nvgStrokeWidth(vg, 1.0);
nvgStrokeColor(vg, color::alpha(bndGetTheme()->menuTheme.textColor, 0.25));
nvgStroke(vg);
nvgMoveTo(ctx.vg, margin, box.size.y / 2.0);
nvgLineTo(ctx.vg, box.size.x - margin, box.size.y / 2.0);
nvgStrokeWidth(ctx.vg, 1.0);
nvgStrokeColor(ctx.vg, color::alpha(bndGetTheme()->menuTheme.textColor, 0.25));
nvgStroke(ctx.vg);
}




+ 2
- 2
src/ui/PasswordField.cpp View File

@@ -4,10 +4,10 @@
namespace rack {


void PasswordField::draw(NVGcontext *vg) {
void PasswordField::draw(const DrawContext &ctx) {
std::string textTmp = text;
text = std::string(textTmp.size(), '*');
TextField::draw(vg);
TextField::draw(ctx);
text = textTmp;
}



+ 2
- 2
src/ui/ProgressBar.cpp View File

@@ -13,10 +13,10 @@ ProgressBar::~ProgressBar() {
delete quantity;
}

void ProgressBar::draw(NVGcontext *vg) {
void ProgressBar::draw(const DrawContext &ctx) {
float progress = quantity ? quantity->getScaledValue() : 0.f;
std::string text = quantity ? quantity->getString() : "";
bndSlider(vg, 0.0, 0.0, box.size.x, box.size.y, BND_CORNER_ALL, BND_DEFAULT, progress, text.c_str(), NULL);
bndSlider(ctx.vg, 0.0, 0.0, box.size.x, box.size.y, BND_CORNER_ALL, BND_DEFAULT, progress, text.c_str(), NULL);
}




+ 2
- 2
src/ui/RadioButton.cpp View File

@@ -13,11 +13,11 @@ RadioButton::~RadioButton() {
delete quantity;
}

void RadioButton::draw(NVGcontext *vg) {
void RadioButton::draw(const DrawContext &ctx) {
std::string label;
if (quantity)
label = quantity->getLabel();
bndRadioButton(vg, 0.0, 0.0, box.size.x, box.size.y, BND_CORNER_NONE, state, -1, label.c_str());
bndRadioButton(ctx.vg, 0.0, 0.0, box.size.x, box.size.y, BND_CORNER_NONE, state, -1, label.c_str());
}

void RadioButton::onEnter(const event::Enter &e) {


+ 2
- 2
src/ui/ScrollBar.cpp View File

@@ -14,8 +14,8 @@ ScrollBar::ScrollBar() {
box.size = math::Vec(BND_SCROLLBAR_WIDTH, BND_SCROLLBAR_HEIGHT);
}

void ScrollBar::draw(NVGcontext *vg) {
bndScrollBar(vg, 0.0, 0.0, box.size.x, box.size.y, state, offset, size);
void ScrollBar::draw(const DrawContext &ctx) {
bndScrollBar(ctx.vg, 0.0, 0.0, box.size.x, box.size.y, state, offset, size);
}

void ScrollBar::onDragStart(const event::DragStart &e) {


+ 4
- 4
src/ui/ScrollWidget.cpp View File

@@ -26,10 +26,10 @@ void ScrollWidget::scrollTo(math::Rect r) {
offset = offset.clampSafe(bound);
}

void ScrollWidget::draw(NVGcontext *vg) {
nvgScissor(vg, 0, 0, box.size.x, box.size.y);
Widget::draw(vg);
nvgResetScissor(vg);
void ScrollWidget::draw(const DrawContext &ctx) {
nvgScissor(ctx.vg, 0, 0, box.size.x, box.size.y);
Widget::draw(ctx);
nvgResetScissor(ctx.vg);
}

void ScrollWidget::step() {


+ 2
- 2
src/ui/Slider.cpp View File

@@ -16,10 +16,10 @@ Slider::~Slider() {
delete quantity;
}

void Slider::draw(NVGcontext *vg) {
void Slider::draw(const DrawContext &ctx) {
float progress = quantity ? quantity->getScaledValue() : 0.f;
std::string text = quantity ? quantity->getString() : "";
bndSlider(vg, 0.0, 0.0, box.size.x, box.size.y, BND_CORNER_NONE, state, progress, text.c_str(), NULL);
bndSlider(ctx.vg, 0.0, 0.0, box.size.x, box.size.y, BND_CORNER_NONE, state, progress, text.c_str(), NULL);
}

void Slider::onDragStart(const event::DragStart &e) {


+ 5
- 5
src/ui/TextField.cpp View File

@@ -7,8 +7,8 @@ TextField::TextField() {
box.size.y = BND_WIDGET_HEIGHT;
}

void TextField::draw(NVGcontext *vg) {
nvgScissor(vg, 0, 0, box.size.x, box.size.y);
void TextField::draw(const DrawContext &ctx) {
nvgScissor(ctx.vg, 0, 0, box.size.x, box.size.y);

BNDwidgetState state;
if (this == app()->event->selectedWidget)
@@ -20,13 +20,13 @@ void TextField::draw(NVGcontext *vg) {

int begin = std::min(cursor, selection);
int end = std::max(cursor, selection);
bndTextField(vg, 0.0, 0.0, box.size.x, box.size.y, BND_CORNER_NONE, state, -1, text.c_str(), begin, end);
bndTextField(ctx.vg, 0.0, 0.0, box.size.x, box.size.y, BND_CORNER_NONE, state, -1, text.c_str(), begin, end);
// Draw placeholder text
if (text.empty() && state != BND_ACTIVE) {
bndIconLabelCaret(vg, 0.0, 0.0, box.size.x, box.size.y, -1, bndGetTheme()->textFieldTheme.itemColor, 13, placeholder.c_str(), bndGetTheme()->textFieldTheme.itemColor, 0, -1);
bndIconLabelCaret(ctx.vg, 0.0, 0.0, box.size.x, box.size.y, -1, bndGetTheme()->textFieldTheme.itemColor, 13, placeholder.c_str(), bndGetTheme()->textFieldTheme.itemColor, 0, -1);
}

nvgResetScissor(vg);
nvgResetScissor(ctx.vg);
}

void TextField::onButton(const event::Button &e) {


+ 4
- 4
src/ui/Tooltip.cpp View File

@@ -13,10 +13,10 @@ void Tooltip::step() {
Widget::step();
}

void Tooltip::draw(NVGcontext *vg) {
bndTooltipBackground(vg, 0.0, 0.0, box.size.x, box.size.y);
bndMenuLabel(vg, 0.0, 0.0, box.size.x, box.size.y, -1, text.c_str());
Widget::draw(vg);
void Tooltip::draw(const DrawContext &ctx) {
bndTooltipBackground(ctx.vg, 0.0, 0.0, box.size.x, box.size.y);
bndMenuLabel(ctx.vg, 0.0, 0.0, box.size.x, box.size.y, -1, text.c_str());
Widget::draw(ctx);
}




+ 19
- 17
src/widgets/FramebufferWidget.cpp View File

@@ -14,17 +14,17 @@ FramebufferWidget::~FramebufferWidget() {
nvgluDeleteFramebuffer(fb);
}

void FramebufferWidget::draw(NVGcontext *vg) {
void FramebufferWidget::draw(const DrawContext &ctx) {
// Bypass framebuffer rendering if we're already drawing in a framebuffer
// In other words, disallow nested framebuffers. They look bad.
if (vg == app()->window->fbVg) {
Widget::draw(vg);
if (ctx.vg == app()->window->fbVg) {
Widget::draw(ctx);
return;
}

// Get world transform
float xform[6];
nvgCurrentTransform(vg, xform);
nvgCurrentTransform(ctx.vg, xform);
// Skew and rotate is not supported
assert(math::isNear(xform[1], 0.f));
assert(math::isNear(xform[2], 0.f));
@@ -65,7 +65,7 @@ void FramebufferWidget::draw(NVGcontext *vg) {
nvgluDeleteFramebuffer(fb);
// Create a framebuffer from the main nanovg context. We will draw to this in the secondary nanovg context.
if (fbSize.isFinite() && !fbSize.isZero())
fb = nvgluCreateFramebuffer(vg, fbSize.x, fbSize.y, 0);
fb = nvgluCreateFramebuffer(ctx.vg, fbSize.x, fbSize.y, 0);
}

if (!fb)
@@ -80,28 +80,28 @@ void FramebufferWidget::draw(NVGcontext *vg) {
return;

// Draw framebuffer image, using world coordinates
nvgSave(vg);
nvgResetTransform(vg);
nvgSave(ctx.vg);
nvgResetTransform(ctx.vg);

nvgBeginPath(vg);
nvgRect(vg,
nvgBeginPath(ctx.vg);
nvgRect(ctx.vg,
offsetI.x + fbBox.pos.x,
offsetI.y + fbBox.pos.y,
fbBox.size.x, fbBox.size.y);
NVGpaint paint = nvgImagePattern(vg,
NVGpaint paint = nvgImagePattern(ctx.vg,
offsetI.x + fbBox.pos.x,
offsetI.y + fbBox.pos.y,
fbBox.size.x, fbBox.size.y,
0.0, fb->image, 1.0);
nvgFillPaint(vg, paint);
nvgFill(vg);
nvgFillPaint(ctx.vg, paint);
nvgFill(ctx.vg);

// For debugging the bounding box of the framebuffer
// nvgStrokeWidth(vg, 2.0);
// nvgStrokeColor(vg, nvgRGBAf(1, 1, 0, 0.5));
// nvgStroke(vg);
// nvgStrokeWidth(ctx.vg, 2.0);
// nvgStrokeColor(ctx.vg, nvgRGBAf(1, 1, 0, 0.5));
// nvgStroke(ctx.vg);

nvgRestore(vg);
nvgRestore(ctx.vg);
}

void FramebufferWidget::drawFramebuffer() {
@@ -115,7 +115,9 @@ void FramebufferWidget::drawFramebuffer() {
nvgTranslate(vg, fbOffset.x, fbOffset.y);
nvgScale(vg, fbScale.x, fbScale.y);

Widget::draw(vg);
DrawContext ctx;
ctx.vg = vg;
Widget::draw(ctx);

glViewport(0.0, 0.0, fbSize.x, fbSize.y);
glClearColor(0.0, 0.0, 0.0, 0.0);


+ 16
- 9
src/widgets/Widget.cpp View File

@@ -93,7 +93,7 @@ void Widget::step() {
}
}

void Widget::draw(NVGcontext *vg) {
void Widget::draw(const DrawContext &ctx) {
for (Widget *child : children) {
// Don't draw if invisible
if (!child->visible)
@@ -102,19 +102,26 @@ void Widget::draw(NVGcontext *vg) {
if (!box.zeroPos().intersects(child->box))
continue;

nvgSave(vg);
nvgTranslate(vg, child->box.pos.x, child->box.pos.y);
child->draw(vg);
nvgSave(ctx.vg);
nvgTranslate(ctx.vg, child->box.pos.x, child->box.pos.y);

DrawContext childCtx = ctx;
child->draw(childCtx);

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
child->draw(ctx.vg);
#pragma GCC diagnostic pop

// Draw red hitboxes
// if (app()->event->hoveredWidget == child) {
// nvgBeginPath(vg);
// nvgRect(vg, 0, 0, child->box.size.x, child->box.size.y);
// nvgFillColor(vg, nvgRGBAf(1, 0, 0, 0.5));
// nvgFill(vg);
// nvgBeginPath(ctx.vg);
// nvgRect(ctx.vg, 0, 0, child->box.size.x, child->box.size.y);
// nvgFillColor(ctx.vg, nvgRGBAf(1, 0, 0, 0.5));
// nvgFill(ctx.vg);
// }

nvgRestore(vg);
nvgRestore(ctx.vg);
}
}



+ 3
- 3
src/widgets/ZoomWidget.cpp View File

@@ -28,10 +28,10 @@ void ZoomWidget::setZoom(float zoom) {
Widget::onZoom(eZoom);
}

void ZoomWidget::draw(NVGcontext *vg) {
void ZoomWidget::draw(const DrawContext &ctx) {
// No need to save the state because that is done in the parent
nvgScale(vg, zoom, zoom);
Widget::draw(vg);
nvgScale(ctx.vg, zoom, zoom);
Widget::draw(ctx);
}




+ 3
- 1
src/window.cpp View File

@@ -359,7 +359,9 @@ void Window::run() {
// nvgReset(vg);
// nvgScale(vg, pixelRatio, pixelRatio);

app()->event->rootWidget->draw(vg);
DrawContext ctx;
ctx.vg = vg;
app()->event->rootWidget->draw(ctx);

glViewport(0, 0, fbWidth, fbHeight);
glClearColor(0.0, 0.0, 0.0, 1.0);


Loading…
Cancel
Save