| @@ -18,13 +18,13 @@ struct WidgetState { | |||||
| /** For middle-click dragging */ | /** For middle-click dragging */ | ||||
| Widget *scrollWidget = NULL; | Widget *scrollWidget = NULL; | ||||
| void handleButton(math::Vec pos, int button, int action, int mods); | |||||
| void handleHover(math::Vec pos, math::Vec mouseDelta); | |||||
| void handleButton(Vec pos, int button, int action, int mods); | |||||
| void handleHover(Vec pos, Vec mouseDelta); | |||||
| void handleLeave(); | void handleLeave(); | ||||
| void handleScroll(math::Vec pos, math::Vec scrollDelta); | |||||
| void handleText(math::Vec pos, int codepoint); | |||||
| void handleKey(math::Vec pos, int key, int scancode, int action, int mods); | |||||
| void handleDrop(math::Vec pos, std::vector<std::string> paths); | |||||
| void handleScroll(Vec pos, Vec scrollDelta); | |||||
| void handleText(Vec pos, int codepoint); | |||||
| void handleKey(Vec pos, int key, int scancode, int action, int mods); | |||||
| void handleDrop(Vec pos, std::vector<std::string> paths); | |||||
| void handleZoom(); | void handleZoom(); | ||||
| /** Prepares a widget for deletion */ | /** Prepares a widget for deletion */ | ||||
| void finalizeWidget(Widget *w); | void finalizeWidget(Widget *w); | ||||
| @@ -17,7 +17,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; | ||||
| math::Vec textOffset; | |||||
| Vec textOffset; | |||||
| NVGcolor color; | NVGcolor color; | ||||
| LedDisplayChoice(); | LedDisplayChoice(); | ||||
| void draw(NVGcontext *vg) override; | void draw(NVGcontext *vg) override; | ||||
| @@ -26,11 +26,11 @@ struct LedDisplayChoice : TransparentWidget { | |||||
| struct LedDisplayTextField : TextField { | struct LedDisplayTextField : TextField { | ||||
| std::shared_ptr<Font> font; | std::shared_ptr<Font> font; | ||||
| math::Vec textOffset; | |||||
| Vec textOffset; | |||||
| NVGcolor color; | NVGcolor color; | ||||
| LedDisplayTextField(); | LedDisplayTextField(); | ||||
| void draw(NVGcontext *vg) override; | void draw(NVGcontext *vg) override; | ||||
| int getTextPosition(math::Vec mousePos) override; | |||||
| int getTextPosition(Vec mousePos) override; | |||||
| }; | }; | ||||
| @@ -64,7 +64,7 @@ struct ModuleWidget : OpaqueWidget { | |||||
| void draw(NVGcontext *vg) override; | void draw(NVGcontext *vg) override; | ||||
| void drawShadow(NVGcontext *vg); | void drawShadow(NVGcontext *vg); | ||||
| math::Vec dragPos; | |||||
| Vec dragPos; | |||||
| void onHover(event::Hover &e) override; | void onHover(event::Hover &e) override; | ||||
| void onButton(event::Button &e) override; | void onButton(event::Button &e) override; | ||||
| void onHoverKey(event::HoverKey &e) override; | void onHoverKey(event::HoverKey &e) override; | ||||
| @@ -15,7 +15,7 @@ struct RackWidget : OpaqueWidget { | |||||
| // Only put WireWidgets in here | // Only put WireWidgets in here | ||||
| WireContainer *wireContainer; | WireContainer *wireContainer; | ||||
| std::string lastPath; | std::string lastPath; | ||||
| math::Vec lastMousePos; | |||||
| Vec lastMousePos; | |||||
| bool lockModules = false; | bool lockModules = false; | ||||
| RackWidget(); | RackWidget(); | ||||
| @@ -45,9 +45,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, math::Rect box); | |||||
| bool requestModuleBox(ModuleWidget *m, Rect box); | |||||
| /** Moves a module to the closest non-colliding position */ | /** Moves a module to the closest non-colliding position */ | ||||
| bool requestModuleBoxNearest(ModuleWidget *m, math::Rect box); | |||||
| bool requestModuleBoxNearest(ModuleWidget *m, Rect box); | |||||
| void step() override; | void step() override; | ||||
| void draw(NVGcontext *vg) override; | void draw(NVGcontext *vg) override; | ||||
| @@ -19,7 +19,7 @@ struct PanelBorder : TransparentWidget { | |||||
| struct SVGPanel : FramebufferWidget { | struct SVGPanel : FramebufferWidget { | ||||
| void step() override { | void step() override { | ||||
| if (math::isNear(gPixelRatio, 1.0)) { | |||||
| if (isNear(gPixelRatio, 1.0)) { | |||||
| // Small details draw poorly at low DPI, so oversample when drawing to the framebuffer | // Small details draw poorly at low DPI, so oversample when drawing to the framebuffer | ||||
| oversample = 2.0; | oversample = 2.0; | ||||
| } | } | ||||
| @@ -12,7 +12,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 */ | ||||
| math::Vec minHandlePos, maxHandlePos; | |||||
| 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); | ||||
| @@ -20,8 +20,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(); | ||||
| math::Vec getOutputPos(); | |||||
| math::Vec getInputPos(); | |||||
| Vec getOutputPos(); | |||||
| 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; | ||||
| @@ -15,7 +15,7 @@ inline float in2px(float in) { | |||||
| return in * SVG_DPI; | return in * SVG_DPI; | ||||
| } | } | ||||
| inline math::Vec in2px(math::Vec in) { | |||||
| inline Vec in2px(Vec in) { | |||||
| return in.mult(SVG_DPI); | return in.mult(SVG_DPI); | ||||
| } | } | ||||
| @@ -24,7 +24,7 @@ inline float mm2px(float mm) { | |||||
| return mm * (SVG_DPI / MM_PER_IN); | return mm * (SVG_DPI / MM_PER_IN); | ||||
| } | } | ||||
| inline math::Vec mm2px(math::Vec mm) { | |||||
| inline Vec mm2px(Vec mm) { | |||||
| return mm.mult(SVG_DPI / MM_PER_IN); | return mm.mult(SVG_DPI / MM_PER_IN); | ||||
| } | } | ||||
| @@ -32,7 +32,7 @@ inline math::Vec mm2px(math::Vec mm) { | |||||
| // A 1HPx3U module should be 15x380 pixels. Thus the width of a module should be a factor of 15. | // 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 math::Vec RACK_GRID_SIZE = math::Vec(RACK_GRID_WIDTH, RACK_GRID_HEIGHT); | |||||
| static const Vec RACK_GRID_SIZE = Vec(RACK_GRID_WIDTH, RACK_GRID_HEIGHT); | |||||
| static const std::string PRESET_FILTERS = "VCV Rack module preset (.vcvm):vcvm"; | static const std::string 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"; | ||||
| @@ -23,7 +23,7 @@ static const NVGcolor CYAN = nvgRGB(0x00, 0xff, 0xff); | |||||
| inline NVGcolor clip(NVGcolor a) { | inline NVGcolor clip(NVGcolor a) { | ||||
| for (int i = 0; i < 4; i++) | for (int i = 0; i < 4; i++) | ||||
| a.rgba[i] = math::clamp(a.rgba[i], 0.f, 1.f); | |||||
| a.rgba[i] = clamp(a.rgba[i], 0.f, 1.f); | |||||
| return a; | return a; | ||||
| } | } | ||||
| @@ -87,9 +87,9 @@ inline std::string toHexString(NVGcolor c) { | |||||
| uint8_t b = std::round(c.b * 255); | uint8_t b = std::round(c.b * 255); | ||||
| uint8_t a = std::round(c.a * 255); | uint8_t a = std::round(c.a * 255); | ||||
| if (a == 255) | if (a == 255) | ||||
| return string::stringf("#%02x%02x%02x", r, g, b); | |||||
| return string::f("#%02x%02x%02x", r, g, b); | |||||
| else | else | ||||
| return string::stringf("#%02x%02x%02x%02x", r, g, b, a); | |||||
| return string::f("#%02x%02x%02x%02x", r, g, b, a); | |||||
| } | } | ||||
| @@ -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 + math::interpolateLinear(minblep, minblepIndex)); | |||||
| buf[index] += dx * (-1.0 + interpolateLinear(minblep, minblepIndex)); | |||||
| } | } | ||||
| } | } | ||||
| float shift() { | float shift() { | ||||
| @@ -23,7 +23,7 @@ struct VUMeter { | |||||
| return (dBScaled >= 0.0) ? 1.0 : 0.0; | return (dBScaled >= 0.0) ? 1.0 : 0.0; | ||||
| } | } | ||||
| else { | else { | ||||
| return math::clamp(dBScaled + i, 0.0, 1.0); | |||||
| return clamp(dBScaled + i, 0.0, 1.0); | |||||
| } | } | ||||
| } | } | ||||
| }; | }; | ||||
| @@ -24,7 +24,7 @@ struct Event { | |||||
| struct Position { | struct Position { | ||||
| /** The pixel coordinate where the event occurred, relative to the Widget it is called on. */ | /** The pixel coordinate where the event occurred, relative to the Widget it is called on. */ | ||||
| math::Vec pos; | |||||
| Vec pos; | |||||
| }; | }; | ||||
| @@ -52,7 +52,7 @@ If `target` is set, other events may occur on that Widget. | |||||
| */ | */ | ||||
| struct Hover : Event, Position { | struct Hover : Event, Position { | ||||
| /** Change in mouse position since the last frame. Can be zero. */ | /** Change in mouse position since the last frame. Can be zero. */ | ||||
| math::Vec mouseDelta; | |||||
| Vec mouseDelta; | |||||
| }; | }; | ||||
| @@ -89,7 +89,7 @@ Recurses until consumed. | |||||
| */ | */ | ||||
| struct HoverScroll : Event, Position { | struct HoverScroll : Event, Position { | ||||
| /** Change of scroll wheel position. */ | /** Change of scroll wheel position. */ | ||||
| math::Vec scrollDelta; | |||||
| Vec scrollDelta; | |||||
| }; | }; | ||||
| @@ -147,7 +147,7 @@ struct DragEnd : Event { | |||||
| `mouseDelta` may be zero. | `mouseDelta` may be zero. | ||||
| */ | */ | ||||
| struct DragMove : Event { | struct DragMove : Event { | ||||
| math::Vec mouseDelta; | |||||
| Vec mouseDelta; | |||||
| }; | }; | ||||
| @@ -156,7 +156,7 @@ Must consume to allow DragEnter, DragLeave, and DragDrop to occur. | |||||
| */ | */ | ||||
| struct DragHover : Event, Position { | struct DragHover : Event, Position { | ||||
| /** Change in mouse position since the last frame. Can be zero. */ | /** Change in mouse position since the last frame. Can be zero. */ | ||||
| math::Vec mouseDelta; | |||||
| Vec mouseDelta; | |||||
| }; | }; | ||||
| /** Occurs when the mouse enters a Widget while dragging. | /** Occurs when the mouse enters a Widget while dragging. | ||||
| @@ -36,14 +36,14 @@ Model *createModel(std::string author, std::string slug, std::string name, Tags. | |||||
| } | } | ||||
| template <class TWidget> | template <class TWidget> | ||||
| TWidget *createWidget(math::Vec pos) { | |||||
| TWidget *createWidget(Vec pos) { | |||||
| TWidget *o = new TWidget; | TWidget *o = new TWidget; | ||||
| o->box.pos = pos; | o->box.pos = pos; | ||||
| return o; | return o; | ||||
| } | } | ||||
| template <class TParamWidget> | template <class TParamWidget> | ||||
| TParamWidget *createParam(math::Vec pos, Module *module, int paramId, float minValue, float maxValue, float defaultValue) { | |||||
| TParamWidget *createParam(Vec pos, Module *module, int paramId, float minValue, float maxValue, float defaultValue) { | |||||
| TParamWidget *o = new TParamWidget; | TParamWidget *o = new TParamWidget; | ||||
| o->box.pos = pos; | o->box.pos = pos; | ||||
| o->module = module; | o->module = module; | ||||
| @@ -54,7 +54,7 @@ TParamWidget *createParam(math::Vec pos, Module *module, int paramId, float minV | |||||
| } | } | ||||
| template <class TParamWidget> | template <class TParamWidget> | ||||
| TParamWidget *createParamCentered(math::Vec pos, Module *module, int paramId, float minValue, float maxValue, float defaultValue) { | |||||
| TParamWidget *createParamCentered(Vec pos, Module *module, int paramId, float minValue, float maxValue, float defaultValue) { | |||||
| TParamWidget *o = new TParamWidget; | TParamWidget *o = new TParamWidget; | ||||
| o->box.pos = pos.minus(o->box.size.div(2)); | o->box.pos = pos.minus(o->box.size.div(2)); | ||||
| o->module = module; | o->module = module; | ||||
| @@ -65,7 +65,7 @@ TParamWidget *createParamCentered(math::Vec pos, Module *module, int paramId, fl | |||||
| } | } | ||||
| template <class TPort> | template <class TPort> | ||||
| TPort *createInput(math::Vec pos, Module *module, int inputId) { | |||||
| TPort *createInput(Vec pos, Module *module, int inputId) { | |||||
| TPort *o = new TPort; | TPort *o = new TPort; | ||||
| o->box.pos = pos; | o->box.pos = pos; | ||||
| o->module = module; | o->module = module; | ||||
| @@ -75,7 +75,7 @@ TPort *createInput(math::Vec pos, Module *module, int inputId) { | |||||
| } | } | ||||
| template <class TPort> | template <class TPort> | ||||
| TPort *createInputCentered(math::Vec pos, Module *module, int inputId) { | |||||
| TPort *createInputCentered(Vec pos, Module *module, int inputId) { | |||||
| TPort *o = new TPort; | TPort *o = new TPort; | ||||
| o->box.pos = pos.minus(o->box.size.div(2)); | o->box.pos = pos.minus(o->box.size.div(2)); | ||||
| o->module = module; | o->module = module; | ||||
| @@ -85,7 +85,7 @@ TPort *createInputCentered(math::Vec pos, Module *module, int inputId) { | |||||
| } | } | ||||
| template <class TPort> | template <class TPort> | ||||
| TPort *createOutput(math::Vec pos, Module *module, int outputId) { | |||||
| TPort *createOutput(Vec pos, Module *module, int outputId) { | |||||
| TPort *o = new TPort; | TPort *o = new TPort; | ||||
| o->box.pos = pos; | o->box.pos = pos; | ||||
| o->module = module; | o->module = module; | ||||
| @@ -95,7 +95,7 @@ TPort *createOutput(math::Vec pos, Module *module, int outputId) { | |||||
| } | } | ||||
| template <class TPort> | template <class TPort> | ||||
| TPort *createOutputCentered(math::Vec pos, Module *module, int outputId) { | |||||
| TPort *createOutputCentered(Vec pos, Module *module, int outputId) { | |||||
| TPort *o = new TPort; | TPort *o = new TPort; | ||||
| o->box.pos = pos.minus(o->box.size.div(2)); | o->box.pos = pos.minus(o->box.size.div(2)); | ||||
| o->module = module; | o->module = module; | ||||
| @@ -105,7 +105,7 @@ TPort *createOutputCentered(math::Vec pos, Module *module, int outputId) { | |||||
| } | } | ||||
| template <class TModuleLightWidget> | template <class TModuleLightWidget> | ||||
| TModuleLightWidget *createLight(math::Vec pos, Module *module, int firstLightId) { | |||||
| TModuleLightWidget *createLight(Vec pos, Module *module, int firstLightId) { | |||||
| TModuleLightWidget *o = new TModuleLightWidget; | TModuleLightWidget *o = new TModuleLightWidget; | ||||
| o->box.pos = pos; | o->box.pos = pos; | ||||
| o->module = module; | o->module = module; | ||||
| @@ -114,7 +114,7 @@ TModuleLightWidget *createLight(math::Vec pos, Module *module, int firstLightId) | |||||
| } | } | ||||
| template <class TModuleLightWidget> | template <class TModuleLightWidget> | ||||
| TModuleLightWidget *createLightCentered(math::Vec pos, Module *module, int firstLightId) { | |||||
| TModuleLightWidget *createLightCentered(Vec pos, Module *module, int firstLightId) { | |||||
| TModuleLightWidget *o = new TModuleLightWidget; | TModuleLightWidget *o = new TModuleLightWidget; | ||||
| o->box.pos = pos.minus(o->box.size.div(2)); | o->box.pos = pos.minus(o->box.size.div(2)); | ||||
| o->module = module; | o->module = module; | ||||
| @@ -4,7 +4,6 @@ | |||||
| namespace rack { | namespace rack { | ||||
| namespace math { | |||||
| //////////////////// | //////////////////// | ||||
| // basic integer functions | // basic integer functions | ||||
| @@ -265,8 +264,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::math::clamp(pos.x + size.x, bound.pos.x, bound.pos.x + bound.size.x) - r.pos.x; | |||||
| r.size.y = rack::math::clamp(pos.y + size.y, bound.pos.y, bound.pos.y + bound.size.y) - r.pos.y; | |||||
| r.size.x = rack::clamp(pos.x + size.x, bound.pos.x, bound.pos.x + bound.size.x) - r.pos.x; | |||||
| r.size.y = rack::clamp(pos.y + size.y, bound.pos.y, bound.pos.y + bound.size.y) - r.pos.y; | |||||
| return r; | return r; | ||||
| } | } | ||||
| /** Nudges the position to fix inside a bounding box */ | /** Nudges the position to fix inside a bounding box */ | ||||
| @@ -307,18 +306,17 @@ struct Rect { | |||||
| inline Vec Vec::clamp(Rect bound) const { | inline Vec Vec::clamp(Rect bound) const { | ||||
| return Vec( | return Vec( | ||||
| rack::math::clamp(x, bound.pos.x, bound.pos.x + bound.size.x), | |||||
| rack::math::clamp(y, bound.pos.y, bound.pos.y + bound.size.y)); | |||||
| rack::clamp(x, bound.pos.x, bound.pos.x + bound.size.x), | |||||
| rack::clamp(y, bound.pos.y, bound.pos.y + bound.size.y)); | |||||
| } | } | ||||
| inline Vec Vec::clampBetween(Rect bound) const { | inline Vec Vec::clampBetween(Rect bound) const { | ||||
| return Vec( | return Vec( | ||||
| rack::math::clampBetween(x, bound.pos.x, bound.pos.x + bound.size.x), | |||||
| rack::math::clampBetween(y, bound.pos.y, bound.pos.y + bound.size.y)); | |||||
| rack::clampBetween(x, bound.pos.x, bound.pos.x + bound.size.x), | |||||
| rack::clampBetween(y, bound.pos.y, bound.pos.y + bound.size.y)); | |||||
| } | } | ||||
| inline Vec Vec::clamp2(Rect bound) const {return clampBetween(bound);} | inline Vec Vec::clamp2(Rect bound) const {return clampBetween(bound);} | ||||
| } // namespace math | |||||
| } // namespace rack | } // namespace rack | ||||
| @@ -16,14 +16,3 @@ | |||||
| #include "app.hpp" | #include "app.hpp" | ||||
| #include "ui.hpp" | #include "ui.hpp" | ||||
| #include "helpers.hpp" | #include "helpers.hpp" | ||||
| namespace rack { | |||||
| // Adopt some sub-namespaces into the main namespace for convenience | |||||
| using namespace math; | |||||
| using string::stringf; | |||||
| } // namespace rack | |||||
| @@ -110,7 +110,7 @@ DEPRECATED static const NVGcolor COLOR_DARK_PANEL = SCHEME_DARK_PANEL; | |||||
| //////////////////// | //////////////////// | ||||
| template <class TScrew> | template <class TScrew> | ||||
| DEPRECATED TScrew *createScrew(math::Vec pos) { | |||||
| DEPRECATED TScrew *createScrew(Vec pos) { | |||||
| return createWidget<TScrew>(pos); | return createWidget<TScrew>(pos); | ||||
| } | } | ||||
| @@ -10,70 +10,19 @@ namespace string { | |||||
| /** Converts a printf format string and optional arguments into a std::string */ | /** Converts a printf format string and optional arguments into a std::string */ | ||||
| inline std::string stringf(const char *format, ...) { | |||||
| va_list args; | |||||
| va_start(args, format); | |||||
| // Compute size of required buffer | |||||
| int size = vsnprintf(NULL, 0, format, args); | |||||
| va_end(args); | |||||
| if (size < 0) | |||||
| return ""; | |||||
| // Create buffer | |||||
| std::string s; | |||||
| s.resize(size); | |||||
| va_start(args, format); | |||||
| vsnprintf(&s[0], size + 1, format, args); | |||||
| va_end(args); | |||||
| return s; | |||||
| } | |||||
| inline std::string lowercase(std::string s) { | |||||
| std::transform(s.begin(), s.end(), s.begin(), ::tolower); | |||||
| return s; | |||||
| } | |||||
| inline std::string uppercase(std::string s) { | |||||
| std::transform(s.begin(), s.end(), s.begin(), ::toupper); | |||||
| return s; | |||||
| } | |||||
| std::string f(const char *format, ...); | |||||
| /** Replaces all characters to lowercase letters */ | |||||
| std::string lowercase(std::string s); | |||||
| /** Replaces all characters to uppercase letters */ | |||||
| std::string uppercase(std::string s); | |||||
| /** Truncates and adds "..." to a string, not exceeding `len` characters */ | /** Truncates and adds "..." to a string, not exceeding `len` characters */ | ||||
| inline std::string ellipsize(std::string s, size_t len) { | |||||
| if (s.size() <= len) | |||||
| return s; | |||||
| else | |||||
| return s.substr(0, len - 3) + "..."; | |||||
| } | |||||
| inline bool startsWith(std::string str, std::string prefix) { | |||||
| return str.substr(0, prefix.size()) == prefix; | |||||
| } | |||||
| inline bool endsWith(std::string str, std::string suffix) { | |||||
| return str.substr(str.size() - suffix.size(), suffix.size()) == suffix; | |||||
| } | |||||
| std::string ellipsize(std::string s, size_t len); | |||||
| bool startsWith(std::string str, std::string prefix); | |||||
| bool endsWith(std::string str, std::string suffix); | |||||
| /** Extracts portions of a path */ | /** Extracts portions of a path */ | ||||
| inline std::string directory(std::string path) { | |||||
| char *pathDup = strdup(path.c_str()); | |||||
| std::string directory = dirname(pathDup); | |||||
| free(pathDup); | |||||
| return directory; | |||||
| } | |||||
| inline std::string filename(std::string path) { | |||||
| char *pathDup = strdup(path.c_str()); | |||||
| std::string filename = basename(pathDup); | |||||
| free(pathDup); | |||||
| return filename; | |||||
| } | |||||
| inline std::string extension(std::string path) { | |||||
| const char *ext = strrchr(filename(path).c_str(), '.'); | |||||
| if (!ext) | |||||
| return ""; | |||||
| return ext + 1; | |||||
| } | |||||
| std::string directory(std::string path); | |||||
| std::string filename(std::string path); | |||||
| std::string extension(std::string path); | |||||
| struct CaseInsensitiveCompare { | struct CaseInsensitiveCompare { | ||||
| bool operator()(const std::string &a, const std::string &b) const { | bool operator()(const std::string &a, const std::string &b) const { | ||||
| @@ -17,7 +17,7 @@ struct IconButton : Button { | |||||
| addChild(fw); | addChild(fw); | ||||
| sw = new SVGWidget; | sw = new SVGWidget; | ||||
| sw->box.pos = math::Vec(2, 2); | |||||
| sw->box.pos = Vec(2, 2); | |||||
| fw->addChild(sw); | fw->addChild(sw); | ||||
| } | } | ||||
| @@ -15,7 +15,7 @@ struct List : OpaqueWidget { | |||||
| if (!child->visible) | if (!child->visible) | ||||
| continue; | continue; | ||||
| // Increment height, set position of child | // Increment height, set position of child | ||||
| child->box.pos = math::Vec(0.0, box.size.y); | |||||
| child->box.pos = Vec(0.0, box.size.y); | |||||
| box.size.y += child->box.size.y; | 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; | ||||
| @@ -12,7 +12,7 @@ struct Menu : OpaqueWidget { | |||||
| MenuEntry *activeEntry = NULL; | MenuEntry *activeEntry = NULL; | ||||
| Menu() { | Menu() { | ||||
| box.size = math::Vec(0, 0); | |||||
| box.size = Vec(0, 0); | |||||
| } | } | ||||
| ~Menu() { | ~Menu() { | ||||
| @@ -42,12 +42,12 @@ struct Menu : OpaqueWidget { | |||||
| Widget::step(); | Widget::step(); | ||||
| // Set positions of children | // Set positions of children | ||||
| box.size = math::Vec(0, 0); | |||||
| box.size = 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 = math::Vec(0, box.size.y); | |||||
| child->box.pos = 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) { | ||||
| @@ -7,7 +7,7 @@ namespace rack { | |||||
| struct MenuEntry : OpaqueWidget { | struct MenuEntry : OpaqueWidget { | ||||
| MenuEntry() { | MenuEntry() { | ||||
| box.size = math::Vec(0, BND_WIDGET_HEIGHT); | |||||
| box.size = Vec(0, BND_WIDGET_HEIGHT); | |||||
| } | } | ||||
| }; | }; | ||||
| @@ -11,7 +11,7 @@ struct ProgressBar : QuantityWidget { | |||||
| } | } | ||||
| void draw(NVGcontext *vg) override { | void draw(NVGcontext *vg) override { | ||||
| float progress = math::rescale(value, minValue, maxValue, 0.0, 1.0); | |||||
| float progress = rescale(value, minValue, maxValue, 0.0, 1.0); | |||||
| bndSlider(vg, 0.0, 0.0, box.size.x, box.size.y, BND_CORNER_ALL, BND_DEFAULT, progress, getText().c_str(), NULL); | bndSlider(vg, 0.0, 0.0, box.size.x, box.size.y, BND_CORNER_ALL, BND_DEFAULT, progress, getText().c_str(), NULL); | ||||
| } | } | ||||
| }; | }; | ||||
| @@ -18,7 +18,7 @@ struct ScrollBar : OpaqueWidget { | |||||
| float size = 0.0; | float size = 0.0; | ||||
| ScrollBar() { | ScrollBar() { | ||||
| box.size = math::Vec(BND_SCROLLBAR_WIDTH, BND_SCROLLBAR_HEIGHT); | |||||
| box.size = Vec(BND_SCROLLBAR_WIDTH, BND_SCROLLBAR_HEIGHT); | |||||
| } | } | ||||
| void draw(NVGcontext *vg) override { | void draw(NVGcontext *vg) override { | ||||
| @@ -44,7 +44,7 @@ struct ScrollWidget : OpaqueWidget { | |||||
| Widget *container; | Widget *container; | ||||
| ScrollBar *horizontalScrollBar; | ScrollBar *horizontalScrollBar; | ||||
| ScrollBar *verticalScrollBar; | ScrollBar *verticalScrollBar; | ||||
| math::Vec offset; | |||||
| Vec offset; | |||||
| ScrollWidget() { | ScrollWidget() { | ||||
| container = new Widget; | container = new Widget; | ||||
| @@ -61,8 +61,8 @@ struct ScrollWidget : OpaqueWidget { | |||||
| addChild(verticalScrollBar); | addChild(verticalScrollBar); | ||||
| } | } | ||||
| void scrollTo(math::Rect r) { | |||||
| math::Rect bound = math::Rect::fromMinMax(r.getBottomRight().minus(box.size), r.pos); | |||||
| void scrollTo(Rect r) { | |||||
| Rect bound = Rect::fromMinMax(r.getBottomRight().minus(box.size), r.pos); | |||||
| offset = offset.clampBetween(bound); | offset = offset.clampBetween(bound); | ||||
| } | } | ||||
| @@ -76,8 +76,8 @@ struct ScrollWidget : OpaqueWidget { | |||||
| Widget::step(); | Widget::step(); | ||||
| // Clamp scroll offset | // Clamp scroll offset | ||||
| math::Vec containerCorner = container->getChildrenBoundingBox().getBottomRight(); | |||||
| math::Rect containerBox = math::Rect(math::Vec(0, 0), containerCorner.minus(box.size)); | |||||
| Vec containerCorner = container->getChildrenBoundingBox().getBottomRight(); | |||||
| Rect containerBox = Rect(Vec(0, 0), containerCorner.minus(box.size)); | |||||
| offset = offset.clamp(containerBox); | 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) | ||||
| @@ -89,9 +89,9 @@ struct ScrollWidget : OpaqueWidget { | |||||
| container->box.pos = offset.neg().round(); | container->box.pos = offset.neg().round(); | ||||
| // Update scrollbar offsets and sizes | // Update scrollbar offsets and sizes | ||||
| math::Vec viewportSize = container->getChildrenBoundingBox().getBottomRight(); | |||||
| math::Vec scrollbarOffset = offset.div(viewportSize.minus(box.size)); | |||||
| math::Vec scrollbarSize = box.size.div(viewportSize); | |||||
| Vec viewportSize = container->getChildrenBoundingBox().getBottomRight(); | |||||
| Vec scrollbarOffset = offset.div(viewportSize.minus(box.size)); | |||||
| Vec scrollbarSize = box.size.div(viewportSize); | |||||
| horizontalScrollBar->visible = (0.0 < scrollbarSize.x && scrollbarSize.x < 1.0); | 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); | ||||
| @@ -101,7 +101,7 @@ struct ScrollWidget : OpaqueWidget { | |||||
| verticalScrollBar->size = scrollbarSize.y; | verticalScrollBar->size = scrollbarSize.y; | ||||
| // Resize scroll bars | // Resize scroll bars | ||||
| math::Vec inner = math::Vec(box.size.x - verticalScrollBar->box.size.x, box.size.y - horizontalScrollBar->box.size.y); | |||||
| Vec inner = Vec(box.size.x - verticalScrollBar->box.size.x, box.size.y - horizontalScrollBar->box.size.y); | |||||
| horizontalScrollBar->box.pos.y = inner.y; | 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; | ||||
| @@ -16,7 +16,7 @@ struct Slider : OpaqueWidget, QuantityWidget { | |||||
| } | } | ||||
| void draw(NVGcontext *vg) override { | void draw(NVGcontext *vg) override { | ||||
| float progress = math::rescale(value, minValue, maxValue, 0.0, 1.0); | |||||
| float progress = rescale(value, minValue, maxValue, 0.0, 1.0); | |||||
| bndSlider(vg, 0.0, 0.0, box.size.x, box.size.y, BND_CORNER_NONE, state, progress, getText().c_str(), NULL); | bndSlider(vg, 0.0, 0.0, box.size.x, box.size.y, BND_CORNER_NONE, state, progress, getText().c_str(), NULL); | ||||
| } | } | ||||
| @@ -183,8 +183,8 @@ struct TextField : OpaqueWidget { | |||||
| } break; | } break; | ||||
| } | } | ||||
| cursor = math::clamp(cursor, 0, (int) text.size()); | |||||
| selection = math::clamp(selection, 0, (int) text.size()); | |||||
| cursor = clamp(cursor, 0, (int) text.size()); | |||||
| selection = clamp(selection, 0, (int) text.size()); | |||||
| e.target = this; | e.target = this; | ||||
| } | } | ||||
| @@ -210,7 +210,7 @@ struct TextField : OpaqueWidget { | |||||
| onChange(eChange); | onChange(eChange); | ||||
| } | } | ||||
| virtual int getTextPosition(math::Vec mousePos) { | |||||
| virtual int getTextPosition(Vec mousePos) { | |||||
| return bndTextFieldTextPosition(gVg, 0.0, 0.0, box.size.x, box.size.y, -1, text.c_str(), mousePos.x, mousePos.y); | return bndTextFieldTextPosition(gVg, 0.0, 0.0, box.size.x, box.size.y, -1, text.c_str(), mousePos.x, mousePos.y); | ||||
| } | } | ||||
| }; | }; | ||||
| @@ -24,7 +24,7 @@ struct QuantityWidget : virtual Widget { | |||||
| } | } | ||||
| void setValue(float value) { | void setValue(float value) { | ||||
| this->value = math::clampBetween(value, minValue, maxValue); | |||||
| this->value = clampBetween(value, minValue, maxValue); | |||||
| event::Change e; | event::Change e; | ||||
| onChange(e); | onChange(e); | ||||
| } | } | ||||
| @@ -41,7 +41,7 @@ struct QuantityWidget : virtual Widget { | |||||
| /** Generates the display value */ | /** Generates the display value */ | ||||
| std::string getText() { | std::string getText() { | ||||
| return string::stringf("%s: %.*f%s", label.c_str(), precision, value, unit.c_str()); | |||||
| return string::f("%s: %.*f%s", label.c_str(), precision, value, unit.c_str()); | |||||
| } | } | ||||
| }; | }; | ||||
| @@ -12,10 +12,10 @@ struct SVGWidget : virtual Widget { | |||||
| /** Sets the box size to the svg image size */ | /** Sets the box size to the svg image size */ | ||||
| void wrap() { | void wrap() { | ||||
| if (svg && svg->handle) { | if (svg && svg->handle) { | ||||
| box.size = math::Vec(svg->handle->width, svg->handle->height); | |||||
| box.size = Vec(svg->handle->width, svg->handle->height); | |||||
| } | } | ||||
| else { | else { | ||||
| box.size = math::Vec(); | |||||
| box.size = Vec(); | |||||
| } | } | ||||
| } | } | ||||
| @@ -18,7 +18,7 @@ struct TransformWidget : virtual Widget { | |||||
| nvgTransformIdentity(transform); | nvgTransformIdentity(transform); | ||||
| } | } | ||||
| void translate(math::Vec delta) { | |||||
| void translate(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); | ||||
| @@ -30,7 +30,7 @@ struct TransformWidget : virtual Widget { | |||||
| nvgTransformPremultiply(transform, t); | nvgTransformPremultiply(transform, t); | ||||
| } | } | ||||
| void scale(math::Vec s) { | |||||
| void scale(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); | ||||
| @@ -10,20 +10,13 @@ | |||||
| namespace rack { | namespace rack { | ||||
| namespace event { | |||||
| struct Event; | |||||
| } // namespace event | |||||
| /** A node in the 2D scene graph | /** A node in the 2D scene graph | ||||
| It is recommended to inherit virtually from Widget instead of directly. | It is recommended to inherit virtually from Widget instead of directly. | ||||
| e.g. `struct MyWidget : virtual Widget {}` | e.g. `struct MyWidget : virtual Widget {}` | ||||
| */ | */ | ||||
| struct Widget { | struct Widget { | ||||
| /** Stores position and size */ | /** Stores position and size */ | ||||
| math::Rect box = math::Rect(math::Vec(), math::Vec(INFINITY, INFINITY)); | |||||
| Rect box = Rect(Vec(), Vec(INFINITY, INFINITY)); | |||||
| /** Automatically set when Widget is added as a child to another Widget */ | /** Automatically set when Widget is added as a child to another Widget */ | ||||
| Widget *parent = NULL; | Widget *parent = NULL; | ||||
| std::list<Widget*> children; | std::list<Widget*> children; | ||||
| @@ -34,15 +27,15 @@ struct Widget { | |||||
| virtual ~Widget(); | virtual ~Widget(); | ||||
| virtual math::Rect getChildrenBoundingBox(); | |||||
| virtual Rect getChildrenBoundingBox(); | |||||
| /** Returns `v` transformed into the coordinate system of `relative` */ | /** Returns `v` transformed into the coordinate system of `relative` */ | ||||
| virtual math::Vec getRelativeOffset(math::Vec v, Widget *relative); | |||||
| virtual Vec getRelativeOffset(Vec v, Widget *relative); | |||||
| /** Returns `v` transformed into world coordinates */ | /** Returns `v` transformed into world coordinates */ | ||||
| math::Vec getAbsoluteOffset(math::Vec v) { | |||||
| Vec getAbsoluteOffset(Vec v) { | |||||
| return getRelativeOffset(v, NULL); | return getRelativeOffset(v, NULL); | ||||
| } | } | ||||
| /** Returns a subset of the given math::Rect bounded by the box of this widget and all ancestors */ | |||||
| virtual math::Rect getViewport(math::Rect r); | |||||
| /** Returns a subset of the given Rect bounded by the box of this widget and all ancestors */ | |||||
| virtual Rect getViewport(Rect r); | |||||
| template <class T> | template <class T> | ||||
| T *getAncestorOfType() { | T *getAncestorOfType() { | ||||
| @@ -8,11 +8,11 @@ namespace rack { | |||||
| struct ZoomWidget : virtual Widget { | struct ZoomWidget : virtual Widget { | ||||
| float zoom = 1.f; | float zoom = 1.f; | ||||
| math::Vec getRelativeOffset(math::Vec v, Widget *relative) override { | |||||
| Vec getRelativeOffset(Vec v, Widget *relative) override { | |||||
| return Widget::getRelativeOffset(v.mult(zoom), relative); | return Widget::getRelativeOffset(v.mult(zoom), relative); | ||||
| } | } | ||||
| math::Rect getViewport(math::Rect r) override { | |||||
| Rect getViewport(Rect r) override { | |||||
| r.pos = r.pos.mult(zoom); | r.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); | ||||
| @@ -57,7 +57,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 math::Vec gMousePos; | |||||
| extern Vec gMousePos; | |||||
| void windowInit(); | void windowInit(); | ||||
| @@ -68,10 +68,10 @@ void windowCursorLock(); | |||||
| void windowCursorUnlock(); | void windowCursorUnlock(); | ||||
| bool windowIsModPressed(); | bool windowIsModPressed(); | ||||
| bool windowIsShiftPressed(); | bool windowIsShiftPressed(); | ||||
| math::Vec windowGetWindowSize(); | |||||
| void windowSetWindowSize(math::Vec size); | |||||
| math::Vec windowGetWindowPos(); | |||||
| void windowSetWindowPos(math::Vec pos); | |||||
| Vec windowGetWindowSize(); | |||||
| void windowSetWindowSize(Vec size); | |||||
| Vec windowGetWindowPos(); | |||||
| void windowSetWindowPos(Vec pos); | |||||
| bool windowIsMaximized(); | bool windowIsMaximized(); | ||||
| void windowSetTheme(NVGcolor bg, NVGcolor fg); | void windowSetTheme(NVGcolor bg, NVGcolor fg); | ||||
| void windowSetFullScreen(bool fullScreen); | void windowSetFullScreen(bool fullScreen); | ||||
| @@ -122,13 +122,13 @@ struct MidiCcChoice : GridChoice { | |||||
| void step() override { | void step() override { | ||||
| if (module->learningId == id) { | if (module->learningId == id) { | ||||
| if (0 <= focusCc) | if (0 <= focusCc) | ||||
| text = string::stringf("%d", focusCc); | |||||
| text = string::f("%d", focusCc); | |||||
| else | else | ||||
| text = "LRN"; | text = "LRN"; | ||||
| color.a = 0.5; | color.a = 0.5; | ||||
| } | } | ||||
| else { | else { | ||||
| text = string::stringf("%d", module->learnedCcs[id]); | |||||
| text = string::f("%d", module->learnedCcs[id]); | |||||
| color.a = 1.0; | color.a = 1.0; | ||||
| if (gWidgetState->selectedWidget == this) | if (gWidgetState->selectedWidget == this) | ||||
| gWidgetState->selectedWidget = NULL; | gWidgetState->selectedWidget = NULL; | ||||
| @@ -317,7 +317,7 @@ struct MIDIToCVInterfaceWidget : ModuleWidget { | |||||
| menu->addChild(construct<MenuLabel>()); | menu->addChild(construct<MenuLabel>()); | ||||
| for (int i = 0; i < 2; i++) { | for (int i = 0; i < 2; i++) { | ||||
| ClockItem *item = createMenuItem<ClockItem>(string::stringf("CLK %d rate", i + 1)); | |||||
| ClockItem *item = createMenuItem<ClockItem>(string::f("CLK %d rate", i + 1)); | |||||
| item->module = module; | item->module = module; | ||||
| item->index = i; | item->index = i; | ||||
| menu->addChild(item); | menu->addChild(item); | ||||
| @@ -169,7 +169,7 @@ struct MidiTrigChoice : GridChoice { | |||||
| }; | }; | ||||
| int oct = note / 12 - 1; | int oct = note / 12 - 1; | ||||
| int semi = note % 12; | int semi = note % 12; | ||||
| text = string::stringf("%s%d", noteNames[semi], oct); | |||||
| text = string::f("%s%d", noteNames[semi], oct); | |||||
| color.a = 1.0; | color.a = 1.0; | ||||
| if (gWidgetState->selectedWidget == this) | if (gWidgetState->selectedWidget == this) | ||||
| @@ -7,7 +7,7 @@ | |||||
| namespace rack { | namespace rack { | ||||
| void WidgetState::handleButton(math::Vec pos, int button, int action, int mods) { | |||||
| void WidgetState::handleButton(Vec pos, int button, int action, int mods) { | |||||
| // event::Button | // event::Button | ||||
| event::Button eButton; | event::Button eButton; | ||||
| eButton.pos = pos; | eButton.pos = pos; | ||||
| @@ -74,7 +74,7 @@ void WidgetState::handleButton(math::Vec pos, int button, int action, int mods) | |||||
| } | } | ||||
| void WidgetState::handleHover(math::Vec pos, math::Vec mouseDelta) { | |||||
| void WidgetState::handleHover(Vec pos, Vec mouseDelta) { | |||||
| if (draggedWidget) { | if (draggedWidget) { | ||||
| // event::DragMove | // event::DragMove | ||||
| event::DragMove eDragMove; | event::DragMove eDragMove; | ||||
| @@ -148,7 +148,7 @@ void WidgetState::handleLeave() { | |||||
| hoveredWidget = NULL; | hoveredWidget = NULL; | ||||
| } | } | ||||
| void WidgetState::handleScroll(math::Vec pos, math::Vec scrollDelta) { | |||||
| void WidgetState::handleScroll(Vec pos, Vec scrollDelta) { | |||||
| // event::HoverScroll | // event::HoverScroll | ||||
| event::HoverScroll eHoverScroll; | event::HoverScroll eHoverScroll; | ||||
| eHoverScroll.pos = pos; | eHoverScroll.pos = pos; | ||||
| @@ -156,7 +156,7 @@ void WidgetState::handleScroll(math::Vec pos, math::Vec scrollDelta) { | |||||
| rootWidget->onHoverScroll(eHoverScroll); | rootWidget->onHoverScroll(eHoverScroll); | ||||
| } | } | ||||
| void WidgetState::handleDrop(math::Vec pos, std::vector<std::string> paths) { | |||||
| void WidgetState::handleDrop(Vec pos, std::vector<std::string> paths) { | |||||
| // event::PathDrop | // event::PathDrop | ||||
| event::PathDrop ePathDrop; | event::PathDrop ePathDrop; | ||||
| ePathDrop.pos = pos; | ePathDrop.pos = pos; | ||||
| @@ -164,7 +164,7 @@ void WidgetState::handleDrop(math::Vec pos, std::vector<std::string> paths) { | |||||
| rootWidget->onPathDrop(ePathDrop); | rootWidget->onPathDrop(ePathDrop); | ||||
| } | } | ||||
| void WidgetState::handleText(math::Vec pos, int codepoint) { | |||||
| void WidgetState::handleText(Vec pos, int codepoint) { | |||||
| if (selectedWidget) { | if (selectedWidget) { | ||||
| // event::SelectText | // event::SelectText | ||||
| event::SelectText eSelectText; | event::SelectText eSelectText; | ||||
| @@ -181,7 +181,7 @@ void WidgetState::handleText(math::Vec pos, int codepoint) { | |||||
| rootWidget->onHoverText(eHoverText); | rootWidget->onHoverText(eHoverText); | ||||
| } | } | ||||
| void WidgetState::handleKey(math::Vec pos, int key, int scancode, int action, int mods) { | |||||
| void WidgetState::handleKey(Vec pos, int key, int scancode, int action, int mods) { | |||||
| if (selectedWidget) { | if (selectedWidget) { | ||||
| // event::SelectKey | // event::SelectKey | ||||
| event::SelectKey eSelectKey; | event::SelectKey eSelectKey; | ||||
| @@ -107,13 +107,13 @@ struct AudioSampleRateChoice : LedDisplayChoice { | |||||
| AudioSampleRateItem *item = new AudioSampleRateItem; | AudioSampleRateItem *item = new AudioSampleRateItem; | ||||
| item->audioIO = audioWidget->audioIO; | item->audioIO = audioWidget->audioIO; | ||||
| item->sampleRate = sampleRate; | item->sampleRate = sampleRate; | ||||
| item->text = string::stringf("%d Hz", sampleRate); | |||||
| item->text = string::f("%d Hz", sampleRate); | |||||
| item->rightText = CHECKMARK(item->sampleRate == audioWidget->audioIO->sampleRate); | item->rightText = CHECKMARK(item->sampleRate == audioWidget->audioIO->sampleRate); | ||||
| menu->addChild(item); | menu->addChild(item); | ||||
| } | } | ||||
| } | } | ||||
| void step() override { | void step() override { | ||||
| text = string::stringf("%g kHz", audioWidget->audioIO->sampleRate / 1000.f); | |||||
| text = string::f("%g kHz", audioWidget->audioIO->sampleRate / 1000.f); | |||||
| } | } | ||||
| }; | }; | ||||
| @@ -140,21 +140,21 @@ struct AudioBlockSizeChoice : LedDisplayChoice { | |||||
| item->audioIO = audioWidget->audioIO; | item->audioIO = audioWidget->audioIO; | ||||
| item->blockSize = blockSize; | item->blockSize = blockSize; | ||||
| float latency = (float) blockSize / audioWidget->audioIO->sampleRate * 1000.0; | float latency = (float) blockSize / audioWidget->audioIO->sampleRate * 1000.0; | ||||
| item->text = string::stringf("%d (%.1f ms)", blockSize, latency); | |||||
| item->text = string::f("%d (%.1f ms)", blockSize, latency); | |||||
| item->rightText = CHECKMARK(item->blockSize == audioWidget->audioIO->blockSize); | item->rightText = CHECKMARK(item->blockSize == audioWidget->audioIO->blockSize); | ||||
| menu->addChild(item); | menu->addChild(item); | ||||
| } | } | ||||
| } | } | ||||
| void step() override { | void step() override { | ||||
| text = string::stringf("%d", audioWidget->audioIO->blockSize); | |||||
| text = string::f("%d", audioWidget->audioIO->blockSize); | |||||
| } | } | ||||
| }; | }; | ||||
| AudioWidget::AudioWidget() { | AudioWidget::AudioWidget() { | ||||
| box.size = mm2px(math::Vec(44, 28)); | |||||
| box.size = mm2px(Vec(44, 28)); | |||||
| math::Vec pos = math::Vec(); | |||||
| Vec pos = Vec(); | |||||
| AudioDriverChoice *driverChoice = createWidget<AudioDriverChoice>(pos); | AudioDriverChoice *driverChoice = createWidget<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); | ||||
| math::Vec center = box.size.div(2.0); | |||||
| 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(event::DragMove &e) { | |||||
| if (windowIsModPressed()) | if (windowIsModPressed()) | ||||
| delta /= 16.f; | delta /= 16.f; | ||||
| dragValue += delta; | dragValue += delta; | ||||
| dragValue = math::clampBetween(dragValue, minValue, maxValue); | |||||
| dragValue = clampBetween(dragValue, minValue, maxValue); | |||||
| if (snap) | if (snap) | ||||
| setValue(std::round(dragValue)); | setValue(std::round(dragValue)); | ||||
| else | else | ||||
| @@ -18,7 +18,7 @@ void LedDisplay::draw(NVGcontext *vg) { | |||||
| LedDisplaySeparator::LedDisplaySeparator() { | LedDisplaySeparator::LedDisplaySeparator() { | ||||
| box.size = math::Vec(); | |||||
| box.size = Vec(); | |||||
| } | } | ||||
| void LedDisplaySeparator::draw(NVGcontext *vg) { | void LedDisplaySeparator::draw(NVGcontext *vg) { | ||||
| @@ -32,10 +32,10 @@ void LedDisplaySeparator::draw(NVGcontext *vg) { | |||||
| LedDisplayChoice::LedDisplayChoice() { | LedDisplayChoice::LedDisplayChoice() { | ||||
| box.size = mm2px(math::Vec(0, 28.0 / 3)); | |||||
| box.size = mm2px(Vec(0, 28.0 / 3)); | |||||
| font = Font::load(asset::global("res/fonts/ShareTechMono-Regular.ttf")); | font = Font::load(asset::global("res/fonts/ShareTechMono-Regular.ttf")); | ||||
| color = nvgRGB(0xff, 0xd7, 0x14); | color = nvgRGB(0xff, 0xd7, 0x14); | ||||
| textOffset = math::Vec(10, 18); | |||||
| textOffset = Vec(10, 18); | |||||
| } | } | ||||
| void LedDisplayChoice::draw(NVGcontext *vg) { | void LedDisplayChoice::draw(NVGcontext *vg) { | ||||
| @@ -65,7 +65,7 @@ void LedDisplayChoice::onButton(event::Button &e) { | |||||
| LedDisplayTextField::LedDisplayTextField() { | LedDisplayTextField::LedDisplayTextField() { | ||||
| font = Font::load(asset::global("res/fonts/ShareTechMono-Regular.ttf")); | font = Font::load(asset::global("res/fonts/ShareTechMono-Regular.ttf")); | ||||
| color = nvgRGB(0xff, 0xd7, 0x14); | color = nvgRGB(0xff, 0xd7, 0x14); | ||||
| textOffset = math::Vec(5, 5); | |||||
| textOffset = Vec(5, 5); | |||||
| } | } | ||||
| @@ -96,7 +96,7 @@ void LedDisplayTextField::draw(NVGcontext *vg) { | |||||
| nvgResetScissor(vg); | nvgResetScissor(vg); | ||||
| } | } | ||||
| int LedDisplayTextField::getTextPosition(math::Vec mousePos) { | |||||
| int LedDisplayTextField::getTextPosition(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, | ||||
| @@ -111,9 +111,9 @@ struct MidiChannelChoice : LedDisplayChoice { | |||||
| MidiWidget::MidiWidget() { | MidiWidget::MidiWidget() { | ||||
| box.size = mm2px(math::Vec(44, 28)); | |||||
| box.size = mm2px(Vec(44, 28)); | |||||
| math::Vec pos = math::Vec(); | |||||
| Vec pos = Vec(); | |||||
| MidiDriverChoice *driverChoice = createWidget<MidiDriverChoice>(pos); | MidiDriverChoice *driverChoice = createWidget<MidiDriverChoice>(pos); | ||||
| driverChoice->midiWidget = this; | driverChoice->midiWidget = this; | ||||
| @@ -58,7 +58,7 @@ struct SeparatorItem : OpaqueWidget { | |||||
| void setText(std::string text) { | void setText(std::string text) { | ||||
| clearChildren(); | clearChildren(); | ||||
| Label *label = createWidget<Label>(math::Vec(0, 12 + itemMargin)); | |||||
| Label *label = createWidget<Label>(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; | ||||
| @@ -109,7 +109,7 @@ struct ModelItem : BrowserListItem { | |||||
| assert(model); | assert(model); | ||||
| this->model = model; | this->model = model; | ||||
| FavoriteRadioButton *favoriteButton = createWidget<FavoriteRadioButton>(math::Vec(8, itemMargin)); | |||||
| FavoriteRadioButton *favoriteButton = createWidget<FavoriteRadioButton>(Vec(8, itemMargin)); | |||||
| favoriteButton->box.size.x = 20; | favoriteButton->box.size.x = 20; | ||||
| favoriteButton->label = "★"; | favoriteButton->label = "★"; | ||||
| addChild(favoriteButton); | addChild(favoriteButton); | ||||
| @@ -124,7 +124,7 @@ struct ModelItem : BrowserListItem { | |||||
| nameLabel->text = model->name; | nameLabel->text = model->name; | ||||
| addChild(nameLabel); | addChild(nameLabel); | ||||
| pluginLabel = createWidget<Label>(math::Vec(0, itemMargin)); | |||||
| pluginLabel = createWidget<Label>(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; | ||||
| @@ -155,7 +155,7 @@ struct AuthorItem : BrowserListItem { | |||||
| void setAuthor(std::string author) { | void setAuthor(std::string author) { | ||||
| clearChildren(); | clearChildren(); | ||||
| this->author = author; | this->author = author; | ||||
| Label *authorLabel = createWidget<Label>(math::Vec(0, 0 + itemMargin)); | |||||
| Label *authorLabel = createWidget<Label>(Vec(0, 0 + itemMargin)); | |||||
| if (author.empty()) | if (author.empty()) | ||||
| authorLabel->text = "Show all modules"; | authorLabel->text = "Show all modules"; | ||||
| else | else | ||||
| @@ -173,7 +173,7 @@ struct TagItem : BrowserListItem { | |||||
| void setTag(ModelTag tag) { | void setTag(ModelTag tag) { | ||||
| clearChildren(); | clearChildren(); | ||||
| this->tag = tag; | this->tag = tag; | ||||
| Label *tagLabel = createWidget<Label>(math::Vec(0, 0 + itemMargin)); | |||||
| Label *tagLabel = createWidget<Label>(Vec(0, 0 + itemMargin)); | |||||
| if (tag == NO_TAG) | if (tag == NO_TAG) | ||||
| tagLabel->text = "Show all tags"; | tagLabel->text = "Show all tags"; | ||||
| else | else | ||||
| @@ -187,7 +187,7 @@ struct TagItem : BrowserListItem { | |||||
| struct ClearFilterItem : BrowserListItem { | struct ClearFilterItem : BrowserListItem { | ||||
| ClearFilterItem() { | ClearFilterItem() { | ||||
| Label *label = createWidget<Label>(math::Vec(0, 0 + itemMargin)); | |||||
| Label *label = createWidget<Label>(Vec(0, 0 + itemMargin)); | |||||
| label->text = "Back"; | label->text = "Back"; | ||||
| addChild(label); | addChild(label); | ||||
| } | } | ||||
| @@ -215,7 +215,7 @@ struct BrowserList : List { | |||||
| void incrementSelection(int delta) { | void incrementSelection(int delta) { | ||||
| selected += delta; | selected += delta; | ||||
| selected = math::clamp(selected, 0, countItems() - 1); | |||||
| selected = clamp(selected, 0, countItems() - 1); | |||||
| } | } | ||||
| int countItems() { | int countItems() { | ||||
| @@ -296,7 +296,7 @@ struct ModuleBrowser : OpaqueWidget { | |||||
| addChild(searchField); | addChild(searchField); | ||||
| moduleList = new BrowserList; | moduleList = new BrowserList; | ||||
| moduleList->box.size = math::Vec(box.size.x, 0.0); | |||||
| moduleList->box.size = 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 = math::clamp(value, 0.f, 1.f); | |||||
| value = clamp(value, 0.f, 1.f); | |||||
| values[i] = value; | values[i] = value; | ||||
| } | } | ||||
| setValues(values); | setValues(values); | ||||
| @@ -199,7 +199,7 @@ void ModuleWidget::load(std::string filename) { | |||||
| json_decref(moduleJ); | json_decref(moduleJ); | ||||
| } | } | ||||
| else { | else { | ||||
| std::string message = string::stringf("JSON parsing error at %s %d:%d %s", error.source, error.line, error.column, error.text); | |||||
| std::string message = string::f("JSON parsing error at %s %d:%d %s", error.source, error.line, error.column, error.text); | |||||
| osdialog_message(OSDIALOG_WARNING, OSDIALOG_OK, message.c_str()); | osdialog_message(OSDIALOG_WARNING, OSDIALOG_OK, message.c_str()); | ||||
| } | } | ||||
| @@ -300,13 +300,13 @@ void ModuleWidget::draw(NVGcontext *vg) { | |||||
| nvgFillColor(vg, nvgRGBAf(0, 0, 0, 0.5)); | nvgFillColor(vg, nvgRGBAf(0, 0, 0, 0.5)); | ||||
| nvgFill(vg); | nvgFill(vg); | ||||
| std::string cpuText = string::stringf("%.0f mS", module->cpuTime * 1000.f); | |||||
| std::string cpuText = string::f("%.0f mS", module->cpuTime * 1000.f); | |||||
| nvgFontFaceId(vg, gGuiFont->handle); | nvgFontFaceId(vg, gGuiFont->handle); | ||||
| nvgFontSize(vg, 12); | nvgFontSize(vg, 12); | ||||
| 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 = math::clamp(module->cpuTime, 0.f, 1.f); | |||||
| float p = 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, | ||||
| @@ -322,7 +322,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 | ||||
| math::Vec b = math::Vec(-10, 30); // Offset from each corner | |||||
| Vec b = Vec(-10, 30); // Offset from each corner | |||||
| nvgRect(vg, b.x - r, b.y - r, box.size.x - 2*b.x + 2*r, box.size.y - 2*b.y + 2*r); | 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); | ||||
| @@ -411,7 +411,7 @@ void ModuleWidget::onDragEnd(event::DragEnd &e) { | |||||
| void ModuleWidget::onDragMove(event::DragMove &e) { | void ModuleWidget::onDragMove(event::DragMove &e) { | ||||
| if (!gRackWidget->lockModules) { | if (!gRackWidget->lockModules) { | ||||
| math::Rect newBox = box; | |||||
| Rect newBox = box; | |||||
| newBox.pos = gRackWidget->lastMousePos.minus(dragPos); | newBox.pos = gRackWidget->lastMousePos.minus(dragPos); | ||||
| gRackWidget->requestModuleBoxNearest(this, newBox); | gRackWidget->requestModuleBoxNearest(this, newBox); | ||||
| } | } | ||||
| @@ -14,7 +14,7 @@ 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 *= math::clamp(values[i], 0.f, 1.f); | |||||
| c.a *= clamp(values[i], 0.f, 1.f); | |||||
| color = color::screen(color, c); | color = color::screen(color, c); | ||||
| } | } | ||||
| color = color::clip(color); | color = color::clip(color); | ||||
| @@ -32,7 +32,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(math::rescale(random::uniform(), 0.f, 1.f, minValue, maxValue)); | |||||
| setValue(rescale(random::uniform(), 0.f, 1.f, minValue, maxValue)); | |||||
| } | } | ||||
| } | } | ||||
| @@ -125,7 +125,7 @@ PluginManagerWidget::PluginManagerWidget() { | |||||
| box.size.y = BND_WIDGET_HEIGHT; | box.size.y = BND_WIDGET_HEIGHT; | ||||
| { | { | ||||
| SequentialLayout *layout = createWidget<SequentialLayout>(math::Vec(0, 0)); | |||||
| SequentialLayout *layout = createWidget<SequentialLayout>(Vec(0, 0)); | |||||
| layout->spacing = 5; | layout->spacing = 5; | ||||
| loginWidget = layout; | loginWidget = layout; | ||||
| @@ -158,7 +158,7 @@ PluginManagerWidget::PluginManagerWidget() { | |||||
| } | } | ||||
| { | { | ||||
| SequentialLayout *layout = createWidget<SequentialLayout>(math::Vec(0, 0)); | |||||
| SequentialLayout *layout = createWidget<SequentialLayout>(Vec(0, 0)); | |||||
| layout->spacing = 5; | layout->spacing = 5; | ||||
| manageWidget = layout; | manageWidget = layout; | ||||
| @@ -181,7 +181,7 @@ PluginManagerWidget::PluginManagerWidget() { | |||||
| } | } | ||||
| { | { | ||||
| SequentialLayout *layout = createWidget<SequentialLayout>(math::Vec(0, 0)); | |||||
| SequentialLayout *layout = createWidget<SequentialLayout>(Vec(0, 0)); | |||||
| layout->spacing = 5; | layout->spacing = 5; | ||||
| downloadWidget = layout; | downloadWidget = layout; | ||||
| @@ -11,7 +11,7 @@ struct PlugLight : MultiLightWidget { | |||||
| PlugLight() { | PlugLight() { | ||||
| addBaseColor(color::GREEN); | addBaseColor(color::GREEN); | ||||
| addBaseColor(color::RED); | addBaseColor(color::RED); | ||||
| box.size = math::Vec(8, 8); | |||||
| box.size = Vec(8, 8); | |||||
| bgColor = color::BLACK_TRANSPARENT; | bgColor = color::BLACK_TRANSPARENT; | ||||
| } | } | ||||
| }; | }; | ||||
| @@ -32,7 +32,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(math::Vec(500, 500)) | |||||
| .plus(Vec(500, 500)) | |||||
| .div(zoomWidget->zoom); | .div(zoomWidget->zoom); | ||||
| Scene::step(); | Scene::step(); | ||||
| @@ -41,7 +41,7 @@ void RackScene::step() { | |||||
| // Version popup message | // Version popup message | ||||
| if (!gLatestVersion.empty()) { | if (!gLatestVersion.empty()) { | ||||
| std::string versionMessage = string::stringf("Rack %s is available.\n\nYou have Rack %s.\n\nClose Rack and download new version on the website?", gLatestVersion.c_str(), gApplicationVersion.c_str()); | |||||
| std::string versionMessage = string::f("Rack %s is available.\n\nYou have Rack %s.\n\nClose Rack and download new version on the website?", gLatestVersion.c_str(), gApplicationVersion.c_str()); | |||||
| if (osdialog_message(OSDIALOG_INFO, OSDIALOG_OK_CANCEL, versionMessage.c_str())) { | if (osdialog_message(OSDIALOG_INFO, OSDIALOG_OK_CANCEL, versionMessage.c_str())) { | ||||
| std::thread t(system::openBrowser, "https://vcvrack.com/"); | std::thread t(system::openBrowser, "https://vcvrack.com/"); | ||||
| t.detach(); | t.detach(); | ||||
| @@ -6,8 +6,8 @@ namespace rack { | |||||
| void RackScrollWidget::step() { | void RackScrollWidget::step() { | ||||
| math::Vec pos = gMousePos; | |||||
| math::Rect viewport = getViewport(box.zeroPos()); | |||||
| Vec pos = gMousePos; | |||||
| Rect viewport = getViewport(box.zeroPos()); | |||||
| // Scroll rack if dragging cable near the edge of the screen | // 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; | ||||
| @@ -28,11 +28,11 @@ struct ModuleContainer : Widget { | |||||
| RackWidget::RackWidget() { | RackWidget::RackWidget() { | ||||
| rails = new FramebufferWidget; | rails = new FramebufferWidget; | ||||
| rails->box.size = math::Vec(); | |||||
| rails->box.size = Vec(); | |||||
| rails->oversample = 1.0; | rails->oversample = 1.0; | ||||
| { | { | ||||
| RackRail *rail = new RackRail; | RackRail *rail = new RackRail; | ||||
| rail->box.size = math::Vec(); | |||||
| rail->box.size = Vec(); | |||||
| rails->addChild(rail); | rails->addChild(rail); | ||||
| } | } | ||||
| addChild(rails); | addChild(rails); | ||||
| @@ -52,7 +52,7 @@ void RackWidget::clear() { | |||||
| wireContainer->clearChildren(); | wireContainer->clearChildren(); | ||||
| moduleContainer->clearChildren(); | moduleContainer->clearChildren(); | ||||
| gRackScene->scrollWidget->offset = math::Vec(0, 0); | |||||
| gRackScene->scrollWidget->offset = Vec(0, 0); | |||||
| } | } | ||||
| void RackWidget::reset() { | void RackWidget::reset() { | ||||
| @@ -151,7 +151,7 @@ void RackWidget::load(std::string filename) { | |||||
| json_decref(rootJ); | json_decref(rootJ); | ||||
| } | } | ||||
| else { | else { | ||||
| std::string message = string::stringf("JSON parsing error at %s %d:%d %s", error.source, error.line, error.column, error.text); | |||||
| std::string message = string::f("JSON parsing error at %s %d:%d %s", error.source, error.line, error.column, error.text); | |||||
| osdialog_message(OSDIALOG_WARNING, OSDIALOG_OK, message.c_str()); | osdialog_message(OSDIALOG_WARNING, OSDIALOG_OK, message.c_str()); | ||||
| } | } | ||||
| @@ -198,7 +198,7 @@ json_t *RackWidget::toJson() { | |||||
| json_t *moduleJ = moduleWidget->toJson(); | json_t *moduleJ = moduleWidget->toJson(); | ||||
| { | { | ||||
| // pos | // pos | ||||
| math::Vec pos = moduleWidget->box.pos.div(RACK_GRID_SIZE).round(); | |||||
| Vec pos = moduleWidget->box.pos.div(RACK_GRID_SIZE).round(); | |||||
| json_t *posJ = json_pack("[i, i]", (int) pos.x, (int) pos.y); | json_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); | ||||
| } | } | ||||
| @@ -281,7 +281,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); | ||||
| math::Vec pos = math::Vec(x, y); | |||||
| Vec pos = Vec(x, y); | |||||
| if (legacy && legacy <= 1) { | if (legacy && legacy <= 1) { | ||||
| moduleWidget->box.pos = pos; | moduleWidget->box.pos = pos; | ||||
| } | } | ||||
| @@ -296,7 +296,7 @@ void RackWidget::fromJson(json_t *rootJ) { | |||||
| json_t *modelSlugJ = json_object_get(moduleJ, "model"); | json_t *modelSlugJ = json_object_get(moduleJ, "model"); | ||||
| std::string pluginSlug = json_string_value(pluginSlugJ); | std::string pluginSlug = json_string_value(pluginSlugJ); | ||||
| std::string modelSlug = json_string_value(modelSlugJ); | std::string modelSlug = json_string_value(modelSlugJ); | ||||
| message += string::stringf("Could not find module \"%s\" of plugin \"%s\"\n", modelSlug.c_str(), pluginSlug.c_str()); | |||||
| message += string::f("Could not find module \"%s\" of plugin \"%s\"\n", modelSlug.c_str(), pluginSlug.c_str()); | |||||
| } | } | ||||
| } | } | ||||
| @@ -395,7 +395,7 @@ void RackWidget::pastePresetClipboard() { | |||||
| if (moduleJ) { | if (moduleJ) { | ||||
| ModuleWidget *moduleWidget = moduleFromJson(moduleJ); | ModuleWidget *moduleWidget = moduleFromJson(moduleJ); | ||||
| // Set moduleWidget position | // Set moduleWidget position | ||||
| math::Rect newBox = moduleWidget->box; | |||||
| 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); | ||||
| @@ -421,12 +421,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); | ||||
| math::Rect clonedBox = clonedModuleWidget->box; | |||||
| 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, math::Rect box) { | |||||
| bool RackWidget::requestModuleBox(ModuleWidget *m, Rect box) { | |||||
| if (box.pos.x < 0 || box.pos.y < 0) | if (box.pos.x < 0 || box.pos.y < 0) | ||||
| return false; | return false; | ||||
| @@ -440,25 +440,25 @@ bool RackWidget::requestModuleBox(ModuleWidget *m, math::Rect box) { | |||||
| return true; | return true; | ||||
| } | } | ||||
| bool RackWidget::requestModuleBoxNearest(ModuleWidget *m, math::Rect box) { | |||||
| bool RackWidget::requestModuleBoxNearest(ModuleWidget *m, 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<math::Vec> positions; | |||||
| std::vector<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(math::Vec(x * RACK_GRID_WIDTH, y * RACK_GRID_HEIGHT)); | |||||
| positions.push_back(Vec(x * RACK_GRID_WIDTH, y * RACK_GRID_HEIGHT)); | |||||
| } | } | ||||
| } | } | ||||
| // Sort possible positions by distance to the requested position | // Sort possible positions by distance to the requested position | ||||
| std::sort(positions.begin(), positions.end(), [box](math::Vec a, math::Vec b) { | |||||
| std::sort(positions.begin(), positions.end(), [box](Vec a, Vec b) { | |||||
| return a.minus(box.pos).norm() < b.minus(box.pos).norm(); | 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 (math::Vec position : positions) { | |||||
| math::Rect newBox = box; | |||||
| for (Vec position : positions) { | |||||
| Rect newBox = box; | |||||
| newBox.pos = position; | newBox.pos = position; | ||||
| if (requestModuleBox(m, newBox)) | if (requestModuleBox(m, newBox)) | ||||
| return true; | return true; | ||||
| @@ -468,15 +468,15 @@ bool RackWidget::requestModuleBoxNearest(ModuleWidget *m, math::Rect box) { | |||||
| void RackWidget::step() { | void RackWidget::step() { | ||||
| // Expand size to fit modules | // Expand size to fit modules | ||||
| math::Vec moduleSize = moduleContainer->getChildrenBoundingBox().getBottomRight(); | |||||
| Vec moduleSize = moduleContainer->getChildrenBoundingBox().getBottomRight(); | |||||
| // We assume that the size is reset by a parent before calling step(). Otherwise it will grow unbounded. | // 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(); | ||||
| math::Rect bound = getViewport(math::Rect(math::Vec(), box.size)); | |||||
| Rect bound = getViewport(Rect(Vec(), box.size)); | |||||
| if (!rails->box.contains(bound)) { | if (!rails->box.contains(bound)) { | ||||
| math::Vec cellMargin = math::Vec(20, 1); | |||||
| Vec cellMargin = Vec(20, 1); | |||||
| rails->box.pos = bound.pos.div(RACK_GRID_SIZE).floor().minus(cellMargin).mult(RACK_GRID_SIZE); | rails->box.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; | ||||
| @@ -512,7 +512,7 @@ void RackWidget::onButton(event::Button &e) { | |||||
| } | } | ||||
| void RackWidget::onZoom(event::Zoom &e) { | void RackWidget::onZoom(event::Zoom &e) { | ||||
| rails->box.size = math::Vec(); | |||||
| rails->box.size = Vec(); | |||||
| OpaqueWidget::onZoom(e); | OpaqueWidget::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 = math::Vec(); | |||||
| shadow->box.size = 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 = math::Vec(0, sw->box.size.y * 0.1); | |||||
| // shadow->box = shadow->box.grow(math::Vec(2, 2)); | |||||
| shadow->box.pos = Vec(0, sw->box.size.y * 0.1); | |||||
| // shadow->box = shadow->box.grow(Vec(2, 2)); | |||||
| } | } | ||||
| void SVGKnob::step() { | 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 = math::rescale(value, minValue, maxValue, minAngle, maxAngle); | |||||
| angle = rescale(value, minValue, maxValue, minAngle, maxAngle); | |||||
| } | } | ||||
| else { | else { | ||||
| angle = math::rescale(value, -1.0, 1.0, minAngle, maxAngle); | |||||
| angle = rescale(value, -1.0, 1.0, minAngle, maxAngle); | |||||
| angle = std::fmod(angle, 2*M_PI); | angle = std::fmod(angle, 2*M_PI); | ||||
| } | } | ||||
| tw->identity(); | tw->identity(); | ||||
| // Rotate SVG | // Rotate SVG | ||||
| math::Vec center = sw->box.getCenter(); | |||||
| 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()); | ||||
| @@ -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 = math::Vec(); | |||||
| shadow->box.size = 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 = math::Vec(0, background->box.size.y * 0.1); | |||||
| // shadow->box = shadow->box.grow(math::Vec(2, 2)); | |||||
| shadow->box.pos = Vec(0, background->box.size.y * 0.1); | |||||
| // shadow->box = shadow->box.grow(Vec(2, 2)); | |||||
| } | } | ||||
| void SVGPort::draw(NVGcontext *vg) { | 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 = math::Vec(math::rescale(value, minValue, maxValue, minHandlePos.x, maxHandlePos.x), math::rescale(value, minValue, maxValue, minHandlePos.y, maxHandlePos.y)); | |||||
| handle->box.pos = Vec(rescale(value, minValue, maxValue, minHandlePos.x, maxHandlePos.x), rescale(value, minValue, maxValue, minHandlePos.y, maxHandlePos.y)); | |||||
| } | } | ||||
| FramebufferWidget::step(); | FramebufferWidget::step(); | ||||
| } | } | ||||
| @@ -20,8 +20,8 @@ void SVGSwitch::addFrame(std::shared_ptr<SVG> svg) { | |||||
| void SVGSwitch::onChange(event::Change &e) { | void SVGSwitch::onChange(event::Change &e) { | ||||
| assert(frames.size() > 0); | assert(frames.size() > 0); | ||||
| float valueScaled = math::rescale(value, minValue, maxValue, 0, frames.size() - 1); | |||||
| int index = math::clamp((int) roundf(valueScaled), 0, (int) frames.size() - 1); | |||||
| float valueScaled = rescale(value, minValue, maxValue, 0, frames.size() - 1); | |||||
| int index = clamp((int) roundf(valueScaled), 0, (int) frames.size() - 1); | |||||
| sw->setSVG(frames[index]); | sw->setSVG(frames[index]); | ||||
| dirty = true; | dirty = true; | ||||
| ParamWidget::onChange(e); | ParamWidget::onChange(e); | ||||
| @@ -14,7 +14,7 @@ struct TooltipIconButton : IconButton { | |||||
| void onEnter(event::Enter &e) override { | void onEnter(event::Enter &e) override { | ||||
| if (!tooltip) { | if (!tooltip) { | ||||
| tooltip = new Tooltip; | tooltip = new Tooltip; | ||||
| tooltip->box.pos = getAbsoluteOffset(math::Vec(0, BND_WIDGET_HEIGHT)); | |||||
| tooltip->box.pos = getAbsoluteOffset(Vec(0, BND_WIDGET_HEIGHT)); | |||||
| tooltip->text = tooltipText; | tooltip->text = tooltipText; | ||||
| gRackScene->addChild(tooltip); | gRackScene->addChild(tooltip); | ||||
| } | } | ||||
| @@ -121,7 +121,7 @@ struct SampleRateButton : TooltipIconButton { | |||||
| } | } | ||||
| void onAction(event::Action &e) override { | void onAction(event::Action &e) override { | ||||
| Menu *menu = createMenu(); | Menu *menu = createMenu(); | ||||
| menu->box.pos = getAbsoluteOffset(math::Vec(0, box.size.y)); | |||||
| menu->box.pos = getAbsoluteOffset(Vec(0, box.size.y)); | |||||
| menu->box.size.x = box.size.x; | menu->box.size.x = box.size.x; | ||||
| menu->addChild(createMenuLabel("Engine sample rate")); | menu->addChild(createMenuLabel("Engine sample rate")); | ||||
| @@ -133,7 +133,7 @@ struct SampleRateButton : TooltipIconButton { | |||||
| std::vector<float> sampleRates = {44100, 48000, 88200, 96000, 176400, 192000}; | std::vector<float> sampleRates = {44100, 48000, 88200, 96000, 176400, 192000}; | ||||
| for (float sampleRate : sampleRates) { | for (float sampleRate : sampleRates) { | ||||
| SampleRateItem *item = new SampleRateItem; | SampleRateItem *item = new SampleRateItem; | ||||
| item->text = string::stringf("%.0f Hz", sampleRate); | |||||
| item->text = string::f("%.0f Hz", sampleRate); | |||||
| item->rightText = CHECKMARK(engineGetSampleRate() == sampleRate); | item->rightText = CHECKMARK(engineGetSampleRate() == sampleRate); | ||||
| item->sampleRate = sampleRate; | item->sampleRate = sampleRate; | ||||
| menu->addChild(item); | menu->addChild(item); | ||||
| @@ -163,7 +163,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 = math::Vec(5, 5); | |||||
| layout->box.pos = Vec(5, 5); | |||||
| layout->spacing = 5; | layout->spacing = 5; | ||||
| addChild(layout); | addChild(layout); | ||||
| @@ -7,7 +7,7 @@ | |||||
| namespace rack { | namespace rack { | ||||
| static void drawPlug(NVGcontext *vg, math::Vec pos, NVGcolor color) { | |||||
| static void drawPlug(NVGcontext *vg, Vec pos, NVGcolor color) { | |||||
| NVGcolor colorOutline = nvgLerpRGBA(color, nvgRGBf(0.0, 0.0, 0.0), 0.5); | NVGcolor colorOutline = nvgLerpRGBA(color, nvgRGBf(0.0, 0.0, 0.0), 0.5); | ||||
| // Plug solid | // Plug solid | ||||
| @@ -28,7 +28,7 @@ static void drawPlug(NVGcontext *vg, math::Vec pos, NVGcolor color) { | |||||
| nvgFill(vg); | nvgFill(vg); | ||||
| } | } | ||||
| static void drawWire(NVGcontext *vg, math::Vec pos1, math::Vec pos2, NVGcolor color, float tension, float opacity) { | |||||
| static void drawWire(NVGcontext *vg, Vec pos1, Vec pos2, NVGcolor color, float tension, float opacity) { | |||||
| NVGcolor colorShadow = nvgRGBAf(0, 0, 0, 0.10); | NVGcolor 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); | ||||
| @@ -38,14 +38,14 @@ static void drawWire(NVGcontext *vg, math::Vec pos1, math::Vec pos2, NVGcolor co | |||||
| nvgGlobalAlpha(vg, powf(opacity, 1.5)); | nvgGlobalAlpha(vg, powf(opacity, 1.5)); | ||||
| float dist = pos1.minus(pos2).norm(); | float dist = pos1.minus(pos2).norm(); | ||||
| math::Vec slump; | |||||
| Vec slump; | |||||
| slump.y = (1.0 - tension) * (150.0 + 1.0*dist); | slump.y = (1.0 - tension) * (150.0 + 1.0*dist); | ||||
| math::Vec pos3 = pos1.plus(pos2).div(2).plus(slump); | |||||
| Vec pos3 = pos1.plus(pos2).div(2).plus(slump); | |||||
| nvgLineJoin(vg, NVG_ROUND); | nvgLineJoin(vg, NVG_ROUND); | ||||
| // Shadow | // Shadow | ||||
| math::Vec pos4 = pos3.plus(slump.mult(0.08)); | |||||
| 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); | ||||
| @@ -119,7 +119,7 @@ void WireWidget::updateWire() { | |||||
| } | } | ||||
| } | } | ||||
| math::Vec WireWidget::getOutputPos() { | |||||
| Vec WireWidget::getOutputPos() { | |||||
| if (outputPort) { | if (outputPort) { | ||||
| return outputPort->getRelativeOffset(outputPort->box.zeroPos().getCenter(), gRackWidget); | return outputPort->getRelativeOffset(outputPort->box.zeroPos().getCenter(), gRackWidget); | ||||
| } | } | ||||
| @@ -131,7 +131,7 @@ math::Vec WireWidget::getOutputPos() { | |||||
| } | } | ||||
| } | } | ||||
| math::Vec WireWidget::getInputPos() { | |||||
| Vec WireWidget::getInputPos() { | |||||
| if (inputPort) { | if (inputPort) { | ||||
| return inputPort->getRelativeOffset(inputPort->box.zeroPos().getCenter(), gRackWidget); | return inputPort->getRelativeOffset(inputPort->box.zeroPos().getCenter(), gRackWidget); | ||||
| } | } | ||||
| @@ -177,15 +177,15 @@ void WireWidget::draw(NVGcontext *vg) { | |||||
| opacity = 1.0; | opacity = 1.0; | ||||
| } | } | ||||
| math::Vec outputPos = getOutputPos(); | |||||
| math::Vec inputPos = getInputPos(); | |||||
| Vec outputPos = getOutputPos(); | |||||
| 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. | ||||
| math::Vec outputPos = getOutputPos(); | |||||
| math::Vec inputPos = getInputPos(); | |||||
| Vec outputPos = getOutputPos(); | |||||
| Vec inputPos = getInputPos(); | |||||
| drawPlug(vg, outputPos, color); | drawPlug(vg, outputPos, color); | ||||
| drawPlug(vg, inputPos, color); | drawPlug(vg, inputPos, color); | ||||
| @@ -122,7 +122,7 @@ std::string AudioIO::getDeviceName(int device) { | |||||
| return deviceInfo.name; | return deviceInfo.name; | ||||
| } | } | ||||
| else if (driver == BRIDGE_DRIVER) { | else if (driver == BRIDGE_DRIVER) { | ||||
| return string::stringf("%d", device + 1); | |||||
| return string::f("%d", device + 1); | |||||
| } | } | ||||
| return ""; | return ""; | ||||
| } | } | ||||
| @@ -134,19 +134,19 @@ std::string AudioIO::getDeviceDetail(int device, int offset) { | |||||
| if (rtAudio) { | if (rtAudio) { | ||||
| RtAudio::DeviceInfo deviceInfo; | RtAudio::DeviceInfo deviceInfo; | ||||
| if (getDeviceInfo(device, &deviceInfo)) { | if (getDeviceInfo(device, &deviceInfo)) { | ||||
| std::string deviceDetail = string::stringf("%s (", deviceInfo.name.c_str()); | |||||
| std::string deviceDetail = string::f("%s (", deviceInfo.name.c_str()); | |||||
| if (offset < (int) deviceInfo.inputChannels) | if (offset < (int) deviceInfo.inputChannels) | ||||
| deviceDetail += string::stringf("%d-%d in", offset + 1, std::min(offset + maxChannels, (int) deviceInfo.inputChannels)); | |||||
| deviceDetail += string::f("%d-%d in", offset + 1, std::min(offset + maxChannels, (int) deviceInfo.inputChannels)); | |||||
| if (offset < (int) deviceInfo.inputChannels && offset < (int) deviceInfo.outputChannels) | if (offset < (int) deviceInfo.inputChannels && offset < (int) deviceInfo.outputChannels) | ||||
| deviceDetail += ", "; | deviceDetail += ", "; | ||||
| if (offset < (int) deviceInfo.outputChannels) | if (offset < (int) deviceInfo.outputChannels) | ||||
| deviceDetail += string::stringf("%d-%d out", offset + 1, std::min(offset + maxChannels, (int) deviceInfo.outputChannels)); | |||||
| deviceDetail += string::f("%d-%d out", offset + 1, std::min(offset + maxChannels, (int) deviceInfo.outputChannels)); | |||||
| deviceDetail += ")"; | deviceDetail += ")"; | ||||
| return deviceDetail; | return deviceDetail; | ||||
| } | } | ||||
| } | } | ||||
| else if (driver == BRIDGE_DRIVER) { | else if (driver == BRIDGE_DRIVER) { | ||||
| return string::stringf("Port %d", device + 1); | |||||
| return string::f("Port %d", device + 1); | |||||
| } | } | ||||
| return ""; | return ""; | ||||
| } | } | ||||
| @@ -226,7 +226,7 @@ void AudioIO::openStream() { | |||||
| if (rtAudio->isStreamOpen()) | if (rtAudio->isStreamOpen()) | ||||
| return; | return; | ||||
| setChannels(math::clamp((int) deviceInfo.outputChannels - offset, 0, maxChannels), math::clamp((int) deviceInfo.inputChannels - offset, 0, maxChannels)); | |||||
| setChannels(clamp((int) deviceInfo.outputChannels - offset, 0, maxChannels), clamp((int) deviceInfo.inputChannels - offset, 0, maxChannels)); | |||||
| if (numOutputs == 0 && numInputs == 0) { | 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); | ||||
| @@ -383,7 +383,7 @@ std::vector<int> BridgeMidiDriver::getInputDeviceIds() { | |||||
| std::string BridgeMidiDriver::getInputDeviceName(int deviceId) { | std::string BridgeMidiDriver::getInputDeviceName(int deviceId) { | ||||
| if (deviceId < 0) | if (deviceId < 0) | ||||
| return ""; | return ""; | ||||
| return string::stringf("Port %d", deviceId + 1); | |||||
| return string::f("Port %d", deviceId + 1); | |||||
| } | } | ||||
| MidiInputDevice *BridgeMidiDriver::subscribeInputDevice(int deviceId, MidiInput *midiInput) { | MidiInputDevice *BridgeMidiDriver::subscribeInputDevice(int deviceId, MidiInput *midiInput) { | ||||
| @@ -22,8 +22,8 @@ void InputDevice::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 math::clamp at -127 instead of -128 for symmetry | |||||
| int8_t cc = math::clamp((int) std::round(axes[i] * 127), -127, 127); | |||||
| // Allow CC value to go negative, but clamp at -127 instead of -128 for symmetry | |||||
| int8_t cc = clamp((int) std::round(axes[i] * 127), -127, 127); | |||||
| if (cc != ccs[i]) { | if (cc != ccs[i]) { | ||||
| ccs[i] = cc; | ccs[i] = cc; | ||||
| @@ -78,7 +78,7 @@ std::string Driver::getInputDeviceName(int deviceId) { | |||||
| if (name) { | if (name) { | ||||
| return name; | return name; | ||||
| } | } | ||||
| return string::stringf(" %d (unavailable)", deviceId + 1); | |||||
| return string::f(" %d (unavailable)", deviceId + 1); | |||||
| } | } | ||||
| MidiInputDevice *Driver::subscribeInputDevice(int deviceId, MidiInput *midiInput) { | MidiInputDevice *Driver::subscribeInputDevice(int deviceId, MidiInput *midiInput) { | ||||
| @@ -61,7 +61,7 @@ void InputDevice::onKeyPress(int key) { | |||||
| default: break; | default: break; | ||||
| } | } | ||||
| octave = math::clamp(octave, 0, 9); | |||||
| octave = clamp(octave, 0, 9); | |||||
| if (note < 0) | if (note < 0) | ||||
| return; | return; | ||||
| @@ -80,7 +80,7 @@ std::string MidiIO::getChannelName(int channel) { | |||||
| if (channel == -1) | if (channel == -1) | ||||
| return "All channels"; | return "All channels"; | ||||
| else | else | ||||
| return string::stringf("Channel %d", channel + 1); | |||||
| return string::f("Channel %d", channel + 1); | |||||
| } | } | ||||
| json_t *MidiIO::toJson() { | json_t *MidiIO::toJson() { | ||||
| @@ -210,7 +210,7 @@ static void loadPlugins(std::string path) { | |||||
| if (!system::isDirectory(pluginPath)) | if (!system::isDirectory(pluginPath)) | ||||
| continue; | continue; | ||||
| if (!loadPlugin(pluginPath)) { | if (!loadPlugin(pluginPath)) { | ||||
| message += string::stringf("Could not load plugin %s\n", pluginPath.c_str()); | |||||
| message += string::f("Could not load plugin %s\n", pluginPath.c_str()); | |||||
| } | } | ||||
| } | } | ||||
| if (!message.empty()) { | if (!message.empty()) { | ||||
| @@ -298,7 +298,7 @@ static void extractPackages(std::string path) { | |||||
| // Extract package | // Extract package | ||||
| if (extractZip(packagePath.c_str(), path.c_str())) { | if (extractZip(packagePath.c_str(), path.c_str())) { | ||||
| WARN("Package %s failed to extract", packagePath.c_str()); | WARN("Package %s failed to extract", packagePath.c_str()); | ||||
| message += string::stringf("Could not extract package %s\n", packagePath.c_str()); | |||||
| message += string::f("Could not extract package %s\n", packagePath.c_str()); | |||||
| continue; | continue; | ||||
| } | } | ||||
| // Remove package | // Remove package | ||||
| @@ -20,12 +20,12 @@ static json_t *settingsToJson() { | |||||
| if (!windowIsMaximized()) { | if (!windowIsMaximized()) { | ||||
| // windowSize | // windowSize | ||||
| math::Vec windowSize = windowGetWindowSize(); | |||||
| 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 | ||||
| math::Vec windowPos = windowGetWindowPos(); | |||||
| 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); | ||||
| } | } | ||||
| @@ -85,7 +85,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(math::Vec(width, height)); | |||||
| windowSetWindowSize(Vec(width, height)); | |||||
| } | } | ||||
| // windowPos | // windowPos | ||||
| @@ -93,7 +93,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(math::Vec(x, y)); | |||||
| windowSetWindowPos(Vec(x, y)); | |||||
| } | } | ||||
| // opacity | // opacity | ||||
| @@ -109,7 +109,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(math::clamp((float) json_number_value(zoomJ), 0.25f, 4.0f)); | |||||
| gRackScene->zoomWidget->setZoom(clamp((float) json_number_value(zoomJ), 0.25f, 4.0f)); | |||||
| gToolbar->zoomSlider->setValue(json_number_value(zoomJ) * 100.0); | gToolbar->zoomSlider->setValue(json_number_value(zoomJ) * 100.0); | ||||
| } | } | ||||
| @@ -0,0 +1,75 @@ | |||||
| #include "string.hpp" | |||||
| namespace rack { | |||||
| namespace string { | |||||
| std::string f(const char *format, ...) { | |||||
| va_list args; | |||||
| va_start(args, format); | |||||
| // Compute size of required buffer | |||||
| int size = vsnprintf(NULL, 0, format, args); | |||||
| va_end(args); | |||||
| if (size < 0) | |||||
| return ""; | |||||
| // Create buffer | |||||
| std::string s; | |||||
| s.resize(size); | |||||
| va_start(args, format); | |||||
| vsnprintf(&s[0], size + 1, format, args); | |||||
| va_end(args); | |||||
| return s; | |||||
| } | |||||
| std::string lowercase(std::string s) { | |||||
| std::transform(s.begin(), s.end(), s.begin(), ::tolower); | |||||
| return s; | |||||
| } | |||||
| std::string uppercase(std::string s) { | |||||
| std::transform(s.begin(), s.end(), s.begin(), ::toupper); | |||||
| return s; | |||||
| } | |||||
| /** Truncates and adds "..." to a string, not exceeding `len` characters */ | |||||
| std::string ellipsize(std::string s, size_t len) { | |||||
| if (s.size() <= len) | |||||
| return s; | |||||
| else | |||||
| return s.substr(0, len - 3) + "..."; | |||||
| } | |||||
| bool startsWith(std::string str, std::string prefix) { | |||||
| return str.substr(0, prefix.size()) == prefix; | |||||
| } | |||||
| bool endsWith(std::string str, std::string suffix) { | |||||
| return str.substr(str.size() - suffix.size(), suffix.size()) == suffix; | |||||
| } | |||||
| /** Extracts portions of a path */ | |||||
| std::string directory(std::string path) { | |||||
| char *pathDup = strdup(path.c_str()); | |||||
| std::string directory = dirname(pathDup); | |||||
| free(pathDup); | |||||
| return directory; | |||||
| } | |||||
| std::string filename(std::string path) { | |||||
| char *pathDup = strdup(path.c_str()); | |||||
| std::string filename = basename(pathDup); | |||||
| free(pathDup); | |||||
| return filename; | |||||
| } | |||||
| std::string extension(std::string path) { | |||||
| const char *ext = strrchr(filename(path).c_str(), '.'); | |||||
| if (!ext) | |||||
| return ""; | |||||
| return ext + 1; | |||||
| } | |||||
| } // namespace network | |||||
| } // namespace rack | |||||
| @@ -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]);) | ||||
| math::Vec s, e; | |||||
| Vec s, e; | |||||
| DEBUG_ONLY(printf(" sx: %f sy: %f ex: %f ey: %f\n", s.x, s.y, e.x, e.y);) | 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(math::Vec p0, math::Vec p1, math::Vec p2, math::Vec p3) { | |||||
| math::Vec b = p2.minus(p0); | |||||
| math::Vec d = p1.minus(p0); | |||||
| math::Vec e = p3.minus(p2); | |||||
| static float getLineCrossing(Vec p0, Vec p1, Vec p2, Vec p3) { | |||||
| Vec b = p2.minus(p0); | |||||
| Vec d = p1.minus(p0); | |||||
| Vec e = p3.minus(p2); | |||||
| float m = d.x * e.y - d.y * e.x; | 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 @@ void svgDraw(NVGcontext *vg, NSVGimage *svg) { | |||||
| // Also assume that the topology is the same if we use straight lines rather than Beziers (not always the case but usually true). | // 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; | ||||
| math::Vec p0 = math::Vec(path->pts[0], path->pts[1]); | |||||
| math::Vec p1 = math::Vec(path->bounds[0] - 1.0, path->bounds[1] - 1.0); | |||||
| Vec p0 = Vec(path->pts[0], path->pts[1]); | |||||
| Vec p1 = Vec(path->bounds[0] - 1.0, path->bounds[1] - 1.0); | |||||
| // Iterate all other paths | // 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 @@ void svgDraw(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 | ||||
| math::Vec p2 = math::Vec(p[-2], p[-1]); | |||||
| Vec p2 = Vec(p[-2], p[-1]); | |||||
| // The current point | // The current point | ||||
| math::Vec p3 = (i < path2->npts) ? math::Vec(p[4], p[5]) : math::Vec(path2->pts[0], path2->pts[1]); | |||||
| Vec p3 = (i < path2->npts) ? Vec(p[4], p[5]) : Vec(path2->pts[0], path2->pts[1]); | |||||
| float crossing = getLineCrossing(p0, p1, p2, p3); | float 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 @@ void svgDraw(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; | ||||
| math::Vec p0 = math::Vec(path->pts[0], path->pts[1]); | |||||
| Vec p0 = Vec(path->pts[0], path->pts[1]); | |||||
| for (int i = 1; i < path->npts; i += 3) { | for (int i = 1; i < path->npts; i += 3) { | ||||
| float *p = &path->pts[2*i]; | float *p = &path->pts[2*i]; | ||||
| math::Vec p1 = (i < path->npts) ? math::Vec(p[4], p[5]) : math::Vec(path->pts[0], path->pts[1]); | |||||
| Vec p1 = (i < path->npts) ? Vec(p[4], p[5]) : Vec(path->pts[0], path->pts[1]); | |||||
| area += 0.5 * (p1.x - p0.x) * (p1.y + p0.y); | 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; | ||||
| @@ -8,7 +8,7 @@ namespace rack { | |||||
| struct FramebufferWidget::Internal { | struct FramebufferWidget::Internal { | ||||
| NVGLUframebuffer *fb = NULL; | NVGLUframebuffer *fb = NULL; | ||||
| math::Rect box; | |||||
| Rect box; | |||||
| ~Internal() { | ~Internal() { | ||||
| setFramebuffer(NULL); | setFramebuffer(NULL); | ||||
| @@ -41,10 +41,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); | ||||
| math::Vec s = math::Vec(xform[0], xform[3]); | |||||
| math::Vec b = math::Vec(xform[4], xform[5]); | |||||
| math::Vec bi = b.floor(); | |||||
| math::Vec bf = b.minus(bi); | |||||
| Vec s = Vec(xform[0], xform[3]); | |||||
| Vec b = Vec(xform[4], xform[5]); | |||||
| Vec bi = b.floor(); | |||||
| Vec bf = b.minus(bi); | |||||
| // Render to framebuffer | // Render to framebuffer | ||||
| if (dirty) { | if (dirty) { | ||||
| @@ -52,9 +52,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(math::Vec(1, 1)); | |||||
| internal->box.size = internal->box.size.mult(s).ceil().plus(Vec(1, 1)); | |||||
| math::Vec fbSize = internal->box.size.mult(gPixelRatio * oversample); | |||||
| Vec fbSize = internal->box.size.mult(gPixelRatio * oversample); | |||||
| if (!fbSize.isFinite()) | if (!fbSize.isFinite()) | ||||
| return; | return; | ||||
| @@ -13,8 +13,8 @@ Widget::~Widget() { | |||||
| clearChildren(); | clearChildren(); | ||||
| } | } | ||||
| math::Rect Widget::getChildrenBoundingBox() { | |||||
| math::Rect bound; | |||||
| Rect Widget::getChildrenBoundingBox() { | |||||
| Rect bound; | |||||
| for (Widget *child : children) { | for (Widget *child : children) { | ||||
| if (child == children.front()) { | if (child == children.front()) { | ||||
| bound = child->box; | bound = child->box; | ||||
| @@ -26,7 +26,7 @@ math::Rect Widget::getChildrenBoundingBox() { | |||||
| return bound; | return bound; | ||||
| } | } | ||||
| math::Vec Widget::getRelativeOffset(math::Vec v, Widget *relative) { | |||||
| Vec Widget::getRelativeOffset(Vec v, Widget *relative) { | |||||
| if (this == relative) { | if (this == relative) { | ||||
| return v; | return v; | ||||
| } | } | ||||
| @@ -37,8 +37,8 @@ math::Vec Widget::getRelativeOffset(math::Vec v, Widget *relative) { | |||||
| return v; | return v; | ||||
| } | } | ||||
| math::Rect Widget::getViewport(math::Rect r) { | |||||
| math::Rect bound; | |||||
| Rect Widget::getViewport(Rect r) { | |||||
| Rect bound; | |||||
| if (parent) { | if (parent) { | ||||
| bound = parent->getViewport(box); | bound = parent->getViewport(box); | ||||
| } | } | ||||
| @@ -41,7 +41,7 @@ float gPixelRatio = 1.0; | |||||
| float gWindowRatio = 1.0; | float gWindowRatio = 1.0; | ||||
| bool gAllowCursorLock = true; | bool gAllowCursorLock = true; | ||||
| int gGuiFrame; | int gGuiFrame; | ||||
| math::Vec gMousePos; | |||||
| Vec gMousePos; | |||||
| std::string lastWindowTitle; | std::string lastWindowTitle; | ||||
| @@ -86,15 +86,15 @@ void mouseButtonStickyCallback(GLFWwindow *window, int button, int action, int m | |||||
| } | } | ||||
| void cursorPosCallback(GLFWwindow* window, double xpos, double ypos) { | void cursorPosCallback(GLFWwindow* window, double xpos, double ypos) { | ||||
| math::Vec mousePos = math::Vec(xpos, ypos).div(gPixelRatio / gWindowRatio).round(); | |||||
| math::Vec mouseDelta = mousePos.minus(gMousePos); | |||||
| Vec mousePos = Vec(xpos, ypos).div(gPixelRatio / gWindowRatio).round(); | |||||
| Vec mouseDelta = mousePos.minus(gMousePos); | |||||
| int cursorMode = glfwGetInputMode(gWindow, GLFW_CURSOR); | 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 math::clamped. | |||||
| // This is not an ideal implementation. For example, if the user drags off the screen, the new mouse position will be clamped. | |||||
| if (cursorMode == GLFW_CURSOR_HIDDEN) { | if (cursorMode == GLFW_CURSOR_HIDDEN) { | ||||
| // CGSetLocalEventsSuppressionInterval(0.0); | // CGSetLocalEventsSuppressionInterval(0.0); | ||||
| glfwSetCursorPos(gWindow, gMousePos.x, gMousePos.y); | glfwSetCursorPos(gWindow, gMousePos.x, gMousePos.y); | ||||
| @@ -117,10 +117,10 @@ void cursorEnterCallback(GLFWwindow* window, int entered) { | |||||
| } | } | ||||
| void scrollCallback(GLFWwindow *window, double x, double y) { | void scrollCallback(GLFWwindow *window, double x, double y) { | ||||
| math::Vec scrollDelta = math::Vec(x, y); | |||||
| Vec scrollDelta = Vec(x, y); | |||||
| #if ARCH_LIN || ARCH_WIN | #if ARCH_LIN || ARCH_WIN | ||||
| if (windowIsShiftPressed()) | if (windowIsShiftPressed()) | ||||
| scrollDelta = math::Vec(y, x); | |||||
| scrollDelta = Vec(y, x); | |||||
| #endif | #endif | ||||
| scrollDelta = scrollDelta.mult(50.0); | scrollDelta = scrollDelta.mult(50.0); | ||||
| @@ -330,7 +330,7 @@ void windowRun() { | |||||
| glfwGetWindowSize(gWindow, &windowWidth, &windowHeight); | glfwGetWindowSize(gWindow, &windowWidth, &windowHeight); | ||||
| gWindowRatio = (float)width / windowWidth; | gWindowRatio = (float)width / windowWidth; | ||||
| gWidgetState->rootWidget->box.size = math::Vec(width, height).div(gPixelRatio); | |||||
| gWidgetState->rootWidget->box.size = Vec(width, height).div(gPixelRatio); | |||||
| // Step scene | // Step scene | ||||
| gWidgetState->rootWidget->step(); | gWidgetState->rootWidget->step(); | ||||
| @@ -385,25 +385,25 @@ bool windowIsShiftPressed() { | |||||
| return glfwGetKey(gWindow, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS || glfwGetKey(gWindow, GLFW_KEY_RIGHT_SHIFT) == GLFW_PRESS; | return glfwGetKey(gWindow, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS || glfwGetKey(gWindow, GLFW_KEY_RIGHT_SHIFT) == GLFW_PRESS; | ||||
| } | } | ||||
| math::Vec windowGetWindowSize() { | |||||
| Vec windowGetWindowSize() { | |||||
| int width, height; | int width, height; | ||||
| glfwGetWindowSize(gWindow, &width, &height); | glfwGetWindowSize(gWindow, &width, &height); | ||||
| return math::Vec(width, height); | |||||
| return Vec(width, height); | |||||
| } | } | ||||
| void windowSetWindowSize(math::Vec size) { | |||||
| void windowSetWindowSize(Vec size) { | |||||
| int width = size.x; | int width = size.x; | ||||
| int height = size.y; | int height = size.y; | ||||
| glfwSetWindowSize(gWindow, width, height); | glfwSetWindowSize(gWindow, width, height); | ||||
| } | } | ||||
| math::Vec windowGetWindowPos() { | |||||
| Vec windowGetWindowPos() { | |||||
| int x, y; | int x, y; | ||||
| glfwGetWindowPos(gWindow, &x, &y); | glfwGetWindowPos(gWindow, &x, &y); | ||||
| return math::Vec(x, y); | |||||
| return Vec(x, y); | |||||
| } | } | ||||
| void windowSetWindowPos(math::Vec pos) { | |||||
| void windowSetWindowPos(Vec pos) { | |||||
| int x = pos.x; | int x = pos.x; | ||||
| int y = pos.y; | int y = pos.y; | ||||
| glfwSetWindowPos(gWindow, x, y); | glfwSetWindowPos(gWindow, x, y); | ||||