mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-26 02:37:01 -06:00
Keep a numeric field caret when focus arrives while the pointer is still down.
Select-all ran on that late focus frame and replaced the drag the press had started.
This commit is contained in:
committed by
bflatastic
parent
433d78284d
commit
8354dbcd74
@@ -398,6 +398,23 @@ fn a_new_numeric_click_selects_all_on_release_without_moving_its_press_caret() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
/// Focus that arrives while the button is still down, without a press event on that frame,
|
||||
/// keeps the caret until release.
|
||||
#[test]
|
||||
fn focus_a_frame_after_the_press_does_not_select_all_until_release() {
|
||||
let mut f = Field::new();
|
||||
let draw = |ui: &mut egui::Ui| numeric_fixture(ui, 0);
|
||||
f.frame(vec![], &draw);
|
||||
let at = f.text_point(field_text(0), 2, 7.0);
|
||||
f.frame(vec![Event::PointerMoved(at), pointer_button(at, true)], &draw);
|
||||
let pressed = f.selection();
|
||||
f.frame(vec![Event::PointerMoved(at)], &draw);
|
||||
assert_eq!(f.selection(), pressed, "holding the button does not select the whole field");
|
||||
assert!(pressed.is_some_and(|(a, b)| a == b));
|
||||
f.frame(vec![pointer_button(at, false)], &draw);
|
||||
assert_eq!(f.selection(), Some((0, field_text(0).len())));
|
||||
}
|
||||
|
||||
fn keyboard_focus_keeps_selecting_the_entire_numeric_field() {
|
||||
for mode in 0..4 {
|
||||
let mut f = Field::new();
|
||||
|
||||
@@ -314,11 +314,19 @@ fn select_all(ui: &Ui, id: egui::Id, text: &str) {
|
||||
/// double-click. A pointer press keeps its caret so dragging selects from the pressed position.
|
||||
fn select_all_on_focus(ui: &Ui, resp: &Response, text: &str) {
|
||||
let pending = resp.id.with("select-all-on-focus-click");
|
||||
let (pressed, released) =
|
||||
ui.input(|i| (i.pointer.button_pressed(egui::PointerButton::Primary), i.pointer.button_released(egui::PointerButton::Primary)));
|
||||
let (pressed, released, down) = ui.input(|i| {
|
||||
(
|
||||
i.pointer.button_pressed(egui::PointerButton::Primary),
|
||||
i.pointer.button_released(egui::PointerButton::Primary),
|
||||
i.pointer.button_down(egui::PointerButton::Primary),
|
||||
)
|
||||
});
|
||||
// Focus can arrive the frame after the press, when `button_pressed` is already false
|
||||
// and the button is still down. Defer select-all until release so a drag keeps its caret.
|
||||
let defer = pressed || (down && resp.hovered());
|
||||
if resp.gained_focus() {
|
||||
ui.data_mut(|d| {
|
||||
if pressed {
|
||||
if defer {
|
||||
d.insert_temp(pending, true);
|
||||
} else {
|
||||
d.remove_temp::<bool>(pending);
|
||||
@@ -329,6 +337,9 @@ fn select_all_on_focus(ui: &Ui, resp: &Response, text: &str) {
|
||||
if resp.lost_focus() {
|
||||
ui.data_mut(|d| d.remove_temp::<bool>(pending));
|
||||
}
|
||||
if resp.gained_focus() && defer {
|
||||
return;
|
||||
}
|
||||
if !(resp.gained_focus() && !pressed || resp.double_clicked() || clicked_focus) {
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user