@@ -15,8 +15,6 @@ namespace app { | |||||
struct AudioWidget : LedDisplay { | struct AudioWidget : LedDisplay { | ||||
/** Not owned */ | |||||
audio::IO *audioIO = NULL; | |||||
LedDisplayChoice *driverChoice; | LedDisplayChoice *driverChoice; | ||||
LedDisplaySeparator *driverSeparator; | LedDisplaySeparator *driverSeparator; | ||||
LedDisplayChoice *deviceChoice; | LedDisplayChoice *deviceChoice; | ||||
@@ -24,8 +22,7 @@ struct AudioWidget : LedDisplay { | |||||
LedDisplayChoice *sampleRateChoice; | LedDisplayChoice *sampleRateChoice; | ||||
LedDisplaySeparator *sampleRateSeparator; | LedDisplaySeparator *sampleRateSeparator; | ||||
LedDisplayChoice *bufferSizeChoice; | LedDisplayChoice *bufferSizeChoice; | ||||
AudioWidget(); | |||||
void step() override; | |||||
void setAudioIO(audio::IO *audioIO); | |||||
}; | }; | ||||
@@ -15,15 +15,12 @@ namespace app { | |||||
struct MidiWidget : LedDisplay { | struct MidiWidget : LedDisplay { | ||||
/** Not owned */ | |||||
midi::IO *midiIO = NULL; | |||||
LedDisplayChoice *driverChoice; | LedDisplayChoice *driverChoice; | ||||
LedDisplaySeparator *driverSeparator; | LedDisplaySeparator *driverSeparator; | ||||
LedDisplayChoice *deviceChoice; | LedDisplayChoice *deviceChoice; | ||||
LedDisplaySeparator *deviceSeparator; | LedDisplaySeparator *deviceSeparator; | ||||
LedDisplayChoice *channelChoice; | LedDisplayChoice *channelChoice; | ||||
MidiWidget(); | |||||
void step() override; | |||||
void setMidiIO(midi::IO *midiIO); | |||||
}; | }; | ||||
@@ -272,8 +272,7 @@ struct AudioInterfaceWidget : ModuleWidget { | |||||
AudioWidget *audioWidget = createWidget<AudioWidget>(mm2px(Vec(3.2122073, 14.837339))); | AudioWidget *audioWidget = createWidget<AudioWidget>(mm2px(Vec(3.2122073, 14.837339))); | ||||
audioWidget->box.size = mm2px(Vec(44, 28)); | audioWidget->box.size = mm2px(Vec(44, 28)); | ||||
if (module) | |||||
audioWidget->audioIO = &module->audioIO; | |||||
audioWidget->setAudioIO(module ? &module->audioIO : NULL); | |||||
addChild(audioWidget); | addChild(audioWidget); | ||||
} | } | ||||
}; | }; | ||||
@@ -139,8 +139,7 @@ struct CV_CCWidget : ModuleWidget { | |||||
typedef Grid16MidiWidget<CcChoice<CV_CC>> TMidiWidget; | typedef Grid16MidiWidget<CcChoice<CV_CC>> TMidiWidget; | ||||
TMidiWidget *midiWidget = createWidget<TMidiWidget>(mm2px(Vec(3.399621, 14.837339))); | TMidiWidget *midiWidget = createWidget<TMidiWidget>(mm2px(Vec(3.399621, 14.837339))); | ||||
midiWidget->box.size = mm2px(Vec(44, 54.667)); | midiWidget->box.size = mm2px(Vec(44, 54.667)); | ||||
if (module) | |||||
midiWidget->midiIO = &module->midiOutput; | |||||
midiWidget->setMidiIO(module ? &module->midiOutput : NULL); | |||||
midiWidget->setModule(module); | midiWidget->setModule(module); | ||||
addChild(midiWidget); | addChild(midiWidget); | ||||
} | } | ||||
@@ -189,8 +189,7 @@ struct CV_GateWidget : ModuleWidget { | |||||
typedef Grid16MidiWidget<NoteChoice<CV_Gate>> TMidiWidget; | typedef Grid16MidiWidget<NoteChoice<CV_Gate>> TMidiWidget; | ||||
TMidiWidget *midiWidget = createWidget<TMidiWidget>(mm2px(Vec(3.399621, 14.837339))); | TMidiWidget *midiWidget = createWidget<TMidiWidget>(mm2px(Vec(3.399621, 14.837339))); | ||||
midiWidget->box.size = mm2px(Vec(44, 54.667)); | midiWidget->box.size = mm2px(Vec(44, 54.667)); | ||||
if (module) | |||||
midiWidget->midiIO = &module->midiOutput; | |||||
midiWidget->setMidiIO(module ? &module->midiOutput : NULL); | |||||
midiWidget->setModule(module); | midiWidget->setModule(module); | ||||
addChild(midiWidget); | addChild(midiWidget); | ||||
} | } | ||||
@@ -346,8 +346,7 @@ struct CV_MIDIWidget : ModuleWidget { | |||||
MidiWidget *midiWidget = createWidget<MidiWidget>(mm2px(Vec(3.41891, 14.8373))); | MidiWidget *midiWidget = createWidget<MidiWidget>(mm2px(Vec(3.41891, 14.8373))); | ||||
midiWidget->box.size = mm2px(Vec(33.840, 28)); | midiWidget->box.size = mm2px(Vec(33.840, 28)); | ||||
if (module) | |||||
midiWidget->midiIO = &module->midiOutput; | |||||
midiWidget->setMidiIO(module ? &module->midiOutput : NULL); | |||||
addChild(midiWidget); | addChild(midiWidget); | ||||
} | } | ||||
@@ -167,8 +167,7 @@ struct MIDI_CCWidget : ModuleWidget { | |||||
typedef Grid16MidiWidget<CcChoice<MIDI_CC>> TMidiWidget; | typedef Grid16MidiWidget<CcChoice<MIDI_CC>> TMidiWidget; | ||||
TMidiWidget *midiWidget = createWidget<TMidiWidget>(mm2px(Vec(3.399621, 14.837339))); | TMidiWidget *midiWidget = createWidget<TMidiWidget>(mm2px(Vec(3.399621, 14.837339))); | ||||
midiWidget->box.size = mm2px(Vec(44, 54.667)); | midiWidget->box.size = mm2px(Vec(44, 54.667)); | ||||
if (module) | |||||
midiWidget->midiIO = &module->midiInput; | |||||
midiWidget->setMidiIO(module ? &module->midiInput : NULL); | |||||
midiWidget->setModule(module); | midiWidget->setModule(module); | ||||
addChild(midiWidget); | addChild(midiWidget); | ||||
} | } | ||||
@@ -540,8 +540,7 @@ struct MIDI_CVWidget : ModuleWidget { | |||||
MidiWidget *midiWidget = createWidget<MidiWidget>(mm2px(Vec(3.41891, 14.8373))); | MidiWidget *midiWidget = createWidget<MidiWidget>(mm2px(Vec(3.41891, 14.8373))); | ||||
midiWidget->box.size = mm2px(Vec(33.840, 28)); | midiWidget->box.size = mm2px(Vec(33.840, 28)); | ||||
if (module) | |||||
midiWidget->midiIO = &module->midiInput; | |||||
midiWidget->setMidiIO(module ? &module->midiInput : NULL); | |||||
addChild(midiWidget); | addChild(midiWidget); | ||||
} | } | ||||
@@ -196,8 +196,7 @@ struct MIDI_GateWidget : ModuleWidget { | |||||
typedef Grid16MidiWidget<NoteChoice<MIDI_Gate>> TMidiWidget; | typedef Grid16MidiWidget<NoteChoice<MIDI_Gate>> TMidiWidget; | ||||
TMidiWidget *midiWidget = createWidget<TMidiWidget>(mm2px(Vec(3.399621, 14.837339))); | TMidiWidget *midiWidget = createWidget<TMidiWidget>(mm2px(Vec(3.399621, 14.837339))); | ||||
midiWidget->box.size = mm2px(Vec(44, 54.667)); | midiWidget->box.size = mm2px(Vec(44, 54.667)); | ||||
if (module) | |||||
midiWidget->midiIO = &module->midiInput; | |||||
midiWidget->setMidiIO(module ? &module->midiInput : NULL); | |||||
midiWidget->setModule(module); | midiWidget->setModule(module); | ||||
addChild(midiWidget); | addChild(midiWidget); | ||||
} | } | ||||
@@ -72,8 +72,7 @@ struct MIDI_MapWidget : ModuleWidget { | |||||
MIDI_MapDisplay *midiWidget = createWidget<MIDI_MapDisplay>(mm2px(Vec(3.4, 14.839))); | MIDI_MapDisplay *midiWidget = createWidget<MIDI_MapDisplay>(mm2px(Vec(3.4, 14.839))); | ||||
midiWidget->box.size = mm2px(Vec(43.999, 102.664)); | midiWidget->box.size = mm2px(Vec(43.999, 102.664)); | ||||
if (module) | |||||
midiWidget->midiIO = &module->midiInput; | |||||
midiWidget->setMidiIO(module ? &module->midiInput : NULL); | |||||
midiWidget->setModule(module); | midiWidget->setModule(module); | ||||
addChild(midiWidget); | addChild(midiWidget); | ||||
} | } | ||||
@@ -16,25 +16,25 @@ struct AudioDriverItem : ui::MenuItem { | |||||
}; | }; | ||||
struct AudioDriverChoice : LedDisplayChoice { | struct AudioDriverChoice : LedDisplayChoice { | ||||
AudioWidget *audioWidget; | |||||
audio::IO *audioIO; | |||||
void onAction(const event::Action &e) override { | void onAction(const event::Action &e) override { | ||||
if (!audioWidget->audioIO) | |||||
if (!audioIO) | |||||
return; | return; | ||||
ui::Menu *menu = createMenu(); | ui::Menu *menu = createMenu(); | ||||
menu->addChild(createMenuLabel("Audio driver")); | menu->addChild(createMenuLabel("Audio driver")); | ||||
for (int driver : audioWidget->audioIO->getDrivers()) { | |||||
for (int driver : audioIO->getDrivers()) { | |||||
AudioDriverItem *item = new AudioDriverItem; | AudioDriverItem *item = new AudioDriverItem; | ||||
item->audioIO = audioWidget->audioIO; | |||||
item->audioIO = audioIO; | |||||
item->driver = driver; | item->driver = driver; | ||||
item->text = audioWidget->audioIO->getDriverName(driver); | |||||
item->rightText = CHECKMARK(item->driver == audioWidget->audioIO->driver); | |||||
item->text = audioIO->getDriverName(driver); | |||||
item->rightText = CHECKMARK(item->driver == audioIO->driver); | |||||
menu->addChild(item); | menu->addChild(item); | ||||
} | } | ||||
} | } | ||||
void step() override { | void step() override { | ||||
if (audioWidget->audioIO) | |||||
text = audioWidget->audioIO->getDriverName(audioWidget->audioIO->driver); | |||||
if (audioIO) | |||||
text = audioIO->getDriverName(audioIO->driver); | |||||
else | else | ||||
text = ""; | text = ""; | ||||
} | } | ||||
@@ -51,44 +51,44 @@ struct AudioDeviceItem : ui::MenuItem { | |||||
}; | }; | ||||
struct AudioDeviceChoice : LedDisplayChoice { | struct AudioDeviceChoice : LedDisplayChoice { | ||||
AudioWidget *audioWidget; | |||||
audio::IO *audioIO; | |||||
/** Prevents devices with a ridiculous number of channels from being displayed */ | /** Prevents devices with a ridiculous number of channels from being displayed */ | ||||
int maxTotalChannels = 128; | int maxTotalChannels = 128; | ||||
void onAction(const event::Action &e) override { | void onAction(const event::Action &e) override { | ||||
if (!audioWidget->audioIO) | |||||
if (!audioIO) | |||||
return; | return; | ||||
ui::Menu *menu = createMenu(); | ui::Menu *menu = createMenu(); | ||||
menu->addChild(createMenuLabel("Audio device")); | menu->addChild(createMenuLabel("Audio device")); | ||||
int deviceCount = audioWidget->audioIO->getDeviceCount(); | |||||
int deviceCount = audioIO->getDeviceCount(); | |||||
{ | { | ||||
AudioDeviceItem *item = new AudioDeviceItem; | AudioDeviceItem *item = new AudioDeviceItem; | ||||
item->audioIO = audioWidget->audioIO; | |||||
item->audioIO = audioIO; | |||||
item->device = -1; | item->device = -1; | ||||
item->text = "(No device)"; | item->text = "(No device)"; | ||||
item->rightText = CHECKMARK(item->device == audioWidget->audioIO->device); | |||||
item->rightText = CHECKMARK(item->device == audioIO->device); | |||||
menu->addChild(item); | menu->addChild(item); | ||||
} | } | ||||
for (int device = 0; device < deviceCount; device++) { | for (int device = 0; device < deviceCount; device++) { | ||||
int channels = std::min(maxTotalChannels, audioWidget->audioIO->getDeviceChannels(device)); | |||||
for (int offset = 0; offset < channels; offset += audioWidget->audioIO->maxChannels) { | |||||
int channels = std::min(maxTotalChannels, audioIO->getDeviceChannels(device)); | |||||
for (int offset = 0; offset < channels; offset += audioIO->maxChannels) { | |||||
AudioDeviceItem *item = new AudioDeviceItem; | AudioDeviceItem *item = new AudioDeviceItem; | ||||
item->audioIO = audioWidget->audioIO; | |||||
item->audioIO = audioIO; | |||||
item->device = device; | item->device = device; | ||||
item->offset = offset; | item->offset = offset; | ||||
item->text = audioWidget->audioIO->getDeviceDetail(device, offset); | |||||
item->rightText = CHECKMARK(item->device == audioWidget->audioIO->device && item->offset == audioWidget->audioIO->offset); | |||||
item->text = audioIO->getDeviceDetail(device, offset); | |||||
item->rightText = CHECKMARK(item->device == audioIO->device && item->offset == audioIO->offset); | |||||
menu->addChild(item); | menu->addChild(item); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
void step() override { | void step() override { | ||||
if (!audioWidget->audioIO) { | |||||
if (!audioIO) { | |||||
text = ""; | text = ""; | ||||
return; | return; | ||||
} | } | ||||
text = audioWidget->audioIO->getDeviceDetail(audioWidget->audioIO->device, audioWidget->audioIO->offset); | |||||
text = audioIO->getDeviceDetail(audioIO->device, audioIO->offset); | |||||
if (text.empty()) { | if (text.empty()) { | ||||
text = "(No device)"; | text = "(No device)"; | ||||
color.a = 0.5f; | color.a = 0.5f; | ||||
@@ -109,29 +109,29 @@ struct AudioSampleRateItem : ui::MenuItem { | |||||
}; | }; | ||||
struct AudioSampleRateChoice : LedDisplayChoice { | struct AudioSampleRateChoice : LedDisplayChoice { | ||||
AudioWidget *audioWidget; | |||||
audio::IO *audioIO; | |||||
void onAction(const event::Action &e) override { | void onAction(const event::Action &e) override { | ||||
if (!audioWidget->audioIO) | |||||
if (!audioIO) | |||||
return; | return; | ||||
ui::Menu *menu = createMenu(); | ui::Menu *menu = createMenu(); | ||||
menu->addChild(createMenuLabel("Sample rate")); | menu->addChild(createMenuLabel("Sample rate")); | ||||
std::vector<int> sampleRates = audioWidget->audioIO->getSampleRates(); | |||||
std::vector<int> sampleRates = audioIO->getSampleRates(); | |||||
if (sampleRates.empty()) { | if (sampleRates.empty()) { | ||||
menu->addChild(createMenuLabel("(Locked by device)")); | menu->addChild(createMenuLabel("(Locked by device)")); | ||||
} | } | ||||
for (int sampleRate : sampleRates) { | for (int sampleRate : sampleRates) { | ||||
AudioSampleRateItem *item = new AudioSampleRateItem; | AudioSampleRateItem *item = new AudioSampleRateItem; | ||||
item->audioIO = audioWidget->audioIO; | |||||
item->audioIO = audioIO; | |||||
item->sampleRate = sampleRate; | item->sampleRate = sampleRate; | ||||
item->text = string::f("%d Hz", sampleRate); | item->text = string::f("%d Hz", sampleRate); | ||||
item->rightText = CHECKMARK(item->sampleRate == audioWidget->audioIO->sampleRate); | |||||
item->rightText = CHECKMARK(item->sampleRate == audioIO->sampleRate); | |||||
menu->addChild(item); | menu->addChild(item); | ||||
} | } | ||||
} | } | ||||
void step() override { | void step() override { | ||||
if (audioWidget->audioIO) | |||||
text = string::f("%g kHz", audioWidget->audioIO->sampleRate / 1000.f); | |||||
if (audioIO) | |||||
text = string::f("%g kHz", audioIO->sampleRate / 1000.f); | |||||
else | else | ||||
text = ""; | text = ""; | ||||
} | } | ||||
@@ -147,86 +147,82 @@ struct AudioBlockSizeItem : ui::MenuItem { | |||||
}; | }; | ||||
struct AudioBlockSizeChoice : LedDisplayChoice { | struct AudioBlockSizeChoice : LedDisplayChoice { | ||||
AudioWidget *audioWidget; | |||||
audio::IO *audioIO; | |||||
void onAction(const event::Action &e) override { | void onAction(const event::Action &e) override { | ||||
if (!audioWidget->audioIO) | |||||
if (!audioIO) | |||||
return; | return; | ||||
ui::Menu *menu = createMenu(); | ui::Menu *menu = createMenu(); | ||||
menu->addChild(createMenuLabel("Block size")); | menu->addChild(createMenuLabel("Block size")); | ||||
std::vector<int> blockSizes = audioWidget->audioIO->getBlockSizes(); | |||||
std::vector<int> blockSizes = audioIO->getBlockSizes(); | |||||
if (blockSizes.empty()) { | if (blockSizes.empty()) { | ||||
menu->addChild(createMenuLabel("(Locked by device)")); | menu->addChild(createMenuLabel("(Locked by device)")); | ||||
} | } | ||||
for (int blockSize : blockSizes) { | for (int blockSize : blockSizes) { | ||||
AudioBlockSizeItem *item = new AudioBlockSizeItem; | AudioBlockSizeItem *item = new AudioBlockSizeItem; | ||||
item->audioIO = audioWidget->audioIO; | |||||
item->audioIO = audioIO; | |||||
item->blockSize = blockSize; | item->blockSize = blockSize; | ||||
float latency = (float) blockSize / audioWidget->audioIO->sampleRate * 1000.0; | |||||
float latency = (float) blockSize / audioIO->sampleRate * 1000.0; | |||||
item->text = string::f("%d (%.1f ms)", blockSize, latency); | item->text = string::f("%d (%.1f ms)", blockSize, latency); | ||||
item->rightText = CHECKMARK(item->blockSize == audioWidget->audioIO->blockSize); | |||||
item->rightText = CHECKMARK(item->blockSize == audioIO->blockSize); | |||||
menu->addChild(item); | menu->addChild(item); | ||||
} | } | ||||
} | } | ||||
void step() override { | void step() override { | ||||
if (audioWidget->audioIO) | |||||
text = string::f("%d", audioWidget->audioIO->blockSize); | |||||
if (audioIO) | |||||
text = string::f("%d", audioIO->blockSize); | |||||
else | else | ||||
text = ""; | text = ""; | ||||
} | } | ||||
}; | }; | ||||
AudioWidget::AudioWidget() { | |||||
box.size = mm2px(math::Vec(44, 28)); | |||||
void AudioWidget::setAudioIO(audio::IO *audioIO) { | |||||
clearChildren(); | |||||
math::Vec pos = math::Vec(); | |||||
math::Vec pos; | |||||
AudioDriverChoice *driverChoice = createWidget<AudioDriverChoice>(pos); | AudioDriverChoice *driverChoice = createWidget<AudioDriverChoice>(pos); | ||||
driverChoice->audioWidget = this; | |||||
driverChoice->box.size.x = box.size.x; | |||||
driverChoice->audioIO = audioIO; | |||||
addChild(driverChoice); | addChild(driverChoice); | ||||
pos = driverChoice->box.getBottomLeft(); | pos = driverChoice->box.getBottomLeft(); | ||||
this->driverChoice = driverChoice; | this->driverChoice = driverChoice; | ||||
this->driverSeparator = createWidget<LedDisplaySeparator>(pos); | this->driverSeparator = createWidget<LedDisplaySeparator>(pos); | ||||
this->driverSeparator->box.size.x = box.size.x; | |||||
addChild(this->driverSeparator); | addChild(this->driverSeparator); | ||||
AudioDeviceChoice *deviceChoice = createWidget<AudioDeviceChoice>(pos); | AudioDeviceChoice *deviceChoice = createWidget<AudioDeviceChoice>(pos); | ||||
deviceChoice->audioWidget = this; | |||||
deviceChoice->box.size.x = box.size.x; | |||||
deviceChoice->audioIO = audioIO; | |||||
addChild(deviceChoice); | addChild(deviceChoice); | ||||
pos = deviceChoice->box.getBottomLeft(); | pos = deviceChoice->box.getBottomLeft(); | ||||
this->deviceChoice = deviceChoice; | this->deviceChoice = deviceChoice; | ||||
this->deviceSeparator = createWidget<LedDisplaySeparator>(pos); | this->deviceSeparator = createWidget<LedDisplaySeparator>(pos); | ||||
this->deviceSeparator->box.size.x = box.size.x; | |||||
addChild(this->deviceSeparator); | addChild(this->deviceSeparator); | ||||
AudioSampleRateChoice *sampleRateChoice = createWidget<AudioSampleRateChoice>(pos); | AudioSampleRateChoice *sampleRateChoice = createWidget<AudioSampleRateChoice>(pos); | ||||
sampleRateChoice->audioWidget = this; | |||||
sampleRateChoice->box.size.x = box.size.x / 2; | |||||
sampleRateChoice->audioIO = audioIO; | |||||
addChild(sampleRateChoice); | addChild(sampleRateChoice); | ||||
this->sampleRateChoice = sampleRateChoice; | this->sampleRateChoice = sampleRateChoice; | ||||
this->sampleRateSeparator = createWidget<LedDisplaySeparator>(pos); | this->sampleRateSeparator = createWidget<LedDisplaySeparator>(pos); | ||||
this->sampleRateSeparator->box.pos.x = box.size.x / 2; | |||||
this->sampleRateSeparator->box.size.y = this->sampleRateChoice->box.size.y; | this->sampleRateSeparator->box.size.y = this->sampleRateChoice->box.size.y; | ||||
addChild(this->sampleRateSeparator); | addChild(this->sampleRateSeparator); | ||||
AudioBlockSizeChoice *bufferSizeChoice = createWidget<AudioBlockSizeChoice>(pos); | AudioBlockSizeChoice *bufferSizeChoice = createWidget<AudioBlockSizeChoice>(pos); | ||||
bufferSizeChoice->audioWidget = this; | |||||
bufferSizeChoice->box.pos.x = box.size.x / 2; | |||||
bufferSizeChoice->box.size.x = box.size.x / 2; | |||||
bufferSizeChoice->audioIO = audioIO; | |||||
addChild(bufferSizeChoice); | addChild(bufferSizeChoice); | ||||
this->bufferSizeChoice = bufferSizeChoice; | this->bufferSizeChoice = bufferSizeChoice; | ||||
} | } | ||||
void AudioWidget::step() { | |||||
this->driverChoice->box.size.x = box.size.x; | |||||
this->driverSeparator->box.size.x = box.size.x; | |||||
this->deviceChoice->box.size.x = box.size.x; | |||||
this->deviceSeparator->box.size.x = box.size.x; | |||||
this->sampleRateChoice->box.size.x = box.size.x / 2; | |||||
this->sampleRateSeparator->box.pos.x = box.size.x / 2; | |||||
this->bufferSizeChoice->box.pos.x = box.size.x / 2; | |||||
this->bufferSizeChoice->box.size.x = box.size.x / 2; | |||||
LedDisplay::step(); | |||||
} | |||||
} // namespace app | } // namespace app | ||||
} // namespace rack | } // namespace rack |
@@ -16,28 +16,28 @@ struct MidiDriverItem : ui::MenuItem { | |||||
}; | }; | ||||
struct MidiDriverChoice : LedDisplayChoice { | struct MidiDriverChoice : LedDisplayChoice { | ||||
MidiWidget *midiWidget; | |||||
midi::IO *midiIO; | |||||
void onAction(const event::Action &e) override { | void onAction(const event::Action &e) override { | ||||
if (!midiWidget->midiIO) | |||||
if (!midiIO) | |||||
return; | return; | ||||
ui::Menu *menu = createMenu(); | ui::Menu *menu = createMenu(); | ||||
menu->addChild(createMenuLabel("MIDI driver")); | menu->addChild(createMenuLabel("MIDI driver")); | ||||
for (int driverId : midiWidget->midiIO->getDriverIds()) { | |||||
for (int driverId : midiIO->getDriverIds()) { | |||||
MidiDriverItem *item = new MidiDriverItem; | MidiDriverItem *item = new MidiDriverItem; | ||||
item->midiIO = midiWidget->midiIO; | |||||
item->midiIO = midiIO; | |||||
item->driverId = driverId; | item->driverId = driverId; | ||||
item->text = midiWidget->midiIO->getDriverName(driverId); | |||||
item->rightText = CHECKMARK(item->driverId == midiWidget->midiIO->driverId); | |||||
item->text = midiIO->getDriverName(driverId); | |||||
item->rightText = CHECKMARK(item->driverId == midiIO->driverId); | |||||
menu->addChild(item); | menu->addChild(item); | ||||
} | } | ||||
} | } | ||||
void step() override { | void step() override { | ||||
if (!midiWidget->midiIO) { | |||||
if (!midiIO) { | |||||
text = ""; | text = ""; | ||||
return; | return; | ||||
} | } | ||||
text = midiWidget->midiIO->getDriverName(midiWidget->midiIO->driverId); | |||||
text = midiIO->getDriverName(midiIO->driverId); | |||||
if (text.empty()) { | if (text.empty()) { | ||||
text = "(No driver)"; | text = "(No driver)"; | ||||
color.a = 0.5f; | color.a = 0.5f; | ||||
@@ -57,36 +57,36 @@ struct MidiDeviceItem : ui::MenuItem { | |||||
}; | }; | ||||
struct MidiDeviceChoice : LedDisplayChoice { | struct MidiDeviceChoice : LedDisplayChoice { | ||||
MidiWidget *midiWidget; | |||||
midi::IO *midiIO; | |||||
void onAction(const event::Action &e) override { | void onAction(const event::Action &e) override { | ||||
if (!midiWidget->midiIO) | |||||
if (!midiIO) | |||||
return; | return; | ||||
ui::Menu *menu = createMenu(); | ui::Menu *menu = createMenu(); | ||||
menu->addChild(createMenuLabel("MIDI device")); | menu->addChild(createMenuLabel("MIDI device")); | ||||
{ | { | ||||
MidiDeviceItem *item = new MidiDeviceItem; | MidiDeviceItem *item = new MidiDeviceItem; | ||||
item->midiIO = midiWidget->midiIO; | |||||
item->midiIO = midiIO; | |||||
item->deviceId = -1; | item->deviceId = -1; | ||||
item->text = "(No device)"; | item->text = "(No device)"; | ||||
item->rightText = CHECKMARK(item->deviceId == midiWidget->midiIO->deviceId); | |||||
item->rightText = CHECKMARK(item->deviceId == midiIO->deviceId); | |||||
menu->addChild(item); | menu->addChild(item); | ||||
} | } | ||||
for (int deviceId : midiWidget->midiIO->getDeviceIds()) { | |||||
for (int deviceId : midiIO->getDeviceIds()) { | |||||
MidiDeviceItem *item = new MidiDeviceItem; | MidiDeviceItem *item = new MidiDeviceItem; | ||||
item->midiIO = midiWidget->midiIO; | |||||
item->midiIO = midiIO; | |||||
item->deviceId = deviceId; | item->deviceId = deviceId; | ||||
item->text = midiWidget->midiIO->getDeviceName(deviceId); | |||||
item->rightText = CHECKMARK(item->deviceId == midiWidget->midiIO->deviceId); | |||||
item->text = midiIO->getDeviceName(deviceId); | |||||
item->rightText = CHECKMARK(item->deviceId == midiIO->deviceId); | |||||
menu->addChild(item); | menu->addChild(item); | ||||
} | } | ||||
} | } | ||||
void step() override { | void step() override { | ||||
if (!midiWidget->midiIO) { | |||||
if (!midiIO) { | |||||
text = ""; | text = ""; | ||||
return; | return; | ||||
} | } | ||||
text = midiWidget->midiIO->getDeviceName(midiWidget->midiIO->deviceId); | |||||
text = midiIO->getDeviceName(midiIO->deviceId); | |||||
if (text.empty()) { | if (text.empty()) { | ||||
text = "(No device)"; | text = "(No device)"; | ||||
color.a = 0.5f; | color.a = 0.5f; | ||||
@@ -106,69 +106,65 @@ struct MidiChannelItem : ui::MenuItem { | |||||
}; | }; | ||||
struct MidiChannelChoice : LedDisplayChoice { | struct MidiChannelChoice : LedDisplayChoice { | ||||
MidiWidget *midiWidget; | |||||
midi::IO *midiIO; | |||||
void onAction(const event::Action &e) override { | void onAction(const event::Action &e) override { | ||||
if (!midiWidget->midiIO) | |||||
if (!midiIO) | |||||
return; | return; | ||||
ui::Menu *menu = createMenu(); | ui::Menu *menu = createMenu(); | ||||
menu->addChild(createMenuLabel("MIDI channel")); | menu->addChild(createMenuLabel("MIDI channel")); | ||||
for (int channel : midiWidget->midiIO->getChannels()) { | |||||
for (int channel : midiIO->getChannels()) { | |||||
MidiChannelItem *item = new MidiChannelItem; | MidiChannelItem *item = new MidiChannelItem; | ||||
item->midiIO = midiWidget->midiIO; | |||||
item->midiIO = midiIO; | |||||
item->channel = channel; | item->channel = channel; | ||||
item->text = midiWidget->midiIO->getChannelName(channel); | |||||
item->rightText = CHECKMARK(item->channel == midiWidget->midiIO->channel); | |||||
item->text = midiIO->getChannelName(channel); | |||||
item->rightText = CHECKMARK(item->channel == midiIO->channel); | |||||
menu->addChild(item); | menu->addChild(item); | ||||
} | } | ||||
} | } | ||||
void step() override { | void step() override { | ||||
if (midiWidget->midiIO) | |||||
text = midiWidget->midiIO->getChannelName(midiWidget->midiIO->channel); | |||||
if (midiIO) | |||||
text = midiIO->getChannelName(midiIO->channel); | |||||
else | else | ||||
text = ""; | text = ""; | ||||
} | } | ||||
}; | }; | ||||
MidiWidget::MidiWidget() { | |||||
box.size = mm2px(math::Vec(44, 28)); | |||||
void MidiWidget::setMidiIO(midi::IO *midiIO) { | |||||
clearChildren(); | |||||
math::Vec pos = math::Vec(); | |||||
math::Vec pos; | |||||
MidiDriverChoice *driverChoice = createWidget<MidiDriverChoice>(pos); | MidiDriverChoice *driverChoice = createWidget<MidiDriverChoice>(pos); | ||||
driverChoice->midiWidget = this; | |||||
driverChoice->box.size.x = box.size.x; | |||||
driverChoice->midiIO = midiIO; | |||||
addChild(driverChoice); | addChild(driverChoice); | ||||
pos = driverChoice->box.getBottomLeft(); | pos = driverChoice->box.getBottomLeft(); | ||||
this->driverChoice = driverChoice; | this->driverChoice = driverChoice; | ||||
this->driverSeparator = createWidget<LedDisplaySeparator>(pos); | this->driverSeparator = createWidget<LedDisplaySeparator>(pos); | ||||
this->driverSeparator->box.size.x = box.size.x; | |||||
addChild(this->driverSeparator); | addChild(this->driverSeparator); | ||||
MidiDeviceChoice *deviceChoice = createWidget<MidiDeviceChoice>(pos); | MidiDeviceChoice *deviceChoice = createWidget<MidiDeviceChoice>(pos); | ||||
deviceChoice->midiWidget = this; | |||||
deviceChoice->box.size.x = box.size.x; | |||||
deviceChoice->midiIO = midiIO; | |||||
addChild(deviceChoice); | addChild(deviceChoice); | ||||
pos = deviceChoice->box.getBottomLeft(); | pos = deviceChoice->box.getBottomLeft(); | ||||
this->deviceChoice = deviceChoice; | this->deviceChoice = deviceChoice; | ||||
this->deviceSeparator = createWidget<LedDisplaySeparator>(pos); | this->deviceSeparator = createWidget<LedDisplaySeparator>(pos); | ||||
this->deviceSeparator->box.size.x = box.size.x; | |||||
addChild(this->deviceSeparator); | addChild(this->deviceSeparator); | ||||
MidiChannelChoice *channelChoice = createWidget<MidiChannelChoice>(pos); | MidiChannelChoice *channelChoice = createWidget<MidiChannelChoice>(pos); | ||||
channelChoice->midiWidget = this; | |||||
channelChoice->box.size.x = box.size.x; | |||||
channelChoice->midiIO = midiIO; | |||||
addChild(channelChoice); | addChild(channelChoice); | ||||
this->channelChoice = channelChoice; | this->channelChoice = channelChoice; | ||||
} | } | ||||
void MidiWidget::step() { | |||||
this->driverChoice->box.size.x = box.size.x; | |||||
this->driverSeparator->box.size.x = box.size.x; | |||||
this->deviceChoice->box.size.x = box.size.x; | |||||
this->deviceSeparator->box.size.x = box.size.x; | |||||
this->channelChoice->box.size.x = box.size.x; | |||||
LedDisplay::step(); | |||||
} | |||||
} // namespace app | } // namespace app | ||||
} // namespace rack | } // namespace rack |