Browse Source

Make SequentialLayout resize according to its contents. Fix margins of model container in Module Browser.

tags/v2.0.0
Andrew Belt 3 years ago
parent
commit
42af36fa0b
5 changed files with 24 additions and 60 deletions
  1. +0
    -19
      include/ui/MarginLayout.hpp
  2. +1
    -1
      src/app/CableWidget.cpp
  3. +12
    -10
      src/app/ModuleBrowser.cpp
  4. +0
    -20
      src/ui/MarginLayout.cpp
  5. +11
    -10
      src/ui/SequentialLayout.cpp

+ 0
- 19
include/ui/MarginLayout.hpp View File

@@ -1,19 +0,0 @@
#pragma once
#include <widget/Widget.hpp>
#include <ui/common.hpp>


namespace rack {
namespace ui {


/** Positions children with a margin between the layout's box. */
struct MarginLayout : widget::Widget {
math::Vec margin;

void step() override;
};


} // namespace ui
} // namespace rack

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

@@ -108,7 +108,7 @@ json_t* CableWidget::toJson() {
void CableWidget::fromJson(json_t* rootJ) { void CableWidget::fromJson(json_t* rootJ) {
json_t* colorJ = json_object_get(rootJ, "color"); json_t* colorJ = json_object_get(rootJ, "color");
if (colorJ) { if (colorJ) {
// In <=v0.6.0, patches used JSON objects. Just ignore them if so and use the existing cable color.
// In <v0.6.0, cables used JSON objects instead of hex strings. Just ignore them if so and use the existing cable color.
if (json_is_string(colorJ)) if (json_is_string(colorJ))
color = color::fromHexString(json_string_value(colorJ)); color = color::fromHexString(json_string_value(colorJ));
} }


+ 12
- 10
src/app/ModuleBrowser.cpp View File

@@ -9,7 +9,6 @@
#include <ui/MenuOverlay.hpp> #include <ui/MenuOverlay.hpp>
#include <ui/ScrollWidget.hpp> #include <ui/ScrollWidget.hpp>
#include <ui/SequentialLayout.hpp> #include <ui/SequentialLayout.hpp>
#include <ui/MarginLayout.hpp>
#include <ui/Label.hpp> #include <ui/Label.hpp>
#include <ui/Slider.hpp> #include <ui/Slider.hpp>
#include <ui/TextField.hpp> #include <ui/TextField.hpp>
@@ -440,7 +439,7 @@ struct ModuleBrowser : widget::OpaqueWidget {
ClearButton* clearButton; ClearButton* clearButton;


ui::ScrollWidget* modelScroll; ui::ScrollWidget* modelScroll;
ui::MarginLayout* modelMargin;
widget::Widget* modelMargin;
ui::SequentialLayout* modelContainer; ui::SequentialLayout* modelContainer;


std::string search; std::string search;
@@ -450,12 +449,12 @@ struct ModuleBrowser : widget::OpaqueWidget {
std::map<plugin::Model*, float> prefilteredModelScores; std::map<plugin::Model*, float> prefilteredModelScores;


ModuleBrowser() { ModuleBrowser() {
float margin = 10;
const float margin = 10;


// Header // Header
headerLayout = new ui::SequentialLayout; headerLayout = new ui::SequentialLayout;
headerLayout->box.pos = math::Vec(0, 0); headerLayout->box.pos = math::Vec(0, 0);
headerLayout->box.size.y = BND_WIDGET_HEIGHT + 2 * margin;
headerLayout->box.size.y = 0;
headerLayout->margin = math::Vec(margin, margin); headerLayout->margin = math::Vec(margin, margin);
headerLayout->spacing = math::Vec(margin, margin); headerLayout->spacing = math::Vec(margin, margin);
addChild(headerLayout); addChild(headerLayout);
@@ -482,9 +481,10 @@ struct ModuleBrowser : widget::OpaqueWidget {
clearButton->browser = this; clearButton->browser = this;
headerLayout->addChild(clearButton); headerLayout->addChild(clearButton);


widget::Widget* spacer1 = new widget::Widget;
spacer1->box.size.x = 20;
headerLayout->addChild(spacer1);
// widget::Widget* spacer1 = new widget::Widget;
// spacer1->box.size.x = 20;
// spacer1->box.size.y = 0;
// headerLayout->addChild(spacer1);


SortButton* sortButton = new SortButton; SortButton* sortButton = new SortButton;
sortButton->box.size.x = 150; sortButton->box.size.x = 150;
@@ -507,11 +507,11 @@ struct ModuleBrowser : widget::OpaqueWidget {
modelScroll->box.pos.y = BND_WIDGET_HEIGHT; modelScroll->box.pos.y = BND_WIDGET_HEIGHT;
addChild(modelScroll); addChild(modelScroll);


modelMargin = new ui::MarginLayout;
modelMargin->margin = math::Vec(margin, 0);
modelMargin = new widget::Widget;
modelScroll->container->addChild(modelMargin); modelScroll->container->addChild(modelMargin);


modelContainer = new ui::SequentialLayout; modelContainer = new ui::SequentialLayout;
modelContainer->margin = math::Vec(margin, 0);
modelContainer->spacing = math::Vec(margin, margin); modelContainer->spacing = math::Vec(margin, margin);
modelMargin->addChild(modelContainer); modelMargin->addChild(modelContainer);


@@ -558,10 +558,12 @@ struct ModuleBrowser : widget::OpaqueWidget {


headerLayout->box.size.x = box.size.x; headerLayout->box.size.x = box.size.x;


const float margin = 10;
modelScroll->box.pos = headerLayout->box.getBottomLeft(); modelScroll->box.pos = headerLayout->box.getBottomLeft();
modelScroll->box.size = box.size.minus(modelScroll->box.pos); modelScroll->box.size = box.size.minus(modelScroll->box.pos);
modelMargin->box.size.x = modelScroll->box.size.x; modelMargin->box.size.x = modelScroll->box.size.x;
modelMargin->box.size.y = modelContainer->getChildrenBoundingBox().size.y + 2 * modelMargin->margin.y;
modelMargin->box.size.y = modelContainer->box.size.y + margin;
modelContainer->box.size.x = modelMargin->box.size.x - margin;


OpaqueWidget::step(); OpaqueWidget::step();
} }


+ 0
- 20
src/ui/MarginLayout.cpp View File

@@ -1,20 +0,0 @@
#include <ui/MarginLayout.hpp>
#include <vector>


namespace rack {
namespace ui {


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

math::Rect childBox = box.zeroPos().grow(margin.neg());
for (Widget* child : children) {
child->box = childBox;
}
}


} // namespace ui
} // namespace rack

+ 11
- 10
src/ui/SequentialLayout.cpp View File

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




/** We assume horizontal orientation in this file, but we can achieve vertical orientation just by swapping the axes.
*/
#define X(v) (orientation == HORIZONTAL_ORIENTATION ? (v).x : (v).y) #define X(v) (orientation == HORIZONTAL_ORIENTATION ? (v).x : (v).y)
#define Y(v) (orientation == HORIZONTAL_ORIENTATION ? (v).y : (v).x) #define Y(v) (orientation == HORIZONTAL_ORIENTATION ? (v).y : (v).x)


@@ -14,16 +16,13 @@ namespace ui {
void SequentialLayout::step() { void SequentialLayout::step() {
Widget::step(); Widget::step();


math::Rect bound;
bound.pos = margin;
bound.size = box.size.minus(margin.mult(2));
float boundWidth = X(box.size) - 2 * X(margin);


// Sort widgets into rows (or columns if vertical) // Sort widgets into rows (or columns if vertical)
std::vector<widget::Widget*> row; std::vector<widget::Widget*> row;
math::Vec cursor = bound.pos;
math::Vec cursor = margin;
auto flushRow = [&]() { auto flushRow = [&]() {
// For center and right alignment, compute offset from the left margin // For center and right alignment, compute offset from the left margin
float offset = 0.f;
if (alignment != LEFT_ALIGNMENT) { if (alignment != LEFT_ALIGNMENT) {
float rowWidth = 0.f; float rowWidth = 0.f;
for (widget::Widget* child : row) { for (widget::Widget* child : row) {
@@ -32,16 +31,15 @@ void SequentialLayout::step() {
rowWidth -= X(spacing); rowWidth -= X(spacing);


if (alignment == CENTER_ALIGNMENT) if (alignment == CENTER_ALIGNMENT)
offset = (X(bound.size) - rowWidth) / 2;
X(cursor) += (boundWidth - rowWidth) / 2;
else if (alignment == RIGHT_ALIGNMENT) else if (alignment == RIGHT_ALIGNMENT)
offset = X(bound.size) - rowWidth;
X(cursor) += boundWidth - rowWidth;
} }


// Set positions of widgets // Set positions of widgets
float maxHeight = 0.f; float maxHeight = 0.f;
for (widget::Widget* child : row) { for (widget::Widget* child : row) {
child->box.pos = cursor; child->box.pos = cursor;
X(child->box.pos) += offset;
X(cursor) += X(child->box.size) + X(spacing); X(cursor) += X(child->box.size) + X(spacing);


if (Y(child->box.size) > maxHeight) if (Y(child->box.size) > maxHeight)
@@ -50,20 +48,21 @@ void SequentialLayout::step() {
row.clear(); row.clear();


// Reset cursor to next line // Reset cursor to next line
X(cursor) = X(bound.pos);
X(cursor) = X(margin);
Y(cursor) += maxHeight + Y(spacing); Y(cursor) += maxHeight + Y(spacing);
}; };


// Iterate through children until row is full // Iterate through children until row is full
float rowWidth = 0.0; float rowWidth = 0.0;
for (widget::Widget* child : children) { for (widget::Widget* child : children) {
// Skip invisible children
if (!child->isVisible()) { if (!child->isVisible()) {
child->box.pos = math::Vec(); child->box.pos = math::Vec();
continue; continue;
} }


// Should we wrap the widget now? // Should we wrap the widget now?
if (!row.empty() && rowWidth + X(child->box.size) > X(bound.size)) {
if (!row.empty() && rowWidth + X(child->box.size) > boundWidth) {
flushRow(); flushRow();
rowWidth = 0.0; rowWidth = 0.0;
} }
@@ -76,6 +75,8 @@ void SequentialLayout::step() {
if (!row.empty()) { if (!row.empty()) {
flushRow(); flushRow();
} }

Y(box.size) = Y(cursor) - Y(spacing) + Y(margin);
} }






Loading…
Cancel
Save