@@ -1,5 +1,5 @@ | |||||
RACK_DIR ?= . | RACK_DIR ?= . | ||||
VERSION = 1.0.0dev | |||||
VERSION = 1.dev | |||||
FLAGS += \ | FLAGS += \ | ||||
-Iinclude \ | -Iinclude \ | ||||
@@ -16,7 +16,7 @@ inline float in2px(float inches) { | |||||
return inches * SVG_DPI; | return inches * SVG_DPI; | ||||
} | } | ||||
inline Vec in2px(Vec inches) { | |||||
inline math::Vec in2px(math::Vec inches) { | |||||
return inches.mult(SVG_DPI); | return inches.mult(SVG_DPI); | ||||
} | } | ||||
@@ -24,7 +24,7 @@ inline float mm2px(float millimeters) { | |||||
return millimeters * (SVG_DPI / MM_PER_IN); | return millimeters * (SVG_DPI / MM_PER_IN); | ||||
} | } | ||||
inline Vec mm2px(Vec millimeters) { | |||||
inline math::Vec mm2px(math::Vec millimeters) { | |||||
return millimeters.mult(SVG_DPI / MM_PER_IN); | return millimeters.mult(SVG_DPI / MM_PER_IN); | ||||
} | } | ||||
@@ -45,7 +45,7 @@ struct SVGPanel; | |||||
// A 1HPx3U module should be 15x380 pixels. Thus the width of a module should be a factor of 15. | // 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_WIDTH = 15; | ||||
static const float RACK_GRID_HEIGHT = 380; | static const float RACK_GRID_HEIGHT = 380; | ||||
static const Vec RACK_GRID_SIZE = Vec(RACK_GRID_WIDTH, RACK_GRID_HEIGHT); | |||||
static const math::Vec RACK_GRID_SIZE = math::Vec(RACK_GRID_WIDTH, RACK_GRID_HEIGHT); | |||||
static const std::string PRESET_FILTERS = "VCV Rack module preset (.vcvm):vcvm"; | static const std::string PRESET_FILTERS = "VCV Rack module preset (.vcvm):vcvm"; | ||||
static const std::string PATCH_FILTERS = "VCV Rack patch (.vcv):vcv"; | static const std::string PATCH_FILTERS = "VCV Rack patch (.vcv):vcv"; | ||||
@@ -103,7 +103,7 @@ struct ModuleWidget : OpaqueWidget { | |||||
void draw(NVGcontext *vg) override; | void draw(NVGcontext *vg) override; | ||||
void drawShadow(NVGcontext *vg); | void drawShadow(NVGcontext *vg); | ||||
Vec dragPos; | |||||
math::Vec dragPos; | |||||
void onMouseDown(EventMouseDown &e) override; | void onMouseDown(EventMouseDown &e) override; | ||||
void onMouseMove(EventMouseMove &e) override; | void onMouseMove(EventMouseMove &e) override; | ||||
void onHoverKey(EventHoverKey &e) override; | void onHoverKey(EventHoverKey &e) override; | ||||
@@ -124,8 +124,8 @@ struct WireWidget : OpaqueWidget { | |||||
~WireWidget(); | ~WireWidget(); | ||||
/** Synchronizes the plugged state of the widget to the owned wire */ | /** Synchronizes the plugged state of the widget to the owned wire */ | ||||
void updateWire(); | void updateWire(); | ||||
Vec getOutputPos(); | |||||
Vec getInputPos(); | |||||
math::Vec getOutputPos(); | |||||
math::Vec getInputPos(); | |||||
json_t *toJson(); | json_t *toJson(); | ||||
void fromJson(json_t *rootJ); | void fromJson(json_t *rootJ); | ||||
void draw(NVGcontext *vg) override; | void draw(NVGcontext *vg) override; | ||||
@@ -152,7 +152,7 @@ struct RackWidget : OpaqueWidget { | |||||
// Only put WireWidgets in here | // Only put WireWidgets in here | ||||
WireContainer *wireContainer; | WireContainer *wireContainer; | ||||
std::string lastPath; | std::string lastPath; | ||||
Vec lastMousePos; | |||||
math::Vec lastMousePos; | |||||
bool lockModules = false; | bool lockModules = false; | ||||
RackWidget(); | RackWidget(); | ||||
@@ -182,9 +182,9 @@ struct RackWidget : OpaqueWidget { | |||||
void deleteModule(ModuleWidget *m); | void deleteModule(ModuleWidget *m); | ||||
void cloneModule(ModuleWidget *m); | void cloneModule(ModuleWidget *m); | ||||
/** Sets a module's box if non-colliding. Returns true if set */ | /** Sets a module's box if non-colliding. Returns true if set */ | ||||
bool requestModuleBox(ModuleWidget *m, Rect box); | |||||
bool requestModuleBox(ModuleWidget *m, math::Rect box); | |||||
/** Moves a module to the closest non-colliding position */ | /** Moves a module to the closest non-colliding position */ | ||||
bool requestModuleBoxNearest(ModuleWidget *m, Rect box); | |||||
bool requestModuleBoxNearest(ModuleWidget *m, math::Rect box); | |||||
void step() override; | void step() override; | ||||
void draw(NVGcontext *vg) override; | void draw(NVGcontext *vg) override; | ||||
@@ -198,12 +198,6 @@ struct RackRail : TransparentWidget { | |||||
void draw(NVGcontext *vg) override; | void draw(NVGcontext *vg) override; | ||||
}; | }; | ||||
struct Panel : TransparentWidget { | |||||
NVGcolor backgroundColor; | |||||
std::shared_ptr<Image> backgroundImage; | |||||
void draw(NVGcontext *vg) override; | |||||
}; | |||||
struct SVGPanel : FramebufferWidget { | struct SVGPanel : FramebufferWidget { | ||||
void step() override; | void step() override; | ||||
void setBackground(std::shared_ptr<SVG> svg); | void setBackground(std::shared_ptr<SVG> svg); | ||||
@@ -218,7 +212,7 @@ struct Component : OpaqueWidget { | |||||
Module *module = NULL; | Module *module = NULL; | ||||
template <typename T = Component> | template <typename T = Component> | ||||
static T *create(Vec pos, Module *module) { | |||||
static T *create(math::Vec pos, Module *module) { | |||||
T *o = new T(); | T *o = new T(); | ||||
o->box.pos = pos; | o->box.pos = pos; | ||||
o->module = module; | o->module = module; | ||||
@@ -251,7 +245,7 @@ struct ParamWidget : Component, QuantityWidget { | |||||
void onChange(EventChange &e) override; | void onChange(EventChange &e) override; | ||||
template <typename T = ParamWidget> | template <typename T = ParamWidget> | ||||
static T *create(Vec pos, Module *module, int paramId, float minValue, float maxValue, float defaultValue) { | |||||
static T *create(math::Vec pos, Module *module, int paramId, float minValue, float maxValue, float defaultValue) { | |||||
T *o = Component::create<T>(pos, module); | T *o = Component::create<T>(pos, module); | ||||
o->paramId = paramId; | o->paramId = paramId; | ||||
o->setLimits(minValue, maxValue); | o->setLimits(minValue, maxValue); | ||||
@@ -294,7 +288,7 @@ struct SVGSlider : Knob, FramebufferWidget { | |||||
SVGWidget *background; | SVGWidget *background; | ||||
SVGWidget *handle; | SVGWidget *handle; | ||||
/** Intermediate positions will be interpolated between these positions */ | /** Intermediate positions will be interpolated between these positions */ | ||||
Vec minHandlePos, maxHandlePos; | |||||
math::Vec minHandlePos, maxHandlePos; | |||||
SVGSlider(); | SVGSlider(); | ||||
void setSVGs(std::shared_ptr<SVG> backgroundSVG, std::shared_ptr<SVG> handleSVG); | void setSVGs(std::shared_ptr<SVG> backgroundSVG, std::shared_ptr<SVG> handleSVG); | ||||
@@ -361,7 +355,7 @@ struct LedDisplaySeparator : TransparentWidget { | |||||
struct LedDisplayChoice : TransparentWidget { | struct LedDisplayChoice : TransparentWidget { | ||||
std::string text; | std::string text; | ||||
std::shared_ptr<Font> font; | std::shared_ptr<Font> font; | ||||
Vec textOffset; | |||||
math::Vec textOffset; | |||||
NVGcolor color; | NVGcolor color; | ||||
LedDisplayChoice(); | LedDisplayChoice(); | ||||
void draw(NVGcontext *vg) override; | void draw(NVGcontext *vg) override; | ||||
@@ -370,11 +364,11 @@ struct LedDisplayChoice : TransparentWidget { | |||||
struct LedDisplayTextField : TextField { | struct LedDisplayTextField : TextField { | ||||
std::shared_ptr<Font> font; | std::shared_ptr<Font> font; | ||||
Vec textOffset; | |||||
math::Vec textOffset; | |||||
NVGcolor color; | NVGcolor color; | ||||
LedDisplayTextField(); | LedDisplayTextField(); | ||||
void draw(NVGcontext *vg) override; | void draw(NVGcontext *vg) override; | ||||
int getTextPosition(Vec mousePos) override; | |||||
int getTextPosition(math::Vec mousePos) override; | |||||
}; | }; | ||||
@@ -438,7 +432,7 @@ struct ModuleLightWidget : MultiLightWidget { | |||||
void step() override; | void step() override; | ||||
template <typename T = ModuleLightWidget> | template <typename T = ModuleLightWidget> | ||||
static T *create(Vec pos, Module *module, int firstLightId) { | |||||
static T *create(math::Vec pos, Module *module, int firstLightId) { | |||||
T *o = Widget::create<T>(pos); | T *o = Widget::create<T>(pos); | ||||
o->module = module; | o->module = module; | ||||
o->firstLightId = firstLightId; | o->firstLightId = firstLightId; | ||||
@@ -471,7 +465,7 @@ struct Port : Component { | |||||
void onDragLeave(EventDragEnter &e) override; | void onDragLeave(EventDragEnter &e) override; | ||||
template <typename T = Port> | template <typename T = Port> | ||||
static T *create(Vec pos, PortType type, Module *module, int portId) { | |||||
static T *create(math::Vec pos, PortType type, Module *module, int portId) { | |||||
T *o = Component::create<T>(pos, module); | T *o = Component::create<T>(pos, module); | ||||
o->type = type; | o->type = type; | ||||
o->portId = portId; | o->portId = portId; | ||||
@@ -1,27 +1,26 @@ | |||||
#pragma once | #pragma once | ||||
#include "app.hpp" | |||||
#include "asset.hpp" | |||||
#include "rack.hpp" | |||||
namespace rack { | namespace rack { | ||||
//////////////////// | //////////////////// | ||||
// Colors | |||||
// Color scheme | |||||
//////////////////// | //////////////////// | ||||
static const NVGcolor COLOR_BLACK_TRANSPARENT = nvgRGBA(0x00, 0x00, 0x00, 0x00); | |||||
static const NVGcolor COLOR_BLACK = nvgRGB(0x00, 0x00, 0x00); | |||||
static const NVGcolor COLOR_WHITE = nvgRGB(0xff, 0xff, 0xff); | |||||
static const NVGcolor COLOR_RED = nvgRGB(0xed, 0x2c, 0x24); | |||||
static const NVGcolor COLOR_ORANGE = nvgRGB(0xf2, 0xb1, 0x20); | |||||
static const NVGcolor COLOR_YELLOW = nvgRGB(0xf9, 0xdf, 0x1c); | |||||
static const NVGcolor COLOR_GREEN = nvgRGB(0x90, 0xc7, 0x3e); | |||||
static const NVGcolor COLOR_CYAN = nvgRGB(0x22, 0xe6, 0xef); | |||||
static const NVGcolor COLOR_BLUE = nvgRGB(0x29, 0xb2, 0xef); | |||||
static const NVGcolor COLOR_PURPLE = nvgRGB(0xd5, 0x2b, 0xed); | |||||
static const NVGcolor COLOR_LIGHT_PANEL = nvgRGB(0xe6, 0xe6, 0xe6); | |||||
static const NVGcolor COLOR_DARK_PANEL = nvgRGB(0x17, 0x17, 0x17); | |||||
static const NVGcolor SCHEME_BLACK_TRANSPARENT = nvgRGBA(0x00, 0x00, 0x00, 0x00); | |||||
static const NVGcolor SCHEME_BLACK = nvgRGB(0x00, 0x00, 0x00); | |||||
static const NVGcolor SCHEME_WHITE = nvgRGB(0xff, 0xff, 0xff); | |||||
static const NVGcolor SCHEME_RED = nvgRGB(0xed, 0x2c, 0x24); | |||||
static const NVGcolor SCHEME_ORANGE = nvgRGB(0xf2, 0xb1, 0x20); | |||||
static const NVGcolor SCHEME_YELLOW = nvgRGB(0xf9, 0xdf, 0x1c); | |||||
static const NVGcolor SCHEME_GREEN = nvgRGB(0x90, 0xc7, 0x3e); | |||||
static const NVGcolor SCHEME_CYAN = nvgRGB(0x22, 0xe6, 0xef); | |||||
static const NVGcolor SCHEME_BLUE = nvgRGB(0x29, 0xb2, 0xef); | |||||
static const NVGcolor SCHEME_PURPLE = nvgRGB(0xd5, 0x2b, 0xed); | |||||
static const NVGcolor SCHEME_LIGHT_PANEL = nvgRGB(0xe6, 0xe6, 0xe6); | |||||
static const NVGcolor SCHEME_DARK_PANEL = nvgRGB(0x17, 0x17, 0x17); | |||||
//////////////////// | //////////////////// | ||||
// Knobs | // Knobs | ||||
@@ -407,41 +406,41 @@ struct GrayModuleLightWidget : ModuleLightWidget { | |||||
struct RedLight : GrayModuleLightWidget { | struct RedLight : GrayModuleLightWidget { | ||||
RedLight() { | RedLight() { | ||||
addBaseColor(COLOR_RED); | |||||
addBaseColor(SCHEME_RED); | |||||
} | } | ||||
}; | }; | ||||
struct GreenLight : GrayModuleLightWidget { | struct GreenLight : GrayModuleLightWidget { | ||||
GreenLight() { | GreenLight() { | ||||
addBaseColor(COLOR_GREEN); | |||||
addBaseColor(SCHEME_GREEN); | |||||
} | } | ||||
}; | }; | ||||
struct YellowLight : GrayModuleLightWidget { | struct YellowLight : GrayModuleLightWidget { | ||||
YellowLight() { | YellowLight() { | ||||
addBaseColor(COLOR_YELLOW); | |||||
addBaseColor(SCHEME_YELLOW); | |||||
} | } | ||||
}; | }; | ||||
struct BlueLight : GrayModuleLightWidget { | struct BlueLight : GrayModuleLightWidget { | ||||
BlueLight() { | BlueLight() { | ||||
addBaseColor(COLOR_BLUE); | |||||
addBaseColor(SCHEME_BLUE); | |||||
} | } | ||||
}; | }; | ||||
/** Reads two adjacent lightIds, so `lightId` and `lightId + 1` must be defined */ | /** Reads two adjacent lightIds, so `lightId` and `lightId + 1` must be defined */ | ||||
struct GreenRedLight : GrayModuleLightWidget { | struct GreenRedLight : GrayModuleLightWidget { | ||||
GreenRedLight() { | GreenRedLight() { | ||||
addBaseColor(COLOR_GREEN); | |||||
addBaseColor(COLOR_RED); | |||||
addBaseColor(SCHEME_GREEN); | |||||
addBaseColor(SCHEME_RED); | |||||
} | } | ||||
}; | }; | ||||
struct RedGreenBlueLight : GrayModuleLightWidget { | struct RedGreenBlueLight : GrayModuleLightWidget { | ||||
RedGreenBlueLight() { | RedGreenBlueLight() { | ||||
addBaseColor(COLOR_RED); | |||||
addBaseColor(COLOR_GREEN); | |||||
addBaseColor(COLOR_BLUE); | |||||
addBaseColor(SCHEME_RED); | |||||
addBaseColor(SCHEME_GREEN); | |||||
addBaseColor(SCHEME_BLUE); | |||||
} | } | ||||
}; | }; | ||||
@@ -490,7 +489,7 @@ struct TinyLight : BASE { | |||||
template <typename BASE> | template <typename BASE> | ||||
struct LEDBezelLight : BASE { | struct LEDBezelLight : BASE { | ||||
LEDBezelLight() { | LEDBezelLight() { | ||||
this->bgColor = COLOR_BLACK_TRANSPARENT; | |||||
this->bgColor = color::BLACK_TRANSPARENT; | |||||
this->box.size = mm2px(Vec(6.0, 6.0)); | this->box.size = mm2px(Vec(6.0, 6.0)); | ||||
} | } | ||||
}; | }; | ||||
@@ -501,7 +500,7 @@ Don't add this as a child of the PB61303 itself. Instead, just place it over it | |||||
template <typename BASE> | template <typename BASE> | ||||
struct PB61303Light : BASE { | struct PB61303Light : BASE { | ||||
PB61303Light() { | PB61303Light() { | ||||
this->bgColor = COLOR_BLACK_TRANSPARENT; | |||||
this->bgColor = color::BLACK_TRANSPARENT; | |||||
this->box.size = mm2px(Vec(9.0, 9.0)); | this->box.size = mm2px(Vec(9.0, 9.0)); | ||||
} | } | ||||
}; | }; | ||||
@@ -611,17 +610,5 @@ struct ScrewBlack : SVGScrew { | |||||
} | } | ||||
}; | }; | ||||
struct LightPanel : Panel { | |||||
LightPanel() { | |||||
backgroundColor = COLOR_LIGHT_PANEL; | |||||
} | |||||
}; | |||||
struct DarkPanel : Panel { | |||||
DarkPanel() { | |||||
backgroundColor = COLOR_DARK_PANEL; | |||||
} | |||||
}; | |||||
} // namespace rack | } // namespace rack |
@@ -1,6 +1,6 @@ | |||||
#pragma once | #pragma once | ||||
#include "util/math.hpp" | |||||
#include "math.hpp" | |||||
namespace rack { | namespace rack { | ||||
@@ -1,6 +1,6 @@ | |||||
#pragma once | #pragma once | ||||
#include "util/math.hpp" | |||||
#include "math.hpp" | |||||
namespace rack { | namespace rack { | ||||
@@ -1,6 +1,6 @@ | |||||
#pragma once | #pragma once | ||||
#include "util/math.hpp" | |||||
#include "math.hpp" | |||||
namespace rack { | namespace rack { | ||||
@@ -1,6 +1,6 @@ | |||||
#pragma once | #pragma once | ||||
#include "util/math.hpp" | |||||
#include "math.hpp" | |||||
namespace rack { | namespace rack { | ||||
@@ -23,7 +23,7 @@ struct MinBLEP { | |||||
for (int j = 0; j < 2*ZERO_CROSSINGS; j++) { | for (int j = 0; j < 2*ZERO_CROSSINGS; j++) { | ||||
float minblepIndex = ((float)j - p) * oversample; | float minblepIndex = ((float)j - p) * oversample; | ||||
int index = (pos + j) % (2*ZERO_CROSSINGS); | int index = (pos + j) % (2*ZERO_CROSSINGS); | ||||
buf[index] += dx * (-1.0 + interpolateLinear(minblep, minblepIndex)); | |||||
buf[index] += dx * (-1.0 + math::interpolateLinear(minblep, minblepIndex)); | |||||
} | } | ||||
} | } | ||||
float shift() { | float shift() { | ||||
@@ -1,7 +1,7 @@ | |||||
#pragma once | #pragma once | ||||
#include <list> | #include <list> | ||||
#include "util/math.hpp" | |||||
#include "math.hpp" | |||||
namespace rack { | namespace rack { | ||||
@@ -16,7 +16,7 @@ struct Event { | |||||
}; | }; | ||||
struct EventPosition : Event { | struct EventPosition : Event { | ||||
Vec pos; | |||||
math::Vec pos; | |||||
}; | }; | ||||
/////////// | /////////// | ||||
@@ -34,7 +34,7 @@ struct EventMouseUp : EventPosition { | |||||
}; | }; | ||||
struct EventMouseMove : EventPosition { | struct EventMouseMove : EventPosition { | ||||
Vec mouseRel; | |||||
math::Vec mouseRel; | |||||
Widget *target = NULL; | Widget *target = NULL; | ||||
}; | }; | ||||
@@ -64,7 +64,7 @@ struct EventKey : Event { | |||||
}; | }; | ||||
struct EventScroll : EventPosition { | struct EventScroll : EventPosition { | ||||
Vec scrollRel; | |||||
math::Vec scrollRel; | |||||
}; | }; | ||||
///////////// | ///////////// | ||||
@@ -76,7 +76,7 @@ struct EventDragEnd : Event { | |||||
}; | }; | ||||
struct EventDragMove : Event { | struct EventDragMove : Event { | ||||
Vec mouseRel; | |||||
math::Vec mouseRel; | |||||
}; | }; | ||||
struct EventDragEnter : Event { | struct EventDragEnter : Event { | ||||
@@ -34,7 +34,7 @@ Model *createModel(std::string author, std::string slug, std::string name, Tags. | |||||
} | } | ||||
template <class TWidget> | template <class TWidget> | ||||
TWidget *createWidget(Vec pos) { | |||||
TWidget *createWidget(math::Vec pos) { | |||||
TWidget *w = new TWidget(); | TWidget *w = new TWidget(); | ||||
w->box.pos = pos; | w->box.pos = pos; | ||||
return w; | return w; | ||||
@@ -42,12 +42,12 @@ TWidget *createWidget(Vec pos) { | |||||
/** Deprecated. Use createWidget<TScrew>() instead */ | /** Deprecated. Use createWidget<TScrew>() instead */ | ||||
template <class TScrew> | template <class TScrew> | ||||
DEPRECATED TScrew *createScrew(Vec pos) { | |||||
DEPRECATED TScrew *createScrew(math::Vec pos) { | |||||
return createWidget<TScrew>(pos); | return createWidget<TScrew>(pos); | ||||
} | } | ||||
template <class TParamWidget> | template <class TParamWidget> | ||||
TParamWidget *createParam(Vec pos, Module *module, int paramId, float minValue, float maxValue, float defaultValue) { | |||||
TParamWidget *createParam(math::Vec pos, Module *module, int paramId, float minValue, float maxValue, float defaultValue) { | |||||
TParamWidget *param = new TParamWidget(); | TParamWidget *param = new TParamWidget(); | ||||
param->box.pos = pos; | param->box.pos = pos; | ||||
param->module = module; | param->module = module; | ||||
@@ -58,7 +58,7 @@ TParamWidget *createParam(Vec pos, Module *module, int paramId, float minValue, | |||||
} | } | ||||
template <class TParamWidget> | template <class TParamWidget> | ||||
TParamWidget *createParamCentered(Vec pos, Module *module, int paramId, float minValue, float maxValue, float defaultValue) { | |||||
TParamWidget *createParamCentered(math::Vec pos, Module *module, int paramId, float minValue, float maxValue, float defaultValue) { | |||||
TParamWidget *param = new TParamWidget(); | TParamWidget *param = new TParamWidget(); | ||||
param->box.pos = pos.minus(param->box.size.div(2)); | param->box.pos = pos.minus(param->box.size.div(2)); | ||||
param->module = module; | param->module = module; | ||||
@@ -69,7 +69,7 @@ TParamWidget *createParamCentered(Vec pos, Module *module, int paramId, float mi | |||||
} | } | ||||
template <class TPort> | template <class TPort> | ||||
TPort *createInput(Vec pos, Module *module, int inputId) { | |||||
TPort *createInput(math::Vec pos, Module *module, int inputId) { | |||||
TPort *port = new TPort(); | TPort *port = new TPort(); | ||||
port->box.pos = pos; | port->box.pos = pos; | ||||
port->module = module; | port->module = module; | ||||
@@ -79,7 +79,7 @@ TPort *createInput(Vec pos, Module *module, int inputId) { | |||||
} | } | ||||
template <class TPort> | template <class TPort> | ||||
TPort *createInputCentered(Vec pos, Module *module, int inputId) { | |||||
TPort *createInputCentered(math::Vec pos, Module *module, int inputId) { | |||||
TPort *port = new TPort(); | TPort *port = new TPort(); | ||||
port->box.pos = pos.minus(port->box.size.div(2)); | port->box.pos = pos.minus(port->box.size.div(2)); | ||||
port->module = module; | port->module = module; | ||||
@@ -89,7 +89,7 @@ TPort *createInputCentered(Vec pos, Module *module, int inputId) { | |||||
} | } | ||||
template <class TPort> | template <class TPort> | ||||
TPort *createOutput(Vec pos, Module *module, int outputId) { | |||||
TPort *createOutput(math::Vec pos, Module *module, int outputId) { | |||||
TPort *port = new TPort(); | TPort *port = new TPort(); | ||||
port->box.pos = pos; | port->box.pos = pos; | ||||
port->module = module; | port->module = module; | ||||
@@ -99,7 +99,7 @@ TPort *createOutput(Vec pos, Module *module, int outputId) { | |||||
} | } | ||||
template <class TPort> | template <class TPort> | ||||
TPort *createOutputCentered(Vec pos, Module *module, int outputId) { | |||||
TPort *createOutputCentered(math::Vec pos, Module *module, int outputId) { | |||||
TPort *port = new TPort(); | TPort *port = new TPort(); | ||||
port->box.pos = pos.minus(port->box.size.div(2)); | port->box.pos = pos.minus(port->box.size.div(2)); | ||||
port->module = module; | port->module = module; | ||||
@@ -109,7 +109,7 @@ TPort *createOutputCentered(Vec pos, Module *module, int outputId) { | |||||
} | } | ||||
template <class TModuleLightWidget> | template <class TModuleLightWidget> | ||||
TModuleLightWidget *createLight(Vec pos, Module *module, int firstLightId) { | |||||
TModuleLightWidget *createLight(math::Vec pos, Module *module, int firstLightId) { | |||||
TModuleLightWidget *light = new TModuleLightWidget(); | TModuleLightWidget *light = new TModuleLightWidget(); | ||||
light->box.pos = pos; | light->box.pos = pos; | ||||
light->module = module; | light->module = module; | ||||
@@ -118,7 +118,7 @@ TModuleLightWidget *createLight(Vec pos, Module *module, int firstLightId) { | |||||
} | } | ||||
template <class TModuleLightWidget> | template <class TModuleLightWidget> | ||||
TModuleLightWidget *createLightCentered(Vec pos, Module *module, int firstLightId) { | |||||
TModuleLightWidget *createLightCentered(math::Vec pos, Module *module, int firstLightId) { | |||||
TModuleLightWidget *light = new TModuleLightWidget(); | TModuleLightWidget *light = new TModuleLightWidget(); | ||||
light->box.pos = pos.minus(light->box.size.div(2)); | light->box.pos = pos.minus(light->box.size.div(2)); | ||||
light->module = module; | light->module = module; | ||||
@@ -6,6 +6,7 @@ | |||||
namespace rack { | namespace rack { | ||||
namespace math { | |||||
//////////////////// | //////////////////// | ||||
// basic integer functions | // basic integer functions | ||||
@@ -35,11 +36,21 @@ inline int clampBetween(int x, int a, int b) { | |||||
return clamp(x, std::min(a, b), std::max(a, b)); | return clamp(x, std::min(a, b), std::max(a, b)); | ||||
} | } | ||||
/** Euclidean modulus, always returns 0 <= mod < base for positive base. | |||||
/** Euclidean modulus. Always returns 0 <= mod < b. | |||||
b must be positive. | |||||
*/ | */ | ||||
inline int eucMod(int a, int base) { | |||||
int mod = a % base; | |||||
return (mod >= 0) ? mod : mod + base; | |||||
inline int eucMod(int a, int b) { | |||||
int mod = a % b; | |||||
return (mod >= 0) ? mod : mod + b; | |||||
} | |||||
/** Euclidean division. | |||||
b must be positive. | |||||
*/ | |||||
inline int eucDiv(int a, int b) { | |||||
int mod = a % b; | |||||
int div = a / b; | |||||
return (mod >= 0) ? div : div - 1; | |||||
} | } | ||||
/** Returns floor(log_2(n)), or 0 if n == 1. | /** Returns floor(log_2(n)), or 0 if n == 1. | ||||
@@ -224,11 +235,14 @@ struct Rect { | |||||
Vec getCenter() { | Vec getCenter() { | ||||
return pos.plus(size.mult(0.5f)); | return pos.plus(size.mult(0.5f)); | ||||
} | } | ||||
Vec getTopLeft() { | |||||
return pos; | |||||
} | |||||
Vec getTopRight() { | Vec getTopRight() { | ||||
return pos.plus(Vec(size.x, 0.0f)); | |||||
return pos.plus(Vec(size.x, 0.f)); | |||||
} | } | ||||
Vec getBottomLeft() { | Vec getBottomLeft() { | ||||
return pos.plus(Vec(0.0f, size.y)); | |||||
return pos.plus(Vec(0.f, size.y)); | |||||
} | } | ||||
Vec getBottomRight() { | Vec getBottomRight() { | ||||
return pos.plus(size); | return pos.plus(size); | ||||
@@ -238,8 +252,8 @@ struct Rect { | |||||
Rect r; | Rect r; | ||||
r.pos.x = clampBetween(pos.x, bound.pos.x, bound.pos.x + bound.size.x); | 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.pos.y = clampBetween(pos.y, bound.pos.y, bound.pos.y + bound.size.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; | |||||
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; | |||||
return r; | return r; | ||||
} | } | ||||
/** Nudges the position to fix inside a bounding box */ | /** Nudges the position to fix inside a bounding box */ | ||||
@@ -261,9 +275,7 @@ struct Rect { | |||||
} | } | ||||
/** Returns a Rect with its position set to zero */ | /** Returns a Rect with its position set to zero */ | ||||
Rect zeroPos() { | Rect zeroPos() { | ||||
Rect r; | |||||
r.size = size; | |||||
return r; | |||||
return Rect(Vec(), size); | |||||
} | } | ||||
Rect grow(Vec delta) { | Rect grow(Vec delta) { | ||||
Rect r; | Rect r; | ||||
@@ -282,14 +294,14 @@ struct Rect { | |||||
inline Vec Vec::clamp(Rect bound) { | inline Vec Vec::clamp(Rect bound) { | ||||
return Vec( | return Vec( | ||||
rack::clamp(x, bound.pos.x, bound.pos.x + bound.size.x), | |||||
rack::clamp(y, bound.pos.y, bound.pos.y + bound.size.y)); | |||||
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)); | |||||
} | } | ||||
inline Vec Vec::clampBetween(Rect bound) { | inline Vec Vec::clampBetween(Rect bound) { | ||||
return Vec( | return Vec( | ||||
rack::clampBetween(x, bound.pos.x, bound.pos.x + bound.size.x), | |||||
rack::clampBetween(y, bound.pos.y, bound.pos.y + bound.size.y)); | |||||
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)); | |||||
} | } | ||||
inline Vec Vec::clamp2(Rect bound) {return clampBetween(bound);} | inline Vec Vec::clamp2(Rect bound) {return clampBetween(bound);} | ||||
@@ -329,4 +341,5 @@ DEPRECATED inline float interpf(const float *p, float x) {return interpolateLine | |||||
DEPRECATED inline void cmultf(float *cr, float *ci, float ar, float ai, float br, float bi) {return cmult(cr, ci, ar, ai, br, bi);} | DEPRECATED inline void cmultf(float *cr, float *ci, float ar, float ai, float br, float bi) {return cmult(cr, ci, ar, ai, br, bi);} | ||||
} // namespace math | |||||
} // namespace rack | } // namespace rack |
@@ -8,5 +8,13 @@ | |||||
#include "widgets.hpp" | #include "widgets.hpp" | ||||
#include "app.hpp" | #include "app.hpp" | ||||
#include "ui.hpp" | #include "ui.hpp" | ||||
#include "componentlibrary.hpp" | |||||
#include "helpers.hpp" | #include "helpers.hpp" | ||||
namespace rack { | |||||
using namespace math; | |||||
} // namespace rack |
@@ -70,7 +70,7 @@ struct Menu : OpaqueWidget { | |||||
MenuEntry *activeEntry = NULL; | MenuEntry *activeEntry = NULL; | ||||
Menu() { | Menu() { | ||||
box.size = Vec(0, 0); | |||||
box.size = math::Vec(0, 0); | |||||
} | } | ||||
~Menu(); | ~Menu(); | ||||
/** Deprecated. Just use addChild(child) instead */ | /** Deprecated. Just use addChild(child) instead */ | ||||
@@ -85,11 +85,11 @@ struct Menu : OpaqueWidget { | |||||
struct MenuEntry : OpaqueWidget { | struct MenuEntry : OpaqueWidget { | ||||
MenuEntry() { | MenuEntry() { | ||||
box.size = Vec(0, BND_WIDGET_HEIGHT); | |||||
box.size = math::Vec(0, BND_WIDGET_HEIGHT); | |||||
} | } | ||||
template <typename T = MenuEntry> | template <typename T = MenuEntry> | ||||
static T *create() { | static T *create() { | ||||
T *o = Widget::create<T>(Vec()); | |||||
T *o = Widget::create<T>(math::Vec()); | |||||
return o; | return o; | ||||
} | } | ||||
}; | }; | ||||
@@ -199,10 +199,10 @@ struct ScrollWidget : OpaqueWidget { | |||||
Widget *container; | Widget *container; | ||||
ScrollBar *horizontalScrollBar; | ScrollBar *horizontalScrollBar; | ||||
ScrollBar *verticalScrollBar; | ScrollBar *verticalScrollBar; | ||||
Vec offset; | |||||
math::Vec offset; | |||||
ScrollWidget(); | ScrollWidget(); | ||||
void scrollTo(Rect r); | |||||
void scrollTo(math::Rect r); | |||||
void draw(NVGcontext *vg) override; | void draw(NVGcontext *vg) override; | ||||
void step() override; | void step() override; | ||||
void onMouseMove(EventMouseMove &e) override; | void onMouseMove(EventMouseMove &e) override; | ||||
@@ -234,7 +234,7 @@ struct TextField : OpaqueWidget { | |||||
void insertText(std::string text); | void insertText(std::string text); | ||||
/** Replaces the entire text */ | /** Replaces the entire text */ | ||||
void setText(std::string text); | void setText(std::string text); | ||||
virtual int getTextPosition(Vec mousePos); | |||||
virtual int getTextPosition(math::Vec mousePos); | |||||
virtual void onTextChange() {} | virtual void onTextChange() {} | ||||
}; | }; | ||||
@@ -6,64 +6,92 @@ | |||||
namespace rack { | namespace rack { | ||||
namespace color { | |||||
// TODO Make these non-inline in Rack v1 | |||||
static const NVGcolor BLACK_TRANSPARENT = nvgRGBA(0x00, 0x00, 0x00, 0x00); | |||||
static const NVGcolor BLACK = nvgRGB(0x00, 0x00, 0x00); | |||||
static const NVGcolor WHITE = nvgRGB(0xff, 0xff, 0xff); | |||||
static const NVGcolor WHITE_TRANSPARENT = nvgRGB(0xff, 0xff, 0xff); | |||||
static const NVGcolor RED = nvgRGB(0xff, 0x00, 0x00); | |||||
static const NVGcolor GREEN = nvgRGB(0x00, 0xff, 0x00); | |||||
static const NVGcolor BLUE = nvgRGB(0x00, 0x00, 0xff); | |||||
static const NVGcolor YELLOW = nvgRGB(0xff, 0xff, 0x00); | |||||
static const NVGcolor MAGENTA = nvgRGB(0xff, 0x00, 0xff); | |||||
static const NVGcolor CYAN = nvgRGB(0x00, 0xff, 0xff); | |||||
inline NVGcolor colorClip(NVGcolor a) { | |||||
inline NVGcolor clip(NVGcolor a) { | |||||
for (int i = 0; i < 4; i++) | for (int i = 0; i < 4; i++) | ||||
a.rgba[i] = clamp(a.rgba[i], 0.f, 1.f); | |||||
a.rgba[i] = math::clamp(a.rgba[i], 0.f, 1.f); | |||||
return a; | return a; | ||||
} | } | ||||
inline NVGcolor colorMinus(NVGcolor a, NVGcolor b) { | |||||
inline NVGcolor minus(NVGcolor a, NVGcolor b) { | |||||
for (int i = 0; i < 3; i++) | for (int i = 0; i < 3; i++) | ||||
a.rgba[i] -= b.rgba[i]; | a.rgba[i] -= b.rgba[i]; | ||||
return a; | return a; | ||||
} | } | ||||
inline NVGcolor colorPlus(NVGcolor a, NVGcolor b) { | |||||
inline NVGcolor plus(NVGcolor a, NVGcolor b) { | |||||
for (int i = 0; i < 3; i++) | for (int i = 0; i < 3; i++) | ||||
a.rgba[i] += b.rgba[i]; | a.rgba[i] += b.rgba[i]; | ||||
return a; | return a; | ||||
} | } | ||||
inline NVGcolor colorMult(NVGcolor a, NVGcolor b) { | |||||
inline NVGcolor mult(NVGcolor a, NVGcolor b) { | |||||
for (int i = 0; i < 3; i++) | for (int i = 0; i < 3; i++) | ||||
a.rgba[i] *= b.rgba[i]; | a.rgba[i] *= b.rgba[i]; | ||||
return a; | return a; | ||||
} | } | ||||
inline NVGcolor colorMult(NVGcolor a, float x) { | |||||
inline NVGcolor mult(NVGcolor a, float x) { | |||||
for (int i = 0; i < 3; i++) | for (int i = 0; i < 3; i++) | ||||
a.rgba[i] *= x; | a.rgba[i] *= x; | ||||
return a; | return a; | ||||
} | } | ||||
/** Screen blending with alpha compositing */ | /** Screen blending with alpha compositing */ | ||||
inline NVGcolor colorScreen(NVGcolor a, NVGcolor b) { | |||||
inline NVGcolor screen(NVGcolor a, NVGcolor b) { | |||||
if (a.a == 0.0) | if (a.a == 0.0) | ||||
return b; | return b; | ||||
if (b.a == 0.0) | if (b.a == 0.0) | ||||
return a; | return a; | ||||
a = colorMult(a, a.a); | |||||
b = colorMult(b, b.a); | |||||
NVGcolor c = colorMinus(colorPlus(a, b), colorMult(a, b)); | |||||
a = mult(a, a.a); | |||||
b = mult(b, b.a); | |||||
NVGcolor c = minus(plus(a, b), mult(a, b)); | |||||
c.a = a.a + b.a - a.a * b.a; | c.a = a.a + b.a - a.a * b.a; | ||||
c = colorMult(c, 1.f / c.a); | |||||
c = colorClip(c); | |||||
c = mult(c, 1.f / c.a); | |||||
c = clip(c); | |||||
return c; | return c; | ||||
} | } | ||||
inline NVGcolor colorAlpha(NVGcolor a, float alpha) { | |||||
inline NVGcolor alpha(NVGcolor a, float alpha) { | |||||
a.a *= alpha; | a.a *= alpha; | ||||
return a; | return a; | ||||
} | } | ||||
NVGcolor colorFromHexString(std::string s); | |||||
std::string colorToHexString(NVGcolor c); | |||||
inline NVGcolor fromHexString(std::string s) { | |||||
uint8_t r = 0; | |||||
uint8_t g = 0; | |||||
uint8_t b = 0; | |||||
uint8_t a = 255; | |||||
sscanf(s.c_str(), "#%2hhx%2hhx%2hhx%2hhx", &r, &g, &b, &a); | |||||
return nvgRGBA(r, g, b, a); | |||||
} | |||||
inline std::string toHexString(NVGcolor c) { | |||||
uint8_t r = std::round(c.r * 255); | |||||
uint8_t g = std::round(c.g * 255); | |||||
uint8_t b = std::round(c.b * 255); | |||||
uint8_t a = std::round(c.a * 255); | |||||
if (a == 255) | |||||
return stringf("#%02x%02x%02x", r, g, b); | |||||
else | |||||
return stringf("#%02x%02x%02x%02x", r, g, b, a); | |||||
} | |||||
} // namespace color | |||||
} // namespace rack | } // namespace rack |
@@ -1,11 +1,12 @@ | |||||
#pragma once | #pragma once | ||||
// Include most of the C standard library for convenience | |||||
// Include most of the C++ standard library for convenience | |||||
#include <cstdlib> | #include <cstdlib> | ||||
#include <cstdio> | #include <cstdio> | ||||
#include <cstdint> | #include <cstdint> | ||||
#include <cstring> | #include <cstring> | ||||
#include <cassert> | #include <cassert> | ||||
#include <climits> | |||||
#include <string> | #include <string> | ||||
#include <vector> | #include <vector> | ||||
@@ -82,7 +83,7 @@ to get its size in bytes. | |||||
#endif | #endif | ||||
#include "util/math.hpp" | |||||
#include "math.hpp" | |||||
namespace rack { | namespace rack { | ||||
@@ -50,22 +50,22 @@ Never inherit from Widget directly. Instead, inherit from VirtualWidget declared | |||||
*/ | */ | ||||
struct Widget { | struct Widget { | ||||
/** Stores position and size */ | /** Stores position and size */ | ||||
Rect box = Rect(Vec(), Vec(INFINITY, INFINITY)); | |||||
math::Rect box = math::Rect(math::Vec(), math::Vec(INFINITY, INFINITY)); | |||||
Widget *parent = NULL; | Widget *parent = NULL; | ||||
std::list<Widget*> children; | std::list<Widget*> children; | ||||
bool visible = true; | bool visible = true; | ||||
virtual ~Widget(); | virtual ~Widget(); | ||||
virtual Rect getChildrenBoundingBox(); | |||||
virtual math::Rect getChildrenBoundingBox(); | |||||
/** Returns `v` transformed into the coordinate system of `relative` */ | /** Returns `v` transformed into the coordinate system of `relative` */ | ||||
virtual Vec getRelativeOffset(Vec v, Widget *relative); | |||||
virtual math::Vec getRelativeOffset(math::Vec v, Widget *relative); | |||||
/** Returns `v` transformed into world coordinates */ | /** Returns `v` transformed into world coordinates */ | ||||
Vec getAbsoluteOffset(Vec v) { | |||||
math::Vec getAbsoluteOffset(math::Vec v) { | |||||
return getRelativeOffset(v, NULL); | return getRelativeOffset(v, NULL); | ||||
} | } | ||||
/** Returns a subset of the given Rect bounded by the box of this widget and all ancestors */ | |||||
virtual Rect getViewport(Rect r); | |||||
/** 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); | |||||
template <class T> | template <class T> | ||||
T *getAncestorOfType() { | T *getAncestorOfType() { | ||||
@@ -111,7 +111,7 @@ struct Widget { | |||||
/** Called when a mouse button is released over this widget */ | /** Called when a mouse button is released over this widget */ | ||||
virtual void onMouseUp(EventMouseUp &e); | virtual void onMouseUp(EventMouseUp &e); | ||||
/** Called when the mouse moves over this widget. | /** Called when the mouse moves over this widget. | ||||
Called on every frame, even if `mouseRel = Vec(0, 0)`. | |||||
Called on every frame, even if `mouseRel = math::Vec(0, 0)`. | |||||
*/ | */ | ||||
virtual void onMouseMove(EventMouseMove &e); | virtual void onMouseMove(EventMouseMove &e); | ||||
/** Called when a key is pressed while hovering over this widget */ | /** Called when a key is pressed while hovering over this widget */ | ||||
@@ -154,10 +154,10 @@ struct Widget { | |||||
/** Helper function for creating and initializing a Widget with certain arguments (in this case just the position). | /** Helper function for creating and initializing a Widget with certain arguments (in this case just the position). | ||||
In this project, you will find this idiom everywhere, as an easier alternative to constructor arguments, for building a Widget (or a subclass) with a one-liner. | In this project, you will find this idiom everywhere, as an easier alternative to constructor arguments, for building a Widget (or a subclass) with a one-liner. | ||||
Example: | Example: | ||||
addChild(Widget::create<SVGWidget>(Vec(10, 10))) | |||||
addChild(Widget::create<SVGWidget>(math::Vec(10, 10))) | |||||
*/ | */ | ||||
template <typename T = Widget> | template <typename T = Widget> | ||||
static T *create(Vec pos = Vec()) { | |||||
static T *create(math::Vec pos = math::Vec()) { | |||||
T *o = new T(); | T *o = new T(); | ||||
o->box.pos = pos; | o->box.pos = pos; | ||||
return o; | return o; | ||||
@@ -172,18 +172,18 @@ struct TransformWidget : VirtualWidget { | |||||
/** The transformation matrix */ | /** The transformation matrix */ | ||||
float transform[6]; | float transform[6]; | ||||
TransformWidget(); | TransformWidget(); | ||||
Rect getChildrenBoundingBox() override; | |||||
math::Rect getChildrenBoundingBox() override; | |||||
void identity(); | void identity(); | ||||
void translate(Vec delta); | |||||
void translate(math::Vec delta); | |||||
void rotate(float angle); | void rotate(float angle); | ||||
void scale(Vec s); | |||||
void scale(math::Vec s); | |||||
void draw(NVGcontext *vg) override; | void draw(NVGcontext *vg) override; | ||||
}; | }; | ||||
struct ZoomWidget : VirtualWidget { | struct ZoomWidget : VirtualWidget { | ||||
float zoom = 1.0; | float zoom = 1.0; | ||||
Vec getRelativeOffset(Vec v, Widget *relative) override; | |||||
Rect getViewport(Rect r) override; | |||||
math::Vec getRelativeOffset(math::Vec v, Widget *relative) override; | |||||
math::Rect getViewport(math::Rect r) override; | |||||
void setZoom(float zoom); | void setZoom(float zoom); | ||||
void draw(NVGcontext *vg) override; | void draw(NVGcontext *vg) override; | ||||
void onMouseDown(EventMouseDown &e) override; | void onMouseDown(EventMouseDown &e) override; | ||||
@@ -232,14 +232,6 @@ struct OpaqueWidget : VirtualWidget { | |||||
} | } | ||||
}; | }; | ||||
struct SpriteWidget : VirtualWidget { | |||||
Vec spriteOffset; | |||||
Vec spriteSize; | |||||
std::shared_ptr<Image> spriteImage; | |||||
int index = 0; | |||||
void draw(NVGcontext *vg) override; | |||||
}; | |||||
struct SVGWidget : VirtualWidget { | struct SVGWidget : VirtualWidget { | ||||
std::shared_ptr<SVG> svg; | std::shared_ptr<SVG> svg; | ||||
/** Sets the box size to the svg image size */ | /** Sets the box size to the svg image size */ | ||||
@@ -28,7 +28,7 @@ This is not equal to gPixelRatio in general. | |||||
extern float gWindowRatio; | extern float gWindowRatio; | ||||
extern bool gAllowCursorLock; | extern bool gAllowCursorLock; | ||||
extern int gGuiFrame; | extern int gGuiFrame; | ||||
extern Vec gMousePos; | |||||
extern math::Vec gMousePos; | |||||
void windowInit(); | void windowInit(); | ||||
@@ -39,10 +39,10 @@ void windowCursorLock(); | |||||
void windowCursorUnlock(); | void windowCursorUnlock(); | ||||
bool windowIsModPressed(); | bool windowIsModPressed(); | ||||
bool windowIsShiftPressed(); | bool windowIsShiftPressed(); | ||||
Vec windowGetWindowSize(); | |||||
void windowSetWindowSize(Vec size); | |||||
Vec windowGetWindowPos(); | |||||
void windowSetWindowPos(Vec pos); | |||||
math::Vec windowGetWindowSize(); | |||||
void windowSetWindowSize(math::Vec size); | |||||
math::Vec windowGetWindowPos(); | |||||
void windowSetWindowPos(math::Vec pos); | |||||
bool windowIsMaximized(); | bool windowIsMaximized(); | ||||
void windowSetTheme(NVGcolor bg, NVGcolor fg); | void windowSetTheme(NVGcolor bg, NVGcolor fg); | ||||
void windowSetFullScreen(bool fullScreen); | void windowSetFullScreen(bool fullScreen); | ||||
@@ -57,7 +57,7 @@ struct ModuleResizeHandle : Widget { | |||||
struct BlankWidget : ModuleWidget { | struct BlankWidget : ModuleWidget { | ||||
Panel *panel; | |||||
// Panel *panel; | |||||
Widget *topRightScrew; | Widget *topRightScrew; | ||||
Widget *bottomRightScrew; | Widget *bottomRightScrew; | ||||
Widget *rightHandle; | Widget *rightHandle; | ||||
@@ -65,11 +65,11 @@ struct BlankWidget : ModuleWidget { | |||||
BlankWidget(Module *module) : ModuleWidget(module) { | BlankWidget(Module *module) : ModuleWidget(module) { | ||||
box.size = Vec(RACK_GRID_WIDTH * 10, RACK_GRID_HEIGHT); | box.size = Vec(RACK_GRID_WIDTH * 10, RACK_GRID_HEIGHT); | ||||
{ | |||||
panel = new LightPanel(); | |||||
panel->box.size = box.size; | |||||
addChild(panel); | |||||
} | |||||
// { | |||||
// panel = new LightPanel(); | |||||
// panel->box.size = box.size; | |||||
// addChild(panel); | |||||
// } | |||||
ModuleResizeHandle *leftHandle = new ModuleResizeHandle(); | ModuleResizeHandle *leftHandle = new ModuleResizeHandle(); | ||||
ModuleResizeHandle *rightHandle = new ModuleResizeHandle(); | ModuleResizeHandle *rightHandle = new ModuleResizeHandle(); | ||||
@@ -87,7 +87,7 @@ struct BlankWidget : ModuleWidget { | |||||
} | } | ||||
void step() override { | void step() override { | ||||
panel->box.size = box.size; | |||||
// panel->box.size = box.size; | |||||
topRightScrew->box.pos.x = box.size.x - 30; | topRightScrew->box.pos.x = box.size.x - 30; | ||||
bottomRightScrew->box.pos.x = box.size.x - 30; | bottomRightScrew->box.pos.x = box.size.x - 30; | ||||
if (box.size.x < RACK_GRID_WIDTH * 6) { | if (box.size.x < RACK_GRID_WIDTH * 6) { | ||||
@@ -1,4 +1,5 @@ | |||||
#include "rack.hpp" | #include "rack.hpp" | ||||
#include "componentlibrary.hpp" | |||||
using namespace rack; | using namespace rack; | ||||
@@ -151,9 +151,9 @@ struct AudioBlockSizeChoice : LedDisplayChoice { | |||||
AudioWidget::AudioWidget() { | AudioWidget::AudioWidget() { | ||||
box.size = mm2px(Vec(44, 28)); | |||||
box.size = mm2px(math::Vec(44, 28)); | |||||
Vec pos = Vec(); | |||||
math::Vec pos = math::Vec(); | |||||
AudioDriverChoice *driverChoice = Widget::create<AudioDriverChoice>(pos); | AudioDriverChoice *driverChoice = Widget::create<AudioDriverChoice>(pos); | ||||
driverChoice->audioWidget = this; | driverChoice->audioWidget = this; | ||||
@@ -15,7 +15,7 @@ void CircularShadow::draw(NVGcontext *vg) { | |||||
nvgBeginPath(vg); | nvgBeginPath(vg); | ||||
nvgRect(vg, -blurRadius, -blurRadius, box.size.x + 2*blurRadius, box.size.y + 2*blurRadius); | nvgRect(vg, -blurRadius, -blurRadius, box.size.x + 2*blurRadius, box.size.y + 2*blurRadius); | ||||
Vec center = box.size.div(2.0); | |||||
math::Vec center = box.size.div(2.0); | |||||
float radius = center.x; | float radius = center.x; | ||||
NVGcolor icol = nvgRGBAf(0.0, 0.0, 0.0, opacity); | NVGcolor icol = nvgRGBAf(0.0, 0.0, 0.0, opacity); | ||||
NVGcolor ocol = nvgRGBAf(0.0, 0.0, 0.0, 0.0); | NVGcolor ocol = nvgRGBAf(0.0, 0.0, 0.0, 0.0); | ||||
@@ -36,7 +36,7 @@ void Knob::onDragMove(EventDragMove &e) { | |||||
if (windowIsModPressed()) | if (windowIsModPressed()) | ||||
delta /= 16.f; | delta /= 16.f; | ||||
dragValue += delta; | dragValue += delta; | ||||
dragValue = clampBetween(dragValue, minValue, maxValue); | |||||
dragValue = math::clampBetween(dragValue, minValue, maxValue); | |||||
if (snap) | if (snap) | ||||
setValue(std::round(dragValue)); | setValue(std::round(dragValue)); | ||||
else | else | ||||
@@ -17,7 +17,7 @@ void LedDisplay::draw(NVGcontext *vg) { | |||||
LedDisplaySeparator::LedDisplaySeparator() { | LedDisplaySeparator::LedDisplaySeparator() { | ||||
box.size = Vec(); | |||||
box.size = math::Vec(); | |||||
} | } | ||||
void LedDisplaySeparator::draw(NVGcontext *vg) { | void LedDisplaySeparator::draw(NVGcontext *vg) { | ||||
@@ -31,10 +31,10 @@ void LedDisplaySeparator::draw(NVGcontext *vg) { | |||||
LedDisplayChoice::LedDisplayChoice() { | LedDisplayChoice::LedDisplayChoice() { | ||||
box.size = mm2px(Vec(0, 28.0 / 3)); | |||||
box.size = mm2px(math::Vec(0, 28.0 / 3)); | |||||
font = Font::load(assetGlobal("res/fonts/ShareTechMono-Regular.ttf")); | font = Font::load(assetGlobal("res/fonts/ShareTechMono-Regular.ttf")); | ||||
color = nvgRGB(0xff, 0xd7, 0x14); | color = nvgRGB(0xff, 0xd7, 0x14); | ||||
textOffset = Vec(10, 18); | |||||
textOffset = math::Vec(10, 18); | |||||
} | } | ||||
void LedDisplayChoice::draw(NVGcontext *vg) { | void LedDisplayChoice::draw(NVGcontext *vg) { | ||||
@@ -65,7 +65,7 @@ void LedDisplayChoice::onMouseDown(EventMouseDown &e) { | |||||
LedDisplayTextField::LedDisplayTextField() { | LedDisplayTextField::LedDisplayTextField() { | ||||
font = Font::load(assetGlobal("res/fonts/ShareTechMono-Regular.ttf")); | font = Font::load(assetGlobal("res/fonts/ShareTechMono-Regular.ttf")); | ||||
color = nvgRGB(0xff, 0xd7, 0x14); | color = nvgRGB(0xff, 0xd7, 0x14); | ||||
textOffset = Vec(5, 5); | |||||
textOffset = math::Vec(5, 5); | |||||
} | } | ||||
@@ -96,7 +96,7 @@ void LedDisplayTextField::draw(NVGcontext *vg) { | |||||
nvgResetScissor(vg); | nvgResetScissor(vg); | ||||
} | } | ||||
int LedDisplayTextField::getTextPosition(Vec mousePos) { | |||||
int LedDisplayTextField::getTextPosition(math::Vec mousePos) { | |||||
bndSetFont(font->handle); | bndSetFont(font->handle); | ||||
int textPos = bndIconLabelTextPosition(gVg, textOffset.x, textOffset.y, | int textPos = bndIconLabelTextPosition(gVg, textOffset.x, textOffset.y, | ||||
box.size.x - 2*textOffset.x, box.size.y - 2*textOffset.y, | box.size.x - 2*textOffset.x, box.size.y - 2*textOffset.y, | ||||
@@ -38,7 +38,7 @@ void LightWidget::drawHalo(NVGcontext *vg) { | |||||
nvgRect(vg, radius - oradius, radius - oradius, 2*oradius, 2*oradius); | nvgRect(vg, radius - oradius, radius - oradius, 2*oradius, 2*oradius); | ||||
NVGpaint paint; | NVGpaint paint; | ||||
NVGcolor icol = colorMult(color, 0.08); | |||||
NVGcolor icol = color::mult(color, 0.08); | |||||
NVGcolor ocol = nvgRGB(0, 0, 0); | NVGcolor ocol = nvgRGB(0, 0, 0); | ||||
paint = nvgRadialGradient(vg, radius, radius, radius, oradius, icol, ocol); | paint = nvgRadialGradient(vg, radius, radius, radius, oradius, icol, ocol); | ||||
nvgFillPaint(vg, paint); | nvgFillPaint(vg, paint); | ||||
@@ -110,9 +110,9 @@ struct MidiChannelChoice : LedDisplayChoice { | |||||
MidiWidget::MidiWidget() { | MidiWidget::MidiWidget() { | ||||
box.size = mm2px(Vec(44, 28)); | |||||
box.size = mm2px(math::Vec(44, 28)); | |||||
Vec pos = Vec(); | |||||
math::Vec pos = math::Vec(); | |||||
MidiDriverChoice *driverChoice = Widget::create<MidiDriverChoice>(pos); | MidiDriverChoice *driverChoice = Widget::create<MidiDriverChoice>(pos); | ||||
driverChoice->midiWidget = this; | driverChoice->midiWidget = this; | ||||
@@ -56,7 +56,7 @@ struct SeparatorItem : OpaqueWidget { | |||||
void setText(std::string text) { | void setText(std::string text) { | ||||
clearChildren(); | clearChildren(); | ||||
Label *label = Widget::create<Label>(Vec(0, 12 + itemMargin)); | |||||
Label *label = Widget::create<Label>(math::Vec(0, 12 + itemMargin)); | |||||
label->text = text; | label->text = text; | ||||
label->fontSize = 20; | label->fontSize = 20; | ||||
label->color.a *= 0.5; | label->color.a *= 0.5; | ||||
@@ -107,7 +107,7 @@ struct ModelItem : BrowserListItem { | |||||
assert(model); | assert(model); | ||||
this->model = model; | this->model = model; | ||||
FavoriteRadioButton *favoriteButton = Widget::create<FavoriteRadioButton>(Vec(8, itemMargin)); | |||||
FavoriteRadioButton *favoriteButton = Widget::create<FavoriteRadioButton>(math::Vec(8, itemMargin)); | |||||
favoriteButton->box.size.x = 20; | favoriteButton->box.size.x = 20; | ||||
favoriteButton->label = "★"; | favoriteButton->label = "★"; | ||||
addChild(favoriteButton); | addChild(favoriteButton); | ||||
@@ -122,7 +122,7 @@ struct ModelItem : BrowserListItem { | |||||
nameLabel->text = model->name; | nameLabel->text = model->name; | ||||
addChild(nameLabel); | addChild(nameLabel); | ||||
pluginLabel = Widget::create<Label>(Vec(0, itemMargin)); | |||||
pluginLabel = Widget::create<Label>(math::Vec(0, itemMargin)); | |||||
pluginLabel->alignment = Label::RIGHT_ALIGNMENT; | pluginLabel->alignment = Label::RIGHT_ALIGNMENT; | ||||
pluginLabel->text = model->plugin->slug + " " + model->plugin->version; | pluginLabel->text = model->plugin->slug + " " + model->plugin->version; | ||||
pluginLabel->color.a = 0.5; | pluginLabel->color.a = 0.5; | ||||
@@ -153,7 +153,7 @@ struct AuthorItem : BrowserListItem { | |||||
void setAuthor(std::string author) { | void setAuthor(std::string author) { | ||||
clearChildren(); | clearChildren(); | ||||
this->author = author; | this->author = author; | ||||
Label *authorLabel = Widget::create<Label>(Vec(0, 0 + itemMargin)); | |||||
Label *authorLabel = Widget::create<Label>(math::Vec(0, 0 + itemMargin)); | |||||
if (author.empty()) | if (author.empty()) | ||||
authorLabel->text = "Show all modules"; | authorLabel->text = "Show all modules"; | ||||
else | else | ||||
@@ -171,7 +171,7 @@ struct TagItem : BrowserListItem { | |||||
void setTag(ModelTag tag) { | void setTag(ModelTag tag) { | ||||
clearChildren(); | clearChildren(); | ||||
this->tag = tag; | this->tag = tag; | ||||
Label *tagLabel = Widget::create<Label>(Vec(0, 0 + itemMargin)); | |||||
Label *tagLabel = Widget::create<Label>(math::Vec(0, 0 + itemMargin)); | |||||
if (tag == NO_TAG) | if (tag == NO_TAG) | ||||
tagLabel->text = "Show all tags"; | tagLabel->text = "Show all tags"; | ||||
else | else | ||||
@@ -185,7 +185,7 @@ struct TagItem : BrowserListItem { | |||||
struct ClearFilterItem : BrowserListItem { | struct ClearFilterItem : BrowserListItem { | ||||
ClearFilterItem() { | ClearFilterItem() { | ||||
Label *label = Widget::create<Label>(Vec(0, 0 + itemMargin)); | |||||
Label *label = Widget::create<Label>(math::Vec(0, 0 + itemMargin)); | |||||
label->text = "Back"; | label->text = "Back"; | ||||
addChild(label); | addChild(label); | ||||
} | } | ||||
@@ -213,7 +213,7 @@ struct BrowserList : List { | |||||
void incrementSelection(int delta) { | void incrementSelection(int delta) { | ||||
selected += delta; | selected += delta; | ||||
selected = clamp(selected, 0, countItems() - 1); | |||||
selected = math::clamp(selected, 0, countItems() - 1); | |||||
} | } | ||||
int countItems() { | int countItems() { | ||||
@@ -294,7 +294,7 @@ struct ModuleBrowser : OpaqueWidget { | |||||
addChild(searchField); | addChild(searchField); | ||||
moduleList = new BrowserList(); | moduleList = new BrowserList(); | ||||
moduleList->box.size = Vec(box.size.x, 0.0); | |||||
moduleList->box.size = math::Vec(box.size.x, 0.0); | |||||
// Module Scroll | // Module Scroll | ||||
moduleScroll = new ScrollWidget(); | moduleScroll = new ScrollWidget(); | ||||
@@ -12,7 +12,7 @@ void ModuleLightWidget::step() { | |||||
for (size_t i = 0; i < baseColors.size(); i++) { | for (size_t i = 0; i < baseColors.size(); i++) { | ||||
float value = module->lights[firstLightId + i].getBrightness(); | float value = module->lights[firstLightId + i].getBrightness(); | ||||
value = clamp(value, 0.f, 1.f); | |||||
value = math::clamp(value, 0.f, 1.f); | |||||
values[i] = value; | values[i] = value; | ||||
} | } | ||||
setValues(values); | setValues(values); | ||||
@@ -310,7 +310,7 @@ void ModuleWidget::draw(NVGcontext *vg) { | |||||
nvgFillColor(vg, nvgRGBf(1, 1, 1)); | nvgFillColor(vg, nvgRGBf(1, 1, 1)); | ||||
nvgText(vg, 10.0, box.size.y - 6.0, cpuText.c_str(), NULL); | nvgText(vg, 10.0, box.size.y - 6.0, cpuText.c_str(), NULL); | ||||
float p = clamp(module->cpuTime, 0.f, 1.f); | |||||
float p = math::clamp(module->cpuTime, 0.f, 1.f); | |||||
nvgBeginPath(vg); | nvgBeginPath(vg); | ||||
nvgRect(vg, | nvgRect(vg, | ||||
0, (1.f - p) * box.size.y, | 0, (1.f - p) * box.size.y, | ||||
@@ -326,7 +326,7 @@ void ModuleWidget::drawShadow(NVGcontext *vg) { | |||||
nvgBeginPath(vg); | nvgBeginPath(vg); | ||||
float r = 20; // Blur radius | float r = 20; // Blur radius | ||||
float c = 20; // Corner radius | float c = 20; // Corner radius | ||||
Vec b = Vec(-10, 30); // Offset from each corner | |||||
math::Vec b = math::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); | 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 shadowColor = nvgRGBAf(0, 0, 0, 0.2); | ||||
NVGcolor transparentColor = nvgRGBAf(0, 0, 0, 0); | NVGcolor transparentColor = nvgRGBAf(0, 0, 0, 0); | ||||
@@ -422,7 +422,7 @@ void ModuleWidget::onDragEnd(EventDragEnd &e) { | |||||
void ModuleWidget::onDragMove(EventDragMove &e) { | void ModuleWidget::onDragMove(EventDragMove &e) { | ||||
if (!gRackWidget->lockModules) { | if (!gRackWidget->lockModules) { | ||||
Rect newBox = box; | |||||
math::Rect newBox = box; | |||||
newBox.pos = gRackWidget->lastMousePos.minus(dragPos); | newBox.pos = gRackWidget->lastMousePos.minus(dragPos); | ||||
gRackWidget->requestModuleBoxNearest(this, newBox); | gRackWidget->requestModuleBoxNearest(this, newBox); | ||||
} | } | ||||
@@ -14,10 +14,10 @@ void MultiLightWidget::setValues(const std::vector<float> &values) { | |||||
color = nvgRGBAf(0, 0, 0, 0); | color = nvgRGBAf(0, 0, 0, 0); | ||||
for (size_t i = 0; i < baseColors.size(); i++) { | for (size_t i = 0; i < baseColors.size(); i++) { | ||||
NVGcolor c = baseColors[i]; | NVGcolor c = baseColors[i]; | ||||
c.a *= clamp(values[i], 0.f, 1.f); | |||||
color = colorScreen(color, c); | |||||
c.a *= math::clamp(values[i], 0.f, 1.f); | |||||
color = color::screen(color, c); | |||||
} | } | ||||
color = colorClip(color); | |||||
color = color::clip(color); | |||||
} | } | ||||
@@ -1,37 +0,0 @@ | |||||
#include "app.hpp" | |||||
namespace rack { | |||||
void Panel::draw(NVGcontext *vg) { | |||||
nvgBeginPath(vg); | |||||
nvgRect(vg, 0.0, 0.0, box.size.x, box.size.y); | |||||
// Background color | |||||
if (backgroundColor.a > 0) { | |||||
nvgFillColor(vg, backgroundColor); | |||||
nvgFill(vg); | |||||
} | |||||
// Background image | |||||
if (backgroundImage) { | |||||
int width, height; | |||||
nvgImageSize(vg, backgroundImage->handle, &width, &height); | |||||
NVGpaint paint = nvgImagePattern(vg, 0.0, 0.0, width, height, 0.0, backgroundImage->handle, 1.0); | |||||
nvgFillPaint(vg, paint); | |||||
nvgFill(vg); | |||||
} | |||||
// Border | |||||
NVGcolor borderColor = nvgRGBAf(0.5, 0.5, 0.5, 0.5); | |||||
nvgBeginPath(vg); | |||||
nvgRect(vg, 0.5, 0.5, box.size.x - 1.0, box.size.y - 1.0); | |||||
nvgStrokeColor(vg, borderColor); | |||||
nvgStrokeWidth(vg, 1.0); | |||||
nvgStroke(vg); | |||||
Widget::draw(vg); | |||||
} | |||||
} // namespace rack |
@@ -31,7 +31,7 @@ void ParamWidget::reset() { | |||||
void ParamWidget::randomize() { | void ParamWidget::randomize() { | ||||
// Infinite params should not be randomized | // Infinite params should not be randomized | ||||
if (randomizable && std::isfinite(minValue) && std::isfinite(maxValue)) { | if (randomizable && std::isfinite(minValue) && std::isfinite(maxValue)) { | ||||
setValue(rescale(randomUniform(), 0.f, 1.f, minValue, maxValue)); | |||||
setValue(math::rescale(randomUniform(), 0.f, 1.f, minValue, maxValue)); | |||||
} | } | ||||
} | } | ||||
@@ -123,7 +123,7 @@ PluginManagerWidget::PluginManagerWidget() { | |||||
box.size.y = BND_WIDGET_HEIGHT; | box.size.y = BND_WIDGET_HEIGHT; | ||||
{ | { | ||||
SequentialLayout *layout = Widget::create<SequentialLayout>(Vec(0, 0)); | |||||
SequentialLayout *layout = Widget::create<SequentialLayout>(math::Vec(0, 0)); | |||||
layout->spacing = 5; | layout->spacing = 5; | ||||
loginWidget = layout; | loginWidget = layout; | ||||
@@ -156,7 +156,7 @@ PluginManagerWidget::PluginManagerWidget() { | |||||
} | } | ||||
{ | { | ||||
SequentialLayout *layout = Widget::create<SequentialLayout>(Vec(0, 0)); | |||||
SequentialLayout *layout = Widget::create<SequentialLayout>(math::Vec(0, 0)); | |||||
layout->spacing = 5; | layout->spacing = 5; | ||||
manageWidget = layout; | manageWidget = layout; | ||||
@@ -179,7 +179,7 @@ PluginManagerWidget::PluginManagerWidget() { | |||||
} | } | ||||
{ | { | ||||
SequentialLayout *layout = Widget::create<SequentialLayout>(Vec(0, 0)); | |||||
SequentialLayout *layout = Widget::create<SequentialLayout>(math::Vec(0, 0)); | |||||
layout->spacing = 5; | layout->spacing = 5; | ||||
downloadWidget = layout; | downloadWidget = layout; | ||||
@@ -9,10 +9,10 @@ namespace rack { | |||||
struct PlugLight : MultiLightWidget { | struct PlugLight : MultiLightWidget { | ||||
PlugLight() { | PlugLight() { | ||||
addBaseColor(COLOR_GREEN); | |||||
addBaseColor(COLOR_RED); | |||||
box.size = Vec(8, 8); | |||||
bgColor = COLOR_BLACK_TRANSPARENT; | |||||
addBaseColor(color::GREEN); | |||||
addBaseColor(color::RED); | |||||
box.size = math::Vec(8, 8); | |||||
bgColor = color::BLACK_TRANSPARENT; | |||||
} | } | ||||
}; | }; | ||||
@@ -35,7 +35,7 @@ void RackScene::step() { | |||||
// Resize to be a bit larger than the ScrollWidget viewport | // Resize to be a bit larger than the ScrollWidget viewport | ||||
gRackWidget->box.size = scrollWidget->box.size | gRackWidget->box.size = scrollWidget->box.size | ||||
.minus(scrollWidget->container->box.pos) | .minus(scrollWidget->container->box.pos) | ||||
.plus(Vec(500, 500)) | |||||
.plus(math::Vec(500, 500)) | |||||
.div(zoomWidget->zoom); | .div(zoomWidget->zoom); | ||||
Scene::step(); | Scene::step(); | ||||
@@ -6,8 +6,8 @@ namespace rack { | |||||
void RackScrollWidget::step() { | void RackScrollWidget::step() { | ||||
Vec pos = gMousePos; | |||||
Rect viewport = getViewport(box.zeroPos()); | |||||
math::Vec pos = gMousePos; | |||||
math::Rect viewport = getViewport(box.zeroPos()); | |||||
// Scroll rack if dragging cable near the edge of the screen | // Scroll rack if dragging cable near the edge of the screen | ||||
if (gRackWidget->wireContainer->activeWire) { | if (gRackWidget->wireContainer->activeWire) { | ||||
float margin = 20.0; | float margin = 20.0; | ||||
@@ -32,11 +32,11 @@ struct ModuleContainer : Widget { | |||||
RackWidget::RackWidget() { | RackWidget::RackWidget() { | ||||
rails = new FramebufferWidget(); | rails = new FramebufferWidget(); | ||||
rails->box.size = Vec(); | |||||
rails->box.size = math::Vec(); | |||||
rails->oversample = 1.0; | rails->oversample = 1.0; | ||||
{ | { | ||||
RackRail *rail = new RackRail(); | RackRail *rail = new RackRail(); | ||||
rail->box.size = Vec(); | |||||
rail->box.size = math::Vec(); | |||||
rails->addChild(rail); | rails->addChild(rail); | ||||
} | } | ||||
addChild(rails); | addChild(rails); | ||||
@@ -56,7 +56,7 @@ void RackWidget::clear() { | |||||
wireContainer->clearChildren(); | wireContainer->clearChildren(); | ||||
moduleContainer->clearChildren(); | moduleContainer->clearChildren(); | ||||
gRackScene->scrollWidget->offset = Vec(0, 0); | |||||
gRackScene->scrollWidget->offset = math::Vec(0, 0); | |||||
} | } | ||||
void RackWidget::reset() { | void RackWidget::reset() { | ||||
@@ -202,7 +202,7 @@ json_t *RackWidget::toJson() { | |||||
json_t *moduleJ = moduleWidget->toJson(); | json_t *moduleJ = moduleWidget->toJson(); | ||||
{ | { | ||||
// pos | // pos | ||||
Vec pos = moduleWidget->box.pos.div(RACK_GRID_SIZE).round(); | |||||
math::Vec pos = moduleWidget->box.pos.div(RACK_GRID_SIZE).round(); | |||||
json_t *posJ = json_pack("[i, i]", (int) pos.x, (int) pos.y); | json_t *posJ = json_pack("[i, i]", (int) pos.x, (int) pos.y); | ||||
json_object_set_new(moduleJ, "pos", posJ); | json_object_set_new(moduleJ, "pos", posJ); | ||||
} | } | ||||
@@ -285,7 +285,7 @@ void RackWidget::fromJson(json_t *rootJ) { | |||||
json_t *posJ = json_object_get(moduleJ, "pos"); | json_t *posJ = json_object_get(moduleJ, "pos"); | ||||
double x, y; | double x, y; | ||||
json_unpack(posJ, "[F, F]", &x, &y); | json_unpack(posJ, "[F, F]", &x, &y); | ||||
Vec pos = Vec(x, y); | |||||
math::Vec pos = math::Vec(x, y); | |||||
if (legacy && legacy <= 1) { | if (legacy && legacy <= 1) { | ||||
moduleWidget->box.pos = pos; | moduleWidget->box.pos = pos; | ||||
} | } | ||||
@@ -399,7 +399,7 @@ void RackWidget::pastePresetClipboard() { | |||||
if (moduleJ) { | if (moduleJ) { | ||||
ModuleWidget *moduleWidget = moduleFromJson(moduleJ); | ModuleWidget *moduleWidget = moduleFromJson(moduleJ); | ||||
// Set moduleWidget position | // Set moduleWidget position | ||||
Rect newBox = moduleWidget->box; | |||||
math::Rect newBox = moduleWidget->box; | |||||
newBox.pos = lastMousePos.minus(newBox.size.div(2)); | newBox.pos = lastMousePos.minus(newBox.size.div(2)); | ||||
requestModuleBoxNearest(moduleWidget, newBox); | requestModuleBoxNearest(moduleWidget, newBox); | ||||
@@ -425,12 +425,12 @@ void RackWidget::cloneModule(ModuleWidget *m) { | |||||
json_t *moduleJ = m->toJson(); | json_t *moduleJ = m->toJson(); | ||||
ModuleWidget *clonedModuleWidget = moduleFromJson(moduleJ); | ModuleWidget *clonedModuleWidget = moduleFromJson(moduleJ); | ||||
json_decref(moduleJ); | json_decref(moduleJ); | ||||
Rect clonedBox = clonedModuleWidget->box; | |||||
math::Rect clonedBox = clonedModuleWidget->box; | |||||
clonedBox.pos = m->box.pos; | clonedBox.pos = m->box.pos; | ||||
requestModuleBoxNearest(clonedModuleWidget, clonedBox); | requestModuleBoxNearest(clonedModuleWidget, clonedBox); | ||||
} | } | ||||
bool RackWidget::requestModuleBox(ModuleWidget *m, Rect box) { | |||||
bool RackWidget::requestModuleBox(ModuleWidget *m, math::Rect box) { | |||||
if (box.pos.x < 0 || box.pos.y < 0) | if (box.pos.x < 0 || box.pos.y < 0) | ||||
return false; | return false; | ||||
@@ -444,25 +444,25 @@ bool RackWidget::requestModuleBox(ModuleWidget *m, Rect box) { | |||||
return true; | return true; | ||||
} | } | ||||
bool RackWidget::requestModuleBoxNearest(ModuleWidget *m, Rect box) { | |||||
bool RackWidget::requestModuleBoxNearest(ModuleWidget *m, math::Rect box) { | |||||
// Create possible positions | // Create possible positions | ||||
int x0 = roundf(box.pos.x / RACK_GRID_WIDTH); | int x0 = roundf(box.pos.x / RACK_GRID_WIDTH); | ||||
int y0 = roundf(box.pos.y / RACK_GRID_HEIGHT); | int y0 = roundf(box.pos.y / RACK_GRID_HEIGHT); | ||||
std::vector<Vec> positions; | |||||
std::vector<math::Vec> positions; | |||||
for (int y = std::max(0, y0 - 8); y < y0 + 8; y++) { | for (int y = std::max(0, y0 - 8); y < y0 + 8; y++) { | ||||
for (int x = std::max(0, x0 - 400); x < x0 + 400; x++) { | for (int x = std::max(0, x0 - 400); x < x0 + 400; x++) { | ||||
positions.push_back(Vec(x * RACK_GRID_WIDTH, y * RACK_GRID_HEIGHT)); | |||||
positions.push_back(math::Vec(x * RACK_GRID_WIDTH, y * RACK_GRID_HEIGHT)); | |||||
} | } | ||||
} | } | ||||
// Sort possible positions by distance to the requested position | // Sort possible positions by distance to the requested position | ||||
std::sort(positions.begin(), positions.end(), [box](Vec a, Vec b) { | |||||
std::sort(positions.begin(), positions.end(), [box](math::Vec a, math::Vec b) { | |||||
return a.minus(box.pos).norm() < b.minus(box.pos).norm(); | return a.minus(box.pos).norm() < b.minus(box.pos).norm(); | ||||
}); | }); | ||||
// Find a position that does not collide | // Find a position that does not collide | ||||
for (Vec position : positions) { | |||||
Rect newBox = box; | |||||
for (math::Vec position : positions) { | |||||
math::Rect newBox = box; | |||||
newBox.pos = position; | newBox.pos = position; | ||||
if (requestModuleBox(m, newBox)) | if (requestModuleBox(m, newBox)) | ||||
return true; | return true; | ||||
@@ -472,15 +472,15 @@ bool RackWidget::requestModuleBoxNearest(ModuleWidget *m, Rect box) { | |||||
void RackWidget::step() { | void RackWidget::step() { | ||||
// Expand size to fit modules | // Expand size to fit modules | ||||
Vec moduleSize = moduleContainer->getChildrenBoundingBox().getBottomRight(); | |||||
math::Vec moduleSize = moduleContainer->getChildrenBoundingBox().getBottomRight(); | |||||
// We assume that the size is reset by a parent before calling step(). Otherwise it will grow unbounded. | // We assume that the size is reset by a parent before calling step(). Otherwise it will grow unbounded. | ||||
box.size = box.size.max(moduleSize); | box.size = box.size.max(moduleSize); | ||||
// Adjust size and position of rails | // Adjust size and position of rails | ||||
Widget *rail = rails->children.front(); | Widget *rail = rails->children.front(); | ||||
Rect bound = getViewport(Rect(Vec(), box.size)); | |||||
math::Rect bound = getViewport(math::Rect(math::Vec(), box.size)); | |||||
if (!rails->box.contains(bound)) { | if (!rails->box.contains(bound)) { | ||||
Vec cellMargin = Vec(20, 1); | |||||
math::Vec cellMargin = math::Vec(20, 1); | |||||
rails->box.pos = bound.pos.div(RACK_GRID_SIZE).floor().minus(cellMargin).mult(RACK_GRID_SIZE); | 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->box.size = bound.size.plus(cellMargin.mult(RACK_GRID_SIZE).mult(2)); | ||||
rails->dirty = true; | rails->dirty = true; | ||||
@@ -519,7 +519,7 @@ void RackWidget::onMouseDown(EventMouseDown &e) { | |||||
} | } | ||||
void RackWidget::onZoom(EventZoom &e) { | void RackWidget::onZoom(EventZoom &e) { | ||||
rails->box.size = Vec(); | |||||
rails->box.size = math::Vec(); | |||||
Widget::onZoom(e); | Widget::onZoom(e); | ||||
} | } | ||||
@@ -7,7 +7,7 @@ namespace rack { | |||||
SVGKnob::SVGKnob() { | SVGKnob::SVGKnob() { | ||||
shadow = new CircularShadow(); | shadow = new CircularShadow(); | ||||
addChild(shadow); | addChild(shadow); | ||||
shadow->box.size = Vec(); | |||||
shadow->box.size = math::Vec(); | |||||
tw = new TransformWidget(); | tw = new TransformWidget(); | ||||
addChild(tw); | addChild(tw); | ||||
@@ -21,8 +21,8 @@ void SVGKnob::setSVG(std::shared_ptr<SVG> svg) { | |||||
tw->box.size = sw->box.size; | tw->box.size = sw->box.size; | ||||
box.size = sw->box.size; | box.size = sw->box.size; | ||||
shadow->box.size = sw->box.size; | shadow->box.size = sw->box.size; | ||||
shadow->box.pos = Vec(0, sw->box.size.y * 0.1); | |||||
// shadow->box = shadow->box.grow(Vec(2, 2)); | |||||
shadow->box.pos = math::Vec(0, sw->box.size.y * 0.1); | |||||
// shadow->box = shadow->box.grow(math::Vec(2, 2)); | |||||
} | } | ||||
void SVGKnob::step() { | void SVGKnob::step() { | ||||
@@ -30,15 +30,15 @@ void SVGKnob::step() { | |||||
if (dirty) { | if (dirty) { | ||||
float angle; | float angle; | ||||
if (std::isfinite(minValue) && std::isfinite(maxValue)) { | if (std::isfinite(minValue) && std::isfinite(maxValue)) { | ||||
angle = rescale(value, minValue, maxValue, minAngle, maxAngle); | |||||
angle = math::rescale(value, minValue, maxValue, minAngle, maxAngle); | |||||
} | } | ||||
else { | else { | ||||
angle = rescale(value, -1.0, 1.0, minAngle, maxAngle); | |||||
angle = math::rescale(value, -1.0, 1.0, minAngle, maxAngle); | |||||
angle = std::fmod(angle, 2*M_PI); | angle = std::fmod(angle, 2*M_PI); | ||||
} | } | ||||
tw->identity(); | tw->identity(); | ||||
// Rotate SVG | // Rotate SVG | ||||
Vec center = sw->box.getCenter(); | |||||
math::Vec center = sw->box.getCenter(); | |||||
tw->translate(center); | tw->translate(center); | ||||
tw->rotate(angle); | tw->rotate(angle); | ||||
tw->translate(center.neg()); | tw->translate(center.neg()); | ||||
@@ -18,7 +18,7 @@ struct PanelBorder : TransparentWidget { | |||||
void SVGPanel::step() { | void SVGPanel::step() { | ||||
if (isNear(gPixelRatio, 1.0)) { | |||||
if (math::isNear(gPixelRatio, 1.0)) { | |||||
// Small details draw poorly at low DPI, so oversample when drawing to the framebuffer | // Small details draw poorly at low DPI, so oversample when drawing to the framebuffer | ||||
oversample = 2.0; | oversample = 2.0; | ||||
} | } | ||||
@@ -9,7 +9,7 @@ SVGPort::SVGPort() { | |||||
addChild(shadow); | addChild(shadow); | ||||
// Avoid breakage if plugins fail to call setSVG() | // Avoid breakage if plugins fail to call setSVG() | ||||
// In that case, just disable the shadow. | // In that case, just disable the shadow. | ||||
shadow->box.size = Vec(); | |||||
shadow->box.size = math::Vec(); | |||||
background = new SVGWidget(); | background = new SVGWidget(); | ||||
addChild(background); | addChild(background); | ||||
@@ -19,8 +19,8 @@ void SVGPort::setSVG(std::shared_ptr<SVG> svg) { | |||||
background->setSVG(svg); | background->setSVG(svg); | ||||
box.size = background->box.size; | box.size = background->box.size; | ||||
shadow->box.size = background->box.size; | shadow->box.size = background->box.size; | ||||
shadow->box.pos = Vec(0, background->box.size.y * 0.1); | |||||
// shadow->box = shadow->box.grow(Vec(2, 2)); | |||||
shadow->box.pos = math::Vec(0, background->box.size.y * 0.1); | |||||
// shadow->box = shadow->box.grow(math::Vec(2, 2)); | |||||
} | } | ||||
void SVGPort::draw(NVGcontext *vg) { | void SVGPort::draw(NVGcontext *vg) { | ||||
@@ -25,7 +25,7 @@ void SVGSlider::setSVGs(std::shared_ptr<SVG> backgroundSVG, std::shared_ptr<SVG> | |||||
void SVGSlider::step() { | void SVGSlider::step() { | ||||
if (dirty) { | if (dirty) { | ||||
// Interpolate handle position | // Interpolate handle position | ||||
handle->box.pos = Vec(rescale(value, minValue, maxValue, minHandlePos.x, maxHandlePos.x), rescale(value, minValue, maxValue, minHandlePos.y, maxHandlePos.y)); | |||||
handle->box.pos = math::Vec(math::rescale(value, minValue, maxValue, minHandlePos.x, maxHandlePos.x), math::rescale(value, minValue, maxValue, minHandlePos.y, maxHandlePos.y)); | |||||
} | } | ||||
FramebufferWidget::step(); | FramebufferWidget::step(); | ||||
} | } | ||||
@@ -20,8 +20,8 @@ void SVGSwitch::addFrame(std::shared_ptr<SVG> svg) { | |||||
void SVGSwitch::onChange(EventChange &e) { | void SVGSwitch::onChange(EventChange &e) { | ||||
assert(frames.size() > 0); | assert(frames.size() > 0); | ||||
float valueScaled = rescale(value, minValue, maxValue, 0, frames.size() - 1); | |||||
int index = clamp((int) roundf(valueScaled), 0, (int) frames.size() - 1); | |||||
float valueScaled = math::rescale(value, minValue, maxValue, 0, frames.size() - 1); | |||||
int index = math::clamp((int) roundf(valueScaled), 0, (int) frames.size() - 1); | |||||
sw->setSVG(frames[index]); | sw->setSVG(frames[index]); | ||||
dirty = true; | dirty = true; | ||||
ParamWidget::onChange(e); | ParamWidget::onChange(e); | ||||
@@ -13,7 +13,7 @@ struct TooltipIconButton : IconButton { | |||||
void onMouseEnter(EventMouseEnter &e) override { | void onMouseEnter(EventMouseEnter &e) override { | ||||
if (!tooltip) { | if (!tooltip) { | ||||
tooltip = new Tooltip(); | tooltip = new Tooltip(); | ||||
tooltip->box.pos = getAbsoluteOffset(Vec(0, BND_WIDGET_HEIGHT)); | |||||
tooltip->box.pos = getAbsoluteOffset(math::Vec(0, BND_WIDGET_HEIGHT)); | |||||
tooltip->text = tooltipText; | tooltip->text = tooltipText; | ||||
gScene->addChild(tooltip); | gScene->addChild(tooltip); | ||||
} | } | ||||
@@ -120,7 +120,7 @@ struct SampleRateButton : TooltipIconButton { | |||||
} | } | ||||
void onAction(EventAction &e) override { | void onAction(EventAction &e) override { | ||||
Menu *menu = gScene->createMenu(); | Menu *menu = gScene->createMenu(); | ||||
menu->box.pos = getAbsoluteOffset(Vec(0, box.size.y)); | |||||
menu->box.pos = getAbsoluteOffset(math::Vec(0, box.size.y)); | |||||
menu->box.size.x = box.size.x; | menu->box.size.x = box.size.x; | ||||
menu->addChild(MenuLabel::create("Engine sample rate")); | menu->addChild(MenuLabel::create("Engine sample rate")); | ||||
@@ -162,7 +162,7 @@ Toolbar::Toolbar() { | |||||
box.size.y = BND_WIDGET_HEIGHT + 2*5; | box.size.y = BND_WIDGET_HEIGHT + 2*5; | ||||
SequentialLayout *layout = new SequentialLayout(); | SequentialLayout *layout = new SequentialLayout(); | ||||
layout->box.pos = Vec(5, 5); | |||||
layout->box.pos = math::Vec(5, 5); | |||||
layout->spacing = 5; | layout->spacing = 5; | ||||
addChild(layout); | addChild(layout); | ||||
@@ -6,7 +6,7 @@ | |||||
namespace rack { | namespace rack { | ||||
static void drawPlug(NVGcontext *vg, Vec pos, NVGcolor color) { | |||||
static void drawPlug(NVGcontext *vg, math::Vec pos, NVGcolor color) { | |||||
NVGcolor colorOutline = nvgLerpRGBA(color, nvgRGBf(0.0, 0.0, 0.0), 0.5); | NVGcolor colorOutline = nvgLerpRGBA(color, nvgRGBf(0.0, 0.0, 0.0), 0.5); | ||||
// Plug solid | // Plug solid | ||||
@@ -27,7 +27,7 @@ static void drawPlug(NVGcontext *vg, Vec pos, NVGcolor color) { | |||||
nvgFill(vg); | nvgFill(vg); | ||||
} | } | ||||
static void drawWire(NVGcontext *vg, Vec pos1, Vec pos2, NVGcolor color, float tension, float opacity) { | |||||
static void drawWire(NVGcontext *vg, math::Vec pos1, math::Vec pos2, NVGcolor color, float tension, float opacity) { | |||||
NVGcolor colorShadow = nvgRGBAf(0, 0, 0, 0.10); | NVGcolor colorShadow = nvgRGBAf(0, 0, 0, 0.10); | ||||
NVGcolor colorOutline = nvgLerpRGBA(color, nvgRGBf(0.0, 0.0, 0.0), 0.5); | NVGcolor colorOutline = nvgLerpRGBA(color, nvgRGBf(0.0, 0.0, 0.0), 0.5); | ||||
@@ -37,14 +37,14 @@ static void drawWire(NVGcontext *vg, Vec pos1, Vec pos2, NVGcolor color, float t | |||||
nvgGlobalAlpha(vg, powf(opacity, 1.5)); | nvgGlobalAlpha(vg, powf(opacity, 1.5)); | ||||
float dist = pos1.minus(pos2).norm(); | float dist = pos1.minus(pos2).norm(); | ||||
Vec slump; | |||||
math::Vec slump; | |||||
slump.y = (1.0 - tension) * (150.0 + 1.0*dist); | slump.y = (1.0 - tension) * (150.0 + 1.0*dist); | ||||
Vec pos3 = pos1.plus(pos2).div(2).plus(slump); | |||||
math::Vec pos3 = pos1.plus(pos2).div(2).plus(slump); | |||||
nvgLineJoin(vg, NVG_ROUND); | nvgLineJoin(vg, NVG_ROUND); | ||||
// Shadow | // Shadow | ||||
Vec pos4 = pos3.plus(slump.mult(0.08)); | |||||
math::Vec pos4 = pos3.plus(slump.mult(0.08)); | |||||
nvgBeginPath(vg); | nvgBeginPath(vg); | ||||
nvgMoveTo(vg, pos1.x, pos1.y); | nvgMoveTo(vg, pos1.x, pos1.y); | ||||
nvgQuadTo(vg, pos4.x, pos4.y, pos2.x, pos2.y); | nvgQuadTo(vg, pos4.x, pos4.y, pos2.x, pos2.y); | ||||
@@ -118,7 +118,7 @@ void WireWidget::updateWire() { | |||||
} | } | ||||
} | } | ||||
Vec WireWidget::getOutputPos() { | |||||
math::Vec WireWidget::getOutputPos() { | |||||
if (outputPort) { | if (outputPort) { | ||||
return outputPort->getRelativeOffset(outputPort->box.zeroPos().getCenter(), gRackWidget); | return outputPort->getRelativeOffset(outputPort->box.zeroPos().getCenter(), gRackWidget); | ||||
} | } | ||||
@@ -130,7 +130,7 @@ Vec WireWidget::getOutputPos() { | |||||
} | } | ||||
} | } | ||||
Vec WireWidget::getInputPos() { | |||||
math::Vec WireWidget::getInputPos() { | |||||
if (inputPort) { | if (inputPort) { | ||||
return inputPort->getRelativeOffset(inputPort->box.zeroPos().getCenter(), gRackWidget); | return inputPort->getRelativeOffset(inputPort->box.zeroPos().getCenter(), gRackWidget); | ||||
} | } | ||||
@@ -144,7 +144,7 @@ Vec WireWidget::getInputPos() { | |||||
json_t *WireWidget::toJson() { | json_t *WireWidget::toJson() { | ||||
json_t *rootJ = json_object(); | json_t *rootJ = json_object(); | ||||
std::string s = colorToHexString(color); | |||||
std::string s = color::toHexString(color); | |||||
json_object_set_new(rootJ, "color", json_string(s.c_str())); | json_object_set_new(rootJ, "color", json_string(s.c_str())); | ||||
return rootJ; | return rootJ; | ||||
} | } | ||||
@@ -156,7 +156,7 @@ void WireWidget::fromJson(json_t *rootJ) { | |||||
if (json_is_object(colorJ)) | if (json_is_object(colorJ)) | ||||
color = jsonToColor(colorJ); | color = jsonToColor(colorJ); | ||||
else | else | ||||
color = colorFromHexString(json_string_value(colorJ)); | |||||
color = color::fromHexString(json_string_value(colorJ)); | |||||
} | } | ||||
} | } | ||||
@@ -176,15 +176,15 @@ void WireWidget::draw(NVGcontext *vg) { | |||||
opacity = 1.0; | opacity = 1.0; | ||||
} | } | ||||
Vec outputPos = getOutputPos(); | |||||
Vec inputPos = getInputPos(); | |||||
math::Vec outputPos = getOutputPos(); | |||||
math::Vec inputPos = getInputPos(); | |||||
drawWire(vg, outputPos, inputPos, color, tension, opacity); | drawWire(vg, outputPos, inputPos, color, tension, opacity); | ||||
} | } | ||||
void WireWidget::drawPlugs(NVGcontext *vg) { | 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. | // TODO Figure out a way to draw plugs first and wires last, and cut the plug portion of the wire off. | ||||
Vec outputPos = getOutputPos(); | |||||
Vec inputPos = getInputPos(); | |||||
math::Vec outputPos = getOutputPos(); | |||||
math::Vec inputPos = getInputPos(); | |||||
drawPlug(vg, outputPos, color); | drawPlug(vg, outputPos, color); | ||||
drawPlug(vg, inputPos, color); | drawPlug(vg, inputPos, color); | ||||
@@ -225,7 +225,7 @@ void AudioIO::openStream() { | |||||
if (rtAudio->isStreamOpen()) | if (rtAudio->isStreamOpen()) | ||||
return; | return; | ||||
setChannels(clamp((int) deviceInfo.outputChannels - offset, 0, maxChannels), clamp((int) deviceInfo.inputChannels - offset, 0, maxChannels)); | |||||
setChannels(math::clamp((int) deviceInfo.outputChannels - offset, 0, maxChannels), math::clamp((int) deviceInfo.inputChannels - offset, 0, maxChannels)); | |||||
if (numOutputs == 0 && numInputs == 0) { | if (numOutputs == 0 && numInputs == 0) { | ||||
warn("RtAudio device %d has 0 inputs and 0 outputs", device); | warn("RtAudio device %d has 0 inputs and 0 outputs", device); | ||||
@@ -21,8 +21,8 @@ void GamepadInputDevice::step() { | |||||
// Convert axes to MIDI CC | // Convert axes to MIDI CC | ||||
ccs.resize(numAxes); | ccs.resize(numAxes); | ||||
for (int i = 0; i < numAxes; i++) { | for (int i = 0; i < numAxes; i++) { | ||||
// Allow CC value to go negative, but clamp at -127 instead of -128 for symmetry | |||||
int8_t cc = clamp((int) roundf(axes[i] * 127), -127, 127); | |||||
// Allow CC value to go negative, but math::clamp at -127 instead of -128 for symmetry | |||||
int8_t cc = math::clamp((int) roundf(axes[i] * 127), -127, 127); | |||||
if (cc != ccs[i]) { | if (cc != ccs[i]) { | ||||
ccs[i] = cc; | ccs[i] = cc; | ||||
@@ -60,7 +60,7 @@ void KeyboardInputDevice::onKeyPress(int key) { | |||||
default: break; | default: break; | ||||
} | } | ||||
octave = clamp(octave, 0, 9); | |||||
octave = math::clamp(octave, 0, 9); | |||||
if (note < 0) | if (note < 0) | ||||
return; | return; | ||||
@@ -22,12 +22,12 @@ static json_t *settingsToJson() { | |||||
if (!windowIsMaximized()) { | if (!windowIsMaximized()) { | ||||
// windowSize | // windowSize | ||||
Vec windowSize = windowGetWindowSize(); | |||||
math::Vec windowSize = windowGetWindowSize(); | |||||
json_t *windowSizeJ = json_pack("[f, f]", windowSize.x, windowSize.y); | json_t *windowSizeJ = json_pack("[f, f]", windowSize.x, windowSize.y); | ||||
json_object_set_new(rootJ, "windowSize", windowSizeJ); | json_object_set_new(rootJ, "windowSize", windowSizeJ); | ||||
// windowPos | // windowPos | ||||
Vec windowPos = windowGetWindowPos(); | |||||
math::Vec windowPos = windowGetWindowPos(); | |||||
json_t *windowPosJ = json_pack("[f, f]", windowPos.x, windowPos.y); | json_t *windowPosJ = json_pack("[f, f]", windowPos.x, windowPos.y); | ||||
json_object_set_new(rootJ, "windowPos", windowPosJ); | json_object_set_new(rootJ, "windowPos", windowPosJ); | ||||
} | } | ||||
@@ -87,7 +87,7 @@ static void settingsFromJson(json_t *rootJ) { | |||||
if (windowSizeJ) { | if (windowSizeJ) { | ||||
double width, height; | double width, height; | ||||
json_unpack(windowSizeJ, "[F, F]", &width, &height); | json_unpack(windowSizeJ, "[F, F]", &width, &height); | ||||
windowSetWindowSize(Vec(width, height)); | |||||
windowSetWindowSize(math::Vec(width, height)); | |||||
} | } | ||||
// windowPos | // windowPos | ||||
@@ -95,7 +95,7 @@ static void settingsFromJson(json_t *rootJ) { | |||||
if (windowPosJ) { | if (windowPosJ) { | ||||
double x, y; | double x, y; | ||||
json_unpack(windowPosJ, "[F, F]", &x, &y); | json_unpack(windowPosJ, "[F, F]", &x, &y); | ||||
windowSetWindowPos(Vec(x, y)); | |||||
windowSetWindowPos(math::Vec(x, y)); | |||||
} | } | ||||
// opacity | // opacity | ||||
@@ -111,7 +111,7 @@ static void settingsFromJson(json_t *rootJ) { | |||||
// zoom | // zoom | ||||
json_t *zoomJ = json_object_get(rootJ, "zoom"); | json_t *zoomJ = json_object_get(rootJ, "zoom"); | ||||
if (zoomJ) { | if (zoomJ) { | ||||
gRackScene->zoomWidget->setZoom(clamp((float) json_number_value(zoomJ), 0.25f, 4.0f)); | |||||
gRackScene->zoomWidget->setZoom(math::clamp((float) json_number_value(zoomJ), 0.25f, 4.0f)); | |||||
gToolbar->zoomSlider->setValue(json_number_value(zoomJ) * 100.0); | gToolbar->zoomSlider->setValue(json_number_value(zoomJ) * 100.0); | ||||
} | } | ||||
@@ -12,7 +12,7 @@ IconButton::IconButton() { | |||||
addChild(fw); | addChild(fw); | ||||
sw = new SVGWidget(); | sw = new SVGWidget(); | ||||
sw->box.pos = Vec(2, 2); | |||||
sw->box.pos = math::Vec(2, 2); | |||||
fw->addChild(sw); | fw->addChild(sw); | ||||
} | } | ||||
@@ -13,7 +13,7 @@ void List::step() { | |||||
if (!child->visible) | if (!child->visible) | ||||
continue; | continue; | ||||
// Increment height, set position of child | // Increment height, set position of child | ||||
child->box.pos = Vec(0.0, box.size.y); | |||||
child->box.pos = math::Vec(0.0, box.size.y); | |||||
box.size.y += child->box.size.y; | box.size.y += child->box.size.y; | ||||
// Resize width of child | // Resize width of child | ||||
child->box.size.x = box.size.x; | child->box.size.x = box.size.x; | ||||
@@ -25,12 +25,12 @@ void Menu::step() { | |||||
Widget::step(); | Widget::step(); | ||||
// Set positions of children | // Set positions of children | ||||
box.size = Vec(0, 0); | |||||
box.size = math::Vec(0, 0); | |||||
for (Widget *child : children) { | for (Widget *child : children) { | ||||
if (!child->visible) | if (!child->visible) | ||||
continue; | continue; | ||||
// Increment height, set position of child | // Increment height, set position of child | ||||
child->box.pos = Vec(0, box.size.y); | |||||
child->box.pos = math::Vec(0, box.size.y); | |||||
box.size.y += child->box.size.y; | box.size.y += child->box.size.y; | ||||
// Increase width based on maximum width of child | // Increase width based on maximum width of child | ||||
if (child->box.size.x > box.size.x) { | if (child->box.size.x > box.size.x) { | ||||
@@ -16,7 +16,7 @@ void MenuSeparator::draw(NVGcontext *vg) { | |||||
nvgMoveTo(vg, margin, box.size.y / 2.0); | nvgMoveTo(vg, margin, box.size.y / 2.0); | ||||
nvgLineTo(vg, box.size.x - margin, box.size.y / 2.0); | nvgLineTo(vg, box.size.x - margin, box.size.y / 2.0); | ||||
nvgStrokeWidth(vg, 1.0); | nvgStrokeWidth(vg, 1.0); | ||||
nvgStrokeColor(vg, colorAlpha(bndGetTheme()->menuTheme.textColor, 0.25)); | |||||
nvgStrokeColor(vg, color::alpha(bndGetTheme()->menuTheme.textColor, 0.25)); | |||||
nvgStroke(vg); | nvgStroke(vg); | ||||
} | } | ||||
@@ -4,7 +4,7 @@ | |||||
namespace rack { | namespace rack { | ||||
void ProgressBar::draw(NVGcontext *vg) { | void ProgressBar::draw(NVGcontext *vg) { | ||||
float progress = rescale(value, minValue, maxValue, 0.0, 1.0); | |||||
float progress = math::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); | bndSlider(vg, 0.0, 0.0, box.size.x, box.size.y, BND_CORNER_ALL, BND_DEFAULT, progress, getText().c_str(), NULL); | ||||
} | } | ||||
@@ -13,7 +13,7 @@ void Scene::setOverlay(Widget *w) { | |||||
if (w) { | if (w) { | ||||
addChild(w); | addChild(w); | ||||
overlay = w; | overlay = w; | ||||
overlay->box.pos = Vec(); | |||||
overlay->box.pos = math::Vec(); | |||||
} | } | ||||
} | } | ||||
@@ -31,7 +31,7 @@ Menu *Scene::createMenu() { | |||||
void Scene::step() { | void Scene::step() { | ||||
if (overlay) { | if (overlay) { | ||||
overlay->box.pos = Vec(0, 0); | |||||
overlay->box.pos = math::Vec(0, 0); | |||||
overlay->box.size = box.size; | overlay->box.size = box.size; | ||||
} | } | ||||
@@ -17,7 +17,7 @@ struct ScrollBar : OpaqueWidget { | |||||
float size = 0.0; | float size = 0.0; | ||||
ScrollBar() { | ScrollBar() { | ||||
box.size = Vec(BND_SCROLLBAR_WIDTH, BND_SCROLLBAR_HEIGHT); | |||||
box.size = math::Vec(BND_SCROLLBAR_WIDTH, BND_SCROLLBAR_HEIGHT); | |||||
} | } | ||||
void draw(NVGcontext *vg) override { | void draw(NVGcontext *vg) override { | ||||
@@ -60,8 +60,8 @@ ScrollWidget::ScrollWidget() { | |||||
addChild(verticalScrollBar); | addChild(verticalScrollBar); | ||||
} | } | ||||
void ScrollWidget::scrollTo(Rect r) { | |||||
Rect bound = Rect::fromMinMax(r.getBottomRight().minus(box.size), r.pos); | |||||
void ScrollWidget::scrollTo(math::Rect r) { | |||||
math::Rect bound = math::Rect::fromMinMax(r.getBottomRight().minus(box.size), r.pos); | |||||
offset = offset.clampBetween(bound); | offset = offset.clampBetween(bound); | ||||
} | } | ||||
@@ -75,8 +75,8 @@ void ScrollWidget::step() { | |||||
Widget::step(); | Widget::step(); | ||||
// Clamp scroll offset | // Clamp scroll offset | ||||
Vec containerCorner = container->getChildrenBoundingBox().getBottomRight(); | |||||
Rect containerBox = Rect(Vec(0, 0), containerCorner.minus(box.size)); | |||||
math::Vec containerCorner = container->getChildrenBoundingBox().getBottomRight(); | |||||
math::Rect containerBox = math::Rect(math::Vec(0, 0), containerCorner.minus(box.size)); | |||||
offset = offset.clamp(containerBox); | offset = offset.clamp(containerBox); | ||||
// Lock offset to top/left if no scrollbar will display | // Lock offset to top/left if no scrollbar will display | ||||
if (containerBox.size.x < 0.0) | if (containerBox.size.x < 0.0) | ||||
@@ -88,9 +88,9 @@ void ScrollWidget::step() { | |||||
container->box.pos = offset.neg().round(); | container->box.pos = offset.neg().round(); | ||||
// Update scrollbar offsets and sizes | // Update scrollbar offsets and sizes | ||||
Vec viewportSize = container->getChildrenBoundingBox().getBottomRight(); | |||||
Vec scrollbarOffset = offset.div(viewportSize.minus(box.size)); | |||||
Vec scrollbarSize = box.size.div(viewportSize); | |||||
math::Vec viewportSize = container->getChildrenBoundingBox().getBottomRight(); | |||||
math::Vec scrollbarOffset = offset.div(viewportSize.minus(box.size)); | |||||
math::Vec scrollbarSize = box.size.div(viewportSize); | |||||
horizontalScrollBar->visible = (0.0 < scrollbarSize.x && scrollbarSize.x < 1.0); | horizontalScrollBar->visible = (0.0 < scrollbarSize.x && scrollbarSize.x < 1.0); | ||||
verticalScrollBar->visible = (0.0 < scrollbarSize.y && scrollbarSize.y < 1.0); | verticalScrollBar->visible = (0.0 < scrollbarSize.y && scrollbarSize.y < 1.0); | ||||
@@ -100,7 +100,7 @@ void ScrollWidget::step() { | |||||
verticalScrollBar->size = scrollbarSize.y; | verticalScrollBar->size = scrollbarSize.y; | ||||
// Resize scroll bars | // Resize scroll bars | ||||
Vec inner = Vec(box.size.x - verticalScrollBar->box.size.x, box.size.y - horizontalScrollBar->box.size.y); | |||||
math::Vec inner = math::Vec(box.size.x - verticalScrollBar->box.size.x, box.size.y - horizontalScrollBar->box.size.y); | |||||
horizontalScrollBar->box.pos.y = inner.y; | horizontalScrollBar->box.pos.y = inner.y; | ||||
verticalScrollBar->box.pos.x = inner.x; | verticalScrollBar->box.pos.x = inner.x; | ||||
horizontalScrollBar->box.size.x = verticalScrollBar->visible ? inner.x : box.size.x; | horizontalScrollBar->box.size.x = verticalScrollBar->visible ? inner.x : box.size.x; | ||||
@@ -7,7 +7,7 @@ namespace rack { | |||||
#define SLIDER_SENSITIVITY 0.001 | #define SLIDER_SENSITIVITY 0.001 | ||||
void Slider::draw(NVGcontext *vg) { | void Slider::draw(NVGcontext *vg) { | ||||
float progress = rescale(value, minValue, maxValue, 0.0, 1.0); | |||||
float progress = math::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); | bndSlider(vg, 0.0, 0.0, box.size.x, box.size.y, BND_CORNER_NONE, state, progress, getText().c_str(), NULL); | ||||
} | } | ||||
@@ -166,8 +166,8 @@ void TextField::onKey(EventKey &e) { | |||||
} break; | } break; | ||||
} | } | ||||
cursor = clamp(cursor, 0, (int) text.size()); | |||||
selection = clamp(selection, 0, (int) text.size()); | |||||
cursor = math::clamp(cursor, 0, (int) text.size()); | |||||
selection = math::clamp(selection, 0, (int) text.size()); | |||||
e.consumed = true; | e.consumed = true; | ||||
} | } | ||||
@@ -189,7 +189,7 @@ void TextField::setText(std::string text) { | |||||
onTextChange(); | onTextChange(); | ||||
} | } | ||||
int TextField::getTextPosition(Vec mousePos) { | |||||
int TextField::getTextPosition(math::Vec mousePos) { | |||||
return bndTextFieldTextPosition(gVg, 0.0, 0.0, box.size.x, box.size.y, -1, text.c_str(), mousePos.x, mousePos.y); | return bndTextFieldTextPosition(gVg, 0.0, 0.0, box.size.x, box.size.y, -1, text.c_str(), mousePos.x, mousePos.y); | ||||
} | } | ||||
@@ -1,28 +0,0 @@ | |||||
#include "util/color.hpp" | |||||
namespace rack { | |||||
NVGcolor colorFromHexString(std::string s) { | |||||
uint8_t r = 0; | |||||
uint8_t g = 0; | |||||
uint8_t b = 0; | |||||
uint8_t a = 255; | |||||
sscanf(s.c_str(), "#%2hhx%2hhx%2hhx%2hhx", &r, &g, &b, &a); | |||||
return nvgRGBA(r, g, b, a); | |||||
} | |||||
std::string colorToHexString(NVGcolor c) { | |||||
uint8_t r = roundf(c.r * 255); | |||||
uint8_t g = roundf(c.g * 255); | |||||
uint8_t b = roundf(c.b * 255); | |||||
uint8_t a = roundf(c.a * 255); | |||||
if (a == 255) | |||||
return stringf("#%02x%02x%02x", r, g, b); | |||||
else | |||||
return stringf("#%02x%02x%02x%02x", r, g, b, a); | |||||
} | |||||
} // namespace rack |
@@ -9,7 +9,7 @@ namespace rack { | |||||
struct FramebufferWidget::Internal { | struct FramebufferWidget::Internal { | ||||
NVGLUframebuffer *fb = NULL; | NVGLUframebuffer *fb = NULL; | ||||
Rect box; | |||||
math::Rect box; | |||||
~Internal() { | ~Internal() { | ||||
setFramebuffer(NULL); | setFramebuffer(NULL); | ||||
@@ -42,10 +42,10 @@ void FramebufferWidget::draw(NVGcontext *vg) { | |||||
// Skew and rotate is not supported | // Skew and rotate is not supported | ||||
assert(std::abs(xform[1]) < 1e-6); | assert(std::abs(xform[1]) < 1e-6); | ||||
assert(std::abs(xform[2]) < 1e-6); | assert(std::abs(xform[2]) < 1e-6); | ||||
Vec s = Vec(xform[0], xform[3]); | |||||
Vec b = Vec(xform[4], xform[5]); | |||||
Vec bi = b.floor(); | |||||
Vec bf = b.minus(bi); | |||||
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); | |||||
// Render to framebuffer | // Render to framebuffer | ||||
if (dirty) { | if (dirty) { | ||||
@@ -53,9 +53,9 @@ void FramebufferWidget::draw(NVGcontext *vg) { | |||||
internal->box = getChildrenBoundingBox(); | internal->box = getChildrenBoundingBox(); | ||||
internal->box.pos = internal->box.pos.mult(s).floor(); | internal->box.pos = internal->box.pos.mult(s).floor(); | ||||
internal->box.size = internal->box.size.mult(s).ceil().plus(Vec(1, 1)); | |||||
internal->box.size = internal->box.size.mult(s).ceil().plus(math::Vec(1, 1)); | |||||
Vec fbSize = internal->box.size.mult(gPixelRatio * oversample); | |||||
math::Vec fbSize = internal->box.size.mult(gPixelRatio * oversample); | |||||
if (!fbSize.isFinite()) | if (!fbSize.isFinite()) | ||||
return; | return; | ||||
@@ -9,7 +9,7 @@ QuantityWidget::QuantityWidget() { | |||||
} | } | ||||
void QuantityWidget::setValue(float value) { | void QuantityWidget::setValue(float value) { | ||||
this->value = clamp(value, fminf(minValue, maxValue), fmaxf(minValue, maxValue)); | |||||
this->value = math::clamp(value, fminf(minValue, maxValue), fmaxf(minValue, maxValue)); | |||||
EventChange e; | EventChange e; | ||||
onChange(e); | onChange(e); | ||||
} | } | ||||
@@ -25,7 +25,7 @@ static NVGpaint getPaint(NVGcontext *vg, NSVGpaint *p) { | |||||
float inverse[6]; | float inverse[6]; | ||||
nvgTransformInverse(inverse, g->xform); | 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]);) | DEBUG_ONLY(printf(" inverse: %f %f %f %f %f %f\n", inverse[0], inverse[1], inverse[2], inverse[3], inverse[4], inverse[5]);) | ||||
Vec s, e; | |||||
math::Vec s, e; | |||||
DEBUG_ONLY(printf(" sx: %f sy: %f ex: %f ey: %f\n", s.x, s.y, e.x, e.y);) | 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)? | // 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); | 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 */ | /** Returns the parameterized value of the line p2--p3 where it intersects with p0--p1 */ | ||||
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); | |||||
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); | |||||
float m = d.x * e.y - d.y * e.x; | float m = d.x * e.y - d.y * e.x; | ||||
// Check if lines are parallel, or if either pair of points are equal | // Check if lines are parallel, or if either pair of points are equal | ||||
if (std::abs(m) < 1e-6) | if (std::abs(m) < 1e-6) | ||||
@@ -93,8 +93,8 @@ static void drawSVG(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). | // 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). | // 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; | int crossings = 0; | ||||
Vec p0 = Vec(path->pts[0], path->pts[1]); | |||||
Vec p1 = Vec(path->bounds[0] - 1.0, path->bounds[1] - 1.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); | |||||
// Iterate all other paths | // Iterate all other paths | ||||
for (NSVGpath *path2 = shape->paths; path2; path2 = path2->next) { | for (NSVGpath *path2 = shape->paths; path2; path2 = path2->next) { | ||||
if (path2 == path) | if (path2 == path) | ||||
@@ -106,9 +106,9 @@ static void drawSVG(NVGcontext *vg, NSVGimage *svg) { | |||||
for (int i = 1; i < path2->npts + 3; i += 3) { | for (int i = 1; i < path2->npts + 3; i += 3) { | ||||
float *p = &path2->pts[2*i]; | float *p = &path2->pts[2*i]; | ||||
// The previous point | // The previous point | ||||
Vec p2 = Vec(p[-2], p[-1]); | |||||
math::Vec p2 = math::Vec(p[-2], p[-1]); | |||||
// The current point | // The current point | ||||
Vec p3 = (i < path2->npts) ? Vec(p[4], p[5]) : Vec(path2->pts[0], path2->pts[1]); | |||||
math::Vec p3 = (i < path2->npts) ? math::Vec(p[4], p[5]) : math::Vec(path2->pts[0], path2->pts[1]); | |||||
float crossing = getLineCrossing(p0, p1, p2, p3); | float crossing = getLineCrossing(p0, p1, p2, p3); | ||||
float crossing2 = getLineCrossing(p2, p3, p0, p1); | float crossing2 = getLineCrossing(p2, p3, p0, p1); | ||||
if (0.0 <= crossing && crossing < 1.0 && 0.0 <= crossing2) { | if (0.0 <= crossing && crossing < 1.0 && 0.0 <= crossing2) { | ||||
@@ -125,10 +125,10 @@ static void drawSVG(NVGcontext *vg, NSVGimage *svg) { | |||||
/* | /* | ||||
// Shoelace algorithm for computing the area, and thus the winding direction | // Shoelace algorithm for computing the area, and thus the winding direction | ||||
float area = 0.0; | float area = 0.0; | ||||
Vec p0 = Vec(path->pts[0], path->pts[1]); | |||||
math::Vec p0 = math::Vec(path->pts[0], path->pts[1]); | |||||
for (int i = 1; i < path->npts; i += 3) { | for (int i = 1; i < path->npts; i += 3) { | ||||
float *p = &path->pts[2*i]; | float *p = &path->pts[2*i]; | ||||
Vec p1 = (i < path->npts) ? Vec(p[4], p[5]) : Vec(path->pts[0], path->pts[1]); | |||||
math::Vec p1 = (i < path->npts) ? math::Vec(p[4], p[5]) : math::Vec(path->pts[0], path->pts[1]); | |||||
area += 0.5 * (p1.x - p0.x) * (p1.y + p0.y); | 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); | printf("%f %f, %f %f\n", p0.x, p0.y, p1.x, p1.y); | ||||
p0 = p1; | p0 = p1; | ||||
@@ -197,10 +197,10 @@ static void drawSVG(NVGcontext *vg, NSVGimage *svg) { | |||||
void SVGWidget::wrap() { | void SVGWidget::wrap() { | ||||
if (svg && svg->handle) { | if (svg && svg->handle) { | ||||
box.size = Vec(svg->handle->width, svg->handle->height); | |||||
box.size = math::Vec(svg->handle->width, svg->handle->height); | |||||
} | } | ||||
else { | else { | ||||
box.size = Vec(); | |||||
box.size = math::Vec(); | |||||
} | } | ||||
} | } | ||||
@@ -1,23 +0,0 @@ | |||||
#include "widgets.hpp" | |||||
namespace rack { | |||||
void SpriteWidget::draw(NVGcontext *vg) { | |||||
int width, height; | |||||
nvgImageSize(vg, spriteImage->handle, &width, &height); | |||||
int stride = width / spriteSize.x; | |||||
if (stride == 0) { | |||||
warn("Size of SpriteWidget is %d, %d but spriteSize is %f, %f", width, height, spriteSize.x, spriteSize.y); | |||||
return; | |||||
} | |||||
Vec offset = Vec((index % stride) * spriteSize.x, (index / stride) * spriteSize.y); | |||||
NVGpaint paint = nvgImagePattern(vg, spriteOffset.x - offset.x, spriteOffset.y - offset.y, width, height, 0.0, spriteImage->handle, 1.0); | |||||
nvgFillPaint(vg, paint); | |||||
nvgBeginPath(vg); | |||||
nvgRect(vg, spriteOffset.x, spriteOffset.y, spriteSize.x, spriteSize.y); | |||||
nvgFill(vg); | |||||
} | |||||
} // namespace rack |
@@ -8,20 +8,20 @@ TransformWidget::TransformWidget() { | |||||
identity(); | identity(); | ||||
} | } | ||||
Rect TransformWidget::getChildrenBoundingBox() { | |||||
Rect bound = Widget::getChildrenBoundingBox(); | |||||
Vec topLeft = bound.pos; | |||||
Vec bottomRight = bound.getBottomRight(); | |||||
math::Rect TransformWidget::getChildrenBoundingBox() { | |||||
math::Rect bound = Widget::getChildrenBoundingBox(); | |||||
math::Vec topLeft = bound.pos; | |||||
math::Vec bottomRight = bound.getBottomRight(); | |||||
nvgTransformPoint(&topLeft.x, &topLeft.y, transform, topLeft.x, topLeft.y); | nvgTransformPoint(&topLeft.x, &topLeft.y, transform, topLeft.x, topLeft.y); | ||||
nvgTransformPoint(&bottomRight.x, &bottomRight.y, transform, bottomRight.x, bottomRight.y); | nvgTransformPoint(&bottomRight.x, &bottomRight.y, transform, bottomRight.x, bottomRight.y); | ||||
return Rect(topLeft, bottomRight.minus(topLeft)); | |||||
return math::Rect(topLeft, bottomRight.minus(topLeft)); | |||||
} | } | ||||
void TransformWidget::identity() { | void TransformWidget::identity() { | ||||
nvgTransformIdentity(transform); | nvgTransformIdentity(transform); | ||||
} | } | ||||
void TransformWidget::translate(Vec delta) { | |||||
void TransformWidget::translate(math::Vec delta) { | |||||
float t[6]; | float t[6]; | ||||
nvgTransformTranslate(t, delta.x, delta.y); | nvgTransformTranslate(t, delta.x, delta.y); | ||||
nvgTransformPremultiply(transform, t); | nvgTransformPremultiply(transform, t); | ||||
@@ -33,7 +33,7 @@ void TransformWidget::rotate(float angle) { | |||||
nvgTransformPremultiply(transform, t); | nvgTransformPremultiply(transform, t); | ||||
} | } | ||||
void TransformWidget::scale(Vec s) { | |||||
void TransformWidget::scale(math::Vec s) { | |||||
float t[6]; | float t[6]; | ||||
nvgTransformScale(t, s.x, s.y); | nvgTransformScale(t, s.x, s.y); | ||||
nvgTransformPremultiply(transform, t); | nvgTransformPremultiply(transform, t); | ||||
@@ -17,8 +17,8 @@ Widget::~Widget() { | |||||
clearChildren(); | clearChildren(); | ||||
} | } | ||||
Rect Widget::getChildrenBoundingBox() { | |||||
Rect bound; | |||||
math::Rect Widget::getChildrenBoundingBox() { | |||||
math::Rect bound; | |||||
for (Widget *child : children) { | for (Widget *child : children) { | ||||
if (child == children.front()) { | if (child == children.front()) { | ||||
bound = child->box; | bound = child->box; | ||||
@@ -30,7 +30,7 @@ Rect Widget::getChildrenBoundingBox() { | |||||
return bound; | return bound; | ||||
} | } | ||||
Vec Widget::getRelativeOffset(Vec v, Widget *relative) { | |||||
math::Vec Widget::getRelativeOffset(math::Vec v, Widget *relative) { | |||||
if (this == relative) { | if (this == relative) { | ||||
return v; | return v; | ||||
} | } | ||||
@@ -41,8 +41,8 @@ Vec Widget::getRelativeOffset(Vec v, Widget *relative) { | |||||
return v; | return v; | ||||
} | } | ||||
Rect Widget::getViewport(Rect r) { | |||||
Rect bound; | |||||
math::Rect Widget::getViewport(math::Rect r) { | |||||
math::Rect bound; | |||||
if (parent) { | if (parent) { | ||||
bound = parent->getViewport(box); | bound = parent->getViewport(box); | ||||
} | } | ||||
@@ -118,7 +118,7 @@ void Widget::draw(NVGcontext *vg) { | |||||
} | } | ||||
#define RECURSE_EVENT_POSITION(_method) { \ | #define RECURSE_EVENT_POSITION(_method) { \ | ||||
Vec pos = e.pos; \ | |||||
math::Vec pos = e.pos; \ | |||||
for (auto it = children.rbegin(); it != children.rend(); it++) { \ | for (auto it = children.rbegin(); it != children.rend(); it++) { \ | ||||
Widget *child = *it; \ | Widget *child = *it; \ | ||||
if (!child->visible) \ | if (!child->visible) \ | ||||
@@ -4,11 +4,11 @@ | |||||
namespace rack { | namespace rack { | ||||
Vec ZoomWidget::getRelativeOffset(Vec v, Widget *relative) { | |||||
math::Vec ZoomWidget::getRelativeOffset(math::Vec v, Widget *relative) { | |||||
return Widget::getRelativeOffset(v.mult(zoom), relative); | return Widget::getRelativeOffset(v.mult(zoom), relative); | ||||
} | } | ||||
Rect ZoomWidget::getViewport(Rect r) { | |||||
math::Rect ZoomWidget::getViewport(math::Rect r) { | |||||
r.pos = r.pos.mult(zoom); | r.pos = r.pos.mult(zoom); | ||||
r.size = r.size.mult(zoom); | r.size = r.size.mult(zoom); | ||||
r = Widget::getViewport(r); | r = Widget::getViewport(r); | ||||
@@ -31,42 +31,42 @@ void ZoomWidget::draw(NVGcontext *vg) { | |||||
} | } | ||||
void ZoomWidget::onMouseDown(EventMouseDown &e) { | void ZoomWidget::onMouseDown(EventMouseDown &e) { | ||||
Vec pos = e.pos; | |||||
math::Vec pos = e.pos; | |||||
e.pos = e.pos.div(zoom); | e.pos = e.pos.div(zoom); | ||||
Widget::onMouseDown(e); | Widget::onMouseDown(e); | ||||
e.pos = pos; | e.pos = pos; | ||||
} | } | ||||
void ZoomWidget::onMouseUp(EventMouseUp &e) { | void ZoomWidget::onMouseUp(EventMouseUp &e) { | ||||
Vec pos = e.pos; | |||||
math::Vec pos = e.pos; | |||||
e.pos = e.pos.div(zoom); | e.pos = e.pos.div(zoom); | ||||
Widget::onMouseUp(e); | Widget::onMouseUp(e); | ||||
e.pos = pos; | e.pos = pos; | ||||
} | } | ||||
void ZoomWidget::onMouseMove(EventMouseMove &e) { | void ZoomWidget::onMouseMove(EventMouseMove &e) { | ||||
Vec pos = e.pos; | |||||
math::Vec pos = e.pos; | |||||
e.pos = e.pos.div(zoom); | e.pos = e.pos.div(zoom); | ||||
Widget::onMouseMove(e); | Widget::onMouseMove(e); | ||||
e.pos = pos; | e.pos = pos; | ||||
} | } | ||||
void ZoomWidget::onHoverKey(EventHoverKey &e) { | void ZoomWidget::onHoverKey(EventHoverKey &e) { | ||||
Vec pos = e.pos; | |||||
math::Vec pos = e.pos; | |||||
e.pos = e.pos.div(zoom); | e.pos = e.pos.div(zoom); | ||||
Widget::onHoverKey(e); | Widget::onHoverKey(e); | ||||
e.pos = pos; | e.pos = pos; | ||||
} | } | ||||
void ZoomWidget::onScroll(EventScroll &e) { | void ZoomWidget::onScroll(EventScroll &e) { | ||||
Vec pos = e.pos; | |||||
math::Vec pos = e.pos; | |||||
e.pos = e.pos.div(zoom); | e.pos = e.pos.div(zoom); | ||||
Widget::onScroll(e); | Widget::onScroll(e); | ||||
e.pos = pos; | e.pos = pos; | ||||
} | } | ||||
void ZoomWidget::onPathDrop(EventPathDrop &e) { | void ZoomWidget::onPathDrop(EventPathDrop &e) { | ||||
Vec pos = e.pos; | |||||
math::Vec pos = e.pos; | |||||
e.pos = e.pos.div(zoom); | e.pos = e.pos.div(zoom); | ||||
Widget::onPathDrop(e); | Widget::onPathDrop(e); | ||||
e.pos = pos; | e.pos = pos; | ||||
@@ -42,7 +42,7 @@ float gPixelRatio = 1.0; | |||||
float gWindowRatio = 1.0; | float gWindowRatio = 1.0; | ||||
bool gAllowCursorLock = true; | bool gAllowCursorLock = true; | ||||
int gGuiFrame; | int gGuiFrame; | ||||
Vec gMousePos; | |||||
math::Vec gMousePos; | |||||
std::string lastWindowTitle; | std::string lastWindowTitle; | ||||
@@ -152,15 +152,15 @@ void mouseButtonStickyCallback(GLFWwindow *window, int button, int action, int m | |||||
} | } | ||||
void cursorPosCallback(GLFWwindow* window, double xpos, double ypos) { | void cursorPosCallback(GLFWwindow* window, double xpos, double ypos) { | ||||
Vec mousePos = Vec(xpos, ypos).div(gPixelRatio / gWindowRatio).round(); | |||||
Vec mouseRel = mousePos.minus(gMousePos); | |||||
math::Vec mousePos = math::Vec(xpos, ypos).div(gPixelRatio / gWindowRatio).round(); | |||||
math::Vec mouseRel = mousePos.minus(gMousePos); | |||||
int cursorMode = glfwGetInputMode(gWindow, GLFW_CURSOR); | int cursorMode = glfwGetInputMode(gWindow, GLFW_CURSOR); | ||||
(void) cursorMode; | (void) cursorMode; | ||||
#ifdef ARCH_MAC | #ifdef ARCH_MAC | ||||
// Workaround for Mac. We can't use GLFW_CURSOR_DISABLED because it's buggy, so implement it on our own. | // 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 clamped. | |||||
// This is not an ideal implementation. For example, if the user drags off the screen, the new mouse position will be math::clamped. | |||||
if (cursorMode == GLFW_CURSOR_HIDDEN) { | if (cursorMode == GLFW_CURSOR_HIDDEN) { | ||||
// CGSetLocalEventsSuppressionInterval(0.0); | // CGSetLocalEventsSuppressionInterval(0.0); | ||||
glfwSetCursorPos(gWindow, gMousePos.x, gMousePos.y); | glfwSetCursorPos(gWindow, gMousePos.x, gMousePos.y); | ||||
@@ -241,10 +241,10 @@ void cursorEnterCallback(GLFWwindow* window, int entered) { | |||||
} | } | ||||
void scrollCallback(GLFWwindow *window, double x, double y) { | void scrollCallback(GLFWwindow *window, double x, double y) { | ||||
Vec scrollRel = Vec(x, y); | |||||
math::Vec scrollRel = math::Vec(x, y); | |||||
#if ARCH_LIN || ARCH_WIN | #if ARCH_LIN || ARCH_WIN | ||||
if (windowIsShiftPressed()) | if (windowIsShiftPressed()) | ||||
scrollRel = Vec(y, x); | |||||
scrollRel = math::Vec(y, x); | |||||
#endif | #endif | ||||
// onScroll | // onScroll | ||||
EventScroll e; | EventScroll e; | ||||
@@ -478,7 +478,7 @@ void windowRun() { | |||||
glfwGetWindowSize(gWindow, &windowWidth, &windowHeight); | glfwGetWindowSize(gWindow, &windowWidth, &windowHeight); | ||||
gWindowRatio = (float)width / windowWidth; | gWindowRatio = (float)width / windowWidth; | ||||
gScene->box.size = Vec(width, height).div(gPixelRatio); | |||||
gScene->box.size = math::Vec(width, height).div(gPixelRatio); | |||||
// Step scene | // Step scene | ||||
gScene->step(); | gScene->step(); | ||||
@@ -533,25 +533,25 @@ bool windowIsShiftPressed() { | |||||
return glfwGetKey(gWindow, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS || glfwGetKey(gWindow, GLFW_KEY_RIGHT_SHIFT) == GLFW_PRESS; | return glfwGetKey(gWindow, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS || glfwGetKey(gWindow, GLFW_KEY_RIGHT_SHIFT) == GLFW_PRESS; | ||||
} | } | ||||
Vec windowGetWindowSize() { | |||||
math::Vec windowGetWindowSize() { | |||||
int width, height; | int width, height; | ||||
glfwGetWindowSize(gWindow, &width, &height); | glfwGetWindowSize(gWindow, &width, &height); | ||||
return Vec(width, height); | |||||
return math::Vec(width, height); | |||||
} | } | ||||
void windowSetWindowSize(Vec size) { | |||||
void windowSetWindowSize(math::Vec size) { | |||||
int width = size.x; | int width = size.x; | ||||
int height = size.y; | int height = size.y; | ||||
glfwSetWindowSize(gWindow, width, height); | glfwSetWindowSize(gWindow, width, height); | ||||
} | } | ||||
Vec windowGetWindowPos() { | |||||
math::Vec windowGetWindowPos() { | |||||
int x, y; | int x, y; | ||||
glfwGetWindowPos(gWindow, &x, &y); | glfwGetWindowPos(gWindow, &x, &y); | ||||
return Vec(x, y); | |||||
return math::Vec(x, y); | |||||
} | } | ||||
void windowSetWindowPos(Vec pos) { | |||||
void windowSetWindowPos(math::Vec pos) { | |||||
int x = pos.x; | int x = pos.x; | ||||
int y = pos.y; | int y = pos.y; | ||||
glfwSetWindowPos(gWindow, x, y); | glfwSetWindowPos(gWindow, x, y); | ||||
@@ -568,14 +568,14 @@ void windowSetTheme(NVGcolor bg, NVGcolor fg) { | |||||
w.outlineColor = bg; | w.outlineColor = bg; | ||||
w.itemColor = fg; | w.itemColor = fg; | ||||
w.innerColor = bg; | w.innerColor = bg; | ||||
w.innerSelectedColor = colorPlus(bg, nvgRGB(0x30, 0x30, 0x30)); | |||||
w.innerSelectedColor = color::plus(bg, nvgRGB(0x30, 0x30, 0x30)); | |||||
w.textColor = fg; | w.textColor = fg; | ||||
w.textSelectedColor = fg; | w.textSelectedColor = fg; | ||||
w.shadeTop = 0; | w.shadeTop = 0; | ||||
w.shadeDown = 0; | w.shadeDown = 0; | ||||
BNDtheme t; | BNDtheme t; | ||||
t.backgroundColor = colorPlus(bg, nvgRGB(0x30, 0x30, 0x30)); | |||||
t.backgroundColor = color::plus(bg, nvgRGB(0x30, 0x30, 0x30)); | |||||
t.regularTheme = w; | t.regularTheme = w; | ||||
t.toolTheme = w; | t.toolTheme = w; | ||||
t.radioTheme = w; | t.radioTheme = w; | ||||
@@ -590,18 +590,18 @@ void windowSetTheme(NVGcolor bg, NVGcolor fg) { | |||||
t.menuItemTheme = w; | t.menuItemTheme = w; | ||||
t.sliderTheme.itemColor = bg; | t.sliderTheme.itemColor = bg; | ||||
t.sliderTheme.innerColor = colorPlus(bg, nvgRGB(0x50, 0x50, 0x50)); | |||||
t.sliderTheme.innerSelectedColor = colorPlus(bg, nvgRGB(0x60, 0x60, 0x60)); | |||||
t.sliderTheme.innerColor = color::plus(bg, nvgRGB(0x50, 0x50, 0x50)); | |||||
t.sliderTheme.innerSelectedColor = color::plus(bg, nvgRGB(0x60, 0x60, 0x60)); | |||||
t.textFieldTheme = t.sliderTheme; | t.textFieldTheme = t.sliderTheme; | ||||
t.textFieldTheme.textColor = colorMinus(bg, nvgRGB(0x20, 0x20, 0x20)); | |||||
t.textFieldTheme.textColor = color::minus(bg, nvgRGB(0x20, 0x20, 0x20)); | |||||
t.textFieldTheme.textSelectedColor = t.textFieldTheme.textColor; | t.textFieldTheme.textSelectedColor = t.textFieldTheme.textColor; | ||||
t.scrollBarTheme.itemColor = colorPlus(bg, nvgRGB(0x50, 0x50, 0x50)); | |||||
t.scrollBarTheme.itemColor = color::plus(bg, nvgRGB(0x50, 0x50, 0x50)); | |||||
t.scrollBarTheme.innerColor = bg; | t.scrollBarTheme.innerColor = bg; | ||||
t.menuTheme.innerColor = colorMinus(bg, nvgRGB(0x10, 0x10, 0x10)); | |||||
t.menuTheme.textColor = colorMinus(fg, nvgRGB(0x50, 0x50, 0x50)); | |||||
t.menuTheme.innerColor = color::minus(bg, nvgRGB(0x10, 0x10, 0x10)); | |||||
t.menuTheme.textColor = color::minus(fg, nvgRGB(0x50, 0x50, 0x50)); | |||||
t.menuTheme.textSelectedColor = t.menuTheme.textColor; | t.menuTheme.textSelectedColor = t.menuTheme.textColor; | ||||
bndSetTheme(t); | bndSetTheme(t); | ||||