A just-opened dialog gives its focus to the first enabled field, not a greyed-out one
This commit is contained in:
parent
2ff64993eb
commit
689ad46999
|
|
@ -412,8 +412,8 @@ pub fn show(app: &mut VectorcraftApp, ctx: &egui::Context) {
|
|||
ui.set_max_width(spec.max_width.map_or(room, |w| w.min(room)));
|
||||
modal::heading(ui, &heading);
|
||||
ui.add_space(12.0);
|
||||
// Just opened: its first field takes the keyboard focus, as in the reference app (type a
|
||||
// value, press Enter). Only the body's fields can take it.
|
||||
// Just opened: its first enabled field takes the keyboard focus, as in the reference app
|
||||
// (type a value, press Enter). Only the body's fields can take it.
|
||||
if focus_first {
|
||||
ui.data_mut(|m| m.insert_temp(widgets::dialog_focus_flag(), true));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -566,6 +566,37 @@ fn a_dialog_opened_by_a_click_focuses_its_first_field_each_time_it_opens() {
|
|||
}
|
||||
}
|
||||
|
||||
/// A greyed-out field can't hold the keyboard focus, so it doesn't take a just-opened dialog's
|
||||
/// either: the focus waits for the first enabled field. Blend Options on Smooth Color shows its
|
||||
/// steps greyed out; choosing Specified Steps enables the field and it takes the focus (type a
|
||||
/// count, press Enter).
|
||||
#[test]
|
||||
fn a_dialogs_focus_skips_a_greyed_out_first_field() {
|
||||
let mut app = app();
|
||||
let ctx = egui::Context::default();
|
||||
theme::install_fonts(&ctx);
|
||||
theme::apply(&ctx, Default::default());
|
||||
let frame = |app: &mut VectorcraftApp, events: Vec<egui::Event>| {
|
||||
let mut out = ctx.run_ui(egui::RawInput { events, ..Default::default() }, |ui| show(app, ui.ctx()));
|
||||
out.textures_delta.clear();
|
||||
};
|
||||
let enter = egui::Event::Key { key: egui::Key::Enter, physical_key: None, pressed: true, repeat: false, modifiers: Default::default() };
|
||||
app.run("ui.blendOptions", json!({})).unwrap();
|
||||
app.ui.dialog.as_mut().unwrap().fields.insert("spacing".into(), json!("smooth"));
|
||||
for _ in 0..3 {
|
||||
frame(&mut app, vec![]);
|
||||
}
|
||||
assert!(ctx.memory(|m| m.focused()).is_none(), "nothing to type in yet");
|
||||
app.ui.dialog.as_mut().unwrap().fields.insert("spacing".into(), json!("steps"));
|
||||
frame(&mut app, vec![]);
|
||||
assert!(ctx.memory(|m| m.focused()).is_some(), "the steps field takes the focus once it is enabled");
|
||||
frame(&mut app, vec![egui::Event::Text("7".into())]);
|
||||
frame(&mut app, vec![enter]);
|
||||
assert!(app.ui.dialog.is_none());
|
||||
let info = app.run("object.blend.info", json!({})).unwrap();
|
||||
assert_eq!((info["spacing"].clone(), info["steps"].clone()), (json!("steps"), json!(7)), "{info}");
|
||||
}
|
||||
|
||||
/// #1000: a count typed in Object › Create Object Mosaic… reaches the command (a whole number typed
|
||||
/// in a command's dialog is an integer), so the mosaic has that many columns, not the 10 × 10 grid.
|
||||
#[test]
|
||||
|
|
|
|||
|
|
@ -280,16 +280,17 @@ fn step_value(ui: &Ui, resp: &Response, buf: &mut String, read: impl Fn(&str) ->
|
|||
}
|
||||
|
||||
/// The flag `dialogs::show` raises while it draws the body of a dialog that has just opened; the
|
||||
/// first field drawn takes it ([`take_dialog_focus`]).
|
||||
/// first enabled field drawn takes it ([`take_dialog_focus`]).
|
||||
pub(crate) fn dialog_focus_flag() -> egui::Id {
|
||||
egui::Id::new("dialog-focus-first-field")
|
||||
}
|
||||
|
||||
/// If field `id` (showing `text`) is the first field of a dialog that has just opened, give it the
|
||||
/// keyboard focus with all of `text` selected: typing replaces the value and Enter applies it.
|
||||
/// If field `id` (showing `text`) is the first enabled field of a dialog that has just opened, give
|
||||
/// it the keyboard focus with all of `text` selected: typing replaces the value and Enter applies it.
|
||||
pub(crate) fn take_dialog_focus(ui: &Ui, id: egui::Id, text: &str) {
|
||||
// A new window's first frame only measures its contents: nothing can take focus yet.
|
||||
if ui.is_sizing_pass() || ui.data_mut(|d| d.remove_temp::<bool>(dialog_focus_flag())).is_none() {
|
||||
// A new window's first frame only measures its contents: nothing can take focus yet. Nor can a
|
||||
// greyed-out field (egui drops its focus): the flag stays for the first field that is enabled.
|
||||
if ui.is_sizing_pass() || !ui.is_enabled() || ui.data_mut(|d| d.remove_temp::<bool>(dialog_focus_flag())).is_none() {
|
||||
return;
|
||||
}
|
||||
focus_field(ui, id, text);
|
||||
|
|
|
|||
Loading…
Reference in New Issue