From 3bc1f4f547594e40b0b0a7595676175014724644 Mon Sep 17 00:00:00 2001 From: Benjamin Klum Date: Sun, 27 Oct 2024 09:47:07 +0100 Subject: [PATCH] #1290 Make it possible to pick virtual control elements in main mapping that are actually available --- Cargo.lock | 2 +- main/Cargo.toml | 2 +- main/src/infrastructure/ui/mapping_panel.rs | 88 +++++++++++++++------ 3 files changed, 66 insertions(+), 26 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5dbbe6499..926bbd3cb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2958,7 +2958,7 @@ dependencies = [ [[package]] name = "helgobox" -version = "2.16.11" +version = "2.16.12" dependencies = [ "anyhow", "approx", diff --git a/main/Cargo.toml b/main/Cargo.toml index b5fcff8b1..fdd880ae0 100644 --- a/main/Cargo.toml +++ b/main/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "helgobox" -version = "2.16.11" +version = "2.16.12" authors = ["Benjamin Klum "] edition = "2021" build = "build.rs" diff --git a/main/src/infrastructure/ui/mapping_panel.rs b/main/src/infrastructure/ui/mapping_panel.rs index 29e5d24a5..2499237cc 100644 --- a/main/src/infrastructure/ui/mapping_panel.rs +++ b/main/src/infrastructure/ui/mapping_panel.rs @@ -687,10 +687,12 @@ impl MappingPanel { let control_element_type = mapping.borrow().target_model.control_element_character(); let window = self.view.require_window(); - let text = prompt_for_predefined_control_element_name( + let text = pick_virtual_control_element( window, control_element_type, &HashMap::default(), + true, + true, ) .ok_or("nothing picked")?; let element_id = text.parse().unwrap_or_default(); @@ -819,8 +821,15 @@ impl MappingPanel { } fn handle_source_line_4_button_press(&self) -> Result<(), &'static str> { - let mapping = self.displayed_mapping().ok_or("no mapping set")?; - let control_element_type = mapping.borrow().source_model.control_element_character(); + let (control_element_type, control_enabled, feedback_enabled) = { + let m = self.displayed_mapping().ok_or("no mapping set")?; + let m = m.borrow(); + ( + m.source_model.control_element_character(), + m.control_is_enabled(), + m.feedback_is_enabled(), + ) + }; let window = self.view.require_window(); let controller_mappings: Vec<_> = { let session = self.session(); @@ -832,10 +841,12 @@ impl MappingPanel { }; let grouped_mappings = group_mappings_by_virtual_control_element(controller_mappings.iter()); - let text = prompt_for_predefined_control_element_name( + let text = pick_virtual_control_element( window, control_element_type, &grouped_mappings, + control_enabled, + feedback_enabled, ) .ok_or("nothing picked")?; let control_element_id = text.parse().unwrap_or_default(); @@ -7750,35 +7761,63 @@ fn osc_arg_indexes() -> impl Iterator { iter::once((-1isize, "-".to_string())).chain((0..9).map(|i| (i as isize, (i + 1).to_string()))) } -fn prompt_for_predefined_control_element_name( +fn pick_virtual_control_element( window: Window, character: VirtualControlElementCharacter, grouped_mappings: &NonCryptoHashMap>, + for_control: bool, + for_feedback: bool, ) -> Option { let pure_menu = { use swell_ui::menu_tree::*; - let daw_control_names = match character { - VirtualControlElementCharacter::Multi => { - control_element_domains::daw::PREDEFINED_VIRTUAL_MULTI_NAMES - } - VirtualControlElementCharacter::Button => { - control_element_domains::daw::PREDEFINED_VIRTUAL_BUTTON_NAMES - } - }; - let grid_control_names = match character { - VirtualControlElementCharacter::Multi => { - control_element_domains::grid::PREDEFINED_VIRTUAL_MULTI_NAMES - } - VirtualControlElementCharacter::Button => { - control_element_domains::grid::PREDEFINED_VIRTUAL_BUTTON_NAMES - } + let daw_control_names: Vec<_> = + control_element_domains::daw::PREDEFINED_VIRTUAL_BUTTON_NAMES + .iter() + .chain(control_element_domains::daw::PREDEFINED_VIRTUAL_MULTI_NAMES.iter()) + .map(|e| *e) + .collect(); + let grid_control_names: Vec<_> = + control_element_domains::grid::PREDEFINED_VIRTUAL_BUTTON_NAMES + .iter() + .chain(control_element_domains::grid::PREDEFINED_VIRTUAL_MULTI_NAMES.iter()) + .map(|e| *e) + .collect(); + + let include_actual_element = |mappings: &[&SharedMapping]| -> bool { + mappings.iter().any(|m| { + let m = m.borrow(); + if !m.is_enabled() { + return false; + } + if for_control && !m.control_is_enabled() { + return false; + } + if for_feedback && !m.feedback_is_enabled() { + return false; + } + true + }) }; + let currently_available_elements: Vec<_> = grouped_mappings + .iter() + .filter(|(e, mappings)| match e { + VirtualControlElement::Indexed { id, character: ch } => { + *ch == character && include_actual_element(mappings) + } + VirtualControlElement::Named { id, character } => include_actual_element(mappings), + }) + .map(|(e, _)| e.id().to_string()) + .collect(); let entries = vec![ + menu( + "", + build_slash_menu_entries(¤tly_available_elements, ""), + ), menu( "DAW control", - build_slash_menu_entries(daw_control_names, ""), + build_slash_menu_entries(&daw_control_names, ""), ), - menu("Grid", build_slash_menu_entries(grid_control_names, "")), + menu("Grid", build_slash_menu_entries(&grid_control_names, "")), menu( "Numbered", chunked_number_menu(100, 10, true, |i| { @@ -8062,13 +8101,14 @@ fn open_send_midi_menu(window: Window) -> Option { } fn build_slash_menu_entries( - names: &[&str], + names: &[impl AsRef], prefix: &str, ) -> Vec> { use swell_ui::menu_tree::*; let mut entries = Vec::new(); for (key, group) in &names .iter() + .map(|e| e.as_ref()) .sorted() .group_by(|name| extract_first_segment(name)) { @@ -8080,7 +8120,7 @@ fn build_slash_menu_entries( } else { format!("{prefix}/{name}") }; - entries.push(item(*name, full_name)); + entries.push(item(name, full_name)); } } else { // A nested entry (menu).