Browse Source

Header cleanup. ModuleBrowser work.

tags/v1.0.0
Andrew Belt 5 years ago
parent
commit
f967c68110
10 changed files with 101 additions and 73 deletions
  1. +1
    -1
      docs/Makefile
  2. +17
    -11
      include/component.hpp
  3. +4
    -5
      include/dsp/fft.hpp
  4. +12
    -11
      include/dsp/vumeter.hpp
  5. +2
    -2
      include/plugin/Plugin.hpp
  6. +6
    -2
      include/rack.hpp
  7. +2
    -1
      src/app/CableWidget.cpp
  8. +54
    -38
      src/app/ModuleBrowser.cpp
  9. +1
    -1
      src/plugin.cpp
  10. +2
    -1
      src/ui/List.cpp

+ 1
- 1
docs/Makefile View File

@@ -8,7 +8,7 @@ run: doxygen
http-server html

upload: doxygen
rsync html/ vcvrack.com:vcvrack.com/docs/ -ruvz --delete
rsync html/ vcvrack.com:vcvrack.com/docs/ -ruz --info=progress2 --delete

clean:
rm -rfv html

+ 17
- 11
include/component.hpp View File

@@ -1,5 +1,11 @@
#pragma once
#include "rack.hpp"
#include "app/SvgKnob.hpp"
#include "app/SvgSlider.hpp"
#include "app/SvgPort.hpp"
#include "app/ModuleLightWidget.hpp"
#include "app/SvgSwitch.hpp"
#include "app/SvgScrew.hpp"
#include "asset.hpp"


