mirror of
https://github.com/storytold/gridcraft.git
synced 2026-11-02 07:06:48 -06:00
UI: Insert Function: Enter on the category list doesn't confirm the dialog
egui clicks a focused control on Enter as on Space, so Enter on the focused category list opened it, and the dialog's OK handling took the same key press and inserted the selected function. Enter in the open list did the same while picking a category. The dialog now leaves Enter to the category list while the list has the focus or its menu is open (or was open as the frame started, since Enter on a row closes it in that frame). Enter in the search box or on the function list still confirms. Test: function_library::enter_on_the_category_list_does_not_confirm_insert_function tabs to the list, presses Enter (the list opens, the dialog stays open, nothing is inserted), presses Enter again in the open list (still open, nothing inserted), then Shift+Tab back to the search box, where Enter confirms.
This commit is contained in:
@@ -29,7 +29,10 @@ pub(super) fn insert_function(app: &mut SheetApp, ui: &mut egui::Ui, d: &mut Dia
|
||||
} else {
|
||||
lib::category_id(&saved).map(lib::category_label).unwrap_or(MOST_RECENTLY_USED).to_string()
|
||||
};
|
||||
ui.horizontal(|ui| {
|
||||
// The category list is the dialog's only menu, so a menu open as the frame starts is its own
|
||||
// (Enter on a row picks it and closes the menu in this frame).
|
||||
let menu_was_open = egui::Popup::is_any_open(ui.ctx());
|
||||
let picker = ui.horizontal(|ui| {
|
||||
let label = ui.label(language.tr("Or select a category:"));
|
||||
craft_ui::ComboBox::from_id_salt("insertFunctionCategory")
|
||||
.width(220.0)
|
||||
@@ -40,8 +43,14 @@ pub(super) fn insert_function(app: &mut SheetApp, ui: &mut egui::Ui, d: &mut Dia
|
||||
}
|
||||
})
|
||||
.response
|
||||
.labelled_by(label.id);
|
||||
.labelled_by(label.id)
|
||||
});
|
||||
// Enter on the category list or in its menu opens it or picks a category, as Space does
|
||||
// (egui clicks a focused control on either key); it does not also confirm the dialog.
|
||||
let picker = picker.inner;
|
||||
if menu_was_open || picker.has_focus() || craft_ui::ComboBox::is_open(ui.ctx(), picker.id) {
|
||||
ui.input_mut(|i| i.consume_key(egui::Modifiers::NONE, egui::Key::Enter));
|
||||
}
|
||||
if category != saved {
|
||||
d.list_index = 0;
|
||||
}
|
||||
|
||||
@@ -263,6 +263,41 @@ fn insert_function_lets_tab_reach_the_category_list() {
|
||||
assert_eq!(listed(&h), before + 1, "the list is open");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn enter_on_the_category_list_does_not_confirm_insert_function() {
|
||||
use egui::accesskit::Role;
|
||||
let mut h = formulas_tab(1440.0);
|
||||
click(&mut h, "Insert Function");
|
||||
h.run_steps(3);
|
||||
let open = |h: &Harness| h.state().dialog.as_ref().is_some_and(|d| d.name == "insertFunction");
|
||||
let listed = |h: &Harness| h.get_all_by_label("Date & Time").count();
|
||||
let closed = listed(&h);
|
||||
h.input_mut().events.extend([key_event(Key::Tab, true), key_event(Key::Tab, false)]);
|
||||
h.run_steps(5);
|
||||
assert!(h.get_by_role(Role::ComboBox).is_focused(), "Tab reaches the category list");
|
||||
// Enter on the focused list opens it, as Space does; the dialog stays open and nothing is
|
||||
// inserted.
|
||||
h.input_mut().events.extend([key_event(Key::Enter, true), key_event(Key::Enter, false)]);
|
||||
h.run_steps(3);
|
||||
assert!(open(&h), "Enter on the category list leaves the dialog open");
|
||||
assert_eq!(editor_text(&h), None, "no function is inserted");
|
||||
assert_eq!(listed(&h), closed + 1, "Enter opens the list");
|
||||
// Enter again, with the list open, closes it and still does not confirm.
|
||||
h.input_mut().events.extend([key_event(Key::Enter, true), key_event(Key::Enter, false)]);
|
||||
h.run_steps(3);
|
||||
assert!(open(&h), "Enter in the open list leaves the dialog open");
|
||||
assert_eq!(editor_text(&h), None);
|
||||
// Back in the search box (Shift+Tab), Enter confirms as before.
|
||||
let shift_tab = |pressed| Event::Key { key: Key::Tab, physical_key: None, pressed, repeat: false, modifiers: Modifiers::SHIFT };
|
||||
h.input_mut().events.extend([shift_tab(true), shift_tab(false)]);
|
||||
h.run_steps(3);
|
||||
assert!(!h.get_by_role(Role::ComboBox).is_focused(), "Shift+Tab leaves the category list");
|
||||
h.input_mut().events.extend([key_event(Key::Enter, true), key_event(Key::Enter, false)]);
|
||||
h.run_steps(3);
|
||||
assert!(!open(&h), "Enter in the search box confirms");
|
||||
assert!(editor_text(&h).is_some_and(|t| t.starts_with('=') && t.ends_with('(')), "{:?}", editor_text(&h));
|
||||
}
|
||||
|
||||
/// The text shapes the last frame painted, with their left edge and width.
|
||||
fn painted_text(h: &Harness) -> Vec<(String, f32, f32)> {
|
||||
let mut out = Vec::new();
|
||||
|
||||
Reference in New Issue
Block a user