BogaudioModules

BogaudioModules for VCV Rack
Log | Files | Refs | README | LICENSE

commit 9c747cb61b880a033f7707c293113c4c36d5c8de
parent 129817f1d9ac70a984c1406e9953e0828d4a61c8
Author: Matt Demanett <matt@demanett.net>
Date:   Tue, 21 Apr 2020 23:35:33 -0400

SWITCH* matrix mixers: add row- and column-exclusive options. #112

Diffstat:
Msrc/matrix_base.cpp | 79+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/matrix_base.hpp | 9+++++++++
Msrc/widgets.cpp | 6+++++-
Msrc/widgets.hpp | 2++
4 files changed, 95 insertions(+), 1 deletion(-)

diff --git a/src/matrix_base.cpp b/src/matrix_base.cpp @@ -77,8 +77,12 @@ void KnobMatrixModule::dataFromJson(json_t* root) { #define INVERTING_PARAM "param" #define INVERTING_DISABLED "disabled" +#define ROW_EXCLUSIVE "row_exclusive" +#define COLUMN_EXCLUSIVE "column_exclusive" + json_t* SwitchMatrixModule::dataToJson() { json_t* root = MatrixBaseModule::dataToJson(); + switch (_inverting) { case CLICK_INVERTING: { json_object_set_new(root, INVERTING, json_string(INVERTING_CLICK)); @@ -93,11 +97,16 @@ json_t* SwitchMatrixModule::dataToJson() { break; } } + + json_object_set_new(root, ROW_EXCLUSIVE, json_boolean(_rowExclusive)); + json_object_set_new(root, COLUMN_EXCLUSIVE, json_boolean(_columnExclusive)); + return root; } void SwitchMatrixModule::dataFromJson(json_t* root) { MatrixBaseModule::dataFromJson(root); + json_t* i = json_object_get(root, INVERTING); if (i) { const char* s = json_string_value(i); @@ -113,6 +122,15 @@ void SwitchMatrixModule::dataFromJson(json_t* root) { } } } + + json_t* re = json_object_get(root, ROW_EXCLUSIVE); + if (re) { + _rowExclusive = json_is_true(re); + } + json_t* ce = json_object_get(root, COLUMN_EXCLUSIVE); + if (ce) { + _columnExclusive = json_is_true(ce); + } } void SwitchMatrixModule::setInverting(Inverting inverting) { @@ -141,3 +159,64 @@ void SwitchMatrixModule::configSwitchParam(int id, const char* label) { configParam(id, -1.0f, 1.0f, 0.0f, label, "%", 0.0f, 100.0f); _switchParamQuantities.push_back(paramQuantities[id]); } + +void SwitchMatrixModule::switchChanged(int id, float value) { + if (value != 0.0f) { + int row = (id - _firstParamID) % _n; + int col = (id - _firstParamID) / _n; + + if (_rowExclusive) { + for (int i = 0; i < col; ++i) { + _switchParamQuantities[i * _n + row]->setValue(0.0f); + } + for (int i = col + 1; i < _n; ++i) { + _switchParamQuantities[i * _n + row]->setValue(0.0f); + } + } + + if (_columnExclusive) { + for (int i = 0; i < row; ++i) { + _switchParamQuantities[col * _n + i]->setValue(0.0f); + } + for (int i = row + 1; i < _n; ++i) { + _switchParamQuantities[col * _n + i]->setValue(0.0f); + } + } + } +} + +void SwitchMatrixModule::setRowExclusive(bool e) { + _rowExclusive = e; + if (e) { + for (int i = 0; i < _n; ++i) { + int j = 0; + for (; j < _n; ++j) { + if (_switchParamQuantities[j * _n + i]->getValue() != 0.0f) { + break; + } + } + ++j; + for (; j < _n; ++j) { + _switchParamQuantities[j * _n + i]->setValue(0.0f); + } + } + } +} + +void SwitchMatrixModule::setColumnExclusive(bool e) { + _columnExclusive = e; + if (e) { + for (int i = 0; i < _n; ++i) { + int j = 0; + for (; j < _n; ++j) { + if (_switchParamQuantities[i * _n + j]->getValue() != 0.0f) { + break; + } + } + ++j; + for (; j < _n; ++j) { + _switchParamQuantities[i * _n + j]->setValue(0.0f); + } + } + } +} diff --git a/src/matrix_base.hpp b/src/matrix_base.hpp @@ -116,6 +116,8 @@ struct SwitchMatrixModule : MatrixModule { }; Inverting _inverting = CLICK_INVERTING; + bool _rowExclusive = false; + bool _columnExclusive = false; std::vector<ParamQuantity*> _switchParamQuantities; SwitchMatrixModule(int n, int firstParamID, int firstInputID, int firstOutputID) @@ -126,6 +128,9 @@ struct SwitchMatrixModule : MatrixModule { void dataFromJson(json_t* root) override; void setInverting(Inverting inverting); void configSwitchParam(int id, const char* label); + void switchChanged(int id, float value); + void setRowExclusive(bool e); + void setColumnExclusive(bool e); }; struct SwitchMatrixModuleWidget : MatrixBaseModuleWidget { @@ -133,6 +138,7 @@ struct SwitchMatrixModuleWidget : MatrixBaseModuleWidget { auto s = dynamic_cast<W*>(createParam<W>(position, module, id)); if (module) { s->setClickToInvertCallback([module]() { return module->_inverting == SwitchMatrixModule::CLICK_INVERTING; }); + s->setOnChangeCallback([module](int id, float value) { module->switchChanged(id, value); }); } addParam(s); } @@ -147,6 +153,9 @@ struct SwitchMatrixModuleWidget : MatrixBaseModuleWidget { i->addItem(OptionMenuItem("By param entry (right-click)", [m]() { return m->_inverting == SwitchMatrixModule::PARAM_INVERTING; }, [m]() { m->setInverting(SwitchMatrixModule::PARAM_INVERTING); })); i->addItem(OptionMenuItem("Disabled", [m]() { return m->_inverting == SwitchMatrixModule::NO_INVERTING; }, [m]() { m->setInverting(SwitchMatrixModule::NO_INVERTING); })); OptionsMenuItem::addToMenu(i, menu); + + menu->addChild(new OptionMenuItem("Exclusive by rows", [m]() { return m->_rowExclusive; }, [m]() { m->setRowExclusive(!m->_rowExclusive); })); + menu->addChild(new OptionMenuItem("Exclusive by columns", [m]() { return m->_columnExclusive; }, [m]() { m->setColumnExclusive(!m->_columnExclusive); })); } }; diff --git a/src/widgets.cpp b/src/widgets.cpp @@ -415,7 +415,11 @@ void InvertingIndicatorButton::onButton(const event::Button& e) { void InvertingIndicatorButton::onChange(const event::Change& e) { fb->dirty = true; if (paramQuantity) { - w->setValue(paramQuantity->getValue()); + float v = paramQuantity->getValue(); + w->setValue(v); + if (onChangeCB) { + onChangeCB(paramQuantity->paramId, v); + } } ParamWidget::onChange(e); } diff --git a/src/widgets.hpp b/src/widgets.hpp @@ -133,10 +133,12 @@ struct InvertingIndicatorButton : ParamWidget { CircularShadow* shadow; IIBWidget* w; std::function<bool()> clickToInvertCB; + std::function<void(int, float)> onChangeCB; InvertingIndicatorButton(int dim); inline void setClickToInvertCallback(std::function<bool()> fn) { clickToInvertCB = fn; } + inline void setOnChangeCallback(std::function<void(int, float)> fn) { onChangeCB = fn; } void reset() override; void randomize() override; void onHover(const event::Hover& e) override;