mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-14 19:26:56 -04:00
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:
1 file changed
+48
-3
@@ -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);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user