Merge pull request #1798 from AyberkA0/fix/1757-palette-arrows

Fix #1757: arrow keys move through the command search results
This commit is contained in:
BFlat authored and GitHub committed 2026-10-14 04:26:46 +07:00
commit 1a506fae4c
1 file changed
+48 -3
+48 -3
View File
@@ -82,6 +82,25 @@ pub fn show(app: &mut VectorcraftApp, ctx: &egui::Context) {
let entries = entries(ctx, crate::i18n::current());
let matches: Vec<&Entry> = entries.iter().filter(|e| q.split_whitespace().all(|w| e.haystack.contains(w))).take(14).collect();
let mut run: Option<String> = None;
// The highlighted result (#1757): Up and Down move it (wrapping), the pointer over a result
// takes it, and a new query starts again from the first.
let sel_id = egui::Id::new("palette-selected");
let (mut sel, last_q) = ctx.data(|d| d.get_temp::<(usize, String)>(sel_id)).unwrap_or_default();
if last_q != q {
sel = 0;
}
let n = matches.len();
if n > 0 {
let (down, up) =
ctx.input_mut(|i| (i.consume_key(egui::Modifiers::NONE, egui::Key::ArrowDown), i.consume_key(egui::Modifiers::NONE, egui::Key::ArrowUp)));
if down {
sel = (sel + 1) % n;
}
if up {
sel = (sel + n - 1) % n;
}
sel = sel.min(n - 1);
}
egui::Area::new(egui::Id::new("palette")).order(egui::Order::Foreground).anchor(egui::Align2::CENTER_TOP, [0.0, 90.0]).show(ctx, |ui| {
egui::Frame::popup(ui.style()).fill(t.panel).inner_margin(egui::Margin::same(10)).show(ui, |ui| {
ui.set_width(520.0);
@@ -93,19 +112,23 @@ pub fn show(app: &mut VectorcraftApp, ctx: &egui::Context) {
egui::Button::new(e.shown.as_str())
.shortcut_text(menus::pretty_shortcut(&e.shortcut))
.min_size(egui::vec2(500.0, 24.0))
.selected(i == 0),
.selected(i == sel),
);
if resp.hovered() && ui.input(|i| i.pointer.delta() != egui::Vec2::ZERO) {
sel = i;
}
if resp.clicked() {
run = Some(e.id.clone());
}
}
if ui.input(|i| i.key_pressed(egui::Key::Enter))
&& let Some(first) = matches.first()
&& let Some(e) = matches.get(sel)
{
run = Some(first.id.clone());
run = Some(e.id.clone());
}
});
});
ctx.data_mut(|d| d.insert_temp(sel_id, (sel, q)));
if let Some(id) = run {
app.ui.palette_open = false;
if let Some(tool) = id.strip_prefix("tool:") {
@@ -170,4 +193,26 @@ mod tests {
let st = app.session.active().unwrap();
assert_eq!((st.selection.len(), st.selection.key), (2, None), "both objects stay selected, without a key");
}
/// #1757: Up and Down move the highlighted result, wrapping at the ends; a new query starts
/// from the first again.
#[test]
fn arrow_keys_move_the_highlighted_result() {
let mut app = VectorcraftApp::new(vectorcraft_engine::Session::new(), crate::Services::default());
app.ui.palette_open = true;
app.ui.palette_query = "zoom".into();
let ctx = egui::Context::default();
let key = |k| egui::Event::Key { key: k, physical_key: None, pressed: true, repeat: false, modifiers: egui::Modifiers::NONE };
let frame = |app: &mut VectorcraftApp, events: Vec<egui::Event>| {
ctx.run_ui(egui::RawInput { events, ..Default::default() }, |ui| show(app, ui.ctx())).textures_delta.clear();
ctx.data(|d| d.get_temp::<(usize, String)>(egui::Id::new("palette-selected"))).unwrap().0
};
assert_eq!(frame(&mut app, vec![]), 0);
assert_eq!(frame(&mut app, vec![key(egui::Key::ArrowDown)]), 1);
assert_eq!(frame(&mut app, vec![key(egui::Key::ArrowUp)]), 0);
let last = frame(&mut app, vec![key(egui::Key::ArrowUp)]);
assert!(last > 1, "Up on the first result wraps to the last: {last}");
app.ui.palette_query = "zoom in".into();
assert_eq!(frame(&mut app, vec![]), 0);
}
}