@@ -60,8 +60,8 @@ struct ModuleWidget : OpaqueWidget { | |||||
std::vector<Port*> outputs; | std::vector<Port*> outputs; | ||||
std::vector<ParamWidget*> params; | std::vector<ParamWidget*> params; | ||||
ModuleWidget(Module *module); | |||||
~ModuleWidget(); | ~ModuleWidget(); | ||||
void setModule(Module *module); | |||||
/** Convenience functions for adding special widgets (calls addChild()) */ | /** Convenience functions for adding special widgets (calls addChild()) */ | ||||
void addInput(Port *input); | void addInput(Port *input); | ||||
void addOutput(Port *output); | void addOutput(Port *output); | ||||
@@ -50,9 +50,9 @@ struct Module { | |||||
/** For CPU usage meter */ | /** For CPU usage meter */ | ||||
float cpuTime = 0.0; | float cpuTime = 0.0; | ||||
/** Deprecated, use constructor below this one */ | |||||
Module() DEPRECATED {} | |||||
/** Constructs Module with a fixed number of params, inputs, and outputs */ | |||||
/** Constructs a Module with no params, inputs, outputs, and lights */ | |||||
Module() {} | |||||
/** Constructs a Module with a fixed number of params, inputs, outputs, and lights */ | |||||
Module(int numParams, int numInputs, int numOutputs, int numLights = 0) { | Module(int numParams, int numInputs, int numOutputs, int numLights = 0) { | ||||
params.resize(numParams); | params.resize(numParams); | ||||
inputs.resize(numInputs); | inputs.resize(numInputs); | ||||
@@ -11,6 +11,7 @@ struct ModuleWidget; | |||||
struct Module; | struct Module; | ||||
struct Model; | struct Model; | ||||
// Subclass this and return a pointer to a new one when init() is called | // Subclass this and return a pointer to a new one when init() is called | ||||
struct Plugin { | struct Plugin { | ||||
/** A list of the models available by this plugin, add with addModel() */ | /** A list of the models available by this plugin, add with addModel() */ | ||||
@@ -39,6 +40,7 @@ struct Plugin { | |||||
void addModel(Model *model); | void addModel(Model *model); | ||||
}; | }; | ||||
struct Model { | struct Model { | ||||
Plugin *plugin = NULL; | Plugin *plugin = NULL; | ||||
/** An identifier for the model, e.g. "VCO". Used for saving patches. The slug, manufacturerSlug pair must be unique. */ | /** An identifier for the model, e.g. "VCO". Used for saving patches. The slug, manufacturerSlug pair must be unique. */ | ||||
@@ -54,10 +56,43 @@ struct Model { | |||||
std::list<ModelTag> tags; | std::list<ModelTag> tags; | ||||
virtual ~Model() {} | virtual ~Model() {} | ||||
/** Creates a headless Module */ | |||||
virtual Module *createModule() { return NULL; } | virtual Module *createModule() { return NULL; } | ||||
/** Creates a ModuleWidget with a Module attached */ | |||||
virtual ModuleWidget *createModuleWidget() { return NULL; } | virtual ModuleWidget *createModuleWidget() { return NULL; } | ||||
/** Creates a ModuleWidget with no Module, useful for previews */ | |||||
virtual ModuleWidget *createModuleWidgetNull() { return NULL; } | |||||
/** Create Model subclass which constructs a specific Module and ModuleWidget subclass */ | |||||
template <typename TModule, typename TModuleWidget, typename... Tags> | |||||
static Model *create(std::string manufacturer, std::string slug, std::string name, Tags... tags) { | |||||
struct TModel : Model { | |||||
Module *createModule() override { | |||||
TModule *module = new TModule(); | |||||
return module; | |||||
} | |||||
ModuleWidget *createModuleWidget() override { | |||||
TModule *module = new TModule(); | |||||
TModuleWidget *moduleWidget = new TModuleWidget(module); | |||||
moduleWidget->model = this; | |||||
return moduleWidget; | |||||
} | |||||
ModuleWidget *createModuleWidgetNull() override { | |||||
TModuleWidget *moduleWidget = new TModuleWidget(NULL); | |||||
moduleWidget->model = this; | |||||
return moduleWidget; | |||||
} | |||||
}; | |||||
TModel *o = new TModel(); | |||||
o->manufacturer = manufacturer; | |||||
o->slug = slug; | |||||
o->name = name; | |||||
o->tags = {tags...}; | |||||
return o; | |||||
} | |||||
}; | }; | ||||
void pluginInit(); | void pluginInit(); | ||||
void pluginDestroy(); | void pluginDestroy(); | ||||
void pluginLogIn(std::string email, std::string password); | void pluginLogIn(std::string email, std::string password); | ||||
@@ -18,8 +18,9 @@ namespace rack { | |||||
// helpers | // helpers | ||||
//////////////////// | //////////////////// | ||||
/** Deprecated, use Model::create<TModule, TModuleWidget>(...) instead */ | |||||
template <class TModuleWidget, typename... Tags> | template <class TModuleWidget, typename... Tags> | ||||
Model *createModel(std::string manufacturer, std::string slug, std::string name, Tags... tags) { | |||||
DEPRECATED Model *createModel(std::string manufacturer, std::string slug, std::string name, Tags... tags) { | |||||
struct TModel : Model { | struct TModel : Model { | ||||
ModuleWidget *createModuleWidget() override { | ModuleWidget *createModuleWidget() override { | ||||
ModuleWidget *moduleWidget = new TModuleWidget(); | ModuleWidget *moduleWidget = new TModuleWidget(); | ||||
@@ -7,22 +7,22 @@ | |||||
namespace rack { | namespace rack { | ||||
ModuleWidget::ModuleWidget(Module *module) { | |||||
if (module) { | |||||
engineAddModule(module); | |||||
} | |||||
this->module = module; | |||||
} | |||||
ModuleWidget::~ModuleWidget() { | ModuleWidget::~ModuleWidget() { | ||||
// Make sure WireWidget destructors are called *before* removing `module` from the rack. | // Make sure WireWidget destructors are called *before* removing `module` from the rack. | ||||
disconnect(); | disconnect(); | ||||
// Remove and delete the Module instance | // Remove and delete the Module instance | ||||
setModule(NULL); | |||||
} | |||||
void ModuleWidget::setModule(Module *module) { | |||||
if (this->module) { | |||||
engineRemoveModule(this->module); | |||||
delete this->module; | |||||
} | |||||
if (module) { | if (module) { | ||||
engineAddModule(module); | |||||
engineRemoveModule(module); | |||||
delete module; | |||||
module = NULL; | |||||
} | } | ||||
this->module = module; | |||||
} | } | ||||
void ModuleWidget::addInput(Port *input) { | void ModuleWidget::addInput(Port *input) { | ||||
@@ -210,99 +210,102 @@ void AudioInterface::step() { | |||||
} | } | ||||
AudioInterfaceWidget::AudioInterfaceWidget() { | |||||
AudioInterface *module = new AudioInterface(); | |||||
setModule(module); | |||||
box.size = Vec(15*12, 380); | |||||
{ | |||||
Panel *panel = new LightPanel(); | |||||
panel->box.size = box.size; | |||||
addChild(panel); | |||||
} | |||||
struct AudioInterfaceWidget : ModuleWidget { | |||||
AudioInterfaceWidget(AudioInterface *module) : ModuleWidget(module) { | |||||
box.size = Vec(15*12, 380); | |||||
{ | |||||
Panel *panel = new LightPanel(); | |||||
panel->box.size = box.size; | |||||
addChild(panel); | |||||
} | |||||
addChild(Widget::create<ScrewSilver>(Vec(15, 0))); | |||||
addChild(Widget::create<ScrewSilver>(Vec(box.size.x-30, 0))); | |||||
addChild(Widget::create<ScrewSilver>(Vec(15, 365))); | |||||
addChild(Widget::create<ScrewSilver>(Vec(box.size.x-30, 365))); | |||||
Vec margin = Vec(5, 2); | |||||
float labelHeight = 15; | |||||
float yPos = margin.y + 100; | |||||
float xPos; | |||||
{ | |||||
Label *label = new Label(); | |||||
label->box.pos = Vec(margin.x, yPos); | |||||
label->text = "Outputs (DACs)"; | |||||
addChild(label); | |||||
yPos += labelHeight + margin.y; | |||||
} | |||||
addChild(Widget::create<ScrewSilver>(Vec(15, 0))); | |||||
addChild(Widget::create<ScrewSilver>(Vec(box.size.x-30, 0))); | |||||
addChild(Widget::create<ScrewSilver>(Vec(15, 365))); | |||||
addChild(Widget::create<ScrewSilver>(Vec(box.size.x-30, 365))); | |||||
Vec margin = Vec(5, 2); | |||||
float labelHeight = 15; | |||||
float yPos = margin.y + 100; | |||||
float xPos; | |||||
{ | |||||
Label *label = new Label(); | |||||
label->box.pos = Vec(margin.x, yPos); | |||||
label->text = "Outputs (DACs)"; | |||||
addChild(label); | |||||
yPos += labelHeight + margin.y; | |||||
} | |||||
yPos += 5; | |||||
xPos = 10; | |||||
for (int i = 0; i < 4; i++) { | |||||
addInput(Port::create<PJ3410Port>(Vec(xPos, yPos), Port::INPUT, module, AudioInterface::AUDIO_INPUT + i)); | |||||
Label *label = new Label(); | |||||
label->box.pos = Vec(xPos + 4, yPos + 28); | |||||
label->text = stringf("%d", i + 1); | |||||
addChild(label); | |||||
yPos += 5; | |||||
xPos = 10; | |||||
for (int i = 0; i < 4; i++) { | |||||
addInput(Port::create<PJ3410Port>(Vec(xPos, yPos), Port::INPUT, module, AudioInterface::AUDIO_INPUT + i)); | |||||
Label *label = new Label(); | |||||
label->box.pos = Vec(xPos + 4, yPos + 28); | |||||
label->text = stringf("%d", i + 1); | |||||
addChild(label); | |||||
xPos += 37 + margin.x; | |||||
} | |||||
yPos += 35 + margin.y; | |||||
yPos += 5; | |||||
xPos = 10; | |||||
for (int i = 4; i < 8; i++) { | |||||
addInput(Port::create<PJ3410Port>(Vec(xPos, yPos), Port::INPUT, module, AudioInterface::AUDIO_INPUT + i)); | |||||
Label *label = new Label(); | |||||
label->box.pos = Vec(xPos + 4, yPos + 28); | |||||
label->text = stringf("%d", i + 1); | |||||
addChild(label); | |||||
xPos += 37 + margin.x; | |||||
} | |||||
yPos += 35 + margin.y; | |||||
{ | |||||
Label *label = new Label(); | |||||
label->box.pos = Vec(margin.x, yPos); | |||||
label->text = "Inputs (ADCs)"; | |||||
addChild(label); | |||||
yPos += labelHeight + margin.y; | |||||
} | |||||
xPos += 37 + margin.x; | |||||
} | |||||
yPos += 35 + margin.y; | |||||
yPos += 5; | |||||
xPos = 10; | |||||
for (int i = 4; i < 8; i++) { | |||||
addInput(Port::create<PJ3410Port>(Vec(xPos, yPos), Port::INPUT, module, AudioInterface::AUDIO_INPUT + i)); | |||||
Label *label = new Label(); | |||||
label->box.pos = Vec(xPos + 4, yPos + 28); | |||||
label->text = stringf("%d", i + 1); | |||||
addChild(label); | |||||
xPos += 37 + margin.x; | |||||
} | |||||
yPos += 35 + margin.y; | |||||
{ | |||||
Label *label = new Label(); | |||||
label->box.pos = Vec(margin.x, yPos); | |||||
label->text = "Inputs (ADCs)"; | |||||
addChild(label); | |||||
yPos += labelHeight + margin.y; | |||||
} | |||||
yPos += 5; | |||||
xPos = 10; | |||||
for (int i = 0; i < 4; i++) { | |||||
Port *port = Port::create<PJ3410Port>(Vec(xPos, yPos), Port::OUTPUT, module, AudioInterface::AUDIO_OUTPUT + i); | |||||
addOutput(port); | |||||
Label *label = new Label(); | |||||
label->box.pos = Vec(xPos + 4, yPos + 28); | |||||
label->text = stringf("%d", i + 1); | |||||
addChild(label); | |||||
xPos += 37 + margin.x; | |||||
} | |||||
yPos += 35 + margin.y; | |||||
yPos += 5; | |||||
xPos = 10; | |||||
for (int i = 4; i < 8; i++) { | |||||
addOutput(Port::create<PJ3410Port>(Vec(xPos, yPos), Port::OUTPUT, module, AudioInterface::AUDIO_OUTPUT + i)); | |||||
Label *label = new Label(); | |||||
label->box.pos = Vec(xPos + 4, yPos + 28); | |||||
label->text = stringf("%d", i + 1); | |||||
addChild(label); | |||||
xPos += 37 + margin.x; | |||||
yPos += 5; | |||||
xPos = 10; | |||||
for (int i = 0; i < 4; i++) { | |||||
Port *port = Port::create<PJ3410Port>(Vec(xPos, yPos), Port::OUTPUT, module, AudioInterface::AUDIO_OUTPUT + i); | |||||
addOutput(port); | |||||
Label *label = new Label(); | |||||
label->box.pos = Vec(xPos + 4, yPos + 28); | |||||
label->text = stringf("%d", i + 1); | |||||
addChild(label); | |||||
xPos += 37 + margin.x; | |||||
} | |||||
yPos += 35 + margin.y; | |||||
yPos += 5; | |||||
xPos = 10; | |||||
for (int i = 4; i < 8; i++) { | |||||
addOutput(Port::create<PJ3410Port>(Vec(xPos, yPos), Port::OUTPUT, module, AudioInterface::AUDIO_OUTPUT + i)); | |||||
Label *label = new Label(); | |||||
label->box.pos = Vec(xPos + 4, yPos + 28); | |||||
label->text = stringf("%d", i + 1); | |||||
addChild(label); | |||||
xPos += 37 + margin.x; | |||||
} | |||||
yPos += 35 + margin.y; | |||||
AudioWidget *audioWidget = construct<USB_B_AudioWidget>(); | |||||
audioWidget->audioIO = &module->audioIO; | |||||
addChild(audioWidget); | |||||
// Lights | |||||
addChild(ModuleLightWidget::create<SmallLight<GreenLight>>(Vec(40, 20), module, AudioInterface::ACTIVE_LIGHT)); | |||||
} | } | ||||
yPos += 35 + margin.y; | |||||
}; | |||||
AudioWidget *audioWidget = construct<USB_B_AudioWidget>(); | |||||
audioWidget->audioIO = &module->audioIO; | |||||
addChild(audioWidget); | |||||
// Lights | |||||
addChild(ModuleLightWidget::create<SmallLight<GreenLight>>(Vec(40, 20), module, AudioInterface::ACTIVE_LIGHT)); | |||||
} | |||||
Model *modelAudioInterface = Model::create<AudioInterface, AudioInterfaceWidget>("Core", "AudioInterface", "Audio Interface", EXTERNAL_TAG); |
@@ -56,58 +56,68 @@ struct ModuleResizeHandle : Widget { | |||||
}; | }; | ||||
BlankWidget::BlankWidget() { | |||||
box.size = Vec(RACK_GRID_WIDTH * 10, RACK_GRID_HEIGHT); | |||||
struct BlankWidget : ModuleWidget { | |||||
Panel *panel; | |||||
Widget *topRightScrew; | |||||
Widget *bottomRightScrew; | |||||
Widget *rightHandle; | |||||
BlankWidget(Module *module) : ModuleWidget(module) { | |||||
box.size = Vec(RACK_GRID_WIDTH * 10, RACK_GRID_HEIGHT); | |||||
{ | |||||
panel = new LightPanel(); | |||||
panel->box.size = box.size; | |||||
addChild(panel); | |||||
} | |||||
{ | |||||
panel = new LightPanel(); | |||||
panel->box.size = box.size; | |||||
addChild(panel); | |||||
ModuleResizeHandle *leftHandle = new ModuleResizeHandle(); | |||||
ModuleResizeHandle *rightHandle = new ModuleResizeHandle(); | |||||
rightHandle->right = true; | |||||
this->rightHandle = rightHandle; | |||||
addChild(leftHandle); | |||||
addChild(rightHandle); | |||||
addChild(Widget::create<ScrewSilver>(Vec(15, 0))); | |||||
addChild(Widget::create<ScrewSilver>(Vec(15, 365))); | |||||
topRightScrew = Widget::create<ScrewSilver>(Vec(box.size.x - 30, 0)); | |||||
bottomRightScrew = Widget::create<ScrewSilver>(Vec(box.size.x - 30, 365)); | |||||
addChild(topRightScrew); | |||||
addChild(bottomRightScrew); | |||||
} | } | ||||
ModuleResizeHandle *leftHandle = new ModuleResizeHandle(); | |||||
ModuleResizeHandle *rightHandle = new ModuleResizeHandle(); | |||||
rightHandle->right = true; | |||||
this->rightHandle = rightHandle; | |||||
addChild(leftHandle); | |||||
addChild(rightHandle); | |||||
addChild(Widget::create<ScrewSilver>(Vec(15, 0))); | |||||
addChild(Widget::create<ScrewSilver>(Vec(15, 365))); | |||||
topRightScrew = Widget::create<ScrewSilver>(Vec(box.size.x - 30, 0)); | |||||
bottomRightScrew = Widget::create<ScrewSilver>(Vec(box.size.x - 30, 365)); | |||||
addChild(topRightScrew); | |||||
addChild(bottomRightScrew); | |||||
} | |||||
void BlankWidget::step() { | |||||
panel->box.size = box.size; | |||||
topRightScrew->box.pos.x = box.size.x - 30; | |||||
bottomRightScrew->box.pos.x = box.size.x - 30; | |||||
if (box.size.x < RACK_GRID_WIDTH * 6) { | |||||
topRightScrew->visible = bottomRightScrew->visible = false; | |||||
} | |||||
else { | |||||
topRightScrew->visible = bottomRightScrew->visible = true; | |||||
void step() override { | |||||
panel->box.size = box.size; | |||||
topRightScrew->box.pos.x = box.size.x - 30; | |||||
bottomRightScrew->box.pos.x = box.size.x - 30; | |||||
if (box.size.x < RACK_GRID_WIDTH * 6) { | |||||
topRightScrew->visible = bottomRightScrew->visible = false; | |||||
} | |||||
else { | |||||
topRightScrew->visible = bottomRightScrew->visible = true; | |||||
} | |||||
rightHandle->box.pos.x = box.size.x - rightHandle->box.size.x; | |||||
ModuleWidget::step(); | |||||
} | } | ||||
rightHandle->box.pos.x = box.size.x - rightHandle->box.size.x; | |||||
ModuleWidget::step(); | |||||
} | |||||
json_t *BlankWidget::toJson() { | |||||
json_t *rootJ = ModuleWidget::toJson(); | |||||
json_t *toJson() override { | |||||
json_t *rootJ = ModuleWidget::toJson(); | |||||
// // width | |||||
json_object_set_new(rootJ, "width", json_real(box.size.x)); | |||||
return rootJ; | |||||
} | |||||
// // width | |||||
json_object_set_new(rootJ, "width", json_real(box.size.x)); | |||||
void fromJson(json_t *rootJ) override { | |||||
ModuleWidget::fromJson(rootJ); | |||||
return rootJ; | |||||
} | |||||
// width | |||||
json_t *widthJ = json_object_get(rootJ, "width"); | |||||
if (widthJ) | |||||
box.size.x = json_number_value(widthJ); | |||||
} | |||||
}; | |||||
void BlankWidget::fromJson(json_t *rootJ) { | |||||
ModuleWidget::fromJson(rootJ); | |||||
// width | |||||
json_t *widthJ = json_object_get(rootJ, "width"); | |||||
if (widthJ) | |||||
box.size.x = json_number_value(widthJ); | |||||
} | |||||
Model *modelBlank = Model::create<Module, BlankWidget>("Core", "Blank", "Blank", BLANK_TAG); |
@@ -6,7 +6,7 @@ | |||||
/* | /* | ||||
* MIDIToCVInterface converts midi note on/off events, velocity , channel aftertouch, pitch wheel and mod wheel to | |||||
* MidiToCvInterface converts midi note on/off events, velocity , channel aftertouch, pitch wheel and mod wheel to | |||||
* CV | * CV | ||||
*/ | */ | ||||
struct MidiValue { | struct MidiValue { | ||||
@@ -16,7 +16,7 @@ struct MidiValue { | |||||
}; | }; | ||||
struct MIDIToCVInterface : Module { | |||||
struct MidiToCvInterface : Module { | |||||
enum ParamIds { | enum ParamIds { | ||||
RESET_PARAM, | RESET_PARAM, | ||||
NUM_PARAMS | NUM_PARAMS | ||||
@@ -51,12 +51,12 @@ struct MIDIToCVInterface : Module { | |||||
SchmittTrigger resetTrigger; | SchmittTrigger resetTrigger; | ||||
MIDIToCVInterface() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) { | |||||
MidiToCvInterface() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) { | |||||
pitchWheel.val = 64; | pitchWheel.val = 64; | ||||
// pitchWheel.tSmooth.set(0, 0); | // pitchWheel.tSmooth.set(0, 0); | ||||
} | } | ||||
~MIDIToCVInterface() { | |||||
~MidiToCvInterface() { | |||||
}; | }; | ||||
void step() override; | void step() override; | ||||
@@ -85,7 +85,7 @@ struct MIDIToCVInterface : Module { | |||||
}; | }; | ||||
/* | /* | ||||
void MIDIToCVInterface::resetMidi() { | |||||
void MidiToCvInterface::resetMidi() { | |||||
mod.val = 0; | mod.val = 0; | ||||
mod.tSmooth.set(0, 0); | mod.tSmooth.set(0, 0); | ||||
pitchWheel.val = 64; | pitchWheel.val = 64; | ||||
@@ -98,7 +98,7 @@ void MIDIToCVInterface::resetMidi() { | |||||
} | } | ||||
*/ | */ | ||||
void MIDIToCVInterface::step() { | |||||
void MidiToCvInterface::step() { | |||||
/* | /* | ||||
if (isPortOpen()) { | if (isPortOpen()) { | ||||
std::vector<unsigned char> message; | std::vector<unsigned char> message; | ||||
@@ -143,7 +143,7 @@ void MIDIToCVInterface::step() { | |||||
lights[ACTIVE_LIGHT].value = midiInput.isActive() ? 1.0 : 0.0; | lights[ACTIVE_LIGHT].value = midiInput.isActive() ? 1.0 : 0.0; | ||||
} | } | ||||
void MIDIToCVInterface::pressNote(int note) { | |||||
void MidiToCvInterface::pressNote(int note) { | |||||
// Remove existing similar note | // Remove existing similar note | ||||
auto it = std::find(notes.begin(), notes.end(), note); | auto it = std::find(notes.begin(), notes.end(), note); | ||||
if (it != notes.end()) | if (it != notes.end()) | ||||
@@ -154,7 +154,7 @@ void MIDIToCVInterface::pressNote(int note) { | |||||
gate = true; | gate = true; | ||||
} | } | ||||
void MIDIToCVInterface::releaseNote(int note) { | |||||
void MidiToCvInterface::releaseNote(int note) { | |||||
// Remove the note | // Remove the note | ||||
auto it = std::find(notes.begin(), notes.end(), note); | auto it = std::find(notes.begin(), notes.end(), note); | ||||
if (it != notes.end()) | if (it != notes.end()) | ||||
@@ -174,7 +174,7 @@ void MIDIToCVInterface::releaseNote(int note) { | |||||
} | } | ||||
} | } | ||||
void MIDIToCVInterface::processMidi(std::vector<unsigned char> msg) { | |||||
void MidiToCvInterface::processMidi(std::vector<unsigned char> msg) { | |||||
/* | /* | ||||
int channel = msg[0] & 0xf; | int channel = msg[0] & 0xf; | ||||
int status = (msg[0] >> 4) & 0xf; | int status = (msg[0] >> 4) & 0xf; | ||||
@@ -229,55 +229,58 @@ void MIDIToCVInterface::processMidi(std::vector<unsigned char> msg) { | |||||
} | } | ||||
MidiToCVWidget::MidiToCVWidget() { | |||||
MIDIToCVInterface *module = new MIDIToCVInterface(); | |||||
setModule(module); | |||||
box.size = Vec(15 * 9, 380); | |||||
struct MidiToCvInterfaceWidget : ModuleWidget { | |||||
MidiToCvInterfaceWidget(MidiToCvInterface *module) : ModuleWidget(module) { | |||||
box.size = Vec(15 * 9, 380); | |||||
{ | |||||
Panel *panel = new LightPanel(); | |||||
panel->box.size = box.size; | |||||
addChild(panel); | |||||
} | |||||
{ | |||||
Panel *panel = new LightPanel(); | |||||
panel->box.size = box.size; | |||||
addChild(panel); | |||||
} | |||||
float margin = 5; | |||||
float labelHeight = 15; | |||||
float yPos = margin; | |||||
float yGap = 35; | |||||
addChild(Widget::create<ScrewSilver>(Vec(15, 0))); | |||||
addChild(Widget::create<ScrewSilver>(Vec(box.size.x - 30, 0))); | |||||
addChild(Widget::create<ScrewSilver>(Vec(15, 365))); | |||||
addChild(Widget::create<ScrewSilver>(Vec(box.size.x - 30, 365))); | |||||
{ | |||||
Label *label = new Label(); | |||||
label->box.pos = Vec(box.size.x - margin - 7 * 15, margin); | |||||
label->text = "MIDI to CV"; | |||||
addChild(label); | |||||
yPos = labelHeight * 2; | |||||
} | |||||
float margin = 5; | |||||
float labelHeight = 15; | |||||
float yPos = margin; | |||||
float yGap = 35; | |||||
addChild(Widget::create<ScrewSilver>(Vec(15, 0))); | |||||
addChild(Widget::create<ScrewSilver>(Vec(box.size.x - 30, 0))); | |||||
addChild(Widget::create<ScrewSilver>(Vec(15, 365))); | |||||
addChild(Widget::create<ScrewSilver>(Vec(box.size.x - 30, 365))); | |||||
{ | |||||
Label *label = new Label(); | |||||
label->box.pos = Vec(box.size.x - margin - 7 * 15, margin); | |||||
label->text = "MIDI to CV"; | |||||
addChild(label); | |||||
yPos = labelHeight * 2; | |||||
} | |||||
addParam(ParamWidget::create<LEDButton>(Vec(7 * 15, labelHeight), module, MidiToCvInterface::RESET_PARAM, 0.0, 1.0, 0.0)); | |||||
addChild(ModuleLightWidget::create<SmallLight<RedLight>>(Vec(7 * 15 + 5, labelHeight + 5), module, MidiToCvInterface::RESET_LIGHT)); | |||||
addParam(ParamWidget::create<LEDButton>(Vec(7 * 15, labelHeight), module, MIDIToCVInterface::RESET_PARAM, 0.0, 1.0, 0.0)); | |||||
addChild(ModuleLightWidget::create<SmallLight<RedLight>>(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"}; | |||||
std::string labels[MIDIToCVInterface::NUM_OUTPUTS] = {"1V/oct", "Gate", "Velocity", "Mod Wheel", "Pitch Wheel", "Aftertouch"}; | |||||
for (int i = 0; i < MidiToCvInterface::NUM_OUTPUTS; i++) { | |||||
Label *label = new Label(); | |||||
label->box.pos = Vec(margin, yPos); | |||||
label->text = labels[i]; | |||||
addChild(label); | |||||
for (int i = 0; i < MIDIToCVInterface::NUM_OUTPUTS; i++) { | |||||
Label *label = new Label(); | |||||
label->box.pos = Vec(margin, yPos); | |||||
label->text = labels[i]; | |||||
addChild(label); | |||||
addOutput(Port::create<PJ3410Port>(Vec(15 * 6, yPos - 5), Port::OUTPUT, module, i)); | |||||
addOutput(Port::create<PJ3410Port>(Vec(15 * 6, yPos - 5), Port::OUTPUT, module, i)); | |||||
yPos += yGap + margin; | |||||
} | |||||
MidiWidget *midiWidget = construct<MIDI_DIN_MidiWidget>(); | |||||
midiWidget->midiIO = &module->midiInput; | |||||
addChild(midiWidget); | |||||
yPos += yGap + margin; | |||||
// Lights | |||||
addChild(ModuleLightWidget::create<SmallLight<GreenLight>>(Vec(40, 20), module, MidiToCvInterface::ACTIVE_LIGHT)); | |||||
} | } | ||||
}; | |||||
MidiWidget *midiWidget = construct<MIDI_DIN_MidiWidget>(); | |||||
midiWidget->midiIO = &module->midiInput; | |||||
addChild(midiWidget); | |||||
// Lights | |||||
addChild(ModuleLightWidget::create<SmallLight<GreenLight>>(Vec(40, 20), module, MIDIToCVInterface::ACTIVE_LIGHT)); | |||||
} | |||||
Model *modelMidiToCvInterface = Model::create<MidiToCvInterface, MidiToCvInterfaceWidget>("Core", "MIDIToCVInterface", "MIDI-to-CV Interface", MIDI_TAG, EXTERNAL_TAG); |
@@ -4,41 +4,48 @@ using namespace rack; | |||||
NotesWidget::NotesWidget() { | |||||
box.size = Vec(RACK_GRID_WIDTH * 18, RACK_GRID_HEIGHT); | |||||
{ | |||||
Panel *panel = new LightPanel(); | |||||
panel->box.size = box.size; | |||||
addChild(panel); | |||||
struct NotesWidget : ModuleWidget { | |||||
TextField *textField; | |||||
NotesWidget(Module *module) : ModuleWidget(module) { | |||||
box.size = Vec(RACK_GRID_WIDTH * 18, RACK_GRID_HEIGHT); | |||||
{ | |||||
Panel *panel = new LightPanel(); | |||||
panel->box.size = box.size; | |||||
addChild(panel); | |||||
} | |||||
addChild(Widget::create<ScrewSilver>(Vec(15, 0))); | |||||
addChild(Widget::create<ScrewSilver>(Vec(15, 365))); | |||||
addChild(Widget::create<ScrewSilver>(Vec(box.size.x - 30, 0))); | |||||
addChild(Widget::create<ScrewSilver>(Vec(box.size.x - 30, 365))); | |||||
textField = new TextField(); | |||||
textField->box.pos = Vec(15, 15); | |||||
textField->box.size = box.size.minus(Vec(30, 30)); | |||||
textField->multiline = true; | |||||
addChild(textField); | |||||
} | } | ||||
addChild(Widget::create<ScrewSilver>(Vec(15, 0))); | |||||
addChild(Widget::create<ScrewSilver>(Vec(15, 365))); | |||||
addChild(Widget::create<ScrewSilver>(Vec(box.size.x - 30, 0))); | |||||
addChild(Widget::create<ScrewSilver>(Vec(box.size.x - 30, 365))); | |||||
json_t *toJson() override { | |||||
json_t *rootJ = ModuleWidget::toJson(); | |||||
textField = new TextField(); | |||||
textField->box.pos = Vec(15, 15); | |||||
textField->box.size = box.size.minus(Vec(30, 30)); | |||||
textField->multiline = true; | |||||
addChild(textField); | |||||
} | |||||
// text | |||||
json_object_set_new(rootJ, "text", json_string(textField->text.c_str())); | |||||
json_t *NotesWidget::toJson() { | |||||
json_t *rootJ = ModuleWidget::toJson(); | |||||
return rootJ; | |||||
} | |||||
// text | |||||
json_object_set_new(rootJ, "text", json_string(textField->text.c_str())); | |||||
void fromJson(json_t *rootJ) override { | |||||
ModuleWidget::fromJson(rootJ); | |||||
return rootJ; | |||||
} | |||||
// text | |||||
json_t *textJ = json_object_get(rootJ, "text"); | |||||
if (textJ) | |||||
textField->text = json_string_value(textJ); | |||||
} | |||||
}; | |||||
void NotesWidget::fromJson(json_t *rootJ) { | |||||
ModuleWidget::fromJson(rootJ); | |||||
// text | |||||
json_t *textJ = json_object_get(rootJ, "text"); | |||||
if (textJ) | |||||
textField->text = json_string_value(textJ); | |||||
} | |||||
Model *modelNotes = Model::create<Module, NotesWidget>("Core", "Notes", "Notes", BLANK_TAG); |
@@ -3,18 +3,16 @@ | |||||
void init(rack::Plugin *p) { | void init(rack::Plugin *p) { | ||||
p->slug = "Core"; | p->slug = "Core"; | ||||
#ifdef VERSION | |||||
p->version = TOSTRING(VERSION); | p->version = TOSTRING(VERSION); | ||||
#endif | |||||
p->addModel(createModel<AudioInterfaceWidget>("Core", "AudioInterface", "Audio Interface", EXTERNAL_TAG)); | |||||
p->addModel(modelAudioInterface); | |||||
p->addModel(modelMidiToCvInterface); | |||||
p->addModel(modelBlank); | |||||
p->addModel(modelNotes); | |||||
p->addModel(createModel<MidiToCVWidget>("Core", "MIDIToCVInterface", "MIDI-to-CV Interface", MIDI_TAG, EXTERNAL_TAG)); | |||||
// TODO | |||||
// p->addModel(createModel<MIDICCToCVWidget>("Core", "MIDICCToCVInterface", "MIDI CC-to-CV Interface", MIDI_TAG, EXTERNAL_TAG)); | // p->addModel(createModel<MIDICCToCVWidget>("Core", "MIDICCToCVInterface", "MIDI CC-to-CV Interface", MIDI_TAG, EXTERNAL_TAG)); | ||||
// p->addModel(createModel<MIDIClockToCVWidget>("Core", "MIDIClockToCVInterface", "MIDI Clock-to-CV Interface", MIDI_TAG, EXTERNAL_TAG, CLOCK_TAG)); | // p->addModel(createModel<MIDIClockToCVWidget>("Core", "MIDIClockToCVInterface", "MIDI Clock-to-CV Interface", MIDI_TAG, EXTERNAL_TAG, CLOCK_TAG)); | ||||
// p->addModel(createModel<MIDITriggerToCVWidget>("Core", "MIDITriggerToCVInterface", "MIDI Trigger-to-CV Interface", MIDI_TAG, EXTERNAL_TAG)); | // p->addModel(createModel<MIDITriggerToCVWidget>("Core", "MIDITriggerToCVInterface", "MIDI Trigger-to-CV Interface", MIDI_TAG, EXTERNAL_TAG)); | ||||
// p->addModel(createModel<QuadMidiToCVWidget>("Core", "QuadMIDIToCVInterface", "Quad MIDI-to-CV Interface", MIDI_TAG, EXTERNAL_TAG, QUAD_TAG)); | // p->addModel(createModel<QuadMidiToCVWidget>("Core", "QuadMIDIToCVInterface", "Quad MIDI-to-CV Interface", MIDI_TAG, EXTERNAL_TAG, QUAD_TAG)); | ||||
p->addModel(createModel<BlankWidget>("Core", "Blank", "Blank", BLANK_TAG)); | |||||
p->addModel(createModel<NotesWidget>("Core", "Notes", "Notes", BLANK_TAG)); | |||||
} | } |
@@ -4,17 +4,16 @@ | |||||
using namespace rack; | using namespace rack; | ||||
extern Model *modelAudioInterface; | |||||
extern Model *modelMidiToCvInterface; | |||||
extern Model *modelBlank; | |||||
extern Model *modelNotes; | |||||
//////////////////// | //////////////////// | ||||
// module widgets | // module widgets | ||||
//////////////////// | //////////////////// | ||||
struct AudioInterfaceWidget : ModuleWidget { | |||||
AudioInterfaceWidget(); | |||||
}; | |||||
struct MidiToCVWidget : ModuleWidget { | |||||
MidiToCVWidget(); | |||||
}; | |||||
// struct MIDICCToCVWidget : ModuleWidget { | // struct MIDICCToCVWidget : ModuleWidget { | ||||
// MIDICCToCVWidget(); | // MIDICCToCVWidget(); | ||||
@@ -35,25 +34,3 @@ struct MidiToCVWidget : ModuleWidget { | |||||
// QuadMidiToCVWidget(); | // QuadMidiToCVWidget(); | ||||
// void step() override; | // void step() override; | ||||
// }; | // }; | ||||
struct BridgeWidget : ModuleWidget { | |||||
BridgeWidget(); | |||||
}; | |||||
struct BlankWidget : ModuleWidget { | |||||
Panel *panel; | |||||
Widget *topRightScrew; | |||||
Widget *bottomRightScrew; | |||||
Widget *rightHandle; | |||||
BlankWidget(); | |||||
void step() override; | |||||
json_t *toJson() override; | |||||
void fromJson(json_t *rootJ) override; | |||||
}; | |||||
struct NotesWidget : ModuleWidget { | |||||
TextField *textField; | |||||
NotesWidget(); | |||||
json_t *toJson() override; | |||||
void fromJson(json_t *rootJ) override; | |||||
}; |