@@ -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) | |||
@@ -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; | |||
}; | |||
@@ -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(); | |||
} | |||
@@ -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; | |||
@@ -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,5 +1,6 @@ | |||
#include "ui/MenuItem.hpp" | |||
namespace rack { | |||
@@ -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 |