More robust midi implementation
Some checks failed
Deploy Website / deploy (push) Failing after 4m58s

This commit is contained in:
2026-01-31 23:58:57 +01:00
parent 15a4300db5
commit 2100b82dad
12 changed files with 393 additions and 201 deletions

View File

@@ -1270,36 +1270,88 @@ fn handle_options_page(ctx: &mut InputContext, key: KeyEvent) -> InputResult {
let delta = if key.code == KeyCode::Left { -1.0 } else { 1.0 };
ctx.link.set_quantum(ctx.link.quantum() + delta);
}
OptionsFocus::MidiOutput => {
let devices = crate::midi::list_midi_outputs();
if !devices.is_empty() {
let current = ctx.app.midi.selected_output.unwrap_or(0);
let new_idx = if key.code == KeyCode::Left {
if current == 0 { devices.len() - 1 } else { current - 1 }
} else {
(current + 1) % devices.len()
};
if ctx.app.midi.connect_output(new_idx).is_ok() {
OptionsFocus::MidiOutput0 | OptionsFocus::MidiOutput1 |
OptionsFocus::MidiOutput2 | OptionsFocus::MidiOutput3 => {
let slot = match ctx.app.options.focus {
OptionsFocus::MidiOutput0 => 0,
OptionsFocus::MidiOutput1 => 1,
OptionsFocus::MidiOutput2 => 2,
OptionsFocus::MidiOutput3 => 3,
_ => 0,
};
let all_devices = crate::midi::list_midi_outputs();
let available: Vec<(usize, &crate::midi::MidiDeviceInfo)> = all_devices
.iter()
.enumerate()
.filter(|(idx, _)| {
ctx.app.midi.selected_outputs[slot] == Some(*idx)
|| !ctx.app.midi.selected_outputs.iter().enumerate()
.any(|(s, sel)| s != slot && *sel == Some(*idx))
})
.collect();
let total_options = available.len() + 1;
let current_pos = ctx.app.midi.selected_outputs[slot]
.and_then(|idx| available.iter().position(|(i, _)| *i == idx))
.map(|p| p + 1)
.unwrap_or(0);
let new_pos = if key.code == KeyCode::Left {
if current_pos == 0 { total_options - 1 } else { current_pos - 1 }
} else {
(current_pos + 1) % total_options
};
if new_pos == 0 {
ctx.app.midi.disconnect_output(slot);
ctx.dispatch(AppCommand::SetStatus(format!(
"MIDI output {slot}: disconnected"
)));
} else {
let (device_idx, device) = available[new_pos - 1];
if ctx.app.midi.connect_output(slot, device_idx).is_ok() {
ctx.dispatch(AppCommand::SetStatus(format!(
"MIDI output: {}",
devices[new_idx].name
"MIDI output {}: {}", slot, device.name
)));
}
}
}
OptionsFocus::MidiInput => {
let devices = crate::midi::list_midi_inputs();
if !devices.is_empty() {
let current = ctx.app.midi.selected_input.unwrap_or(0);
let new_idx = if key.code == KeyCode::Left {
if current == 0 { devices.len() - 1 } else { current - 1 }
} else {
(current + 1) % devices.len()
};
if ctx.app.midi.connect_input(new_idx).is_ok() {
OptionsFocus::MidiInput0 | OptionsFocus::MidiInput1 |
OptionsFocus::MidiInput2 | OptionsFocus::MidiInput3 => {
let slot = match ctx.app.options.focus {
OptionsFocus::MidiInput0 => 0,
OptionsFocus::MidiInput1 => 1,
OptionsFocus::MidiInput2 => 2,
OptionsFocus::MidiInput3 => 3,
_ => 0,
};
let all_devices = crate::midi::list_midi_inputs();
let available: Vec<(usize, &crate::midi::MidiDeviceInfo)> = all_devices
.iter()
.enumerate()
.filter(|(idx, _)| {
ctx.app.midi.selected_inputs[slot] == Some(*idx)
|| !ctx.app.midi.selected_inputs.iter().enumerate()
.any(|(s, sel)| s != slot && *sel == Some(*idx))
})
.collect();
let total_options = available.len() + 1;
let current_pos = ctx.app.midi.selected_inputs[slot]
.and_then(|idx| available.iter().position(|(i, _)| *i == idx))
.map(|p| p + 1)
.unwrap_or(0);
let new_pos = if key.code == KeyCode::Left {
if current_pos == 0 { total_options - 1 } else { current_pos - 1 }
} else {
(current_pos + 1) % total_options
};
if new_pos == 0 {
ctx.app.midi.disconnect_input(slot);
ctx.dispatch(AppCommand::SetStatus(format!(
"MIDI input {slot}: disconnected"
)));
} else {
let (device_idx, device) = available[new_pos - 1];
if ctx.app.midi.connect_input(slot, device_idx).is_ok() {
ctx.dispatch(AppCommand::SetStatus(format!(
"MIDI input: {}",
devices[new_idx].name
"MIDI input {}: {}", slot, device.name
)));
}
}