Browse Source

Remove math namespace

tags/v1.0.0
Andrew Belt 6 years ago
parent
commit
499ceb024f
68 changed files with 323 additions and 319 deletions
  1. +6
    -6
      include/WidgetState.hpp
  2. +3
    -3
      include/app/LedDisplay.hpp
  3. +1
    -1
      include/app/ModuleWidget.hpp
  4. +3
    -3
      include/app/RackWidget.hpp
  5. +1
    -1
      include/app/SVGPanel.hpp
  6. +1
    -1
      include/app/SVGSlider.hpp
  7. +2
    -2
      include/app/WireWidget.hpp
  8. +3
    -3
      include/app/common.hpp
  9. +3
    -3
      include/color.hpp
  10. +1
    -1
      include/dsp/minblep.hpp
  11. +1
    -1
      include/dsp/vumeter.hpp
  12. +5
    -5
      include/event.hpp
  13. +9
    -9
      include/helpers.hpp
  14. +6
    -8
      include/math.hpp
  15. +0
    -11
      include/rack.hpp
  16. +1
    -1
      include/rack0.hpp
  17. +11
    -62
      include/string.hpp
  18. +1
    -1
      include/ui/IconButton.hpp
  19. +1
    -1
      include/ui/List.hpp
  20. +3
    -3
      include/ui/Menu.hpp
  21. +1
    -1
      include/ui/MenuEntry.hpp
  22. +1
    -1
      include/ui/ProgressBar.hpp
  23. +10
    -10
      include/ui/ScrollWidget.hpp
  24. +1
    -1
      include/ui/Slider.hpp
  25. +3
    -3
      include/ui/TextField.hpp
  26. +2
    -2
      include/widgets/QuantityWidget.hpp
  27. +2
    -2
      include/widgets/SVGWidget.hpp
  28. +2
    -2
      include/widgets/TransformWidget.hpp
  29. +6
    -13
      include/widgets/Widget.hpp
  30. +2
    -2
      include/widgets/ZoomWidget.hpp
  31. +5
    -5
      include/window.hpp
  32. +2
    -2
      src/Core/MIDICCToCVInterface.cpp
  33. +1
    -1
      src/Core/MIDIToCVInterface.cpp
  34. +1
    -1
      src/Core/MIDITriggerToCVInterface.cpp
  35. +6
    -6
      src/WidgetState.cpp
  36. +6
    -6
      src/app/AudioWidget.cpp
  37. +1
    -1
      src/app/CircularShadow.cpp
  38. +1
    -1
      src/app/Knob.cpp
  39. +5
    -5
      src/app/LedDisplay.cpp
  40. +2
    -2
      src/app/MidiWidget.cpp
  41. +8
    -8
      src/app/ModuleBrowser.cpp
  42. +1
    -1
      src/app/ModuleLightWidget.cpp
  43. +5
    -5
      src/app/ModuleWidget.cpp
  44. +1
    -1
      src/app/MultiLightWidget.cpp
  45. +1
    -1
      src/app/ParamWidget.cpp
  46. +3
    -3
      src/app/PluginManagerWidget.cpp
  47. +1
    -1
      src/app/Port.cpp
  48. +2
    -2
      src/app/RackScene.cpp
  49. +2
    -2
      src/app/RackScrollWidget.cpp
  50. +20
    -20
      src/app/RackWidget.cpp
  51. +6
    -6
      src/app/SVGKnob.cpp
  52. +3
    -3
      src/app/SVGPort.cpp
  53. +1
    -1
      src/app/SVGSlider.cpp
  54. +2
    -2
      src/app/SVGSwitch.cpp
  55. +4
    -4
      src/app/Toolbar.cpp
  56. +11
    -11
      src/app/WireWidget.cpp
  57. +6
    -6
      src/audio.cpp
  58. +1
    -1
      src/bridge.cpp
  59. +3
    -3
      src/gamepad.cpp
  60. +1
    -1
      src/keyboard.cpp
  61. +1
    -1
      src/midi.cpp
  62. +2
    -2
      src/plugin.cpp
  63. +5
    -5
      src/settings.cpp
  64. +75
    -0
      src/string.cpp
  65. +11
    -11
      src/svg.cpp
  66. +7
    -7
      src/widgets/FramebufferWidget.cpp
  67. +5
    -5
      src/widgets/Widget.cpp
  68. +13
    -13
      src/window.cpp

+ 6
- 6
include/WidgetState.hpp View File