namespace rack {
@@ -294,7 +300,7 @@ struct SynthTechAlco : app::SvgKnob {
minAngle = -0.82*M_PI;
maxAngle = 0.82*M_PI;
setSvg(APP->window->loadSvg(asset::system("res/ComponentLibrary/SynthTechAlco.svg")));
SvgWidget *cap = new SvgWidget;
widget::SvgWidget *cap = new widget::SvgWidget;
cap->setSvg(APP->window->loadSvg(asset::system("res/ComponentLibrary/SynthTechAlco_cap.svg")));
addChild(cap);
}
@@ -344,8 +350,8 @@ struct BefacoSlidePot : app::SvgSlider {

struct LEDSlider : app::SvgSlider {
LEDSlider() {
maxHandlePos = mm2px(math::Vec(0.738, 0.738).plus(math::Vec(2, 0)));
minHandlePos = mm2px(math::Vec(0.738, 22.078).plus(math::Vec(2, 0)));
maxHandlePos = app::mm2px(math::Vec(0.738, 0.738).plus(math::Vec(2, 0)));
minHandlePos = app::mm2px(math::Vec(0.738, 22.078).plus(math::Vec(2, 0)));
setBackgroundSvg(APP->window->loadSvg(asset::system("res/ComponentLibrary/LEDSlider.svg")));
}
};
@@ -467,7 +473,7 @@ struct RGBLight : app::ModuleLightWidget {
template <typename BASE>
struct LargeLight : BASE {
LargeLight() {
this->box.size = mm2px(math::Vec(5.179, 5.179));
this->box.size = app::mm2px(math::Vec(5.179, 5.179));
}
};

@@ -475,7 +481,7 @@ struct LargeLight : BASE {
template <typename BASE>
struct MediumLight : BASE {
MediumLight() {
this->box.size = mm2px(math::Vec(3.176, 3.176));
this->box.size = app::mm2px(math::Vec(3.176, 3.176));
}
};

@@ -483,7 +489,7 @@ struct MediumLight : BASE {
template <typename BASE>
struct SmallLight : BASE {
SmallLight() {
this->box.size = mm2px(math::Vec(2.176, 2.176));
this->box.size = app::mm2px(math::Vec(2.176, 2.176));
}
};

@@ -491,7 +497,7 @@ struct SmallLight : BASE {
template <typename BASE>
struct TinyLight : BASE {
TinyLight() {
this->box.size = mm2px(math::Vec(1.088, 1.088));
this->box.size = app::mm2px(math::Vec(1.088, 1.088));
}
};

@@ -500,18 +506,18 @@ template <typename BASE>
struct LEDBezelLight : BASE {
LEDBezelLight() {
this->bgColor = color::BLACK_TRANSPARENT;
this->box.size = mm2px(math::Vec(6.0, 6.0));
this->box.size = app::mm2px(math::Vec(6.0, 6.0));
}
};

/** A light to displayed over PB61303. Must add a color by subclassing or templating.
Don't add this as a child of the PB61303 itself. Instead, just place it over it as a sibling in the scene graph, offset by mm2px(math::Vec(0.5, 0.5)).
Don't add this as a child of the PB61303 itself. Instead, just place it over it as a sibling in the scene graph, offset by app::mm2px(math::Vec(0.5, 0.5)).
*/
template <typename BASE>
struct PB61303Light : BASE {
PB61303Light() {
this->bgColor = color::BLACK_TRANSPARENT;
this->box.size = mm2px(math::Vec(9.0, 9.0));
this->box.size = app::mm2px(math::Vec(9.0, 9.0));
}
};



+ 4
- 5
include/dsp/fft.hpp View File

@@ -18,8 +18,8 @@ void alignedDelete(T *p) {
}


/** Real-valued FFT context
Wrapper for PFFFT (https://bitbucket.org/jpommier/pffft/)
/** Real-valued FFT context.
Wrapper for [PFFFT](https://bitbucket.org/jpommier/pffft/)
`length` must be a multiple of 32.
*/
struct RealFFT {
@@ -72,8 +72,7 @@ struct RealFFT {
pffft_transform_ordered(setup, input, output, NULL, PFFFT_BACKWARD);
}

/** Scales the RFFT so that
scale(IFFT(FFT(x))) = x
/** Scales the RFFT so that `scale(IFFT(FFT(x))) = x`.
*/
void scale(float *x) {
float a = 1.f / length;
@@ -84,7 +83,7 @@ struct RealFFT {
};


/** Complex-valued FFT context
/** Complex-valued FFT context.
`length` must be a multiple of 16.
*/
struct ComplexFFT {


+ 12
- 11
include/dsp/vumeter.hpp View File

@@ -6,7 +6,7 @@ namespace rack {
namespace dsp {


/** Deprecated. Use VuMeter2. */
/** Deprecated. Use VuMeter2 instead. */
struct VuMeter {
/** Decibel level difference between adjacent meter lights */
float dBInterval = 3.0;
@@ -34,17 +34,18 @@ DEPRECATED typedef VuMeter VUMeter;


/** Models a VU meter with smoothing.
Supports peak and RMS (root-mean-square) metering
Supports peak and RMS (root-mean-square) metering.
Usage example for a strip of lights with 3dB increments:

// Update VuMeter state every frame.
vuMeter.process(deltaTime, output);
// Iterate lights every ~512 frames (less than a screen refresh).
for (int i = 0; i < 6; i++) {
float b = vuMeter.getBrightness(-3.f * (i + 1), -3.f * i);
// No need to use setSmoothBrightness() since VuMeter2 smooths the value for you.
lights[i].setBrightness(b);
}
```
// Update VuMeter state every frame.
vuMeter.process(deltaTime, output);
// Iterate lights every ~512 frames (less than a screen refresh).
for (int i = 0; i < 6; i++) {
float b = vuMeter.getBrightness(-3.f * (i + 1), -3.f * i);
// No need to use setSmoothBrightness() since VuMeter2 smooths the value for you.
lights[i].setBrightness(b);
}
```
*/
struct VuMeter2 {
enum Mode {


+ 2
- 2
include/plugin/Plugin.hpp View File

@@ -1,7 +1,7 @@
#pragma once
#include "common.hpp"
#include <jansson.h>
#include <list>
#include <vector>


namespace rack {
@@ -14,7 +14,7 @@ struct Model;
// Subclass this and return a pointer to a new one when init() is called
struct Plugin {
/** A list of the models available by this plugin, add with addModel() */
std::list<Model*> models;
std::vector<Model*> models;
/** The file path of the plugin's directory */
std::string path;
/** OS-dependent library handle */


+ 6
- 2
include/rack.hpp View File

@@ -1,4 +1,5 @@
#pragma once

// Include most Rack headers for convenience
#include "common.hpp"
#include "math.hpp"
@@ -11,6 +12,7 @@
#include "app.hpp"
#include "midi.hpp"
#include "helpers.hpp"
#include "component.hpp"

#include "widget/Widget.hpp"
#include "widget/TransparentWidget.hpp"
@@ -90,9 +92,12 @@
#include "dsp/vumeter.hpp"
#include "dsp/window.hpp"


namespace rack {


/** Define this macro before including this header to prevent common namespaces from being included in the main `rack::` namespace. */
#ifndef RACK_FLATTEN_NAMESPACES
// Import some namespaces for convenience
using namespace math;
using namespace widget;
@@ -101,9 +106,8 @@ using namespace app;
using plugin::Plugin;
using plugin::Model;
using namespace engine;

namespace component {}
using namespace component;
#endif


} // namespace rack

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

@@ -6,6 +6,7 @@
#include "app.hpp"
#include "patch.hpp"
#include "settings.hpp"
#include "engine/Port.hpp"


namespace rack {
@@ -219,7 +220,7 @@ void CableWidget::draw(const DrawArgs &args) {
float thickness = 5;

if (isComplete()) {
Output *output = &cable->outputModule->outputs[cable->outputId];
engine::Output *output = &cable->outputModule->outputs[cable->outputId];
// Draw opaque if mouse is hovering over a connected port
if (output->channels > 1) {
// Increase thickness if output port is polyphonic


+ 54
- 38
src/app/ModuleBrowser.cpp View File

@@ -79,7 +79,7 @@ struct BrowserOverlay : widget::OpaqueWidget {
};


static const float MODEL_BOX_ZOOM = 0.5f;
static const float MODEL_BOX_ZOOM = 1.0f;


struct ModelBox : widget::OpaqueWidget {
@@ -92,20 +92,23 @@ struct ModelBox : widget::OpaqueWidget {
bool selected = false;

ModelBox() {
box.size.x = 0.f;
box.size.y = std::ceil(RACK_GRID_HEIGHT * MODEL_BOX_ZOOM);
// Approximate size as 10HP before we know the actual size.
// We need a nonzero size, otherwise the parent widget will consider it not in the draw bounds, so its preview will not be lazily created.
box.size.x = 10 * RACK_GRID_WIDTH * MODEL_BOX_ZOOM;
box.size.y = RACK_GRID_HEIGHT * MODEL_BOX_ZOOM;
box.size = box.size.ceil();
}

void setModel(plugin::Model *model) {
this->model = model;

infoWidget = new widget::Widget;
infoWidget->box.size.x = 140;
infoWidget->box.size.y = box.size.y;
infoWidget->hide();
addChild(infoWidget);

math::Vec pos;

// Name label
ui::Label *nameLabel = new ui::Label;
// nameLabel->box.size.x = infoWidget->box.size.x;
nameLabel->box.pos = pos;
@@ -113,6 +116,7 @@ struct ModelBox : widget::OpaqueWidget {
infoWidget->addChild(nameLabel);
pos = nameLabel->box.getBottomLeft();

// Plugin label
ui::Label *pluginLabel = new ui::Label;
// pluginLabel->box.size.x = infoWidget->box.size.x;
pluginLabel->box.pos = pos;
@@ -127,24 +131,23 @@ struct ModelBox : widget::OpaqueWidget {
infoWidget->addChild(descriptionLabel);
pos = descriptionLabel->box.getBottomLeft();

pos.y = infoWidget->box.size.y;
for (const std::string &tag : model->tags) {
ui::Button *tagButton = new ui::Button;
tagButton->box.size.x = infoWidget->box.size.x;
tagButton->box.pos = pos;
tagButton->box.pos.y -= tagButton->box.size.y;
tagButton->text = tag;
infoWidget->addChild(tagButton);
pos = tagButton->box.getTopLeft();
}

ui::Button *favoriteButton = new ui::Button;
favoriteButton->box.size.x = infoWidget->box.size.x;
favoriteButton->box.pos = pos;
favoriteButton->box.pos.y -= favoriteButton->box.size.y;
favoriteButton->text = "★";
infoWidget->addChild(favoriteButton);
pos = favoriteButton->box.getTopLeft();
// for (const std::string &tag : model->tags) {
// ui::Button *tagButton = new ui::Button;
// tagButton->box.size.x = infoWidget->box.size.x;
// tagButton->box.pos = pos;
// tagButton->text = tag;
// infoWidget->addChild(tagButton);
// pos = tagButton->box.getTopLeft();
// }

// // Favorite button
// ui::Button *favoriteButton = new ui::Button;
// favoriteButton->box.size.x = box.size.x;
// favoriteButton->box.pos = pos;
// favoriteButton->box.pos.y -= favoriteButton->box.size.y;
// favoriteButton->text = "★";
// addChild(favoriteButton);
// pos = favoriteButton->box.getTopLeft();
}

void createPreview() {
@@ -171,9 +174,8 @@ struct ModelBox : widget::OpaqueWidget {
zoomWidget->box.size.y = RACK_GRID_HEIGHT * MODEL_BOX_ZOOM;
previewWidget->box.size.x = std::ceil(zoomWidget->box.size.x);

// Reposition infoWidget
infoWidget->box.pos.x = previewWidget->box.size.x;
box.size.x = previewWidget->box.size.x + infoWidget->box.size.x;
infoWidget->box.size = previewWidget->box.size;
box.size.x = previewWidget->box.size.x;
}

void deletePreview() {
@@ -197,6 +199,16 @@ struct ModelBox : widget::OpaqueWidget {
createPreview();
}

// Draw shadow
nvgBeginPath(args.vg);
float r = 10; // Blur radius
float c = 10; // Corner radius
nvgRect(args.vg, -r, -r, box.size.x + 2*r, box.size.y + 2*r);
NVGcolor shadowColor = nvgRGBAf(0, 0, 0, 0.5);
NVGcolor transparentColor = nvgRGBAf(0, 0, 0, 0);
nvgFillPaint(args.vg, nvgBoxGradient(args.vg, 0, 0, box.size.x, box.size.y, c, r, shadowColor, transparentColor));
nvgFill(args.vg);

nvgScissor(args.vg, RECT_ARGS(args.clipBox));
widget::OpaqueWidget::draw(args);
nvgResetScissor(args.vg);
@@ -261,17 +273,18 @@ struct BrowserSidebar : widget::Widget {
searchField = new BrowserSearchField;
addChild(searchField);

// Plugin list
pluginScroll = new ui::ScrollWidget;
pluginScroll->box.pos = searchField->box.getBottomLeft();
addChild(pluginScroll);

pluginList = new ui::List;
pluginScroll->container->addChild(pluginList);

std::set<std::string> pluginNames;
std::vector<std::string> pluginNames;
for (plugin::Plugin *plugin : plugin::plugins) {
pluginNames.insert(plugin->name);
pluginNames.push_back(plugin->name);
}
std::sort(pluginNames.begin(), pluginNames.end(), string::CaseInsensitiveCompare());

for (const std::string &pluginName : pluginNames) {
ui::MenuItem *item = new ui::MenuItem;
@@ -279,8 +292,8 @@ struct BrowserSidebar : widget::Widget {
pluginList->addChild(item);
}

// Tag list
tagScroll = new ui::ScrollWidget;
tagScroll->box.pos = searchField->box.getBottomLeft();
addChild(tagScroll);

tagList = new ui::List;
@@ -295,11 +308,14 @@ struct BrowserSidebar : widget::Widget {

void step() override {
searchField->box.size.x = box.size.x;
pluginScroll->box.size.y = box.size.y - searchField->box.size.y;
pluginList->box.size.x = pluginScroll->box.size.x = box.size.x / 2;
tagScroll->box.pos.x = box.size.x / 2;
tagScroll->box.size.y = box.size.y - searchField->box.size.y;
tagList->box.size.x = tagScroll->box.size.x = box.size.x / 2;
pluginScroll->box.pos = searchField->box.getBottomLeft();
pluginScroll->box.size.y = (box.size.y - searchField->box.size.y) / 2;
pluginScroll->box.size.x = box.size.x;
pluginList->box.size.x = pluginScroll->box.size.x;
tagScroll->box.pos = pluginScroll->box.getBottomLeft().floor();
tagScroll->box.size.y = (box.size.y - searchField->box.size.y) / 2;
tagScroll->box.size.x = box.size.x;
tagList->box.size.x = tagScroll->box.size.x;
widget::Widget::step();
}
};
@@ -313,18 +329,18 @@ struct ModuleBrowser : widget::OpaqueWidget {

ModuleBrowser() {
sidebar = new BrowserSidebar;
sidebar->box.size.x = 300;
sidebar->box.size.x = 200;
addChild(sidebar);

modelScroll = new ui::ScrollWidget;
addChild(modelScroll);

modelMargin = new ui::MarginLayout;
modelMargin->margin = math::Vec(20, 20);
modelMargin->margin = math::Vec(10, 10);
modelScroll->container->addChild(modelMargin);

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

for (plugin::Plugin *plugin : plugin::plugins) {


+ 1
- 1
src/plugin.cpp View File

@@ -527,7 +527,7 @@ Model *getModel(const std::string &pluginSlug, const std::string &modelSlug) {
}


/** List of allowed tags in human display form.
/** List of allowed tags in human display form, alphabetized.
All tags here should be in sentence caps for display consistency.
However, tags are case-insensitive in plugin metadata.
*/


+ 2
- 1
src/ui/List.cpp View File

@@ -13,8 +13,9 @@ void List::step() {
for (widget::Widget *child : children) {
if (!child->visible)
continue;
// Increment height, set position of child
// Set position of child
child->box.pos = math::Vec(0.0, box.size.y);
// Increment height
box.size.y += child->box.size.y;
// Resize width of child
child->box.size.x = box.size.x;


Loading…
Cancel
Save