mirror of
https://github.com/storytold/lightcraft.git
synced 2026-10-28 20:17:18 -06:00
LR-BEHAV-TEXTFIELD: a drag into a select-on-focus field keeps its selection
Select-on-focus selected everything on the press that took the focus, after egui had placed the drag's anchor there: a drag then selected from the start of the text. With a press, the field now waits for the release and selects everything only after a plain click, as a browser's address bar does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
6fb1a24c88
commit
a6e59cc5b3
@@ -195,9 +195,22 @@ impl<'a> TextField<'a> {
|
||||
memo.before = None;
|
||||
}
|
||||
// the start of an edit (not the focus coming back from the menu)
|
||||
let pressing = ui.input(|i| i.pointer.any_down());
|
||||
if focused && memo.before.is_none() {
|
||||
memo.before = Some(self.text.clone());
|
||||
if self.select_on_focus {
|
||||
// a press that took the focus may go on to drag a selection: wait for its release
|
||||
if pressing {
|
||||
memo.select_on_release = true;
|
||||
} else {
|
||||
select_all(ui.ctx(), id, self.text);
|
||||
}
|
||||
}
|
||||
}
|
||||
if memo.select_on_release && !pressing {
|
||||
memo.select_on_release = false;
|
||||
// a plain click selects everything; a drag keeps what it selected
|
||||
if focused && !has_selection(ui.ctx(), id) {
|
||||
select_all(ui.ctx(), id, self.text);
|
||||
}
|
||||
}
|
||||
@@ -264,6 +277,9 @@ struct Memo {
|
||||
action: Option<Action>,
|
||||
/// The focus left for the menu: the edit ends if the menu closes without a choice.
|
||||
away: bool,
|
||||
/// The field took the focus with select-on-focus under a press: select all on its release,
|
||||
/// unless it dragged a selection.
|
||||
select_on_release: bool,
|
||||
/// The frame (egui pass) the field was last drawn in.
|
||||
pass: u64,
|
||||
}
|
||||
@@ -666,4 +682,23 @@ mod tests {
|
||||
rig.key(Key::Escape, Modifiers::NONE);
|
||||
assert_eq!(rig.text, "Porto");
|
||||
}
|
||||
|
||||
/// A field that selects on focus still lets a drag into it select part of the text, as a
|
||||
/// browser's address bar does: only a plain click selects everything.
|
||||
#[test]
|
||||
fn a_drag_into_a_field_that_selects_on_focus_selects_what_it_covers() {
|
||||
let mut rig = Rig::new("Lisbon Portugal Europe Atlantic Ocean");
|
||||
rig.select_on_focus = true;
|
||||
let r = rig.rect(FIELD).expect("the field");
|
||||
let (from, to) = (r.center(), egui::pos2(r.right() + 40.0, r.center().y));
|
||||
let press = |at, pressed| Event::PointerButton { pos: at, button: PointerButton::Primary, pressed, modifiers: Modifiers::NONE };
|
||||
rig.frame(vec![Event::PointerMoved(from), press(from, true)]);
|
||||
for i in 1..=5 {
|
||||
rig.frame(vec![Event::PointerMoved(from + (to - from) * (i as f32 / 5.0))]);
|
||||
}
|
||||
rig.frame(vec![press(to, false)]);
|
||||
rig.settle();
|
||||
rig.type_text("X");
|
||||
assert!(rig.text.starts_with("Lisbon") && rig.text.ends_with('X') && rig.text != "X", "{:?}", rig.text);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user