A press outside a field commits what was typed before the press acts
This commit is contained in:
parent
f4f60b6ac6
commit
d775549258
|
|
@ -446,3 +446,35 @@ fn typed_text_is_committed_when_the_focus_moves_away() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Text typed into a field is committed in the frame of a press elsewhere, before what is drawn
|
||||
/// after the field (the canvas) acts on the press: a click that selects another object must not
|
||||
/// get the typed value, even when both objects show the same one.
|
||||
#[test]
|
||||
fn a_press_on_the_canvas_commits_to_the_object_being_edited() {
|
||||
let mut f = Field::new();
|
||||
// The object the panel shows; both have the value 100.
|
||||
let selected = Cell::new(1);
|
||||
let committed = Cell::new(None);
|
||||
let draw = |ui: &mut egui::Ui| {
|
||||
let got = widgets::range_field(ui, "f", 100.0, 0.0..=1000.0, "%", 0, 80.0);
|
||||
if let Some(v) = got {
|
||||
committed.set(Some((selected.get(), v)));
|
||||
}
|
||||
// The canvas: a press ends text input and selects the other object.
|
||||
if ui.input(|i| i.pointer.primary_pressed() && i.pointer.interact_pos().is_some_and(|p| p.y > 100.0)) {
|
||||
ui.memory_mut(|m| m.stop_text_input());
|
||||
selected.set(2);
|
||||
}
|
||||
got
|
||||
};
|
||||
f.frame(vec![], &draw);
|
||||
let (field, canvas) = (f.rect.get().center(), Pos2::new(200.0, 180.0));
|
||||
f.frame(vec![Event::PointerMoved(field), pointer_button(field, true)], &draw);
|
||||
f.frame(vec![pointer_button(field, false)], &draw);
|
||||
f.frame(vec![Event::Text("42".into())], &draw);
|
||||
f.frame(vec![Event::PointerMoved(canvas), pointer_button(canvas, true)], &draw);
|
||||
f.frame(vec![pointer_button(canvas, false)], &draw);
|
||||
f.frame(vec![], &draw);
|
||||
assert_eq!((committed.get(), selected.get()), (Some((1, 42.0)), 2));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -348,6 +348,15 @@ fn select_all_on_focus(ui: &Ui, resp: &Response, text: &str) {
|
|||
fn recessed_text(ui: &mut Ui, id: egui::Id, shown: &str, width: f32, rows: usize) -> (String, Response, Rect) {
|
||||
let t = Tokens::get(ui.ctx());
|
||||
let editing = ui.memory(|m| m.has_focus(id));
|
||||
// A press outside the field ends its editing in this frame, so the text typed is committed
|
||||
// before the press acts: the canvas, drawn after the panels, may select another object, and a
|
||||
// frame later the text would be committed to that one.
|
||||
if editing
|
||||
&& let Some(at) = ui.input(|i| i.pointer.primary_pressed().then(|| i.pointer.interact_pos()).flatten())
|
||||
&& ui.ctx().read_response(id).is_some_and(|r| !r.rect.contains(at))
|
||||
{
|
||||
ui.memory_mut(|m| m.surrender_focus(id));
|
||||
}
|
||||
// When the value changes under a focused field (the slider beside it, a preview, another
|
||||
// field's edit), its text follows: the text typed for the old value would otherwise go back in
|
||||
// on the next Enter, Tab or arrow key (#1457).
|
||||
|
|
|
|||
Loading…
Reference in New Issue