Browse Source

Add VirtualWidget, add SequentialLayout

tags/v0.6.0
Andrew Belt 6 years ago
parent
commit
940b232d66
6 changed files with 90 additions and 21 deletions
  1. +2
    -2
      include/app.hpp
  2. +31
    -7
      include/ui.hpp
  3. +15
    -9
      include/widgets.hpp
  4. +1
    -1
      src/app/ModuleBrowser.cpp
  5. +2
    -2
      src/ui/Label.cpp
  6. +39
    -0
      src/ui/layouts.cpp

+ 2
- 2
include/app.hpp View File

@@ -322,7 +322,7 @@ struct MomentarySwitch : virtual Switch {
// IO widgets // IO widgets
//////////////////// ////////////////////


struct LedDisplay : Widget {
struct LedDisplay : VirtualWidget {
void draw(NVGcontext *vg) override; void draw(NVGcontext *vg) override;
}; };


@@ -484,7 +484,7 @@ struct Toolbar : OpaqueWidget {
void draw(NVGcontext *vg) override; void draw(NVGcontext *vg) override;
}; };


struct PluginManagerWidget : Widget {
struct PluginManagerWidget : VirtualWidget {
Widget *loginWidget; Widget *loginWidget;
Widget *manageWidget; Widget *manageWidget;
Widget *downloadWidget; Widget *downloadWidget;


+ 31
- 7
include/ui.hpp View File

@@ -5,15 +5,39 @@


namespace rack { 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; 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() { Label() {
box.size.y = BND_WIDGET_HEIGHT; box.size.y = BND_WIDGET_HEIGHT;
} }
@@ -200,7 +224,7 @@ struct ProgressBar : QuantityWidget {
void draw(NVGcontext *vg) override; void draw(NVGcontext *vg) override;
}; };


struct Tooltip : Widget {
struct Tooltip : VirtualWidget {
void step() override; void step() override;
void draw(NVGcontext *vg) override; void draw(NVGcontext *vg) override;
}; };


+ 15
- 9
include/widgets.hpp View File

@@ -44,7 +44,9 @@ struct SVG {
// Base widget // 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 { struct Widget {
/** Stores position and size */ /** Stores position and size */
Rect box = Rect(Vec(), Vec(INFINITY, INFINITY)); 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 */ /** The transformation matrix */
float transform[6]; float transform[6];
TransformWidget(); TransformWidget();
@@ -164,7 +170,7 @@ struct TransformWidget : Widget {
void draw(NVGcontext *vg) override; void draw(NVGcontext *vg) override;
}; };


struct ZoomWidget : Widget {
struct ZoomWidget : VirtualWidget {
float zoom = 1.0; float zoom = 1.0;
Vec getRelativeOffset(Vec v, Widget *relative) override; Vec getRelativeOffset(Vec v, Widget *relative) override;
Rect getViewport(Rect r) override; Rect getViewport(Rect r) override;
@@ -183,7 +189,7 @@ struct ZoomWidget : Widget {
//////////////////// ////////////////////


/** Widget that does not respond to events */ /** Widget that does not respond to events */
struct TransparentWidget : virtual Widget {
struct TransparentWidget : VirtualWidget {
void onMouseDown(EventMouseDown &e) override {} void onMouseDown(EventMouseDown &e) override {}
void onMouseUp(EventMouseUp &e) override {} void onMouseUp(EventMouseUp &e) override {}
void onMouseMove(EventMouseMove &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 */ /** 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 { void onMouseDown(EventMouseDown &e) override {
Widget::onMouseDown(e); Widget::onMouseDown(e);
if (!e.target) if (!e.target)
@@ -216,7 +222,7 @@ struct OpaqueWidget : virtual Widget {
} }
}; };


struct SpriteWidget : virtual Widget {
struct SpriteWidget : VirtualWidget {
Vec spriteOffset; Vec spriteOffset;
Vec spriteSize; Vec spriteSize;
std::shared_ptr<Image> spriteImage; std::shared_ptr<Image> spriteImage;
@@ -224,7 +230,7 @@ struct SpriteWidget : virtual Widget {
void draw(NVGcontext *vg) override; void draw(NVGcontext *vg) override;
}; };


struct SVGWidget : virtual Widget {
struct SVGWidget : VirtualWidget {
std::shared_ptr<SVG> svg; std::shared_ptr<SVG> svg;
/** Sets the box size to the svg image size */ /** Sets the box size to the svg image size */
void wrap(); 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. 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. 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 */ /** Set this to true to re-render the children to the framebuffer the next time it is drawn */
bool dirty = true; bool dirty = true;
/** A margin in pixels around the children in the framebuffer /** A margin in pixels around the children in the framebuffer
@@ -258,7 +264,7 @@ struct FramebufferWidget : virtual Widget {
}; };


/** A Widget representing a float value */ /** A Widget representing a float value */
struct QuantityWidget : virtual Widget {
struct QuantityWidget : VirtualWidget {
float value = 0.0; float value = 0.0;
float minValue = 0.0; float minValue = 0.0;
float maxValue = 1.0; float maxValue = 1.0;


+ 1
- 1
src/app/ModuleBrowser.cpp View File

@@ -95,7 +95,7 @@ struct ModelItem : BrowserListItem {
nameLabel = Widget::create<Label>(Vec(0, 0)); nameLabel = Widget::create<Label>(Vec(0, 0));
addChild(nameLabel); addChild(nameLabel);
manufacturerLabel = Widget::create<Label>(Vec(0, 0)); manufacturerLabel = Widget::create<Label>(Vec(0, 0));
manufacturerLabel->align = Label::RIGHT_ALIGN;
manufacturerLabel->alignment = Label::RIGHT_ALIGNMENT;
addChild(manufacturerLabel); addChild(manufacturerLabel);
tagsLabel = Widget::create<Label>(Vec(26, BND_WIDGET_HEIGHT)); tagsLabel = Widget::create<Label>(Vec(26, BND_WIDGET_HEIGHT));
addChild(tagsLabel); addChild(tagsLabel);


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

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


void Label::draw(NVGcontext *vg) { void Label::draw(NVGcontext *vg) {
float x = 0.0; float x = 0.0;
if (align == RIGHT_ALIGN) {
if (alignment == RIGHT_ALIGNMENT) {
x = box.size.x - bndLabelWidth(vg, -1, text.c_str()); x = box.size.x - bndLabelWidth(vg, -1, text.c_str());
} }
else if (align == CENTER_ALIGN) {
else if (alignment == CENTER_ALIGNMENT) {
x = (box.size.x - bndLabelWidth(vg, -1, text.c_str())) / 2.0; x = (box.size.x - bndLabelWidth(vg, -1, text.c_str())) / 2.0;
} }




+ 39
- 0
src/ui/layouts.cpp View File

@@ -0,0 +1,39 @@
#include "ui.hpp"


namespace rack {


void SequentialLayout::step() {
Widget::step();

float offset = 0.0;
for (Widget *child : children) {
if (!child->visible)
continue;
// Set position
(orientation == HORIZONTAL_ORIENTATION ? child->box.pos.x : child->box.pos.y) = offset;
// Increment by size
offset += (orientation == HORIZONTAL_ORIENTATION ? child->box.size.x : child->box.size.y);
offset += margin;
}

// We're done if left aligned
if (alignment == LEFT_ALIGNMENT)
return;

// Adjust positions based on width of the layout itself
offset -= margin;
if (alignment == RIGHT_ALIGNMENT)
offset -= (orientation == HORIZONTAL_ORIENTATION ? box.size.x : box.size.y);
else if (alignment == CENTER_ALIGNMENT)
offset -= (orientation == HORIZONTAL_ORIENTATION ? box.size.x : box.size.y) / 2.0;
for (Widget *child : children) {
if (!child->visible)
continue;
(orientation == HORIZONTAL_ORIENTATION ? child->box.pos.x : child->box.pos.y) += offset;
}
}


} // namespace rack

Loading…
Cancel
Save