mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-01 05:37:23 -06:00
Merge pull request #1382 from storytold/fix/1367-dialog-refocus
Fix #1367: a dialog opened from a menu takes the keyboard focus every time
This commit is contained in:
@@ -383,6 +383,13 @@ pub fn show(app: &mut VectorcraftApp, ctx: &egui::Context) {
|
||||
}
|
||||
m.get_temp::<bool>(focus_id).unwrap_or(false)
|
||||
});
|
||||
// Not in the frame of a click (the one on the menu item that opened it): egui takes the focus
|
||||
// from a field the click missed, so the field takes it a frame later (#1367).
|
||||
let clicked = ctx.input(|i| i.pointer.any_click());
|
||||
if focus_first && clicked {
|
||||
ctx.request_repaint();
|
||||
}
|
||||
let focus_first = focus_first && !clicked;
|
||||
let spec = spec(&d.kind);
|
||||
if let Some(window) = spec.window {
|
||||
return window(app, ctx);
|
||||
|
||||
@@ -525,6 +525,47 @@ fn a_dialog_opens_with_its_first_field_focused_so_typing_and_enter_apply() {
|
||||
assert_eq!(node.appearance.effects.last().map(|e| e.params["scaleH"].clone()), Some(json!(50.0)));
|
||||
}
|
||||
|
||||
/// #1367: a dialog opened by a click (its menu item) is drawn in the frame of that click, where egui
|
||||
/// takes the focus from a field the click missed: its first field still has the focus, each time it
|
||||
/// opens.
|
||||
#[test]
|
||||
fn a_dialog_opened_by_a_click_focuses_its_first_field_each_time_it_opens() {
|
||||
let mut app = app();
|
||||
app.run("shape.rectangle", json!({"x": 10, "y": 10, "width": 40, "height": 20})).unwrap();
|
||||
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();
|
||||
};
|
||||
// A click away from the dialog, as on a menu item.
|
||||
let click = || {
|
||||
let (pos, button, modifiers) = (egui::pos2(5.0, 5.0), egui::PointerButton::Primary, egui::Modifiers::NONE);
|
||||
let press = |pressed| egui::Event::PointerButton { pos, button, pressed, modifiers };
|
||||
vec![egui::Event::PointerMoved(pos), press(true), press(false)]
|
||||
};
|
||||
type Open = fn(&mut VectorcraftApp);
|
||||
let opens: [(&str, Open); 2] = [
|
||||
("Convert to Shape", |app| drop(app.run("effect.dialog", json!({"effect": "convertToShape.rectangle"})))),
|
||||
("Rasterize", |app| crate::menus::invoke(app, "object.rasterize", json!({}))),
|
||||
];
|
||||
for (name, open) in opens {
|
||||
for turn in 1..=3 {
|
||||
open(&mut app);
|
||||
assert!(app.ui.dialog.is_some(), "{name}");
|
||||
frame(&mut app, click());
|
||||
frame(&mut app, vec![]);
|
||||
frame(&mut app, vec![]);
|
||||
assert!(ctx.memory(|m| m.focused()).is_some(), "{name}, turn {turn}");
|
||||
cancel(&mut app);
|
||||
// A frame without the dialog, as between two uses of it.
|
||||
frame(&mut app, vec![]);
|
||||
assert!(ctx.memory(|m| m.focused()).is_none(), "{name}, turn {turn}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// #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]
|
||||
|
||||
Reference in New Issue
Block a user