Merge PR #1414: UI: Improve Command Palette keyboard navigation and layout

This commit is contained in:
aiongg
2026-10-22 02:35:17 +00:00
+58 -7
View File
@@ -43,6 +43,7 @@ pub struct Dialog {
picture_target: Option<(u64, usize)>,
/// The dialog this one was opened from (Name Manager › New…): it comes back when this closes.
back: Option<Box<Dialog>>,
focus_initialized: bool,
}
impl Dialog {
@@ -77,6 +78,7 @@ impl Dialog {
picture_inbox: None,
picture_target: None,
back: None,
focus_initialized: false,
}
}
@@ -96,6 +98,7 @@ impl Dialog {
picture_inbox: None,
picture_target: None,
back: None,
focus_initialized: false,
}
}
@@ -2271,8 +2274,24 @@ fn manage_rules(app: &mut SheetApp, ui: &mut egui::Ui) {
}
fn command_search(app: &mut SheetApp, ui: &mut egui::Ui, d: &mut Dialog, confirm: &mut bool) {
let r = ui.add(egui::TextEdit::singleline(&mut d.search).desired_width(480.0).hint_text("Type a command, e.g. freeze, chart, bold…"));
r.request_focus();
let (down, up, home, end, pgup, pgdn) = ui.input_mut(|i| {
(
i.consume_key(egui::Modifiers::NONE, Key::ArrowDown),
i.consume_key(egui::Modifiers::NONE, Key::ArrowUp),
i.consume_key(egui::Modifiers::CTRL, Key::Home),
i.consume_key(egui::Modifiers::CTRL, Key::End),
i.consume_key(egui::Modifiers::NONE, Key::PageUp),
i.consume_key(egui::Modifiers::NONE, Key::PageDown),
)
});
let width = ui.available_width();
let r = ui.add(egui::TextEdit::singleline(&mut d.search).desired_width(width).hint_text("Type a command, e.g. freeze, chart, bold…"));
if !d.focus_initialized {
r.request_focus();
d.focus_initialized = true;
}
let q = d.search.to_ascii_lowercase();
let cmds: Vec<(String, String, String)> = app
.session
@@ -2283,19 +2302,51 @@ fn command_search(app: &mut SheetApp, ui: &mut egui::Ui, d: &mut Dialog, confirm
.map(|c| (c.id.to_string(), c.label.to_string(), c.menu.join(" › ")))
.take(40)
.collect();
if ui.input(|i| i.key_pressed(Key::ArrowDown)) {
d.list_index = (d.list_index + 1).min(cmds.len().saturating_sub(1));
let last = cmds.len().saturating_sub(1);
let row_h = ui.spacing().interact_size.y.max(20.0);
let row_step = row_h + ui.spacing().item_spacing.y;
const LIST_HEIGHT: f32 = 320.0;
let page_size = ((LIST_HEIGHT / row_step).floor() as usize).saturating_sub(1).max(1);
if down {
d.list_index = (d.list_index + 1).min(last);
}
if ui.input(|i| i.key_pressed(Key::ArrowUp)) {
if up {
d.list_index = d.list_index.saturating_sub(1);
}
egui::ScrollArea::vertical().max_height(320.0).show(ui, |ui| {
if pgdn {
d.list_index = (d.list_index + page_size).min(last);
}
if pgup {
d.list_index = d.list_index.saturating_sub(page_size);
}
if home {
d.list_index = 0;
}
if end {
d.list_index = last;
}
d.list_index = d.list_index.min(last);
egui::ScrollArea::vertical().max_height(LIST_HEIGHT).auto_shrink([true, false]).show(ui, |ui| {
let scroll_area_width = ui.available_width();
for (i, (id, label, menu)) in cmds.iter().enumerate() {
let r = ui.add(egui::Button::selectable(i == d.list_index, format!("{label} {menu}")).min_size(vec2(480.0, 20.0)));
let r = ui.add(egui::Button::selectable(i == d.list_index, format!("{label} {menu}")).min_size(vec2(scroll_area_width, 20.0)));
if (down || up || home || end || pgup || pgdn) && i == d.list_index && !ui.clip_rect().contains_rect(r.rect) {
r.scroll_to_me(Some(if down || end || pgdn { egui::Align::Max } else { egui::Align::Min }));
}
if r.clicked() {
d.list_index = i;
*confirm = true;
}
r.on_hover_text(id);
}
});