diff --git a/include/app.hpp b/include/app.hpp index 7e1545d6..47ca2dda 100644 --- a/include/app.hpp +++ b/include/app.hpp @@ -218,6 +218,16 @@ struct ParamWidget : OpaqueWidget, QuantityWidget { virtual void randomize(); void onMouseDown(EventMouseDown &e) override; void onChange(EventChange &e) override; + + template + static T *create(Vec pos, Module *module, int paramId, float minValue, float maxValue, float defaultValue) { + T *o = Widget::create(pos); + o->module = module; + o->paramId = paramId; + o->setLimits(minValue, maxValue); + o->setDefaultValue(defaultValue); + return o; + } }; /** Implements vertical dragging behavior for ParamWidgets */ @@ -351,6 +361,14 @@ struct ModuleLightWidget : MultiLightWidget { Module *module = NULL; int firstLightId; void step() override; + + template + static T *create(Vec pos, Module *module, int firstLightId) { + T *o = Widget::create(pos); + o->module = module; + o->firstLightId = firstLightId; + return o; + } }; //////////////////// @@ -378,6 +396,24 @@ struct Port : OpaqueWidget { void onDragDrop(EventDragDrop &e) override; void onDragEnter(EventDragEnter &e) override; void onDragLeave(EventDragEnter &e) override; + + template + static T *createInput(Vec pos, Module *module, int portId) { + T *o = Widget::create(pos); + o->type = INPUT; + o->module = module; + o->portId = portId; + return o; + } + + template + static T *createOutput(Vec pos, Module *module, int portId) { + T *o = Widget::create(pos); + o->type = OUTPUT; + o->module = module; + o->portId = portId; + return o; + } }; struct SVGPort : Port, FramebufferWidget { diff --git a/include/rack.hpp b/include/rack.hpp index 027e3c50..4364f9fc 100644 --- a/include/rack.hpp +++ b/include/rack.hpp @@ -33,15 +33,17 @@ Model *createModel(std::string manufacturer, std::string slug, std::string name, return model; } +/** Deprecated, use Widget::create() instead */ template -TScrew *createScrew(Vec pos) { +DEPRECATED TScrew *createScrew(Vec pos) { TScrew *screw = new TScrew(); screw->box.pos = pos; return screw; } +/** Deprecated, use ParamWidget::create() instead */ template -TParamWidget *createParam(Vec pos, Module *module, int paramId, float minValue, float maxValue, float defaultValue) { +DEPRECATED TParamWidget *createParam(Vec pos, Module *module, int paramId, float minValue, float maxValue, float defaultValue) { TParamWidget *param = new TParamWidget(); param->box.pos = pos; param->module = module; @@ -51,8 +53,9 @@ TParamWidget *createParam(Vec pos, Module *module, int paramId, float minValue, return param; } +/** Deprecated, use Port::createInput() instead */ template -TPort *createInput(Vec pos, Module *module, int inputId) { +DEPRECATED TPort *createInput(Vec pos, Module *module, int inputId) { TPort *port = new TPort(); port->box.pos = pos; port->module = module; @@ -61,8 +64,9 @@ TPort *createInput(Vec pos, Module *module, int inputId) { return port; } +/** Deprecated, use Port::createInput() instead */ template -TPort *createOutput(Vec pos, Module *module, int outputId) { +DEPRECATED TPort *createOutput(Vec pos, Module *module, int outputId) { TPort *port = new TPort(); port->box.pos = pos; port->module = module; @@ -71,8 +75,9 @@ TPort *createOutput(Vec pos, Module *module, int outputId) { return port; } +/** Deprecated, use ModuleLightWidget::create() instead */ template -TModuleLightWidget *createLight(Vec pos, Module *module, int firstLightId) { +DEPRECATED TModuleLightWidget *createLight(Vec pos, Module *module, int firstLightId) { TModuleLightWidget *light = new TModuleLightWidget(); light->box.pos = pos; light->module = module; diff --git a/include/util/math.hpp b/include/util/math.hpp index 8ec9e068..f4b9f586 100644 --- a/include/util/math.hpp +++ b/include/util/math.hpp @@ -271,24 +271,24 @@ inline Vec Vec::clamp(Rect bound) { // Deprecated functions //////////////////// -inline int DEPRECATED mini(int a, int b) {return min(a, b);} -inline int DEPRECATED maxi(int a, int b) {return max(a, b);} -inline int DEPRECATED clampi(int x, int min, int max) {return clamp(x, min, max);} -inline int DEPRECATED absi(int a) {return abs(a);} -inline int DEPRECATED eucmodi(int a, int base) {return eucmod(a, base);} -inline int DEPRECATED log2i(int n) {return log2(n);} -inline bool DEPRECATED ispow2i(int n) {return ispow2(n);} -inline float DEPRECATED absf(float x) {return abs(x);} -inline float DEPRECATED sgnf(float x) {return sgn(x);} -inline float DEPRECATED eucmodf(float a, float base) {return eucmod(a, base);} -inline bool DEPRECATED nearf(float a, float b, float epsilon = 1.0e-6f) {return isNear(a, b, epsilon);} -inline float DEPRECATED clampf(float x, float min, float max) {return clamp(x, min, max);} -inline float DEPRECATED clamp2f(float x, float min, float max) {return clamp2(x, min, max);} -inline float DEPRECATED chopf(float x, float eps) {return chop(x, eps);} -inline float DEPRECATED rescalef(float x, float xMin, float xMax, float yMin, float yMax) {return rescale(x, xMin, xMax, yMin, yMax);} -inline float DEPRECATED crossf(float a, float b, float frac) {return crossfade(a, b, frac);} -inline float DEPRECATED interpf(const float *p, float x) {return interpolateLinear(p, x);} -inline void DEPRECATED cmultf(float *cr, float *ci, float ar, float ai, float br, float bi) {return cmult(cr, ci, ar, ai, br, bi);} +DEPRECATED inline int mini(int a, int b) {return min(a, b);} +DEPRECATED inline int maxi(int a, int b) {return max(a, b);} +DEPRECATED inline int clampi(int x, int min, int max) {return clamp(x, min, max);} +DEPRECATED inline int absi(int a) {return abs(a);} +DEPRECATED inline int eucmodi(int a, int base) {return eucmod(a, base);} +DEPRECATED inline int log2i(int n) {return log2(n);} +DEPRECATED inline bool ispow2i(int n) {return ispow2(n);} +DEPRECATED inline float absf(float x) {return abs(x);} +DEPRECATED inline float sgnf(float x) {return sgn(x);} +DEPRECATED inline float eucmodf(float a, float base) {return eucmod(a, base);} +DEPRECATED inline bool nearf(float a, float b, float epsilon = 1.0e-6f) {return isNear(a, b, epsilon);} +DEPRECATED inline float clampf(float x, float min, float max) {return clamp(x, min, max);} +DEPRECATED inline float clamp2f(float x, float min, float max) {return clamp2(x, min, max);} +DEPRECATED inline float chopf(float x, float eps) {return chop(x, eps);} +DEPRECATED inline float rescalef(float x, float xMin, float xMax, float yMin, float yMax) {return rescale(x, xMin, xMax, yMin, yMax);} +DEPRECATED inline float crossf(float a, float b, float frac) {return crossfade(a, b, frac);} +DEPRECATED inline float interpf(const float *p, float x) {return interpolateLinear(p, x);} +DEPRECATED inline void cmultf(float *cr, float *ci, float ar, float ai, float br, float bi) {return cmult(cr, ci, ar, ai, br, bi);} } // namespace rack diff --git a/include/widgets.hpp b/include/widgets.hpp index 50ea9ff5..832eeddd 100644 --- a/include/widgets.hpp +++ b/include/widgets.hpp @@ -139,6 +139,18 @@ struct Widget { virtual void onAction(EventAction &e) {} virtual void onChange(EventChange &e) {} virtual void onZoom(EventZoom &e); + + /** Helper function for creating and initializing a Widget with certain arguments (in this case just the position). + In this project, you will find this idiom everywhere, as an easier alternative to constructor arguments, for building a Widget (or a subclass) with a one-liner. + Example: + addChild(Widget::create(Vec(0, 0))) + */ + template + static T *create(Vec pos) { + T *o = new T(); + o->box.pos = pos; + return o; + } }; struct TransformWidget : Widget { diff --git a/src/core/AudioInterface.cpp b/src/core/AudioInterface.cpp index 994a16bf..e986caeb 100644 --- a/src/core/AudioInterface.cpp +++ b/src/core/AudioInterface.cpp @@ -220,10 +220,10 @@ AudioInterfaceWidget::AudioInterfaceWidget() { addChild(panel); } - addChild(createScrew(Vec(15, 0))); - addChild(createScrew(Vec(box.size.x-30, 0))); - addChild(createScrew(Vec(15, 365))); - addChild(createScrew(Vec(box.size.x-30, 365))); + addChild(Widget::create(Vec(15, 0))); + addChild(Widget::create(Vec(box.size.x-30, 0))); + addChild(Widget::create(Vec(15, 365))); + addChild(Widget::create(Vec(box.size.x-30, 365))); Vec margin = Vec(5, 2); float labelHeight = 15; @@ -241,7 +241,7 @@ AudioInterfaceWidget::AudioInterfaceWidget() { yPos += 5; xPos = 10; for (int i = 0; i < 4; i++) { - addInput(createInput(Vec(xPos, yPos), module, AudioInterface::AUDIO_INPUT + i)); + addInput(Port::createInput(Vec(xPos, yPos), module, AudioInterface::AUDIO_INPUT + i)); Label *label = new Label(); label->box.pos = Vec(xPos + 4, yPos + 28); label->text = stringf("%d", i + 1); @@ -254,7 +254,7 @@ AudioInterfaceWidget::AudioInterfaceWidget() { yPos += 5; xPos = 10; for (int i = 4; i < 8; i++) { - addInput(createInput(Vec(xPos, yPos), module, AudioInterface::AUDIO_INPUT + i)); + addInput(Port::createInput(Vec(xPos, yPos), module, AudioInterface::AUDIO_INPUT + i)); Label *label = new Label(); label->box.pos = Vec(xPos + 4, yPos + 28); label->text = stringf("%d", i + 1); @@ -275,7 +275,7 @@ AudioInterfaceWidget::AudioInterfaceWidget() { yPos += 5; xPos = 10; for (int i = 0; i < 4; i++) { - Port *port = createOutput(Vec(xPos, yPos), module, AudioInterface::AUDIO_OUTPUT + i); + Port *port = Port::createOutput(Vec(xPos, yPos), module, AudioInterface::AUDIO_OUTPUT + i); addOutput(port); Label *label = new Label(); label->box.pos = Vec(xPos + 4, yPos + 28); @@ -289,7 +289,7 @@ AudioInterfaceWidget::AudioInterfaceWidget() { yPos += 5; xPos = 10; for (int i = 4; i < 8; i++) { - addOutput(createOutput(Vec(xPos, yPos), module, AudioInterface::AUDIO_OUTPUT + i)); + addOutput(Port::createOutput(Vec(xPos, yPos), module, AudioInterface::AUDIO_OUTPUT + i)); Label *label = new Label(); label->box.pos = Vec(xPos + 4, yPos + 28); label->text = stringf("%d", i + 1); @@ -304,5 +304,5 @@ AudioInterfaceWidget::AudioInterfaceWidget() { addChild(audioWidget); // Lights - addChild(createLight>(Vec(40, 20), module, AudioInterface::ACTIVE_LIGHT)); + addChild(ModuleLightWidget::create>(Vec(40, 20), module, AudioInterface::ACTIVE_LIGHT)); } diff --git a/src/core/Blank.cpp b/src/core/Blank.cpp index be397c04..ba4c0e49 100644 --- a/src/core/Blank.cpp +++ b/src/core/Blank.cpp @@ -72,10 +72,10 @@ BlankWidget::BlankWidget() { addChild(leftHandle); addChild(rightHandle); - addChild(createScrew(Vec(15, 0))); - addChild(createScrew(Vec(15, 365))); - topRightScrew = createScrew(Vec(box.size.x - 30, 0)); - bottomRightScrew = createScrew(Vec(box.size.x - 30, 365)); + addChild(Widget::create(Vec(15, 0))); + addChild(Widget::create(Vec(15, 365))); + topRightScrew = Widget::create(Vec(box.size.x - 30, 0)); + bottomRightScrew = Widget::create(Vec(box.size.x - 30, 365)); addChild(topRightScrew); addChild(bottomRightScrew); } diff --git a/src/core/MidiToCV.cpp b/src/core/MidiToCV.cpp index cd2b8900..c236fc7e 100644 --- a/src/core/MidiToCV.cpp +++ b/src/core/MidiToCV.cpp @@ -245,10 +245,10 @@ MidiToCVWidget::MidiToCVWidget() { float yPos = margin; float yGap = 35; - addChild(createScrew(Vec(15, 0))); - addChild(createScrew(Vec(box.size.x - 30, 0))); - addChild(createScrew(Vec(15, 365))); - addChild(createScrew(Vec(box.size.x - 30, 365))); + addChild(Widget::create(Vec(15, 0))); + addChild(Widget::create(Vec(box.size.x - 30, 0))); + addChild(Widget::create(Vec(15, 365))); + addChild(Widget::create(Vec(box.size.x - 30, 365))); { Label *label = new Label(); @@ -258,8 +258,8 @@ MidiToCVWidget::MidiToCVWidget() { yPos = labelHeight * 2; } - addParam(createParam(Vec(7 * 15, labelHeight), module, MIDIToCVInterface::RESET_PARAM, 0.0, 1.0, 0.0)); - addChild(createLight>(Vec(7 * 15 + 5, labelHeight + 5), module, MIDIToCVInterface::RESET_LIGHT)); + addParam(ParamWidget::create(Vec(7 * 15, labelHeight), module, MIDIToCVInterface::RESET_PARAM, 0.0, 1.0, 0.0)); + addChild(ModuleLightWidget::create>(Vec(7 * 15 + 5, labelHeight + 5), module, MIDIToCVInterface::RESET_LIGHT)); std::string labels[MIDIToCVInterface::NUM_OUTPUTS] = {"1V/oct", "Gate", "Velocity", "Mod Wheel", "Pitch Wheel", "Aftertouch"}; @@ -269,7 +269,7 @@ MidiToCVWidget::MidiToCVWidget() { label->text = labels[i]; addChild(label); - addOutput(createOutput(Vec(15 * 6, yPos - 5), module, i)); + addOutput(Port::createOutput(Vec(15 * 6, yPos - 5), module, i)); yPos += yGap + margin; } @@ -279,5 +279,5 @@ MidiToCVWidget::MidiToCVWidget() { addChild(midiWidget); // Lights - addChild(createLight>(Vec(40, 20), module, MIDIToCVInterface::ACTIVE_LIGHT)); + addChild(ModuleLightWidget::create>(Vec(40, 20), module, MIDIToCVInterface::ACTIVE_LIGHT)); }