Browse Source

Make SequentialLayout wrap widgets

tags/v1.0.0
Andrew Belt 5 years ago
parent
commit
5ff841b076
7 changed files with 89 additions and 45 deletions
  1. +1
    -1
      compile.mk
  2. +5
    -34
      include/ui/SequentialLayout.hpp
  3. +14
    -8
      src/app/ModuleBrowser.cpp
  4. +1
    -1
      src/app/Toolbar.cpp
  5. +2
    -1
      src/engine/Engine.cpp
  6. +1
    -0
      src/ui/MenuItem.cpp
  7. +65
    -0
      src/ui/SequentialLayout.cpp

+ 1
- 1
compile.mk View File

@@ -10,7 +10,7 @@ OBJCOPY ?= objcopy
FLAGS += -MMD -MP
FLAGS += -g
# Optimization
FLAGS += -O0 -march=nocona -ffast-math -fno-finite-math-only
FLAGS += -O3 -march=nocona -ffast-math -fno-finite-math-only
FLAGS += -Wall -Wextra -Wno-unused-parameter

ifneq ($(ARCH), mac)


+ 5
- 34
include/ui/SequentialLayout.hpp View File

@@ -12,47 +12,18 @@ struct SequentialLayout : virtual Widget {
HORIZONTAL_ORIENTATION,
VERTICAL_ORIENTATION,
};
Orientation orientation = HORIZONTAL_ORIENTATION;

enum Alignment {
LEFT_ALIGNMENT,
CENTER_ALIGNMENT,
RIGHT_ALIGNMENT,
};

Orientation orientation = HORIZONTAL_ORIENTATION;
Alignment alignment = LEFT_ALIGNMENT;
/** Space between adjacent elements */
float spacing = 0.0;

void step() override {
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 += spacing;
}

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

// Adjust positions based on width of the layout itself
offset -= spacing;
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;
}
}
math::Vec spacing;

void step() override;
};




+ 14
- 8
src/app/ModuleBrowser.cpp View File

@@ -1,20 +1,23 @@
#include <set>
#include <algorithm>
#include "app/ModuleBrowser.hpp"
// TODO clean up
#include "window.hpp"
#include "helpers.hpp"
#include "event.hpp"
#include "ui/Quantity.hpp"
#include "ui/RadioButton.hpp"
#include "ui/Label.hpp"
#include "app/ModuleBrowser.hpp"
#include "app/Scene.hpp"
#include "ui/List.hpp"
#include "ui/TextField.hpp"
#include "ui/SequentialLayout.hpp"
#include "widgets/ObstructWidget.hpp"
#include "widgets/ZoomWidget.hpp"
#include "plugin.hpp"
#include "context.hpp"

#include <set>
#include <algorithm>


namespace rack {

@@ -43,14 +46,17 @@ struct ModuleWidgetWrapper : ObstructWidget {


struct ModuleBrowser : OpaqueWidget {
SequentialLayout *moduleLayout;
ModuleBrowser() {
math::Vec p;
moduleLayout = new SequentialLayout;
moduleLayout->spacing = math::Vec(10, 10);
addChild(moduleLayout);

for (Plugin *plugin : plugin::plugins) {
for (Model *model : plugin->models) {
ModuleWidgetWrapper *wrapper = new ModuleWidgetWrapper;
wrapper->box.pos = p;
wrapper->model = model;
addChild(wrapper);
moduleLayout->addChild(wrapper);

ZoomWidget *zoomWidget = new ZoomWidget;
zoomWidget->setZoom(0.5);
@@ -59,7 +65,6 @@ struct ModuleBrowser : OpaqueWidget {
ModuleWidget *moduleWidget = model->createModuleWidgetNull();
zoomWidget->addChild(moduleWidget);
wrapper->box.size = moduleWidget->box.size.mult(zoomWidget->zoom);
p = wrapper->box.getTopRight().plus(math::Vec(20, 0));
}
}
}
@@ -67,7 +72,8 @@ struct ModuleBrowser : OpaqueWidget {
void step() override {
assert(parent);

box = parent->box.zeroPos().grow(math::Vec(-100, -100));
box = parent->box.zeroPos().grow(math::Vec(-50, -50));
moduleLayout->box.size = box.size;

OpaqueWidget::step();
}


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

@@ -543,7 +543,7 @@ Toolbar::Toolbar() {

SequentialLayout *layout = new SequentialLayout;
layout->box.pos = math::Vec(margin, margin);
layout->spacing = 0.0;
layout->spacing = math::Vec(0, 0);
addChild(layout);

FileButton *fileButton = new FileButton;


+ 2
- 1
src/engine/Engine.cpp View File

@@ -146,7 +146,8 @@ static void Engine_step(Engine *engine) {
auto stopTime = std::chrono::high_resolution_clock::now();
float cpuTime = std::chrono::duration<float>(stopTime - startTime).count() * engine->internal->sampleRate;
// Smooth cpu time
module->cpuTime += (cpuTime - module->cpuTime) * engine->internal->sampleTime / 0.5f;
float powerLambda = 2.f / 10.f;
module->cpuTime += (cpuTime - module->cpuTime) * engine->internal->sampleTime * powerLambda;
}
else {
module->step();


+ 1
- 0
src/ui/MenuItem.cpp View File

@@ -1,5 +1,6 @@
#include "ui/MenuItem.hpp"


namespace rack {




+ 65
- 0
src/ui/SequentialLayout.cpp View File

@@ -0,0 +1,65 @@
#include "ui/SequentialLayout.hpp"
#include <vector>


namespace rack {


#define X(_v) (orientation == HORIZONTAL_ORIENTATION ? (_v).x : (_v).y)
#define Y(_v) (orientation == HORIZONTAL_ORIENTATION ? (_v).y : (_v).x)

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

// Sort widgets into rows (or columns if vertical)
std::vector<std::vector<Widget*>> rows;
rows.resize(1);
float rowWidth = 0.0;
for (Widget *child : children) {
if (!child->visible)
continue;

// Should we wrap the widget now?
if (!rows.back().empty() && rowWidth + X(child->box.size) >= X(box.size)) {
rowWidth = 0.0;
rows.resize(rows.size() + 1);
}

rows.back().push_back(child);
rowWidth += X(child->box.size) + X(spacing);
}

// Position widgets
math::Vec p;
for (auto &row : rows) {
// For center and right alignment, compute offset from the left margin
float offset = 0.0;
if (alignment != LEFT_ALIGNMENT) {
float rowWidth = 0.0;
for (Widget *child : row) {
rowWidth += X(child->box.size) + X(spacing);
}
rowWidth -= X(spacing);

if (alignment == CENTER_ALIGNMENT)
offset = (X(box.size) - rowWidth) / 2;
else if (alignment == RIGHT_ALIGNMENT)
offset = X(box.size) - rowWidth;
}

float maxHeight = 0.0;
for (Widget *child : row) {
child->box.pos = p;
X(child->box.pos) += offset;

X(p) += X(child->box.size) + X(spacing);
if (Y(child->box.size) > maxHeight)
maxHeight = Y(child->box.size);
}
X(p) = 0.0;
Y(p) += maxHeight + Y(spacing);
}
}


} // namespace rack

Loading…
Cancel
Save