From 940b232d662c74bbfe6a6b6dda71533ff514bad6 Mon Sep 17 00:00:00 2001 From: Andrew Belt Date: Sun, 4 Mar 2018 07:18:27 -0500 Subject: [PATCH] Add VirtualWidget, add SequentialLayout --- include/app.hpp | 4 ++-- include/ui.hpp | 38 +++++++++++++++++++++++++++++++------- include/widgets.hpp | 24 +++++++++++++++--------- src/app/ModuleBrowser.cpp | 2 +- src/ui/Label.cpp | 4 ++-- src/ui/layouts.cpp | 39 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 90 insertions(+), 21 deletions(-) create mode 100644 src/ui/layouts.cpp diff --git a/include/app.hpp b/include/app.hpp index 48e3ab7c..3fae0af5 100644 --- a/include/app.hpp +++ b/include/app.hpp @@ -322,7 +322,7 @@ struct MomentarySwitch : virtual Switch { // IO widgets //////////////////// -struct LedDisplay : Widget { +struct LedDisplay : VirtualWidget { void draw(NVGcontext *vg) override; }; @@ -484,7 +484,7 @@ struct Toolbar : OpaqueWidget { void draw(NVGcontext *vg) override; }; -struct PluginManagerWidget : Widget { +struct PluginManagerWidget : VirtualWidget { Widget *loginWidget; Widget *manageWidget; Widget *downloadWidget; diff --git a/include/ui.hpp b/include/ui.hpp index 8476e4b8..5d4c8061 100644 --- a/include/ui.hpp +++ b/include/ui.hpp @@ -5,15 +5,39 @@ namespace rack { +//////////////////// +// Layouts +//////////////////// + +/** Positions children in a row/column based on their widths/heights */ +struct SequentialLayout : virtual Widget { + enum Orientation { + HORIZONTAL_ORIENTATION, + VERTICAL_ORIENTATION, + }; + Orientation orientation = HORIZONTAL_ORIENTATION; + enum Alignment { + LEFT_ALIGNMENT, + CENTER_ALIGNMENT, + RIGHT_ALIGNMENT, + }; + Alignment alignment = LEFT_ALIGNMENT; + float margin = 0.0; + void step() override; +}; + +//////////////////// +// Blendish UI elements +//////////////////// -struct Label : Widget { +struct Label : VirtualWidget { std::string text; - enum Align { - LEFT_ALIGN, - CENTER_ALIGN, - RIGHT_ALIGN + enum Alignment { + LEFT_ALIGNMENT, + CENTER_ALIGNMENT, + RIGHT_ALIGNMENT, }; - Align align = LEFT_ALIGN; + Alignment alignment = LEFT_ALIGNMENT; Label() { box.size.y = BND_WIDGET_HEIGHT; } @@ -200,7 +224,7 @@ struct ProgressBar : QuantityWidget { void draw(NVGcontext *vg) override; }; -struct Tooltip : Widget { +struct Tooltip : VirtualWidget { void step() override; void draw(NVGcontext *vg) override; }; diff --git a/include/widgets.hpp b/include/widgets.hpp index 6fd6fd18..0cc73451 100644 --- a/include/widgets.hpp +++ b/include/widgets.hpp @@ -44,7 +44,9 @@ struct SVG { // Base widget //////////////////// -/** A node in the 2D scene graph */ +/** A node in the 2D scene graph +Never inherit from Widget directly. Instead, inherit from VirtualWidget declared below. +*/ struct Widget { /** Stores position and size */ Rect box = Rect(Vec(), Vec(INFINITY, INFINITY)); @@ -152,7 +154,11 @@ struct Widget { } }; -struct TransformWidget : Widget { +/** Instead of inheriting from Widget directly, inherit from VirtualWidget to guarantee that only one copy of Widget's member variables are used by each instance of the Widget hierarchy. +*/ +struct VirtualWidget : virtual Widget {}; + +struct TransformWidget : VirtualWidget { /** The transformation matrix */ float transform[6]; TransformWidget(); @@ -164,7 +170,7 @@ struct TransformWidget : Widget { void draw(NVGcontext *vg) override; }; -struct ZoomWidget : Widget { +struct ZoomWidget : VirtualWidget { float zoom = 1.0; Vec getRelativeOffset(Vec v, Widget *relative) override; Rect getViewport(Rect r) override; @@ -183,7 +189,7 @@ struct ZoomWidget : Widget { //////////////////// /** Widget that does not respond to events */ -struct TransparentWidget : virtual Widget { +struct TransparentWidget : VirtualWidget { void onMouseDown(EventMouseDown &e) override {} void onMouseUp(EventMouseUp &e) override {} void onMouseMove(EventMouseMove &e) override {} @@ -191,7 +197,7 @@ struct TransparentWidget : virtual Widget { }; /** Widget that automatically responds to all mouse events but gives a chance for children to respond instead */ -struct OpaqueWidget : virtual Widget { +struct OpaqueWidget : VirtualWidget { void onMouseDown(EventMouseDown &e) override { Widget::onMouseDown(e); if (!e.target) @@ -216,7 +222,7 @@ struct OpaqueWidget : virtual Widget { } }; -struct SpriteWidget : virtual Widget { +struct SpriteWidget : VirtualWidget { Vec spriteOffset; Vec spriteSize; std::shared_ptr spriteImage; @@ -224,7 +230,7 @@ struct SpriteWidget : virtual Widget { void draw(NVGcontext *vg) override; }; -struct SVGWidget : virtual Widget { +struct SVGWidget : VirtualWidget { std::shared_ptr svg; /** Sets the box size to the svg image size */ void wrap(); @@ -237,7 +243,7 @@ struct SVGWidget : virtual Widget { When `dirty` is true, its children will be re-rendered on the next call to step() override. Events are not passed to the underlying scene. */ -struct FramebufferWidget : virtual Widget { +struct FramebufferWidget : VirtualWidget { /** Set this to true to re-render the children to the framebuffer the next time it is drawn */ bool dirty = true; /** A margin in pixels around the children in the framebuffer @@ -258,7 +264,7 @@ struct FramebufferWidget : virtual Widget { }; /** A Widget representing a float value */ -struct QuantityWidget : virtual Widget { +struct QuantityWidget : VirtualWidget { float value = 0.0; float minValue = 0.0; float maxValue = 1.0; diff --git a/src/app/ModuleBrowser.cpp b/src/app/ModuleBrowser.cpp index b6d0b57d..579f1286 100644 --- a/src/app/ModuleBrowser.cpp +++ b/src/app/ModuleBrowser.cpp @@ -95,7 +95,7 @@ struct ModelItem : BrowserListItem { nameLabel = Widget::create