diff --git a/src/core/MidiInterface.cpp b/src/core/MidiInterface.cpp index 26489ae9..b6eb0170 100644 --- a/src/core/MidiInterface.cpp +++ b/src/core/MidiInterface.cpp @@ -474,6 +474,7 @@ struct MIDICCToCVInterface : MidiIO, Module { int cc[NUM_OUTPUTS]; int ccNum[NUM_OUTPUTS]; + bool ccNumInited[NUM_OUTPUTS]; float lights[NUM_OUTPUTS]; @@ -507,6 +508,7 @@ struct MIDICCToCVInterface : MidiIO, Module { json_t *ccNumJ = json_object_get(rootJ, std::to_string(i).c_str()); if (ccNumJ) { ccNum[i] = json_integer_value(ccNumJ); + ccNumInited[i] = true; } } @@ -562,45 +564,44 @@ void MIDICCToCVInterface::processMidi(std::vector msg) { } -struct CCNumItem : MenuItem { - MIDICCToCVInterface *midiModule; - int cc; - int num; +struct CCTextField : TextField { + void draw(NVGcontext *vg); - void onAction() { - midiModule->ccNum[num] = cc; - } + int *ccNum; + bool *inited; }; -struct CCNumChoice : ChoiceButton { - MIDICCToCVInterface *midiModule; - int num; - - void onAction() { - Menu *menu = gScene->createMenu(); - menu->box.pos = getAbsolutePos().plus(Vec(0, box.size.y)); - menu->box.size.x = box.size.x; - - for (int cc = 0; cc < 128; cc++) { - CCNumItem *ccNumItem = new CCNumItem(); - ccNumItem->midiModule = midiModule; - ccNumItem->cc = cc; - ccNumItem->num = num; - ccNumItem->text = std::to_string(cc); - menu->pushChild(ccNumItem); +void CCTextField::draw(NVGcontext *vg) { + // Note: this might not be the best way to do this. + // Text field should have a virtual "onTextChange" function or something. + // draw() is triggered way more frequently + if (text.size() > 0) { + if (*inited) { + *inited = false; + text = std::to_string(*ccNum); } - } - - void step() { - text = std::to_string(midiModule->ccNum[num]); - } -}; + try { + *ccNum = std::stoi(text, NULL, 10); + // Only allow valid cc numbers + if (*ccNum < 0 || *ccNum > 127) { + text = ""; + begin = 0; + end = text.size(); + } + } catch (...) { + text = ""; + begin = 0; + end = text.size(); + } + }; + TextField::draw(vg); +} MIDICCToCVWidget::MIDICCToCVWidget() { MIDICCToCVInterface *module = new MIDICCToCVInterface(); setModule(module); - box.size = Vec(15 * 18, 380); + box.size = Vec(16 * 15, 380); { Panel *panel = new LightPanel(); @@ -612,17 +613,29 @@ MIDICCToCVWidget::MIDICCToCVWidget() { float labelHeight = 15; float yPos = margin; + addChild(createScrew(Vec(margin, 0))); + addChild(createScrew(Vec(box.size.x - 15 - margin, 0))); + addChild(createScrew(Vec(margin, 365))); + addChild(createScrew(Vec(box.size.x - 15 - margin, 365))); { Label *label = new Label(); - label->box.pos = Vec(margin, yPos); + label->box.pos = Vec(box.size.x - margin - 11 * 15, margin); label->text = "MIDI CC to CV"; addChild(label); - yPos += labelHeight + margin; + yPos = labelHeight * 2; + + } + + { + Label *label = new Label(); + label->box.pos = Vec(margin, yPos); + label->text = "MIDI Interface"; + addChild(label); MidiChoice *midiChoice = new MidiChoice(); midiChoice->midiModule = dynamic_cast(module); - midiChoice->box.pos = Vec(margin, yPos); - midiChoice->box.size.x = box.size.x - 10; + midiChoice->box.pos = Vec((box.size.x - 10) / 2 + margin, yPos); + midiChoice->box.size.x = (box.size.x / 2.0) - margin; addChild(midiChoice); yPos += midiChoice->box.size.y + margin; } @@ -632,31 +645,31 @@ MIDICCToCVWidget::MIDICCToCVWidget() { label->box.pos = Vec(margin, yPos); label->text = "Channel"; addChild(label); - yPos += labelHeight + margin; ChannelChoice *channelChoice = new ChannelChoice(); channelChoice->midiModule = dynamic_cast(module); - channelChoice->box.pos = Vec(margin, yPos); - channelChoice->box.size.x = box.size.x - 10; + channelChoice->box.pos = Vec((box.size.x - 10) / 2 + margin, yPos); + channelChoice->box.size.x = (box.size.x / 2.0) - margin; addChild(channelChoice); - yPos += channelChoice->box.size.y + margin + 15; + yPos += channelChoice->box.size.y + margin * 2; } for (int i = 0; i < MIDICCToCVInterface::NUM_OUTPUTS; i++) { - CCNumChoice *ccNumChoice = new CCNumChoice(); - ccNumChoice->midiModule = module; - ccNumChoice->num = module->ccNum[i]; - ccNumChoice->box.pos = Vec(10 + (i % 4) * (67), yPos); - ccNumChoice->box.size.x = 15 * 3; + CCTextField *ccNumChoice = new CCTextField(); + ccNumChoice->ccNum = &module->ccNum[i]; + ccNumChoice->inited = &module->ccNumInited[i]; + ccNumChoice->text = std::to_string(module->ccNum[i]); + ccNumChoice->box.pos = Vec(10 + (i % 4) * (63), yPos); + ccNumChoice->box.size.x = 15 * 2; addChild(ccNumChoice); yPos += labelHeight + margin; - addOutput(createOutput(Vec(10 + (i % 4) * (67), yPos + 5), module, i)); - addChild(createValueLight>(Vec((i % 4) * (67) + 32, yPos + 5), &module->lights[i])); + addOutput(createOutput(Vec((i % 4) * (63) + 10, yPos + 5), module, i)); + addChild(createValueLight>(Vec((i % 4) * (63) + 32, yPos + 5), &module->lights[i])); if ((i + 1) % 4 == 0) { - yPos += 40 + margin; + yPos += 50 + margin; } else { yPos -= labelHeight + margin; }