commit 2a684640af4eae5f566be750238613a46542debe
parent 26efd784ab60d77e69088f6f0f98f44cc22931f8
Author: Adam M <aemalone@gmail.com>
Date: Wed, 3 Jul 2019 20:50:52 -0500
Laundry Soup finally does not crash
Diffstat:
6 files changed, 321 insertions(+), 206 deletions(-)
diff --git a/Makefile b/Makefile
@@ -18,6 +18,7 @@ SOURCES += $(wildcard src/ComputerscareSvgPort.cpp)
SOURCES += $(wildcard src/ComputerscareIso.cpp)
SOURCES += $(wildcard src/ComputerscareKnolyPobs.cpp)
SOURCES += $(wildcard src/ComputerscarePatchSequencer.cpp)
+SOURCES += $(wildcard src/ComputerscareLaundrySoup.cpp)
SOURCES += $(wildcard src/ComputerscareDebug.cpp)
SOURCES += $(wildcard src/ComputerscareOhPeas.cpp)
diff --git a/plugin.json b/plugin.json
@@ -29,6 +29,12 @@
"name":"Father and Son Patch Sequencer",
"description":"Patch Sequencer - 10 in, 10 out patch matrix with 16 scenes",
"tags":["Poly","Utility"]
+ },
+
+ {"slug":"computerscare-laundry-soup",
+ "name":"Laundry Soup",
+ "description":"Rhythm sequencer, pulse generator, text-based",
+ "tags":["Sequencer"]
}
]
}
\ No newline at end of file
diff --git a/src/Computerscare.cpp b/src/Computerscare.cpp
@@ -9,7 +9,7 @@ void init(Plugin *p) {
p->addModel(modelComputerscareDebug);
p->addModel(modelComputerscarePatchSequencer);
- //p->addModel(modelComputerscareLaundrySoup);
+ p->addModel(modelComputerscareLaundrySoup);
//p->addModel(modelComputerscareILoveCookies);
p->addModel(modelComputerscareOhPeas);
//p->addModel(modelComputerscareIso);
diff --git a/src/Computerscare.hpp b/src/Computerscare.hpp
@@ -27,7 +27,7 @@ extern Model *modelComputerscareDebug;
extern Model *modelComputerscarePatchSequencer;
-//extern Model *modelComputerscareLaundrySoup;
+extern Model *modelComputerscareLaundrySoup;
//extern Model *modelComputerscareILoveCookies;
extern Model *modelComputerscareOhPeas;
//extern Model *modelComputerscareIso;
@@ -100,7 +100,7 @@ struct ComputerscareDebugFour : app::SvgSwitch {
addFrame(APP->window->loadSvg(asset::plugin(pluginInstance, "res/debug-clock-selector-4way-template.svg")));
}
};
-struct ComputerscareResetButton : SvgSwitch {
+struct ComputerscareResetButton : app::SvgSwitch {
ComputerscareResetButton() {
momentary = true;
addFrame(APP->window->loadSvg(asset::plugin(pluginInstance, "res/computerscare-rst-text.svg")));
@@ -109,14 +109,14 @@ struct ComputerscareResetButton : SvgSwitch {
}
};
-struct ComputerscareClockButton : SvgSwitch {
+struct ComputerscareClockButton : app::SvgSwitch {
ComputerscareClockButton() {
momentary = true;
addFrame(APP->window->loadSvg(asset::plugin(pluginInstance, "res/computerscare-clk-text.svg")));
addFrame(APP->window->loadSvg(asset::plugin(pluginInstance, "res/computerscare-clk-text-red.svg")));
}
};
-struct ComputerscareInvisibleButton : SvgSwitch {
+struct ComputerscareInvisibleButton : app::SvgSwitch {
ComputerscareInvisibleButton() {
addFrame(APP->window->loadSvg(asset::plugin(pluginInstance, "res/computerscare-invisible-button.svg")));
addFrame(APP->window->loadSvg(asset::plugin(pluginInstance, "res/computerscare-invisible-button-frame2.svg")));
diff --git a/src/ComputerscareLaundrySoup.cpp b/src/ComputerscareLaundrySoup.cpp
@@ -9,204 +9,167 @@
#include <iomanip>
struct ComputerscareLaundrySoup;
+struct LaundryTextField;
+struct LaundryTF2;
+struct LaundrySmallDisplay;
+
const int numFields = 6;
-class MyTextField : public LedDisplayTextField {
+/*class MyTextField : public LedDisplayTextField {
public:
int fontSize = 16;
- int rowIndex=0;
+ int rowIndex = 0;
bool inError = false;
MyTextField() : LedDisplayTextField() {}
void setModule(ComputerscareLaundrySoup* _module) {
module = _module;
}
- virtual void onTextChange() override;
+ //virtual void onTextChange() override;
int getTextPosition(Vec mousePos) override {
bndSetFont(font->handle);
int textPos = bndIconLabelTextPosition(gVg, textOffset.x, textOffset.y,
- box.size.x - 2*textOffset.x, box.size.y - 2*textOffset.y,
- -1, fontSize, text.c_str(), mousePos.x, mousePos.y);
+ box.size.x - 2 * textOffset.x, box.size.y - 2 * textOffset.y,
+ -1, fontSize, text.c_str(), mousePos.x, mousePos.y);
bndSetFont(gGuiFont->handle);
return textPos;
}
- void draw(const DrawArgs &args) override {
- nvgScissor(args.vg, 0, 0, box.size.x, box.size.y);
+*/
- // Background
- nvgFontSize(args.vg, fontSize);
- nvgBeginPath(args.vg);
- nvgRoundedRect(args.vg, 0, 0, box.size.x, box.size.y, 10.0);
-
- if(inError) {
- nvgFillColor(args.vg, COLOR_COMPUTERSCARE_PINK);
- }
- else {
- nvgFillColor(args.vg, nvgRGB(0x00, 0x00, 0x00));
- }
- nvgFill(args.vg);
-
- // Text
- if (font->handle >= 0) {
- bndSetFont(font->handle);
-
- NVGcolor highlightColor = color;
- highlightColor.a = 0.5;
- int begin = min(cursor, selection);
- int end = (this == gFocusedWidget) ? max(cursor, selection) : -1;
- //bndTextField(args.vg,textOffset.x,textOffset.y+2, box.size.x, box.size.y, -1, 0, 0, const char *text, int cbegin, int cend);
- bndIconLabelCaret(args.vg, textOffset.x, textOffset.y - 3,
- box.size.x - 2*textOffset.x, box.size.y - 2*textOffset.y,
- -1, color, fontSize, text.c_str(), highlightColor, begin, end);
-
- bndSetFont(gGuiFont->handle);
- }
-
- nvgResetScissor(args.vg);
- };
+/*void MyTextField::onTextChange() {
+ std::string value = module->textFields[this->rowIndex]->text;
+ LaundrySoupSequence lss = LaundrySoupSequence(value);
-private:
- ComputerscareLaundrySoup* module;
-};
+ if(!lss.inError && matchParens(value)) {
+ module->textFields[this->rowIndex]->inError=false;
+ module->setNextAbsoluteSequence(this->rowIndex);
+ module->updateDisplayBlink(this->rowIndex);
+ }
+ else {
+ module->textFields[this->rowIndex]->inError=true;
+ }
+}*/
struct ComputerscareLaundrySoup : Module {
- enum ParamIds {
- MANUAL_CLOCK_PARAM,
- MANUAL_RESET_PARAM,
- INDIVIDUAL_RESET_PARAM,
- NUM_PARAMS = INDIVIDUAL_RESET_PARAM + numFields
- };
- enum InputIds {
+ enum ParamIds {
+ MANUAL_CLOCK_PARAM,
+ MANUAL_RESET_PARAM,
+ INDIVIDUAL_RESET_PARAM,
+ NUM_PARAMS = INDIVIDUAL_RESET_PARAM + numFields
+ };
+ enum InputIds {
GLOBAL_CLOCK_INPUT,
GLOBAL_RESET_INPUT,
CLOCK_INPUT,
RESET_INPUT = CLOCK_INPUT + numFields,
- NUM_INPUTS = RESET_INPUT + numFields
- };
- enum OutputIds {
+ NUM_INPUTS = RESET_INPUT + numFields
+ };
+ enum OutputIds {
TRG_OUTPUT,
FIRST_STEP_OUTPUT = TRG_OUTPUT + numFields,
- NUM_OUTPUTS = FIRST_STEP_OUTPUT + numFields
- };
+ NUM_OUTPUTS = FIRST_STEP_OUTPUT + numFields
+ };
enum LightIds {
- SWITCH_LIGHTS,
+ SWITCH_LIGHTS,
NUM_LIGHTS
- };
+ };
+
+ rack::dsp::SchmittTrigger globalClockTrigger;
+ rack::dsp::SchmittTrigger globalResetTriggerInput;
- SchmittTrigger globalClockTrigger;
- SchmittTrigger globalResetTriggerInput;
+ rack::dsp::SchmittTrigger globalManualClockTrigger;
+ rack::dsp::SchmittTrigger globalManualResetTrigger;
- SchmittTrigger globalManualClockTrigger;
- SchmittTrigger globalManualResetTrigger;
+ rack::dsp::SchmittTrigger clockTriggers[numFields];
+ rack::dsp::SchmittTrigger resetTriggers[numFields];
- SchmittTrigger clockTriggers[numFields];
- SchmittTrigger resetTriggers[numFields];
+ LaundryTF2* textFields[numFields];
+ LaundrySmallDisplay* smallLetterDisplays[numFields];
- MyTextField* textFields[numFields];
- SmallLetterDisplay* smallLetterDisplays[numFields];
+ std::string currentFormula[numFields];
- SchmittTrigger manualResetTriggers[numFields];
+ rack::dsp::SchmittTrigger manualResetTriggers[numFields];
LaundrySoupSequence laundrySequences[numFields];
bool activeStep[numFields] = {false};
bool shouldChange[numFields] = {false};
-
-ComputerscareLaundrySoup() {
- config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS);}
- void process(const ProcessArgs &args) override;
- json_t *toJson() override
- {
- json_t *rootJ = json_object();
-
- json_t *sequencesJ = json_array();
+ ComputerscareLaundrySoup() {
+ config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS);
for (int i = 0; i < numFields; i++) {
- json_t *sequenceJ = json_string(textFields[i]->text.c_str());
- json_array_append_new(sequencesJ, sequenceJ);
- }
- json_object_set_new(rootJ, "sequences", sequencesJ);
-
- return rootJ;
- }
-
- void fromJson(json_t *rootJ) override
- {
- json_t *sequencesJ = json_object_get(rootJ, "sequences");
- if (sequencesJ) {
- for (int i = 0; i < numFields; i++) {
+ currentFormula[i] = "";
+ setNextAbsoluteSequence(i);
+ checkIfShouldChange(i);
+ resetOneOfThem(i);
- json_t *sequenceJ = json_array_get(sequencesJ, i);
- if (sequenceJ)
- textFields[i]->text = json_string_value(sequenceJ);
- }
}
- onCreate();
}
-
+ void process(const ProcessArgs &args) override;
+
+
+
void onRandomize() override {
- randomizeAllFields();
+ //randomizeAllFields();
}
- void randomizeAllFields() {
- std::string mainlookup ="111111111111111111122223333333344444444444444445556667778888888888888999";
- std::string string = "";
- std::string randchar = "";
- int length = 0;
+ /* void randomizeAllFields() {
+ std::string mainlookup = "111111111111111111122223333333344444444444444445556667778888888888888999";
+ std::string string = "";
+ std::string randchar = "";
+ int length = 0;
- for (int i = 0; i < numFields; i++) {
- length = rand() % 12 + 1;
- string = "";
- for(int j = 0; j < length; j++) {
- randchar = mainlookup[rand() % mainlookup.size()];
- string = string + randchar;
+ for (int i = 0; i < numFields; i++) {
+ length = rand() % 12 + 1;
+ string = "";
+ for (int j = 0; j < length; j++) {
+ randchar = mainlookup[rand() % mainlookup.size()];
+ string = string + randchar;
+ }
+ textFields[i]->text = string;
+ setNextAbsoluteSequence(i);
}
- textFields[i]->text = string;
- setNextAbsoluteSequence(i);
- }
- }
+ }*/
-void setNextAbsoluteSequence(int index) {
- shouldChange[index] = true;
-}
-void setAbsoluteSequenceFromQueue(int index) {
- LaundrySoupSequence lss = LaundrySoupSequence(textFields[index]->text);
- laundrySequences[index] = lss;
- if(!lss.inError) {
- laundrySequences[index] = lss;
- //laundrySequences[index].print();
- textFields[index]->inError=false;
+ void setNextAbsoluteSequence(int index) {
+ shouldChange[index] = true;
}
- else {
- printf("ERROR\n");
- //lss.print();
- textFields[index]->inError=true;
+ void setAbsoluteSequenceFromQueue(int index) {
+ LaundrySoupSequence lss = LaundrySoupSequence(currentFormula[index]);
+ laundrySequences[index] = lss;
+ if (!lss.inError) {
+ laundrySequences[index] = lss;
+ laundrySequences[index].print();
+ //textFields[index]->inError = false;
+ }
+ else {
+ printf("ERROR\n");
+ lss.print();
+ //textFields[index]->inError = true;
+ }
}
-}
-void checkIfShouldChange(int index) {
- if(shouldChange[index]) {
- setAbsoluteSequenceFromQueue(index);
- shouldChange[index] = false;
- updateDisplayBlink(index);
+ void checkIfShouldChange(int index) {
+ if (shouldChange[index]) {
+ setAbsoluteSequenceFromQueue(index);
+ shouldChange[index] = false;
+ updateDisplayBlink(index);
+ }
}
-}
-void updateDisplayBlink(int index) {
- smallLetterDisplays[index]->blink = shouldChange[index];
-}
-void onCreate () override
+ void updateDisplayBlink(int index) {
+ // smallLetterDisplays[index]->blink = shouldChange[index];
+ }
+ void onCreate ()
{
- for(int i = 0; i < numFields; i++) {
- setNextAbsoluteSequence(i);
- checkIfShouldChange(i);
- resetOneOfThem(i);
- }
+ printf("onCreate\n");
+
}
void onReset () override
{
+ printf("onReset\n");
onCreate();
}
@@ -220,25 +183,26 @@ void onCreate () override
*/
void incrementInternalStep(int i) {
+ laundrySequences[i].print();
laundrySequences[i].incrementAndCheck();
- if(laundrySequences[i].readHead == 0) {
- this->setChangeImminent(i,false);
+ if (laundrySequences[i].readHead == 0) {
+ this->setChangeImminent(i, false);
}
- this->smallLetterDisplays[i]->value = this->getDisplayString(i);
+ //this->smallLetterDisplays[i]->value = this->getDisplayString(i);
}
std::string getDisplayString(int index) {
std::string lhs = std::to_string(this->laundrySequences[index].readHead + 1);
std::string rhs = std::to_string(this->laundrySequences[index].numSteps);
- padTo(lhs, 3,' ');
- padTo(rhs, 3,' ');
-
+ padTo(lhs, 3, ' ');
+ padTo(rhs, 3, ' ');
+
std::string val = lhs + "\n" + rhs;
return val;
}
- void setChangeImminent(int i,bool value) {
- this->smallLetterDisplays[i]->doubleblink = value;
+ void setChangeImminent(int i, bool value) {
+ // this->smallLetterDisplays[i]->doubleblink = value;
}
void resetOneOfThem(int i) {
this->laundrySequences[i].readHead = -1;
@@ -263,21 +227,21 @@ void ComputerscareLaundrySoup::process(const ProcessArgs &args) {
bool currentResetTriggered = false;
bool currentManualResetClicked;
- for(int i = 0; i < numFields; i++) {
+ for (int i = 0; i < numFields; i++) {
currentResetActive = inputs[RESET_INPUT + i].isConnected();
- currentResetTriggered = resetTriggers[i].process(inputs[RESET_INPUT+i].getVoltage() / 2.f);
+ currentResetTriggered = resetTriggers[i].process(inputs[RESET_INPUT + i].getVoltage() / 2.f);
currentTriggerIsHigh = clockTriggers[i].isHigh();
currentTriggerClocked = clockTriggers[i].process(inputs[CLOCK_INPUT + i].getVoltage());
currentManualResetClicked = manualResetTriggers[i].process(params[INDIVIDUAL_RESET_PARAM + i].getValue());
- if(this->laundrySequences[i].numSteps > 0) {
+ if (this->laundrySequences[i].numSteps > 0) {
if (inputs[CLOCK_INPUT + i].isConnected()) {
- if(currentTriggerClocked || globalManualClockClicked) {
+ if (currentTriggerClocked || globalManualClockClicked) {
incrementInternalStep(i);
activeStep[i] = (this->laundrySequences[i].peekWorkingStep() == 1);
atLastStepAfterIncrement = this->laundrySequences[i].atLastStep();
- if(atLastStepAfterIncrement) checkIfShouldChange(i);
+ if (atLastStepAfterIncrement) checkIfShouldChange(i);
}
}
else {
@@ -285,31 +249,31 @@ void ComputerscareLaundrySoup::process(const ProcessArgs &args) {
incrementInternalStep(i);
activeStep[i] = (this->laundrySequences[i].peekWorkingStep() == 1);
atLastStepAfterIncrement = this->laundrySequences[i].atLastStep();
- if(atLastStepAfterIncrement) checkIfShouldChange(i);
+ if (atLastStepAfterIncrement) checkIfShouldChange(i);
}
}
atFirstStep = (this->laundrySequences[i].readHead == 0);
- if(globalManualResetClicked || currentManualResetClicked) {
- setChangeImminent(i,true);
+ if (globalManualResetClicked || currentManualResetClicked) {
+ setChangeImminent(i, true);
checkIfShouldChange(i);
resetOneOfThem(i);
}
- if( (currentResetActive && currentResetTriggered) || (!currentResetActive && globalResetTriggered)) {
-
- setChangeImminent(i,false);
+ if ( (currentResetActive && currentResetTriggered) || (!currentResetActive && globalResetTriggered)) {
+
+ setChangeImminent(i, false);
checkIfShouldChange(i);
resetOneOfThem(i);
}
else {
- if(atFirstStep && !currentResetActive && !inputs[GLOBAL_RESET_INPUT].isConnected()) {
+ if (atFirstStep && !currentResetActive && !inputs[GLOBAL_RESET_INPUT].isConnected()) {
//checkIfShouldChange(i);
}
}
}
- if(inputs[CLOCK_INPUT + i].isConnected()) {
+ if (inputs[CLOCK_INPUT + i].isConnected()) {
outputs[TRG_OUTPUT + i].setVoltage((currentTriggerIsHigh && activeStep[i]) ? 10.0f : 0.0f);
outputs[FIRST_STEP_OUTPUT + i].setVoltage((currentTriggerIsHigh && atFirstStep) ? 10.f : 0.0f);
}
@@ -319,78 +283,222 @@ void ComputerscareLaundrySoup::process(const ProcessArgs &args) {
}
}
}
+struct LaundryTF2 : ComputerscareTextField
+{
+ ComputerscareLaundrySoup *module;
+ int fontSize = 16;
+ int rowIndex = 0;
+ bool inError = false;
-void MyTextField::onTextChange() {
- std::string value = module->textFields[this->rowIndex]->text;
- LaundrySoupSequence lss = LaundrySoupSequence(value);
-
- if(!lss.inError && matchParens(value)) {
- module->textFields[this->rowIndex]->inError=false;
- module->setNextAbsoluteSequence(this->rowIndex);
- module->updateDisplayBlink(this->rowIndex);
+ LaundryTF2(int i)
+ {
+ rowIndex=i;
+ ComputerscareTextField();
+ };
+ void draw(const DrawArgs &args) override
+ {
+ if (module)
+ {
+ std::string value = text.c_str();
+ if (value != module->currentFormula[rowIndex])
+ {
+ printf("diff %i, %s\n",rowIndex,text.c_str());
+ LaundrySoupSequence lss = LaundrySoupSequence(value);
+
+ if (!lss.inError && matchParens(value)) {
+ inError=false;
+ module->currentFormula[rowIndex] = value;
+ module->setNextAbsoluteSequence(this->rowIndex);
+ //module->updateDisplayBlink(rowIndex);
+ }
+ else {
+ printf("in error %i\n",index);
+ inError = true;
+ }
+ //module->setQuant();
+ }
+ }
+ ComputerscareTextField::draw(args);
}
- else {
- module->textFields[this->rowIndex]->inError=true;
+
+ //void draw(const DrawArgs &args) override;
+ //int getTextPosition(math::Vec mousePos) override;
+};
+/*struct LaundryTextField : LedDisplayTextField
+{
+ ComputerscareLaundrySoup *module;
+ std::shared_ptr<Font> font;
+ math::Vec textOffset;
+ NVGcolor color;
+ int fontSize = 16;
+ int rowIndex = 0;
+ bool inError = false;
+ void onEnter(const event::Enter &e) override;
+ LaundryTextField(int index)
+ {
+ rowIndex = index;
+ LedDisplayTextField();
+ };
+ void draw(const DrawArgs &args) override
+ {
+ if (module)
+ {
+ std::string value = text.c_str();
+ if (text.c_str() != module->textFields[this->rowIndex]->text)
+ {
+ LaundrySoupSequence lss = LaundrySoupSequence(value);
+ // module->currentFormula = text.c_str();
+ // module->setQuant();
+ if (!lss.inError && matchParens(value)) {
+ //module->textFields[this->rowIndex]->inError = false;
+ //module->setNextAbsoluteSequence(this->rowIndex);
+ //module->updateDisplayBlink(this->rowIndex);
+ }
+ else {
+ //module->textFields[this->rowIndex]->inError = true;
+ }
+ }
+ LedDisplayTextField::draw(args);
+ }
+
}
-}
+ //void draw(const DrawArgs &args) override;
+ //int getTextPosition(math::Vec mousePos) override;
+};
+void LaundryTextField::onEnter(const event::Enter &e) {
+ module->setNextAbsoluteSequence(rowIndex);
+ //module->setQuant();
+}*/
+struct LaundrySmallDisplay : SmallLetterDisplay
+{
+ ComputerscareLaundrySoup *module;
+ int type;
+ int index;
+ LaundrySmallDisplay(int i)
+ {
+ index=i;
+ SmallLetterDisplay();
+ };
+ void draw(const DrawArgs &args)
+ {
+ //this->setNumDivisionsString();
+ if (module)
+ {
+ value = module->getDisplayString(index);
+ SmallLetterDisplay::draw(args);
+ }
+ }
+
+};
struct ComputerscareLaundrySoupWidget : ModuleWidget {
double verticalSpacing = 18.4;
int verticalStart = 22;
ComputerscareLaundrySoupWidget(ComputerscareLaundrySoup *module) {
- setModule(module);
- setPanel(APP->window->loadSvg(asset::plugin(plugin, "res/ComputerscareLaundrySoupPanel.svg")));
+ setModule(module);
+ setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/ComputerscareLaundrySoupPanel.svg")));
//global clock input
- addInput(Port::create<InPort>(mm2px(Vec(2 , 0)), Port::INPUT, module, ComputerscareLaundrySoup::GLOBAL_CLOCK_INPUT));
+ addInput(createInput<InPort>(mm2px(Vec(2 , 0)), module, ComputerscareLaundrySoup::GLOBAL_CLOCK_INPUT));
//global reset input
- addInput(Port::create<InPort>(mm2px(Vec(12 , 0)), Port::INPUT, module, ComputerscareLaundrySoup::GLOBAL_RESET_INPUT));
-
- addParam(ParamWidget::create<ComputerscareClockButton>(mm2px(Vec(2 , 8)), module, ComputerscareLaundrySoup::MANUAL_CLOCK_PARAM, 0.0, 1.0, 0.0));
- addParam(ParamWidget::create<ComputerscareResetButton>(mm2px(Vec(12 , 8)), module, ComputerscareLaundrySoup::MANUAL_RESET_PARAM, 0.0, 1.0, 0.0));
-
- for(int i = 0; i < numFields; i++) {
+ addInput(createInput<InPort>(mm2px(Vec(12 , 0)), module, ComputerscareLaundrySoup::GLOBAL_RESET_INPUT));
+
+
+ // addParam(createParam<ComputerscareClockButton>(Vec(2, 321), module, ComputerscareDebug::MANUAL_TRIGGER));
+
+ addParam(createParam<ComputerscareClockButton>(mm2px(Vec(2 , 8)), module, ComputerscareLaundrySoup::MANUAL_CLOCK_PARAM));
+ addParam(createParam<ComputerscareResetButton>(mm2px(Vec(12 , 8)), module, ComputerscareLaundrySoup::MANUAL_RESET_PARAM));
+
+ for (int i = 0; i < numFields; i++) {
//first-step output
- addOutput(Port::create<OutPort>(mm2px(Vec(42 , verticalStart + verticalSpacing*i - 11)), Port::OUTPUT, module, ComputerscareLaundrySoup::FIRST_STEP_OUTPUT + i));
+ addOutput(createOutput<OutPort>(mm2px(Vec(42 , verticalStart + verticalSpacing * i - 11)), module, ComputerscareLaundrySoup::FIRST_STEP_OUTPUT + i));
//individual output
- addOutput(Port::create<OutPort>(mm2px(Vec(54 , verticalStart + verticalSpacing*i - 11)), Port::OUTPUT, module, ComputerscareLaundrySoup::TRG_OUTPUT + i));
+ addOutput(createOutput<OutPort>(mm2px(Vec(54 , verticalStart + verticalSpacing * i - 11)), module, ComputerscareLaundrySoup::TRG_OUTPUT + i));
//individual clock input
- addInput(Port::create<InPort>(mm2px(Vec(2, verticalStart + verticalSpacing*i-10)), Port::INPUT, module, ComputerscareLaundrySoup::CLOCK_INPUT + i));
+ addInput(createInput<InPort>(mm2px(Vec(2, verticalStart + verticalSpacing * i - 10)), module, ComputerscareLaundrySoup::CLOCK_INPUT + i));
//individual reset input
- addInput(Port::create<InPort>(mm2px(Vec(12, verticalStart + verticalSpacing*i-10)), Port::INPUT, module, ComputerscareLaundrySoup::RESET_INPUT + i));
-
- //sequence input field
- textField = Widget::create<MyTextField>(mm2px(Vec(1, verticalStart + verticalSpacing*i)));
- textField->setModule(module);
- textField->box.size = mm2px(Vec(63, 7));
- textField->rowIndex = i;
- textField->multiline = false;
- textField->color = nvgRGB(0xC0, 0xE7, 0xDE);
- addChild(textField);
- module->textFields[i] = textField;
+ addInput(createInput<InPort>(mm2px(Vec(12, verticalStart + verticalSpacing * i - 10)), module, ComputerscareLaundrySoup::RESET_INPUT + i));
+
+
+ /* textFieldTemp = createWidget<LaundryTF2>(mm2px(Vec(1, verticalStart + verticalSpacing * i)));
+ textFieldTemp->module = module;
+ textFieldTemp->box.size = mm2px(Vec(44, 7));
+ textFieldTemp->multiline = false;
+ textFieldTemp->color = nvgRGB(0xC0, 0xE7, 0xDE);
+ textFieldTemp->text = "";
+ textFieldTemp->rowIndex = i;
+ module->textFields[i] = textFieldTemp;
+ textFieldTemp->module = module;
+ addChild(textFieldTemp);*/
+ textFieldTemp = new LaundryTF2(i);
+ textFieldTemp->box.pos = mm2px(Vec(1, verticalStart + verticalSpacing * i));
+ textFieldTemp->module = module;
+ textFieldTemp->box.size = mm2px(Vec(44, 7));
+ textFieldTemp->multiline = false;
+ textFieldTemp->color = nvgRGB(0xC0, 0xE7, 0xDE);
+ textFieldTemp->text = "";
+
+ laundryTextFields[i] = textFieldTemp;
+ addChild(textFieldTemp);
+
// active / total steps display
- smallLetterDisplay = new SmallLetterDisplay();
- smallLetterDisplay->box.pos = mm2px(Vec(22,verticalStart - 9.2 +verticalSpacing*i));
+ smallLetterDisplay = new LaundrySmallDisplay(i);
+ smallLetterDisplay->box.pos = mm2px(Vec(22, verticalStart - 9.2 + verticalSpacing * i));
smallLetterDisplay->box.size = Vec(60, 30);
smallLetterDisplay->value = std::to_string(3);
smallLetterDisplay->baseColor = COLOR_COMPUTERSCARE_LIGHT_GREEN;
+ smallLetterDisplay->module=module;
addChild(smallLetterDisplay);
- module->smallLetterDisplays[i] = smallLetterDisplay;
+ //module->smallLetterDisplays[i] = smallLetterDisplay;
- addParam(ParamWidget::create<ComputerscareInvisibleButton>(mm2px(Vec(20,verticalStart - 9.2 +verticalSpacing*i)), module, ComputerscareLaundrySoup::INDIVIDUAL_RESET_PARAM + i, 0.0, 1.0, 0.0));
+ addParam(createParam<ComputerscareInvisibleButton>(mm2px(Vec(20, verticalStart - 9.2 + verticalSpacing * i)), module, ComputerscareLaundrySoup::INDIVIDUAL_RESET_PARAM + i));
}
+
+ laundry = module;
module->onCreate();
}
- MyTextField* textField;
- SmallLetterDisplay* smallLetterDisplay;
+ json_t *toJson() override
+ {
+ json_t *rootJ = ModuleWidget::toJson();
+
+ json_t *sequencesJ = json_array();
+ for (int i = 0; i < numFields; i++) {
+ json_t *sequenceJ = json_string(laundryTextFields[i]->text.c_str());
+ json_array_append_new(sequencesJ, sequenceJ);
+ }
+ json_object_set_new(rootJ, "sequences", sequencesJ);
+
+ return rootJ;
+ }
+
+ void fromJson(json_t *rootJ) override
+ {
+
+ ModuleWidget::fromJson(rootJ);
+ json_t *sequencesJ = json_object_get(rootJ, "sequences");
+ if (sequencesJ) {
+ for (int i = 0; i < numFields; i++) {
+
+ json_t *sequenceJ = json_array_get(sequencesJ, i);
+ if (sequenceJ)
+ laundryTextFields[i]->text = json_string_value(sequenceJ);
+ }
+ }
+ }
+
+ ComputerscareLaundrySoup *laundry;
+
+ LaundryTF2 *textFieldTemp;
+ LaundryTF2 *laundryTextFields[numFields];
+ LaundrySmallDisplay* smallLetterDisplay;
};
-Model *modelComputerscareLaundrySoup = Model::create<ComputerscareLaundrySoup, ComputerscareLaundrySoupWidget>("computerscare", "computerscare-laundry-soup", "Laundry Soup", SEQUENCER_TAG);
+Model *modelComputerscareLaundrySoup = createModel<ComputerscareLaundrySoup, ComputerscareLaundrySoupWidget>("computerscare-laundry-soup");
diff --git a/src/ComputerscarePatchSequencer.cpp b/src/ComputerscarePatchSequencer.cpp
@@ -207,7 +207,7 @@ struct ComputerscarePatchSequencer : Module {
void ComputerscarePatchSequencer::process(const ProcessArgs &args) {
int numStepsKnobPosition = (int) clamp(roundf(params[STEPS_PARAM].getValue()), 1.0f, 16.0f);
- int channels[10] = {0};
+ //int channels[10] = {0};
for ( int j = 0 ; j < 10 ; j++)
{