diff --git a/crates/ui-egui/src/addons/select.rs b/crates/ui-egui/src/addons/select.rs index 3429fd49a..8f6b25826 100644 --- a/crates/ui-egui/src/addons/select.rs +++ b/crates/ui-egui/src/addons/select.rs @@ -57,7 +57,7 @@ pub(crate) fn shown(names: &[String], query: &str) -> Vec { names.iter().enumerate().filter(|(_, n)| q.is_empty() || n.to_lowercase().contains(&q)).map(|(i, _)| i).collect() } -/// A click on row `i` of the rows `shown`: alone it chooses only that artboard, with Cmd/Ctrl it +/// A click on row `i` of the rows `shown`: alone it chooses only that artboard of those shown, with Cmd/Ctrl it /// toggles it, with Shift it adds the rows from the last one clicked (`anchor`) to it. Returns the /// new anchor. pub(crate) fn click(chosen: &mut Vec, anchor: Option, i: usize, shown: &[usize], shift: bool, command: bool) -> Option { @@ -75,7 +75,11 @@ pub(crate) fn click(chosen: &mut Vec, anchor: Option, i: usize, sh } None => chosen.push(i), }, - _ => *chosen = vec![i], + // Of the rows shown, only this one; rows the search hides keep their state. + _ => { + chosen.retain(|j| !shown.contains(j)); + chosen.push(i); + } } chosen.sort_unstable(); Some(i) diff --git a/crates/ui-egui/src/addons/select/tests.rs b/crates/ui-egui/src/addons/select/tests.rs index f28dedca5..a2c7ef4f3 100644 --- a/crates/ui-egui/src/addons/select/tests.rs +++ b/crates/ui-egui/src/addons/select/tests.rs @@ -45,7 +45,11 @@ fn clicks_choose_toggle_and_extend_rows() { let a = click(&mut c, a, 3, &rows, false, false); assert_eq!((c.clone(), a), (vec![3], Some(3))); let a = click(&mut c, None, 5, &rows, true, false); - assert_eq!((c, a), (vec![5], Some(5))); + assert_eq!((c.clone(), a), (vec![5], Some(5))); + // Board 4, chosen but hidden by the search, stays chosen through a plain click. + c.push(4); + click(&mut c, a, 2, &rows, false, false); + assert_eq!(c, vec![2, 4]); } #[test] @@ -92,7 +96,8 @@ fn double_clicking_a_row_fits_its_artboard_and_keeps_the_choice() { // The search shows boards 0 and 2: row 2 is the second row, but board 2 is the one fitted. let rows = [0, 2]; row_clicked(&mut d, 2, &rows, egui::Modifiers::NONE); - assert_eq!(d.fields["artboards"], json!([2]), "the first click chooses the row"); + // Board 1, hidden by the search, stays chosen. + assert_eq!(d.fields["artboards"], json!([1, 2]), "the first click chooses the row among those shown"); // The dialog frame lends the dialog to its body while the app still shows it. app.ui.dialog = Some(d.clone()); row_double_clicked(&mut app, &mut d, 2);