@@ -18,13 +18,13 @@ struct WidgetState {
/** For middle-click dragging */
Widget *scrollWidget = NULL;

void handleButton(math::Vec pos, int button, int action, int mods);
void handleHover(math::Vec pos, math::Vec mouseDelta);
void handleButton(Vec pos, int button, int action, int mods);
void handleHover(Vec pos, Vec mouseDelta);
void handleLeave();
void handleScroll(math::Vec pos, math::Vec scrollDelta);
void handleText(math::Vec pos, int codepoint);
void handleKey(math::Vec pos, int key, int scancode, int action, int mods);
void handleDrop(math::Vec pos, std::vector<std::string> paths);
void handleScroll(Vec pos, Vec scrollDelta);
void handleText(Vec pos, int codepoint);
void handleKey(Vec pos, int key, int scancode, int action, int mods);
void handleDrop(Vec pos, std::vector<std::string> paths);
void handleZoom();
/** Prepares a widget for deletion */
void finalizeWidget(Widget *w);


+ 3
- 3
include/app/LedDisplay.hpp View File

@@ -17,7 +17,7 @@ struct LedDisplaySeparator : TransparentWidget {
struct LedDisplayChoice : TransparentWidget {
std::string text;
std::shared_ptr<Font> font;
math::Vec textOffset;
Vec textOffset;
NVGcolor color;
LedDisplayChoice();
void draw(NVGcontext *vg) override;
@@ -26,11 +26,11 @@ struct LedDisplayChoice : TransparentWidget {

struct LedDisplayTextField : TextField {
std::shared_ptr<Font> font;
math::Vec textOffset;
Vec textOffset;
NVGcolor color;
LedDisplayTextField();
void draw(NVGcontext *vg) override;
int getTextPosition(math::Vec mousePos) override;
int getTextPosition(Vec mousePos) override;
};




+ 1
- 1
include/app/ModuleWidget.hpp View File

@@ -64,7 +64,7 @@ struct ModuleWidget : OpaqueWidget {
void draw(NVGcontext *vg) override;
void drawShadow(NVGcontext *vg);

math::Vec dragPos;
Vec dragPos;
void onHover(event::Hover &e) override;
void onButton(event::Button &e) override;
void onHoverKey(event::HoverKey &e) override;


+ 3
- 3
include/app/RackWidget.hpp View File

@@ -15,7 +15,7 @@ struct RackWidget : OpaqueWidget {
// Only put WireWidgets in here
WireContainer *wireContainer;
std::string lastPath;
math::Vec lastMousePos;
Vec lastMousePos;
bool lockModules = false;

RackWidget();
@@ -45,9 +45,9 @@ struct RackWidget : OpaqueWidget {
void deleteModule(ModuleWidget *m);
void cloneModule(ModuleWidget *m);
/** Sets a module's box if non-colliding. Returns true if set */
bool requestModuleBox(ModuleWidget *m, math::Rect box);
bool requestModuleBox(ModuleWidget *m, Rect box);
/** Moves a module to the closest non-colliding position */
bool requestModuleBoxNearest(ModuleWidget *m, math::Rect box);
bool requestModuleBoxNearest(ModuleWidget *m, Rect box);

void step() override;
void draw(NVGcontext *vg) override;


+ 1
- 1
include/app/SVGPanel.hpp View File

@@ -19,7 +19,7 @@ struct PanelBorder : TransparentWidget {

struct SVGPanel : FramebufferWidget {
void step() override {
if (math::isNear(gPixelRatio, 1.0)) {
if (isNear(gPixelRatio, 1.0)) {
// Small details draw poorly at low DPI, so oversample when drawing to the framebuffer
oversample = 2.0;
}


+ 1
- 1
include/app/SVGSlider.hpp View File

@@ -12,7 +12,7 @@ struct SVGSlider : Knob, FramebufferWidget {
SVGWidget *background;
SVGWidget *handle;
/** Intermediate positions will be interpolated between these positions */
math::Vec minHandlePos, maxHandlePos;
Vec minHandlePos, maxHandlePos;

SVGSlider();
void setSVGs(std::shared_ptr<SVG> backgroundSVG, std::shared_ptr<SVG> handleSVG);


+ 2
- 2
include/app/WireWidget.hpp View File

@@ -20,8 +20,8 @@ struct WireWidget : OpaqueWidget {
~WireWidget();
/** Synchronizes the plugged state of the widget to the owned wire */
void updateWire();
math::Vec getOutputPos();
math::Vec getInputPos();
Vec getOutputPos();
Vec getInputPos();
json_t *toJson();
void fromJson(json_t *rootJ);
void draw(NVGcontext *vg) override;


+ 3
- 3
include/app/common.hpp View File

@@ -15,7 +15,7 @@ inline float in2px(float in) {
return in * SVG_DPI;
}

inline math::Vec in2px(math::Vec in) {
inline Vec in2px(Vec in) {
return in.mult(SVG_DPI);
}

@@ -24,7 +24,7 @@ inline float mm2px(float mm) {
return mm * (SVG_DPI / MM_PER_IN);
}

inline math::Vec mm2px(math::Vec mm) {
inline Vec mm2px(Vec mm) {
return mm.mult(SVG_DPI / MM_PER_IN);
}

@@ -32,7 +32,7 @@ inline math::Vec mm2px(math::Vec mm) {
// A 1HPx3U module should be 15x380 pixels. Thus the width of a module should be a factor of 15.
static const float RACK_GRID_WIDTH = 15;
static const float RACK_GRID_HEIGHT = 380;
static const math::Vec RACK_GRID_SIZE = math::Vec(RACK_GRID_WIDTH, RACK_GRID_HEIGHT);
static const Vec RACK_GRID_SIZE = Vec(RACK_GRID_WIDTH, RACK_GRID_HEIGHT);
static const std::string PRESET_FILTERS = "VCV Rack module preset (.vcvm):vcvm";
static const std::string PATCH_FILTERS = "VCV Rack patch (.vcv):vcv";



+ 3
- 3
include/color.hpp View File

@@ -23,7 +23,7 @@ static const NVGcolor CYAN = nvgRGB(0x00, 0xff, 0xff);

inline NVGcolor clip(NVGcolor a) {
for (int i = 0; i < 4; i++)
a.rgba[i] = math::clamp(a.rgba[i], 0.f, 1.f);
a.rgba[i] = clamp(a.rgba[i], 0.f, 1.f);
return a;
}

@@ -87,9 +87,9 @@ inline std::string toHexString(NVGcolor c) {
uint8_t b = std::round(c.b * 255);
uint8_t a = std::round(c.a * 255);
if (a == 255)
return string::stringf("#%02x%02x%02x", r, g, b);
return string::f("#%02x%02x%02x", r, g, b);
else
return string::stringf("#%02x%02x%02x%02x", r, g, b, a);
return string::f("#%02x%02x%02x%02x", r, g, b, a);
}




+ 1
- 1
include/dsp/minblep.hpp View File

@@ -23,7 +23,7 @@ struct MinBLEP {
for (int j = 0; j < 2*ZERO_CROSSINGS; j++) {
float minblepIndex = ((float)j - p) * oversample;
int index = (pos + j) % (2*ZERO_CROSSINGS);
buf[index] += dx * (-1.0 + math::interpolateLinear(minblep, minblepIndex));
buf[index] += dx * (-1.0 + interpolateLinear(minblep, minblepIndex));
}
}
float shift() {


+ 1
- 1
include/dsp/vumeter.hpp View File

@@ -23,7 +23,7 @@ struct VUMeter {
return (dBScaled >= 0.0) ? 1.0 : 0.0;
}
else {
return math::clamp(dBScaled + i, 0.0, 1.0);
return clamp(dBScaled + i, 0.0, 1.0);
}
}
};


+ 5
- 5
include/event.hpp View File

@@ -24,7 +24,7 @@ struct Event {

struct Position {
/** The pixel coordinate where the event occurred, relative to the Widget it is called on. */
math::Vec pos;
Vec pos;
};


@@ -52,7 +52,7 @@ If `target` is set, other events may occur on that Widget.
*/
struct Hover : Event, Position {
/** Change in mouse position since the last frame. Can be zero. */
math::Vec mouseDelta;
Vec mouseDelta;
};


@@ -89,7 +89,7 @@ Recurses until consumed.
*/
struct HoverScroll : Event, Position {
/** Change of scroll wheel position. */
math::Vec scrollDelta;
Vec scrollDelta;
};


@@ -147,7 +147,7 @@ struct DragEnd : Event {
`mouseDelta` may be zero.
*/
struct DragMove : Event {
math::Vec mouseDelta;
Vec mouseDelta;
};


@@ -156,7 +156,7 @@ Must consume to allow DragEnter, DragLeave, and DragDrop to occur.
*/
struct DragHover : Event, Position {
/** Change in mouse position since the last frame. Can be zero. */
math::Vec mouseDelta;
Vec mouseDelta;
};

/** Occurs when the mouse enters a Widget while dragging.


+ 9
- 9
include/helpers.hpp View File

@@ -36,14 +36,14 @@ Model *createModel(std::string author, std::string slug, std::string name, Tags.
}

template <class TWidget>
TWidget *createWidget(math::Vec pos) {
TWidget *createWidget(Vec pos) {
TWidget *o = new TWidget;
o->box.pos = pos;
return o;
}

template <class TParamWidget>
TParamWidget *createParam(math::Vec pos, Module *module, int paramId, float minValue, float maxValue, float defaultValue) {
TParamWidget *createParam(Vec pos, Module *module, int paramId, float minValue, float maxValue, float defaultValue) {
TParamWidget *o = new TParamWidget;
o->box.pos = pos;
o->module = module;
@@ -54,7 +54,7 @@ TParamWidget *createParam(math::Vec pos, Module *module, int paramId, float minV
}

template <class TParamWidget>
TParamWidget *createParamCentered(math::Vec pos, Module *module, int paramId, float minValue, float maxValue, float defaultValue) {
TParamWidget *createParamCentered(Vec pos, Module *module, int paramId, float minValue, float maxValue, float defaultValue) {
TParamWidget *o = new TParamWidget;
o->box.pos = pos.minus(o->box.size.div(2));
o->module = module;
@@ -65,7 +65,7 @@ TParamWidget *createParamCentered(math::Vec pos, Module *module, int paramId, fl
}

template <class TPort>
TPort *createInput(math::Vec pos, Module *module, int inputId) {
TPort *createInput(Vec pos, Module *module, int inputId) {
TPort *o = new TPort;
o->box.pos = pos;
o->module = module;
@@ -75,7 +75,7 @@ TPort *createInput(math::Vec pos, Module *module, int inputId) {
}

template <class TPort>
TPort *createInputCentered(math::Vec pos, Module *module, int inputId) {
TPort *createInputCentered(Vec pos, Module *module, int inputId) {
TPort *o = new TPort;
o->box.pos = pos.minus(o->box.size.div(2));
o->module = module;
@@ -85,7 +85,7 @@ TPort *createInputCentered(math::Vec pos, Module *module, int inputId) {
}

template <class TPort>
TPort *createOutput(math::Vec pos, Module *module, int outputId) {
TPort *createOutput(Vec pos, Module *module, int outputId) {
TPort *o = new TPort;
o->box.pos = pos;
o->module = module;
@@ -95,7 +95,7 @@ TPort *createOutput(math::Vec pos, Module *module, int outputId) {
}

template <class TPort>
TPort *createOutputCentered(math::Vec pos, Module *module, int outputId) {
TPort *createOutputCentered(Vec pos, Module *module, int outputId) {
TPort *o = new TPort;
o->box.pos = pos.minus(o->box.size.div(2));
o->module = module;
@@ -105,7 +105,7 @@ TPort *createOutputCentered(math::Vec pos, Module *module, int outputId) {
}

template <class TModuleLightWidget>
TModuleLightWidget *createLight(math::Vec pos, Module *module, int firstLightId) {
TModuleLightWidget *createLight(Vec pos, Module *module, int firstLightId) {
TModuleLightWidget *o = new TModuleLightWidget;
o->box.pos = pos;
o->module = module;
@@ -114,7 +114,7 @@ TModuleLightWidget *createLight(math::Vec pos, Module *module, int firstLightId)
}

template <class TModuleLightWidget>
TModuleLightWidget *createLightCentered(math::Vec pos, Module *module, int firstLightId) {
TModuleLightWidget *createLightCentered(Vec pos, Module *module, int firstLightId) {
TModuleLightWidget *o = new TModuleLightWidget;
o->box.pos = pos.minus(o->box.size.div(2));
o->module = module;


+ 6
- 8
include/math.hpp View File

@@ -4,7 +4,6 @@


namespace rack {
namespace math {

////////////////////
// basic integer functions
@@ -265,8 +264,8 @@ struct Rect {
Rect r;
r.pos.x = clampBetween(pos.x, bound.pos.x, bound.pos.x + bound.size.x);
r.pos.y = clampBetween(pos.y, bound.pos.y, bound.pos.y + bound.size.y);
r.size.x = rack::math::clamp(pos.x + size.x, bound.pos.x, bound.pos.x + bound.size.x) - r.pos.x;
r.size.y = rack::math::clamp(pos.y + size.y, bound.pos.y, bound.pos.y + bound.size.y) - r.pos.y;
r.size.x = rack::clamp(pos.x + size.x, bound.pos.x, bound.pos.x + bound.size.x) - r.pos.x;
r.size.y = rack::clamp(pos.y + size.y, bound.pos.y, bound.pos.y + bound.size.y) - r.pos.y;
return r;
}
/** Nudges the position to fix inside a bounding box */
@@ -307,18 +306,17 @@ struct Rect {

inline Vec Vec::clamp(Rect bound) const {
return Vec(
rack::math::clamp(x, bound.pos.x, bound.pos.x + bound.size.x),
rack::math::clamp(y, bound.pos.y, bound.pos.y + bound.size.y));
rack::clamp(x, bound.pos.x, bound.pos.x + bound.size.x),
rack::clamp(y, bound.pos.y, bound.pos.y + bound.size.y));
}

inline Vec Vec::clampBetween(Rect bound) const {
return Vec(
rack::math::clampBetween(x, bound.pos.x, bound.pos.x + bound.size.x),
rack::math::clampBetween(y, bound.pos.y, bound.pos.y + bound.size.y));
rack::clampBetween(x, bound.pos.x, bound.pos.x + bound.size.x),
rack::clampBetween(y, bound.pos.y, bound.pos.y + bound.size.y));
}

inline Vec Vec::clamp2(Rect bound) const {return clampBetween(bound);}


} // namespace math
} // namespace rack

+ 0
- 11
include/rack.hpp View File

@@ -16,14 +16,3 @@
#include "app.hpp"
#include "ui.hpp"
#include "helpers.hpp"


namespace rack {


// Adopt some sub-namespaces into the main namespace for convenience
using namespace math;
using string::stringf;


} // namespace rack

+ 1
- 1
include/rack0.hpp View File

@@ -110,7 +110,7 @@ DEPRECATED static const NVGcolor COLOR_DARK_PANEL = SCHEME_DARK_PANEL;
////////////////////

template <class TScrew>
DEPRECATED TScrew *createScrew(math::Vec pos) {
DEPRECATED TScrew *createScrew(Vec pos) {
return createWidget<TScrew>(pos);
}



+ 11
- 62
include/string.hpp View File

@@ -10,70 +10,19 @@ namespace string {


/** Converts a printf format string and optional arguments into a std::string */
inline std::string stringf(const char *format, ...) {
va_list args;
va_start(args, format);
// Compute size of required buffer
int size = vsnprintf(NULL, 0, format, args);
va_end(args);
if (size < 0)
return "";
// Create buffer
std::string s;
s.resize(size);
va_start(args, format);
vsnprintf(&s[0], size + 1, format, args);
va_end(args);
return s;
}

inline std::string lowercase(std::string s) {
std::transform(s.begin(), s.end(), s.begin(), ::tolower);
return s;
}

inline std::string uppercase(std::string s) {
std::transform(s.begin(), s.end(), s.begin(), ::toupper);
return s;
}

std::string f(const char *format, ...);
/** Replaces all characters to lowercase letters */
std::string lowercase(std::string s);
/** Replaces all characters to uppercase letters */
std::string uppercase(std::string s);
/** Truncates and adds "..." to a string, not exceeding `len` characters */
inline std::string ellipsize(std::string s, size_t len) {
if (s.size() <= len)
return s;
else
return s.substr(0, len - 3) + "...";
}

inline bool startsWith(std::string str, std::string prefix) {
return str.substr(0, prefix.size()) == prefix;
}

inline bool endsWith(std::string str, std::string suffix) {
return str.substr(str.size() - suffix.size(), suffix.size()) == suffix;
}

std::string ellipsize(std::string s, size_t len);
bool startsWith(std::string str, std::string prefix);
bool endsWith(std::string str, std::string suffix);
/** Extracts portions of a path */
inline std::string directory(std::string path) {
char *pathDup = strdup(path.c_str());
std::string directory = dirname(pathDup);
free(pathDup);
return directory;
}

inline std::string filename(std::string path) {
char *pathDup = strdup(path.c_str());
std::string filename = basename(pathDup);
free(pathDup);
return filename;
}

inline std::string extension(std::string path) {
const char *ext = strrchr(filename(path).c_str(), '.');
if (!ext)
return "";
return ext + 1;
}
std::string directory(std::string path);
std::string filename(std::string path);
std::string extension(std::string path);

struct CaseInsensitiveCompare {
bool operator()(const std::string &a, const std::string &b) const {


+ 1
- 1
include/ui/IconButton.hpp View File

@@ -17,7 +17,7 @@ struct IconButton : Button {
addChild(fw);

sw = new SVGWidget;
sw->box.pos = math::Vec(2, 2);
sw->box.pos = Vec(2, 2);
fw->addChild(sw);
}



+ 1
- 1
include/ui/List.hpp View File

@@ -15,7 +15,7 @@ struct List : OpaqueWidget {
if (!child->visible)
continue;
// Increment height, set position of child
child->box.pos = math::Vec(0.0, box.size.y);
child->box.pos = Vec(0.0, box.size.y);
box.size.y += child->box.size.y;
// Resize width of child
child->box.size.x = box.size.x;


+ 3
- 3
include/ui/Menu.hpp View File

@@ -12,7 +12,7 @@ struct Menu : OpaqueWidget {
MenuEntry *activeEntry = NULL;

Menu() {
box.size = math::Vec(0, 0);
box.size = Vec(0, 0);
}

~Menu() {
@@ -42,12 +42,12 @@ struct Menu : OpaqueWidget {
Widget::step();

// Set positions of children
box.size = math::Vec(0, 0);
box.size = Vec(0, 0);
for (Widget *child : children) {
if (!child->visible)
continue;
// Increment height, set position of child
child->box.pos = math::Vec(0, box.size.y);
child->box.pos = Vec(0, box.size.y);
box.size.y += child->box.size.y;
// Increase width based on maximum width of child
if (child->box.size.x > box.size.x) {


+ 1
- 1
include/ui/MenuEntry.hpp View File

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

struct MenuEntry : OpaqueWidget {
MenuEntry() {
box.size = math::Vec(0, BND_WIDGET_HEIGHT);
box.size = Vec(0, BND_WIDGET_HEIGHT);
}
};



+ 1
- 1
include/ui/ProgressBar.hpp View File

@@ -11,7 +11,7 @@ struct ProgressBar : QuantityWidget {
}

void draw(NVGcontext *vg) override {
float progress = math::rescale(value, minValue, maxValue, 0.0, 1.0);
float progress = rescale(value, minValue, maxValue, 0.0, 1.0);
bndSlider(vg, 0.0, 0.0, box.size.x, box.size.y, BND_CORNER_ALL, BND_DEFAULT, progress, getText().c_str(), NULL);
}
};


+ 10
- 10
include/ui/ScrollWidget.hpp View File

@@ -18,7 +18,7 @@ struct ScrollBar : OpaqueWidget {
float size = 0.0;

ScrollBar() {
box.size = math::Vec(BND_SCROLLBAR_WIDTH, BND_SCROLLBAR_HEIGHT);
box.size = Vec(BND_SCROLLBAR_WIDTH, BND_SCROLLBAR_HEIGHT);
}

void draw(NVGcontext *vg) override {
@@ -44,7 +44,7 @@ struct ScrollWidget : OpaqueWidget {
Widget *container;
ScrollBar *horizontalScrollBar;
ScrollBar *verticalScrollBar;
math::Vec offset;
Vec offset;

ScrollWidget() {
container = new Widget;
@@ -61,8 +61,8 @@ struct ScrollWidget : OpaqueWidget {
addChild(verticalScrollBar);
}

void scrollTo(math::Rect r) {
math::Rect bound = math::Rect::fromMinMax(r.getBottomRight().minus(box.size), r.pos);
void scrollTo(Rect r) {
Rect bound = Rect::fromMinMax(r.getBottomRight().minus(box.size), r.pos);
offset = offset.clampBetween(bound);
}

@@ -76,8 +76,8 @@ struct ScrollWidget : OpaqueWidget {
Widget::step();

// Clamp scroll offset
math::Vec containerCorner = container->getChildrenBoundingBox().getBottomRight();
math::Rect containerBox = math::Rect(math::Vec(0, 0), containerCorner.minus(box.size));
Vec containerCorner = container->getChildrenBoundingBox().getBottomRight();
Rect containerBox = Rect(Vec(0, 0), containerCorner.minus(box.size));
offset = offset.clamp(containerBox);
// Lock offset to top/left if no scrollbar will display
if (containerBox.size.x < 0.0)
@@ -89,9 +89,9 @@ struct ScrollWidget : OpaqueWidget {
container->box.pos = offset.neg().round();

// Update scrollbar offsets and sizes
math::Vec viewportSize = container->getChildrenBoundingBox().getBottomRight();
math::Vec scrollbarOffset = offset.div(viewportSize.minus(box.size));
math::Vec scrollbarSize = box.size.div(viewportSize);
Vec viewportSize = container->getChildrenBoundingBox().getBottomRight();
Vec scrollbarOffset = offset.div(viewportSize.minus(box.size));
Vec scrollbarSize = box.size.div(viewportSize);

horizontalScrollBar->visible = (0.0 < scrollbarSize.x && scrollbarSize.x < 1.0);
verticalScrollBar->visible = (0.0 < scrollbarSize.y && scrollbarSize.y < 1.0);
@@ -101,7 +101,7 @@ struct ScrollWidget : OpaqueWidget {
verticalScrollBar->size = scrollbarSize.y;

// Resize scroll bars
math::Vec inner = math::Vec(box.size.x - verticalScrollBar->box.size.x, box.size.y - horizontalScrollBar->box.size.y);
Vec inner = Vec(box.size.x - verticalScrollBar->box.size.x, box.size.y - horizontalScrollBar->box.size.y);
horizontalScrollBar->box.pos.y = inner.y;
verticalScrollBar->box.pos.x = inner.x;
horizontalScrollBar->box.size.x = verticalScrollBar->visible ? inner.x : box.size.x;


+ 1
- 1
include/ui/Slider.hpp View File

@@ -16,7 +16,7 @@ struct Slider : OpaqueWidget, QuantityWidget {
}

void draw(NVGcontext *vg) override {
float progress = math::rescale(value, minValue, maxValue, 0.0, 1.0);
float progress = rescale(value, minValue, maxValue, 0.0, 1.0);
bndSlider(vg, 0.0, 0.0, box.size.x, box.size.y, BND_CORNER_NONE, state, progress, getText().c_str(), NULL);
}



+ 3
- 3
include/ui/TextField.hpp View File

@@ -183,8 +183,8 @@ struct TextField : OpaqueWidget {
} break;
}

cursor = math::clamp(cursor, 0, (int) text.size());
selection = math::clamp(selection, 0, (int) text.size());
cursor = clamp(cursor, 0, (int) text.size());
selection = clamp(selection, 0, (int) text.size());
e.target = this;
}

@@ -210,7 +210,7 @@ struct TextField : OpaqueWidget {
onChange(eChange);
}

virtual int getTextPosition(math::Vec mousePos) {
virtual int getTextPosition(Vec mousePos) {
return bndTextFieldTextPosition(gVg, 0.0, 0.0, box.size.x, box.size.y, -1, text.c_str(), mousePos.x, mousePos.y);
}
};


+ 2
- 2
include/widgets/QuantityWidget.hpp View File

@@ -24,7 +24,7 @@ struct QuantityWidget : virtual Widget {
}

void setValue(float value) {
this->value = math::clampBetween(value, minValue, maxValue);
this->value = clampBetween(value, minValue, maxValue);
event::Change e;
onChange(e);
}
@@ -41,7 +41,7 @@ struct QuantityWidget : virtual Widget {

/** Generates the display value */
std::string getText() {
return string::stringf("%s: %.*f%s", label.c_str(), precision, value, unit.c_str());
return string::f("%s: %.*f%s", label.c_str(), precision, value, unit.c_str());
}
};



+ 2
- 2
include/widgets/SVGWidget.hpp View File

@@ -12,10 +12,10 @@ struct SVGWidget : virtual Widget {
/** Sets the box size to the svg image size */
void wrap() {
if (svg && svg->handle) {
box.size = math::Vec(svg->handle->width, svg->handle->height);
box.size = Vec(svg->handle->width, svg->handle->height);
}
else {
box.size = math::Vec();
box.size = Vec();
}
}



+ 2
- 2
include/widgets/TransformWidget.hpp View File

@@ -18,7 +18,7 @@ struct TransformWidget : virtual Widget {
nvgTransformIdentity(transform);
}

void translate(math::Vec delta) {
void translate(Vec delta) {
float t[6];
nvgTransformTranslate(t, delta.x, delta.y);
nvgTransformPremultiply(transform, t);
@@ -30,7 +30,7 @@ struct TransformWidget : virtual Widget {
nvgTransformPremultiply(transform, t);
}

void scale(math::Vec s) {
void scale(Vec s) {
float t[6];
nvgTransformScale(t, s.x, s.y);
nvgTransformPremultiply(transform, t);


+ 6
- 13
include/widgets/Widget.hpp View File

@@ -10,20 +10,13 @@
namespace rack {


namespace event {

struct Event;

} // namespace event


/** A node in the 2D scene graph
It is recommended to inherit virtually from Widget instead of directly.
e.g. `struct MyWidget : virtual Widget {}`
*/
struct Widget {
/** Stores position and size */
math::Rect box = math::Rect(math::Vec(), math::Vec(INFINITY, INFINITY));
Rect box = Rect(Vec(), Vec(INFINITY, INFINITY));
/** Automatically set when Widget is added as a child to another Widget */
Widget *parent = NULL;
std::list<Widget*> children;
@@ -34,15 +27,15 @@ struct Widget {

virtual ~Widget();

virtual math::Rect getChildrenBoundingBox();
virtual Rect getChildrenBoundingBox();
/** Returns `v` transformed into the coordinate system of `relative` */
virtual math::Vec getRelativeOffset(math::Vec v, Widget *relative);
virtual Vec getRelativeOffset(Vec v, Widget *relative);
/** Returns `v` transformed into world coordinates */
math::Vec getAbsoluteOffset(math::Vec v) {
Vec getAbsoluteOffset(Vec v) {
return getRelativeOffset(v, NULL);
}
/** Returns a subset of the given math::Rect bounded by the box of this widget and all ancestors */
virtual math::Rect getViewport(math::Rect r);
/** Returns a subset of the given Rect bounded by the box of this widget and all ancestors */
virtual Rect getViewport(Rect r);

template <class T>
T *getAncestorOfType() {


+ 2
- 2
include/widgets/ZoomWidget.hpp View File

@@ -8,11 +8,11 @@ namespace rack {
struct ZoomWidget : virtual Widget {
float zoom = 1.f;

math::Vec getRelativeOffset(math::Vec v, Widget *relative) override {
Vec getRelativeOffset(Vec v, Widget *relative) override {
return Widget::getRelativeOffset(v.mult(zoom), relative);
}

math::Rect getViewport(math::Rect r) override {
Rect getViewport(Rect r) override {
r.pos = r.pos.mult(zoom);
r.size = r.size.mult(zoom);
r = Widget::getViewport(r);


+ 5
- 5
include/window.hpp View File

@@ -57,7 +57,7 @@ This is not equal to gPixelRatio in general.
extern float gWindowRatio;
extern bool gAllowCursorLock;
extern int gGuiFrame;
extern math::Vec gMousePos;
extern Vec gMousePos;


void windowInit();
@@ -68,10 +68,10 @@ void windowCursorLock();
void windowCursorUnlock();
bool windowIsModPressed();
bool windowIsShiftPressed();
math::Vec windowGetWindowSize();
void windowSetWindowSize(math::Vec size);
math::Vec windowGetWindowPos();
void windowSetWindowPos(math::Vec pos);
Vec windowGetWindowSize();
void windowSetWindowSize(Vec size);
Vec windowGetWindowPos();
void windowSetWindowPos(Vec pos);
bool windowIsMaximized();
void windowSetTheme(NVGcolor bg, NVGcolor fg);
void windowSetFullScreen(bool fullScreen);


+ 2
- 2
src/Core/MIDICCToCVInterface.cpp View File

@@ -122,13 +122,13 @@ struct MidiCcChoice : GridChoice {
void step() override {
if (module->learningId == id) {
if (0 <= focusCc)
text = string::stringf("%d", focusCc);
text = string::f("%d", focusCc);
else
text = "LRN";
color.a = 0.5;
}
else {
text = string::stringf("%d", module->learnedCcs[id]);
text = string::f("%d", module->learnedCcs[id]);
color.a = 1.0;
if (gWidgetState->selectedWidget == this)
gWidgetState->selectedWidget = NULL;


+ 1
- 1
src/Core/MIDIToCVInterface.cpp View File

@@ -317,7 +317,7 @@ struct MIDIToCVInterfaceWidget : ModuleWidget {

menu->addChild(construct<MenuLabel>());
for (int i = 0; i < 2; i++) {
ClockItem *item = createMenuItem<ClockItem>(string::stringf("CLK %d rate", i + 1));
ClockItem *item = createMenuItem<ClockItem>(string::f("CLK %d rate", i + 1));
item->module = module;
item->index = i;
menu->addChild(item);


+ 1
- 1
src/Core/MIDITriggerToCVInterface.cpp View File

@@ -169,7 +169,7 @@ struct MidiTrigChoice : GridChoice {
};
int oct = note / 12 - 1;
int semi = note % 12;
text = string::stringf("%s%d", noteNames[semi], oct);
text = string::f("%s%d", noteNames[semi], oct);
color.a = 1.0;

if (gWidgetState->selectedWidget == this)


+ 6
- 6
src/WidgetState.cpp View File

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


void WidgetState::handleButton(math::Vec pos, int button, int action, int mods) {
void WidgetState::handleButton(Vec pos, int button, int action, int mods) {
// event::Button
event::Button eButton;
eButton.pos = pos;
@@ -74,7 +74,7 @@ void WidgetState::handleButton(math::Vec pos, int button, int action, int mods)
}


void WidgetState::handleHover(math::Vec pos, math::Vec mouseDelta) {
void WidgetState::handleHover(Vec pos, Vec mouseDelta) {
if (draggedWidget) {
// event::DragMove
event::DragMove eDragMove;
@@ -148,7 +148,7 @@ void WidgetState::handleLeave() {
hoveredWidget = NULL;
}

void WidgetState::handleScroll(math::Vec pos, math::Vec scrollDelta) {
void WidgetState::handleScroll(Vec pos, Vec scrollDelta) {
// event::HoverScroll
event::HoverScroll eHoverScroll;
eHoverScroll.pos = pos;
@@ -156,7 +156,7 @@ void WidgetState::handleScroll(math::Vec pos, math::Vec scrollDelta) {
rootWidget->onHoverScroll(eHoverScroll);
}

void WidgetState::handleDrop(math::Vec pos, std::vector<std::string> paths) {
void WidgetState::handleDrop(Vec pos, std::vector<std::string> paths) {
// event::PathDrop
event::PathDrop ePathDrop;
ePathDrop.pos = pos;
@@ -164,7 +164,7 @@ void WidgetState::handleDrop(math::Vec pos, std::vector<std::string> paths) {
rootWidget->onPathDrop(ePathDrop);
}

void WidgetState::handleText(math::Vec pos, int codepoint) {
void WidgetState::handleText(Vec pos, int codepoint) {
if (selectedWidget) {
// event::SelectText
event::SelectText eSelectText;
@@ -181,7 +181,7 @@ void WidgetState::handleText(math::Vec pos, int codepoint) {
rootWidget->onHoverText(eHoverText);
}

void WidgetState::handleKey(math::Vec pos, int key, int scancode, int action, int mods) {
void WidgetState::handleKey(Vec pos, int key, int scancode, int action, int mods) {
if (selectedWidget) {
// event::SelectKey
event::SelectKey eSelectKey;


+ 6
- 6
src/app/AudioWidget.cpp View File

@@ -107,13 +107,13 @@ struct AudioSampleRateChoice : LedDisplayChoice {
AudioSampleRateItem *item = new AudioSampleRateItem;
item->audioIO = audioWidget->audioIO;
item->sampleRate = sampleRate;
item->text = string::stringf("%d Hz", sampleRate);
item->text = string::f("%d Hz", sampleRate);
item->rightText = CHECKMARK(item->sampleRate == audioWidget->audioIO->sampleRate);
menu->addChild(item);
}
}
void step() override {
text = string::stringf("%g kHz", audioWidget->audioIO->sampleRate / 1000.f);
text = string::f("%g kHz", audioWidget->audioIO->sampleRate / 1000.f);
}
};

@@ -140,21 +140,21 @@ struct AudioBlockSizeChoice : LedDisplayChoice {
item->audioIO = audioWidget->audioIO;
item->blockSize = blockSize;
float latency = (float) blockSize / audioWidget->audioIO->sampleRate * 1000.0;
item->text = string::stringf("%d (%.1f ms)", blockSize, latency);
item->text = string::f("%d (%.1f ms)", blockSize, latency);
item->rightText = CHECKMARK(item->blockSize == audioWidget->audioIO->blockSize);
menu->addChild(item);
}
}
void step() override {
text = string::stringf("%d", audioWidget->audioIO->blockSize);
text = string::f("%d", audioWidget->audioIO->blockSize);
}
};


AudioWidget::AudioWidget() {
box.size = mm2px(math::Vec(44, 28));
box.size = mm2px(Vec(44, 28));

math::Vec pos = math::Vec();
Vec pos = Vec();

AudioDriverChoice *driverChoice = createWidget<AudioDriverChoice>(pos);
driverChoice->audioWidget = this;


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

@@ -15,7 +15,7 @@ void CircularShadow::draw(NVGcontext *vg) {

nvgBeginPath(vg);
nvgRect(vg, -blurRadius, -blurRadius, box.size.x + 2*blurRadius, box.size.y + 2*blurRadius);
math::Vec center = box.size.div(2.0);
Vec center = box.size.div(2.0);
float radius = center.x;
NVGcolor icol = nvgRGBAf(0.0, 0.0, 0.0, opacity);
NVGcolor ocol = nvgRGBAf(0.0, 0.0, 0.0, 0.0);


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

@@ -36,7 +36,7 @@ void Knob::onDragMove(event::DragMove &e) {
if (windowIsModPressed())
delta /= 16.f;
dragValue += delta;
dragValue = math::clampBetween(dragValue, minValue, maxValue);
dragValue = clampBetween(dragValue, minValue, maxValue);
if (snap)
setValue(std::round(dragValue));
else


+ 5
- 5
src/app/LedDisplay.cpp View File

@@ -18,7 +18,7 @@ void LedDisplay::draw(NVGcontext *vg) {


LedDisplaySeparator::LedDisplaySeparator() {
box.size = math::Vec();
box.size = Vec();
}

void LedDisplaySeparator::draw(NVGcontext *vg) {
@@ -32,10 +32,10 @@ void LedDisplaySeparator::draw(NVGcontext *vg) {


LedDisplayChoice::LedDisplayChoice() {
box.size = mm2px(math::Vec(0, 28.0 / 3));
box.size = mm2px(Vec(0, 28.0 / 3));
font = Font::load(asset::global("res/fonts/ShareTechMono-Regular.ttf"));
color = nvgRGB(0xff, 0xd7, 0x14);
textOffset = math::Vec(10, 18);
textOffset = Vec(10, 18);
}

void LedDisplayChoice::draw(NVGcontext *vg) {
@@ -65,7 +65,7 @@ void LedDisplayChoice::onButton(event::Button &e) {
LedDisplayTextField::LedDisplayTextField() {
font = Font::load(asset::global("res/fonts/ShareTechMono-Regular.ttf"));
color = nvgRGB(0xff, 0xd7, 0x14);
textOffset = math::Vec(5, 5);
textOffset = Vec(5, 5);
}


@@ -96,7 +96,7 @@ void LedDisplayTextField::draw(NVGcontext *vg) {
nvgResetScissor(vg);
}

int LedDisplayTextField::getTextPosition(math::Vec mousePos) {
int LedDisplayTextField::getTextPosition(Vec mousePos) {
bndSetFont(font->handle);
int textPos = bndIconLabelTextPosition(gVg, textOffset.x, textOffset.y,
box.size.x - 2*textOffset.x, box.size.y - 2*textOffset.y,


+ 2
- 2
src/app/MidiWidget.cpp View File

@@ -111,9 +111,9 @@ struct MidiChannelChoice : LedDisplayChoice {


MidiWidget::MidiWidget() {
box.size = mm2px(math::Vec(44, 28));
box.size = mm2px(Vec(44, 28));

math::Vec pos = math::Vec();
Vec pos = Vec();

MidiDriverChoice *driverChoice = createWidget<MidiDriverChoice>(pos);
driverChoice->midiWidget = this;


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

@@ -58,7 +58,7 @@ struct SeparatorItem : OpaqueWidget {

void setText(std::string text) {
clearChildren();
Label *label = createWidget<Label>(math::Vec(0, 12 + itemMargin));
Label *label = createWidget<Label>(Vec(0, 12 + itemMargin));
label->text = text;
label->fontSize = 20;
label->color.a *= 0.5;
@@ -109,7 +109,7 @@ struct ModelItem : BrowserListItem {
assert(model);
this->model = model;

FavoriteRadioButton *favoriteButton = createWidget<FavoriteRadioButton>(math::Vec(8, itemMargin));
FavoriteRadioButton *favoriteButton = createWidget<FavoriteRadioButton>(Vec(8, itemMargin));
favoriteButton->box.size.x = 20;
favoriteButton->label = "★";
addChild(favoriteButton);
@@ -124,7 +124,7 @@ struct ModelItem : BrowserListItem {
nameLabel->text = model->name;
addChild(nameLabel);

pluginLabel = createWidget<Label>(math::Vec(0, itemMargin));
pluginLabel = createWidget<Label>(Vec(0, itemMargin));
pluginLabel->alignment = Label::RIGHT_ALIGNMENT;
pluginLabel->text = model->plugin->slug + " " + model->plugin->version;
pluginLabel->color.a = 0.5;
@@ -155,7 +155,7 @@ struct AuthorItem : BrowserListItem {
void setAuthor(std::string author) {
clearChildren();
this->author = author;
Label *authorLabel = createWidget<Label>(math::Vec(0, 0 + itemMargin));
Label *authorLabel = createWidget<Label>(Vec(0, 0 + itemMargin));
if (author.empty())
authorLabel->text = "Show all modules";
else
@@ -173,7 +173,7 @@ struct TagItem : BrowserListItem {
void setTag(ModelTag tag) {
clearChildren();
this->tag = tag;
Label *tagLabel = createWidget<Label>(math::Vec(0, 0 + itemMargin));
Label *tagLabel = createWidget<Label>(Vec(0, 0 + itemMargin));
if (tag == NO_TAG)
tagLabel->text = "Show all tags";
else
@@ -187,7 +187,7 @@ struct TagItem : BrowserListItem {

struct ClearFilterItem : BrowserListItem {
ClearFilterItem() {
Label *label = createWidget<Label>(math::Vec(0, 0 + itemMargin));
Label *label = createWidget<Label>(Vec(0, 0 + itemMargin));
label->text = "Back";
addChild(label);
}
@@ -215,7 +215,7 @@ struct BrowserList : List {

void incrementSelection(int delta) {
selected += delta;
selected = math::clamp(selected, 0, countItems() - 1);
selected = clamp(selected, 0, countItems() - 1);
}

int countItems() {
@@ -296,7 +296,7 @@ struct ModuleBrowser : OpaqueWidget {
addChild(searchField);

moduleList = new BrowserList;
moduleList->box.size = math::Vec(box.size.x, 0.0);
moduleList->box.size = Vec(box.size.x, 0.0);

// Module Scroll
moduleScroll = new ScrollWidget;


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

@@ -12,7 +12,7 @@ void ModuleLightWidget::step() {

for (size_t i = 0; i < baseColors.size(); i++) {
float value = module->lights[firstLightId + i].getBrightness();
value = math::clamp(value, 0.f, 1.f);
value = clamp(value, 0.f, 1.f);
values[i] = value;
}
setValues(values);


+ 5
- 5
src/app/ModuleWidget.cpp View File

@@ -199,7 +199,7 @@ void ModuleWidget::load(std::string filename) {
json_decref(moduleJ);
}
else {
std::string message = string::stringf("JSON parsing error at %s %d:%d %s", error.source, error.line, error.column, error.text);
std::string message = string::f("JSON parsing error at %s %d:%d %s", error.source, error.line, error.column, error.text);
osdialog_message(OSDIALOG_WARNING, OSDIALOG_OK, message.c_str());
}

@@ -300,13 +300,13 @@ void ModuleWidget::draw(NVGcontext *vg) {
nvgFillColor(vg, nvgRGBAf(0, 0, 0, 0.5));
nvgFill(vg);

std::string cpuText = string::stringf("%.0f mS", module->cpuTime * 1000.f);
std::string cpuText = string::f("%.0f mS", module->cpuTime * 1000.f);
nvgFontFaceId(vg, gGuiFont->handle);
nvgFontSize(vg, 12);
nvgFillColor(vg, nvgRGBf(1, 1, 1));
nvgText(vg, 10.0, box.size.y - 6.0, cpuText.c_str(), NULL);

float p = math::clamp(module->cpuTime, 0.f, 1.f);
float p = clamp(module->cpuTime, 0.f, 1.f);
nvgBeginPath(vg);
nvgRect(vg,
0, (1.f - p) * box.size.y,
@@ -322,7 +322,7 @@ void ModuleWidget::drawShadow(NVGcontext *vg) {
nvgBeginPath(vg);
float r = 20; // Blur radius
float c = 20; // Corner radius
math::Vec b = math::Vec(-10, 30); // Offset from each corner
Vec b = Vec(-10, 30); // Offset from each corner
nvgRect(vg, b.x - r, b.y - r, box.size.x - 2*b.x + 2*r, box.size.y - 2*b.y + 2*r);
NVGcolor shadowColor = nvgRGBAf(0, 0, 0, 0.2);
NVGcolor transparentColor = nvgRGBAf(0, 0, 0, 0);
@@ -411,7 +411,7 @@ void ModuleWidget::onDragEnd(event::DragEnd &e) {

void ModuleWidget::onDragMove(event::DragMove &e) {
if (!gRackWidget->lockModules) {
math::Rect newBox = box;
Rect newBox = box;
newBox.pos = gRackWidget->lastMousePos.minus(dragPos);
gRackWidget->requestModuleBoxNearest(this, newBox);
}


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

@@ -14,7 +14,7 @@ void MultiLightWidget::setValues(const std::vector<float> &values) {
color = nvgRGBAf(0, 0, 0, 0);
for (size_t i = 0; i < baseColors.size(); i++) {
NVGcolor c = baseColors[i];
c.a *= math::clamp(values[i], 0.f, 1.f);
c.a *= clamp(values[i], 0.f, 1.f);
color = color::screen(color, c);
}
color = color::clip(color);


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

@@ -32,7 +32,7 @@ void ParamWidget::reset() {
void ParamWidget::randomize() {
// Infinite params should not be randomized
if (randomizable && std::isfinite(minValue) && std::isfinite(maxValue)) {
setValue(math::rescale(random::uniform(), 0.f, 1.f, minValue, maxValue));
setValue(rescale(random::uniform(), 0.f, 1.f, minValue, maxValue));
}
}



+ 3
- 3
src/app/PluginManagerWidget.cpp View File

@@ -125,7 +125,7 @@ PluginManagerWidget::PluginManagerWidget() {
box.size.y = BND_WIDGET_HEIGHT;

{
SequentialLayout *layout = createWidget<SequentialLayout>(math::Vec(0, 0));
SequentialLayout *layout = createWidget<SequentialLayout>(Vec(0, 0));
layout->spacing = 5;
loginWidget = layout;

@@ -158,7 +158,7 @@ PluginManagerWidget::PluginManagerWidget() {
}

{
SequentialLayout *layout = createWidget<SequentialLayout>(math::Vec(0, 0));
SequentialLayout *layout = createWidget<SequentialLayout>(Vec(0, 0));
layout->spacing = 5;
manageWidget = layout;

@@ -181,7 +181,7 @@ PluginManagerWidget::PluginManagerWidget() {
}

{
SequentialLayout *layout = createWidget<SequentialLayout>(math::Vec(0, 0));
SequentialLayout *layout = createWidget<SequentialLayout>(Vec(0, 0));
layout->spacing = 5;
downloadWidget = layout;



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

@@ -11,7 +11,7 @@ struct PlugLight : MultiLightWidget {
PlugLight() {
addBaseColor(color::GREEN);
addBaseColor(color::RED);
box.size = math::Vec(8, 8);
box.size = Vec(8, 8);
bgColor = color::BLACK_TRANSPARENT;
}
};


+ 2
- 2
src/app/RackScene.cpp View File

@@ -32,7 +32,7 @@ void RackScene::step() {
// Resize to be a bit larger than the ScrollWidget viewport
gRackWidget->box.size = scrollWidget->box.size
.minus(scrollWidget->container->box.pos)
.plus(math::Vec(500, 500))
.plus(Vec(500, 500))
.div(zoomWidget->zoom);

Scene::step();
@@ -41,7 +41,7 @@ void RackScene::step() {

// Version popup message
if (!gLatestVersion.empty()) {
std::string versionMessage = string::stringf("Rack %s is available.\n\nYou have Rack %s.\n\nClose Rack and download new version on the website?", gLatestVersion.c_str(), gApplicationVersion.c_str());
std::string versionMessage = string::f("Rack %s is available.\n\nYou have Rack %s.\n\nClose Rack and download new version on the website?", gLatestVersion.c_str(), gApplicationVersion.c_str());
if (osdialog_message(OSDIALOG_INFO, OSDIALOG_OK_CANCEL, versionMessage.c_str())) {
std::thread t(system::openBrowser, "https://vcvrack.com/");
t.detach();


+ 2
- 2
src/app/RackScrollWidget.cpp View File

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


void RackScrollWidget::step() {
math::Vec pos = gMousePos;
math::Rect viewport = getViewport(box.zeroPos());
Vec pos = gMousePos;
Rect viewport = getViewport(box.zeroPos());
// Scroll rack if dragging cable near the edge of the screen
if (gRackWidget->wireContainer->activeWire) {
float margin = 20.0;


+ 20
- 20
src/app/RackWidget.cpp View File

@@ -28,11 +28,11 @@ struct ModuleContainer : Widget {

RackWidget::RackWidget() {
rails = new FramebufferWidget;
rails->box.size = math::Vec();
rails->box.size = Vec();
rails->oversample = 1.0;
{
RackRail *rail = new RackRail;
rail->box.size = math::Vec();
rail->box.size = Vec();
rails->addChild(rail);
}
addChild(rails);
@@ -52,7 +52,7 @@ void RackWidget::clear() {
wireContainer->clearChildren();
moduleContainer->clearChildren();

gRackScene->scrollWidget->offset = math::Vec(0, 0);
gRackScene->scrollWidget->offset = Vec(0, 0);
}

void RackWidget::reset() {
@@ -151,7 +151,7 @@ void RackWidget::load(std::string filename) {
json_decref(rootJ);
}
else {
std::string message = string::stringf("JSON parsing error at %s %d:%d %s", error.source, error.line, error.column, error.text);
std::string message = string::f("JSON parsing error at %s %d:%d %s", error.source, error.line, error.column, error.text);
osdialog_message(OSDIALOG_WARNING, OSDIALOG_OK, message.c_str());
}

@@ -198,7 +198,7 @@ json_t *RackWidget::toJson() {
json_t *moduleJ = moduleWidget->toJson();
{
// pos
math::Vec pos = moduleWidget->box.pos.div(RACK_GRID_SIZE).round();
Vec pos = moduleWidget->box.pos.div(RACK_GRID_SIZE).round();
json_t *posJ = json_pack("[i, i]", (int) pos.x, (int) pos.y);
json_object_set_new(moduleJ, "pos", posJ);
}
@@ -281,7 +281,7 @@ void RackWidget::fromJson(json_t *rootJ) {
json_t *posJ = json_object_get(moduleJ, "pos");
double x, y;
json_unpack(posJ, "[F, F]", &x, &y);
math::Vec pos = math::Vec(x, y);
Vec pos = Vec(x, y);
if (legacy && legacy <= 1) {
moduleWidget->box.pos = pos;
}
@@ -296,7 +296,7 @@ void RackWidget::fromJson(json_t *rootJ) {
json_t *modelSlugJ = json_object_get(moduleJ, "model");
std::string pluginSlug = json_string_value(pluginSlugJ);
std::string modelSlug = json_string_value(modelSlugJ);
message += string::stringf("Could not find module \"%s\" of plugin \"%s\"\n", modelSlug.c_str(), pluginSlug.c_str());
message += string::f("Could not find module \"%s\" of plugin \"%s\"\n", modelSlug.c_str(), pluginSlug.c_str());
}
}

@@ -395,7 +395,7 @@ void RackWidget::pastePresetClipboard() {
if (moduleJ) {
ModuleWidget *moduleWidget = moduleFromJson(moduleJ);
// Set moduleWidget position
math::Rect newBox = moduleWidget->box;
Rect newBox = moduleWidget->box;
newBox.pos = lastMousePos.minus(newBox.size.div(2));
requestModuleBoxNearest(moduleWidget, newBox);

@@ -421,12 +421,12 @@ void RackWidget::cloneModule(ModuleWidget *m) {
json_t *moduleJ = m->toJson();
ModuleWidget *clonedModuleWidget = moduleFromJson(moduleJ);
json_decref(moduleJ);
math::Rect clonedBox = clonedModuleWidget->box;
Rect clonedBox = clonedModuleWidget->box;
clonedBox.pos = m->box.pos;
requestModuleBoxNearest(clonedModuleWidget, clonedBox);
}

bool RackWidget::requestModuleBox(ModuleWidget *m, math::Rect box) {
bool RackWidget::requestModuleBox(ModuleWidget *m, Rect box) {
if (box.pos.x < 0 || box.pos.y < 0)
return false;

@@ -440,25 +440,25 @@ bool RackWidget::requestModuleBox(ModuleWidget *m, math::Rect box) {
return true;
}

bool RackWidget::requestModuleBoxNearest(ModuleWidget *m, math::Rect box) {
bool RackWidget::requestModuleBoxNearest(ModuleWidget *m, Rect box) {
// Create possible positions
int x0 = roundf(box.pos.x / RACK_GRID_WIDTH);
int y0 = roundf(box.pos.y / RACK_GRID_HEIGHT);
std::vector<math::Vec> positions;
std::vector<Vec> positions;
for (int y = std::max(0, y0 - 8); y < y0 + 8; y++) {
for (int x = std::max(0, x0 - 400); x < x0 + 400; x++) {
positions.push_back(math::Vec(x * RACK_GRID_WIDTH, y * RACK_GRID_HEIGHT));
positions.push_back(Vec(x * RACK_GRID_WIDTH, y * RACK_GRID_HEIGHT));
}
}

// Sort possible positions by distance to the requested position
std::sort(positions.begin(), positions.end(), [box](math::Vec a, math::Vec b) {
std::sort(positions.begin(), positions.end(), [box](Vec a, Vec b) {
return a.minus(box.pos).norm() < b.minus(box.pos).norm();
});

// Find a position that does not collide
for (math::Vec position : positions) {
math::Rect newBox = box;
for (Vec position : positions) {
Rect newBox = box;
newBox.pos = position;
if (requestModuleBox(m, newBox))
return true;
@@ -468,15 +468,15 @@ bool RackWidget::requestModuleBoxNearest(ModuleWidget *m, math::Rect box) {

void RackWidget::step() {
// Expand size to fit modules
math::Vec moduleSize = moduleContainer->getChildrenBoundingBox().getBottomRight();
Vec moduleSize = moduleContainer->getChildrenBoundingBox().getBottomRight();
// We assume that the size is reset by a parent before calling step(). Otherwise it will grow unbounded.
box.size = box.size.max(moduleSize);

// Adjust size and position of rails
Widget *rail = rails->children.front();
math::Rect bound = getViewport(math::Rect(math::Vec(), box.size));
Rect bound = getViewport(Rect(Vec(), box.size));
if (!rails->box.contains(bound)) {
math::Vec cellMargin = math::Vec(20, 1);
Vec cellMargin = Vec(20, 1);
rails->box.pos = bound.pos.div(RACK_GRID_SIZE).floor().minus(cellMargin).mult(RACK_GRID_SIZE);
rails->box.size = bound.size.plus(cellMargin.mult(RACK_GRID_SIZE).mult(2));
rails->dirty = true;
@@ -512,7 +512,7 @@ void RackWidget::onButton(event::Button &e) {
}

void RackWidget::onZoom(event::Zoom &e) {
rails->box.size = math::Vec();
rails->box.size = Vec();
OpaqueWidget::onZoom(e);
}



+ 6
- 6
src/app/SVGKnob.cpp View File

@@ -7,7 +7,7 @@ namespace rack {
SVGKnob::SVGKnob() {
shadow = new CircularShadow;
addChild(shadow);
shadow->box.size = math::Vec();
shadow->box.size = Vec();

tw = new TransformWidget;
addChild(tw);
@@ -21,8 +21,8 @@ void SVGKnob::setSVG(std::shared_ptr<SVG> svg) {
tw->box.size = sw->box.size;
box.size = sw->box.size;
shadow->box.size = sw->box.size;
shadow->box.pos = math::Vec(0, sw->box.size.y * 0.1);
// shadow->box = shadow->box.grow(math::Vec(2, 2));
shadow->box.pos = Vec(0, sw->box.size.y * 0.1);
// shadow->box = shadow->box.grow(Vec(2, 2));
}

void SVGKnob::step() {
@@ -30,15 +30,15 @@ void SVGKnob::step() {
if (dirty) {
float angle;
if (std::isfinite(minValue) && std::isfinite(maxValue)) {
angle = math::rescale(value, minValue, maxValue, minAngle, maxAngle);
angle = rescale(value, minValue, maxValue, minAngle, maxAngle);
}
else {
angle = math::rescale(value, -1.0, 1.0, minAngle, maxAngle);
angle = rescale(value, -1.0, 1.0, minAngle, maxAngle);
angle = std::fmod(angle, 2*M_PI);
}
tw->identity();
// Rotate SVG
math::Vec center = sw->box.getCenter();
Vec center = sw->box.getCenter();
tw->translate(center);
tw->rotate(angle);
tw->translate(center.neg());


+ 3
- 3
src/app/SVGPort.cpp View File

@@ -9,7 +9,7 @@ SVGPort::SVGPort() {
addChild(shadow);
// Avoid breakage if plugins fail to call setSVG()
// In that case, just disable the shadow.
shadow->box.size = math::Vec();
shadow->box.size = Vec();

background = new SVGWidget;
addChild(background);
@@ -19,8 +19,8 @@ void SVGPort::setSVG(std::shared_ptr<SVG> svg) {
background->setSVG(svg);
box.size = background->box.size;
shadow->box.size = background->box.size;
shadow->box.pos = math::Vec(0, background->box.size.y * 0.1);
// shadow->box = shadow->box.grow(math::Vec(2, 2));
shadow->box.pos = Vec(0, background->box.size.y * 0.1);
// shadow->box = shadow->box.grow(Vec(2, 2));
}

void SVGPort::draw(NVGcontext *vg) {


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

@@ -25,7 +25,7 @@ void SVGSlider::setSVGs(std::shared_ptr<SVG> backgroundSVG, std::shared_ptr<SVG>
void SVGSlider::step() {
if (dirty) {
// Interpolate handle position
handle->box.pos = math::Vec(math::rescale(value, minValue, maxValue, minHandlePos.x, maxHandlePos.x), math::rescale(value, minValue, maxValue, minHandlePos.y, maxHandlePos.y));
handle->box.pos = Vec(rescale(value, minValue, maxValue, minHandlePos.x, maxHandlePos.x), rescale(value, minValue, maxValue, minHandlePos.y, maxHandlePos.y));
}
FramebufferWidget::step();
}


+ 2
- 2
src/app/SVGSwitch.cpp View File

@@ -20,8 +20,8 @@ void SVGSwitch::addFrame(std::shared_ptr<SVG> svg) {

void SVGSwitch::onChange(event::Change &e) {
assert(frames.size() > 0);
float valueScaled = math::rescale(value, minValue, maxValue, 0, frames.size() - 1);
int index = math::clamp((int) roundf(valueScaled), 0, (int) frames.size() - 1);
float valueScaled = rescale(value, minValue, maxValue, 0, frames.size() - 1);
int index = clamp((int) roundf(valueScaled), 0, (int) frames.size() - 1);
sw->setSVG(frames[index]);
dirty = true;
ParamWidget::onChange(e);


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

@@ -14,7 +14,7 @@ struct TooltipIconButton : IconButton {
void onEnter(event::Enter &e) override {
if (!tooltip) {
tooltip = new Tooltip;
tooltip->box.pos = getAbsoluteOffset(math::Vec(0, BND_WIDGET_HEIGHT));
tooltip->box.pos = getAbsoluteOffset(Vec(0, BND_WIDGET_HEIGHT));
tooltip->text = tooltipText;
gRackScene->addChild(tooltip);
}
@@ -121,7 +121,7 @@ struct SampleRateButton : TooltipIconButton {
}
void onAction(event::Action &e) override {
Menu *menu = createMenu();
menu->box.pos = getAbsoluteOffset(math::Vec(0, box.size.y));
menu->box.pos = getAbsoluteOffset(Vec(0, box.size.y));
menu->box.size.x = box.size.x;

menu->addChild(createMenuLabel("Engine sample rate"));
@@ -133,7 +133,7 @@ struct SampleRateButton : TooltipIconButton {
std::vector<float> sampleRates = {44100, 48000, 88200, 96000, 176400, 192000};
for (float sampleRate : sampleRates) {
SampleRateItem *item = new SampleRateItem;
item->text = string::stringf("%.0f Hz", sampleRate);
item->text = string::f("%.0f Hz", sampleRate);
item->rightText = CHECKMARK(engineGetSampleRate() == sampleRate);
item->sampleRate = sampleRate;
menu->addChild(item);
@@ -163,7 +163,7 @@ Toolbar::Toolbar() {
box.size.y = BND_WIDGET_HEIGHT + 2*5;

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



+ 11
- 11
src/app/WireWidget.cpp View File

@@ -7,7 +7,7 @@

namespace rack {

static void drawPlug(NVGcontext *vg, math::Vec pos, NVGcolor color) {
static void drawPlug(NVGcontext *vg, Vec pos, NVGcolor color) {
NVGcolor colorOutline = nvgLerpRGBA(color, nvgRGBf(0.0, 0.0, 0.0), 0.5);

// Plug solid
@@ -28,7 +28,7 @@ static void drawPlug(NVGcontext *vg, math::Vec pos, NVGcolor color) {
nvgFill(vg);
}

static void drawWire(NVGcontext *vg, math::Vec pos1, math::Vec pos2, NVGcolor color, float tension, float opacity) {
static void drawWire(NVGcontext *vg, Vec pos1, Vec pos2, NVGcolor color, float tension, float opacity) {
NVGcolor colorShadow = nvgRGBAf(0, 0, 0, 0.10);
NVGcolor colorOutline = nvgLerpRGBA(color, nvgRGBf(0.0, 0.0, 0.0), 0.5);

@@ -38,14 +38,14 @@ static void drawWire(NVGcontext *vg, math::Vec pos1, math::Vec pos2, NVGcolor co
nvgGlobalAlpha(vg, powf(opacity, 1.5));

float dist = pos1.minus(pos2).norm();
math::Vec slump;
Vec slump;
slump.y = (1.0 - tension) * (150.0 + 1.0*dist);
math::Vec pos3 = pos1.plus(pos2).div(2).plus(slump);
Vec pos3 = pos1.plus(pos2).div(2).plus(slump);

nvgLineJoin(vg, NVG_ROUND);

// Shadow
math::Vec pos4 = pos3.plus(slump.mult(0.08));
Vec pos4 = pos3.plus(slump.mult(0.08));
nvgBeginPath(vg);
nvgMoveTo(vg, pos1.x, pos1.y);
nvgQuadTo(vg, pos4.x, pos4.y, pos2.x, pos2.y);
@@ -119,7 +119,7 @@ void WireWidget::updateWire() {
}
}

math::Vec WireWidget::getOutputPos() {
Vec WireWidget::getOutputPos() {
if (outputPort) {
return outputPort->getRelativeOffset(outputPort->box.zeroPos().getCenter(), gRackWidget);
}
@@ -131,7 +131,7 @@ math::Vec WireWidget::getOutputPos() {
}
}

math::Vec WireWidget::getInputPos() {
Vec WireWidget::getInputPos() {
if (inputPort) {
return inputPort->getRelativeOffset(inputPort->box.zeroPos().getCenter(), gRackWidget);
}
@@ -177,15 +177,15 @@ void WireWidget::draw(NVGcontext *vg) {
opacity = 1.0;
}

math::Vec outputPos = getOutputPos();
math::Vec inputPos = getInputPos();
Vec outputPos = getOutputPos();
Vec inputPos = getInputPos();
drawWire(vg, outputPos, inputPos, color, tension, opacity);
}

void WireWidget::drawPlugs(NVGcontext *vg) {
// TODO Figure out a way to draw plugs first and wires last, and cut the plug portion of the wire off.
math::Vec outputPos = getOutputPos();
math::Vec inputPos = getInputPos();
Vec outputPos = getOutputPos();
Vec inputPos = getInputPos();
drawPlug(vg, outputPos, color);
drawPlug(vg, inputPos, color);



+ 6
- 6
src/audio.cpp View File

@@ -122,7 +122,7 @@ std::string AudioIO::getDeviceName(int device) {
return deviceInfo.name;
}
else if (driver == BRIDGE_DRIVER) {
return string::stringf("%d", device + 1);
return string::f("%d", device + 1);
}
return "";
}
@@ -134,19 +134,19 @@ std::string AudioIO::getDeviceDetail(int device, int offset) {
if (rtAudio) {
RtAudio::DeviceInfo deviceInfo;
if (getDeviceInfo(device, &deviceInfo)) {
std::string deviceDetail = string::stringf("%s (", deviceInfo.name.c_str());
std::string deviceDetail = string::f("%s (", deviceInfo.name.c_str());
if (offset < (int) deviceInfo.inputChannels)
deviceDetail += string::stringf("%d-%d in", offset + 1, std::min(offset + maxChannels, (int) deviceInfo.inputChannels));
deviceDetail += string::f("%d-%d in", offset + 1, std::min(offset + maxChannels, (int) deviceInfo.inputChannels));
if (offset < (int) deviceInfo.inputChannels && offset < (int) deviceInfo.outputChannels)
deviceDetail += ", ";
if (offset < (int) deviceInfo.outputChannels)
deviceDetail += string::stringf("%d-%d out", offset + 1, std::min(offset + maxChannels, (int) deviceInfo.outputChannels));
deviceDetail += string::f("%d-%d out", offset + 1, std::min(offset + maxChannels, (int) deviceInfo.outputChannels));
deviceDetail += ")";
return deviceDetail;
}
}
else if (driver == BRIDGE_DRIVER) {
return string::stringf("Port %d", device + 1);
return string::f("Port %d", device + 1);
}
return "";
}
@@ -226,7 +226,7 @@ void AudioIO::openStream() {
if (rtAudio->isStreamOpen())
return;

setChannels(math::clamp((int) deviceInfo.outputChannels - offset, 0, maxChannels), math::clamp((int) deviceInfo.inputChannels - offset, 0, maxChannels));
setChannels(clamp((int) deviceInfo.outputChannels - offset, 0, maxChannels), clamp((int) deviceInfo.inputChannels - offset, 0, maxChannels));

if (numOutputs == 0 && numInputs == 0) {
WARN("RtAudio device %d has 0 inputs and 0 outputs", device);


+ 1
- 1
src/bridge.cpp View File

@@ -383,7 +383,7 @@ std::vector<int> BridgeMidiDriver::getInputDeviceIds() {
std::string BridgeMidiDriver::getInputDeviceName(int deviceId) {
if (deviceId < 0)
return "";
return string::stringf("Port %d", deviceId + 1);
return string::f("Port %d", deviceId + 1);
}

MidiInputDevice *BridgeMidiDriver::subscribeInputDevice(int deviceId, MidiInput *midiInput) {


+ 3
- 3
src/gamepad.cpp View File

@@ -22,8 +22,8 @@ void InputDevice::step() {
// Convert axes to MIDI CC
ccs.resize(numAxes);
for (int i = 0; i < numAxes; i++) {
// Allow CC value to go negative, but math::clamp at -127 instead of -128 for symmetry
int8_t cc = math::clamp((int) std::round(axes[i] * 127), -127, 127);
// Allow CC value to go negative, but clamp at -127 instead of -128 for symmetry
int8_t cc = clamp((int) std::round(axes[i] * 127), -127, 127);
if (cc != ccs[i]) {
ccs[i] = cc;

@@ -78,7 +78,7 @@ std::string Driver::getInputDeviceName(int deviceId) {
if (name) {
return name;
}
return string::stringf(" %d (unavailable)", deviceId + 1);
return string::f(" %d (unavailable)", deviceId + 1);
}

MidiInputDevice *Driver::subscribeInputDevice(int deviceId, MidiInput *midiInput) {


+ 1
- 1
src/keyboard.cpp View File

@@ -61,7 +61,7 @@ void InputDevice::onKeyPress(int key) {
default: break;
}

octave = math::clamp(octave, 0, 9);
octave = clamp(octave, 0, 9);
if (note < 0)
return;



+ 1
- 1
src/midi.cpp View File

@@ -80,7 +80,7 @@ std::string MidiIO::getChannelName(int channel) {
if (channel == -1)
return "All channels";
else
return string::stringf("Channel %d", channel + 1);
return string::f("Channel %d", channel + 1);
}

json_t *MidiIO::toJson() {


+ 2
- 2
src/plugin.cpp View File

@@ -210,7 +210,7 @@ static void loadPlugins(std::string path) {
if (!system::isDirectory(pluginPath))
continue;
if (!loadPlugin(pluginPath)) {
message += string::stringf("Could not load plugin %s\n", pluginPath.c_str());
message += string::f("Could not load plugin %s\n", pluginPath.c_str());
}
}
if (!message.empty()) {
@@ -298,7 +298,7 @@ static void extractPackages(std::string path) {
// Extract package
if (extractZip(packagePath.c_str(), path.c_str())) {
WARN("Package %s failed to extract", packagePath.c_str());
message += string::stringf("Could not extract package %s\n", packagePath.c_str());
message += string::f("Could not extract package %s\n", packagePath.c_str());
continue;
}
// Remove package


+ 5
- 5
src/settings.cpp View File

@@ -20,12 +20,12 @@ static json_t *settingsToJson() {

if (!windowIsMaximized()) {
// windowSize
math::Vec windowSize = windowGetWindowSize();
Vec windowSize = windowGetWindowSize();
json_t *windowSizeJ = json_pack("[f, f]", windowSize.x, windowSize.y);
json_object_set_new(rootJ, "windowSize", windowSizeJ);

// windowPos
math::Vec windowPos = windowGetWindowPos();
Vec windowPos = windowGetWindowPos();
json_t *windowPosJ = json_pack("[f, f]", windowPos.x, windowPos.y);
json_object_set_new(rootJ, "windowPos", windowPosJ);
}
@@ -85,7 +85,7 @@ static void settingsFromJson(json_t *rootJ) {
if (windowSizeJ) {
double width, height;
json_unpack(windowSizeJ, "[F, F]", &width, &height);
windowSetWindowSize(math::Vec(width, height));
windowSetWindowSize(Vec(width, height));
}

// windowPos
@@ -93,7 +93,7 @@ static void settingsFromJson(json_t *rootJ) {
if (windowPosJ) {
double x, y;
json_unpack(windowPosJ, "[F, F]", &x, &y);
windowSetWindowPos(math::Vec(x, y));
windowSetWindowPos(Vec(x, y));
}

// opacity
@@ -109,7 +109,7 @@ static void settingsFromJson(json_t *rootJ) {
// zoom
json_t *zoomJ = json_object_get(rootJ, "zoom");
if (zoomJ) {
gRackScene->zoomWidget->setZoom(math::clamp((float) json_number_value(zoomJ), 0.25f, 4.0f));
gRackScene->zoomWidget->setZoom(clamp((float) json_number_value(zoomJ), 0.25f, 4.0f));
gToolbar->zoomSlider->setValue(json_number_value(zoomJ) * 100.0);
}



+ 75
- 0
src/string.cpp View File

@@ -0,0 +1,75 @@
#include "string.hpp"


namespace rack {
namespace string {


std::string f(const char *format, ...) {
va_list args;
va_start(args, format);
// Compute size of required buffer
int size = vsnprintf(NULL, 0, format, args);
va_end(args);
if (size < 0)
return "";
// Create buffer
std::string s;
s.resize(size);
va_start(args, format);
vsnprintf(&s[0], size + 1, format, args);
va_end(args);
return s;
}

std::string lowercase(std::string s) {
std::transform(s.begin(), s.end(), s.begin(), ::tolower);
return s;
}

std::string uppercase(std::string s) {
std::transform(s.begin(), s.end(), s.begin(), ::toupper);
return s;
}

/** Truncates and adds "..." to a string, not exceeding `len` characters */
std::string ellipsize(std::string s, size_t len) {
if (s.size() <= len)
return s;
else
return s.substr(0, len - 3) + "...";
}

bool startsWith(std::string str, std::string prefix) {
return str.substr(0, prefix.size()) == prefix;
}

bool endsWith(std::string str, std::string suffix) {
return str.substr(str.size() - suffix.size(), suffix.size()) == suffix;
}

/** Extracts portions of a path */
std::string directory(std::string path) {
char *pathDup = strdup(path.c_str());
std::string directory = dirname(pathDup);
free(pathDup);
return directory;
}

std::string filename(std::string path) {
char *pathDup = strdup(path.c_str());
std::string filename = basename(pathDup);
free(pathDup);
return filename;
}

std::string extension(std::string path) {
const char *ext = strrchr(filename(path).c_str(), '.');
if (!ext)
return "";
return ext + 1;
}


} // namespace network
} // namespace rack

+ 11
- 11
src/svg.cpp View File

@@ -25,7 +25,7 @@ static NVGpaint getPaint(NVGcontext *vg, NSVGpaint *p) {
float inverse[6];
nvgTransformInverse(inverse, g->xform);
DEBUG_ONLY(printf(" inverse: %f %f %f %f %f %f\n", inverse[0], inverse[1], inverse[2], inverse[3], inverse[4], inverse[5]);)
math::Vec s, e;
Vec s, e;
DEBUG_ONLY(printf(" sx: %f sy: %f ex: %f ey: %f\n", s.x, s.y, e.x, e.y);)
// Is it always the case that the gradient should be transformed from (0, 0) to (0, 1)?
nvgTransformPoint(&s.x, &s.y, inverse, 0, 0);
@@ -41,10 +41,10 @@ static NVGpaint getPaint(NVGcontext *vg, NSVGpaint *p) {
}

/** Returns the parameterized value of the line p2--p3 where it intersects with p0--p1 */
static float getLineCrossing(math::Vec p0, math::Vec p1, math::Vec p2, math::Vec p3) {
math::Vec b = p2.minus(p0);
math::Vec d = p1.minus(p0);
math::Vec e = p3.minus(p2);
static float getLineCrossing(Vec p0, Vec p1, Vec p2, Vec p3) {
Vec b = p2.minus(p0);
Vec d = p1.minus(p0);
Vec e = p3.minus(p2);
float m = d.x * e.y - d.y * e.x;
// Check if lines are parallel, or if either pair of points are equal
if (std::abs(m) < 1e-6)
@@ -93,8 +93,8 @@ void svgDraw(NVGcontext *vg, NSVGimage *svg) {
// Also assume that the topology is the same if we use straight lines rather than Beziers (not always the case but usually true).
// Using the even-odd fill rule, if we draw a line from a point on the path to a point outside the boundary (e.g. top left) and count the number of times it crosses another path, the parity of this count determines whether the path is a hole (odd) or solid (even).
int crossings = 0;
math::Vec p0 = math::Vec(path->pts[0], path->pts[1]);
math::Vec p1 = math::Vec(path->bounds[0] - 1.0, path->bounds[1] - 1.0);
Vec p0 = Vec(path->pts[0], path->pts[1]);
Vec p1 = Vec(path->bounds[0] - 1.0, path->bounds[1] - 1.0);
// Iterate all other paths
for (NSVGpath *path2 = shape->paths; path2; path2 = path2->next) {
if (path2 == path)
@@ -106,9 +106,9 @@ void svgDraw(NVGcontext *vg, NSVGimage *svg) {
for (int i = 1; i < path2->npts + 3; i += 3) {
float *p = &path2->pts[2*i];
// The previous point
math::Vec p2 = math::Vec(p[-2], p[-1]);
Vec p2 = Vec(p[-2], p[-1]);
// The current point
math::Vec p3 = (i < path2->npts) ? math::Vec(p[4], p[5]) : math::Vec(path2->pts[0], path2->pts[1]);
Vec p3 = (i < path2->npts) ? Vec(p[4], p[5]) : Vec(path2->pts[0], path2->pts[1]);
float crossing = getLineCrossing(p0, p1, p2, p3);
float crossing2 = getLineCrossing(p2, p3, p0, p1);
if (0.0 <= crossing && crossing < 1.0 && 0.0 <= crossing2) {
@@ -125,10 +125,10 @@ void svgDraw(NVGcontext *vg, NSVGimage *svg) {
/*
// Shoelace algorithm for computing the area, and thus the winding direction
float area = 0.0;
math::Vec p0 = math::Vec(path->pts[0], path->pts[1]);
Vec p0 = Vec(path->pts[0], path->pts[1]);
for (int i = 1; i < path->npts; i += 3) {
float *p = &path->pts[2*i];
math::Vec p1 = (i < path->npts) ? math::Vec(p[4], p[5]) : math::Vec(path->pts[0], path->pts[1]);
Vec p1 = (i < path->npts) ? Vec(p[4], p[5]) : Vec(path->pts[0], path->pts[1]);
area += 0.5 * (p1.x - p0.x) * (p1.y + p0.y);
printf("%f %f, %f %f\n", p0.x, p0.y, p1.x, p1.y);
p0 = p1;


+ 7
- 7
src/widgets/FramebufferWidget.cpp View File

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

struct FramebufferWidget::Internal {
NVGLUframebuffer *fb = NULL;
math::Rect box;
Rect box;

~Internal() {
setFramebuffer(NULL);
@@ -41,10 +41,10 @@ void FramebufferWidget::draw(NVGcontext *vg) {
// Skew and rotate is not supported
assert(std::abs(xform[1]) < 1e-6);
assert(std::abs(xform[2]) < 1e-6);
math::Vec s = math::Vec(xform[0], xform[3]);
math::Vec b = math::Vec(xform[4], xform[5]);
math::Vec bi = b.floor();
math::Vec bf = b.minus(bi);
Vec s = Vec(xform[0], xform[3]);
Vec b = Vec(xform[4], xform[5]);
Vec bi = b.floor();
Vec bf = b.minus(bi);

// Render to framebuffer
if (dirty) {
@@ -52,9 +52,9 @@ void FramebufferWidget::draw(NVGcontext *vg) {

internal->box = getChildrenBoundingBox();
internal->box.pos = internal->box.pos.mult(s).floor();
internal->box.size = internal->box.size.mult(s).ceil().plus(math::Vec(1, 1));
internal->box.size = internal->box.size.mult(s).ceil().plus(Vec(1, 1));

math::Vec fbSize = internal->box.size.mult(gPixelRatio * oversample);
Vec fbSize = internal->box.size.mult(gPixelRatio * oversample);

if (!fbSize.isFinite())
return;


+ 5
- 5
src/widgets/Widget.cpp View File

@@ -13,8 +13,8 @@ Widget::~Widget() {
clearChildren();
}

math::Rect Widget::getChildrenBoundingBox() {
math::Rect bound;
Rect Widget::getChildrenBoundingBox() {
Rect bound;
for (Widget *child : children) {
if (child == children.front()) {
bound = child->box;
@@ -26,7 +26,7 @@ math::Rect Widget::getChildrenBoundingBox() {
return bound;
}

math::Vec Widget::getRelativeOffset(math::Vec v, Widget *relative) {
Vec Widget::getRelativeOffset(Vec v, Widget *relative) {
if (this == relative) {
return v;
}
@@ -37,8 +37,8 @@ math::Vec Widget::getRelativeOffset(math::Vec v, Widget *relative) {
return v;
}

math::Rect Widget::getViewport(math::Rect r) {
math::Rect bound;
Rect Widget::getViewport(Rect r) {
Rect bound;
if (parent) {
bound = parent->getViewport(box);
}


+ 13
- 13
src/window.cpp View File

@@ -41,7 +41,7 @@ float gPixelRatio = 1.0;
float gWindowRatio = 1.0;
bool gAllowCursorLock = true;
int gGuiFrame;
math::Vec gMousePos;
Vec gMousePos;

std::string lastWindowTitle;

@@ -86,15 +86,15 @@ void mouseButtonStickyCallback(GLFWwindow *window, int button, int action, int m
}

void cursorPosCallback(GLFWwindow* window, double xpos, double ypos) {
math::Vec mousePos = math::Vec(xpos, ypos).div(gPixelRatio / gWindowRatio).round();
math::Vec mouseDelta = mousePos.minus(gMousePos);
Vec mousePos = Vec(xpos, ypos).div(gPixelRatio / gWindowRatio).round();
Vec mouseDelta = mousePos.minus(gMousePos);

int cursorMode = glfwGetInputMode(gWindow, GLFW_CURSOR);
(void) cursorMode;

#ifdef ARCH_MAC
// Workaround for Mac. We can't use GLFW_CURSOR_DISABLED because it's buggy, so implement it on our own.
// This is not an ideal implementation. For example, if the user drags off the screen, the new mouse position will be math::clamped.
// This is not an ideal implementation. For example, if the user drags off the screen, the new mouse position will be clamped.
if (cursorMode == GLFW_CURSOR_HIDDEN) {
// CGSetLocalEventsSuppressionInterval(0.0);
glfwSetCursorPos(gWindow, gMousePos.x, gMousePos.y);
@@ -117,10 +117,10 @@ void cursorEnterCallback(GLFWwindow* window, int entered) {
}

void scrollCallback(GLFWwindow *window, double x, double y) {
math::Vec scrollDelta = math::Vec(x, y);
Vec scrollDelta = Vec(x, y);
#if ARCH_LIN || ARCH_WIN
if (windowIsShiftPressed())
scrollDelta = math::Vec(y, x);
scrollDelta = Vec(y, x);
#endif
scrollDelta = scrollDelta.mult(50.0);

@@ -330,7 +330,7 @@ void windowRun() {
glfwGetWindowSize(gWindow, &windowWidth, &windowHeight);
gWindowRatio = (float)width / windowWidth;

gWidgetState->rootWidget->box.size = math::Vec(width, height).div(gPixelRatio);
gWidgetState->rootWidget->box.size = Vec(width, height).div(gPixelRatio);

// Step scene
gWidgetState->rootWidget->step();
@@ -385,25 +385,25 @@ bool windowIsShiftPressed() {
return glfwGetKey(gWindow, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS || glfwGetKey(gWindow, GLFW_KEY_RIGHT_SHIFT) == GLFW_PRESS;
}

math::Vec windowGetWindowSize() {
Vec windowGetWindowSize() {
int width, height;
glfwGetWindowSize(gWindow, &width, &height);
return math::Vec(width, height);
return Vec(width, height);
}

void windowSetWindowSize(math::Vec size) {
void windowSetWindowSize(Vec size) {
int width = size.x;
int height = size.y;
glfwSetWindowSize(gWindow, width, height);
}

math::Vec windowGetWindowPos() {
Vec windowGetWindowPos() {
int x, y;
glfwGetWindowPos(gWindow, &x, &y);
return math::Vec(x, y);
return Vec(x, y);
}

void windowSetWindowPos(math::Vec pos) {
void windowSetWindowPos(Vec pos) {
int x = pos.x;
int y = pos.y;
glfwSetWindowPos(gWindow, x, y);


Loading…
Cancel
Save