mirror of
https://github.com/storytold/figcraft.git
synced 2026-11-08 19:42:05 +00:00
Field scrub: the field senses drags only with Alt held or a scrub going on, so a touch swipe stays the scroll area's
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
7e6f88c469
commit
9783af9347
2 files changed
+31
-9
No files matched your search
@@ -1216,11 +1216,11 @@ fn alt_held_over_a_field_scrubs_it() {
|
||||
drag(&mut u, at, 25.0, Modifiers::NONE);
|
||||
assert_eq!(geom(&u, a).0, 35.0, "without Alt the field doesn't scrub");
|
||||
assert_eq!(undo_steps(&u), steps + 1);
|
||||
// Alt and the press in the same frame still scrub, and Alt let go before the button still
|
||||
// ends the scrub with its undo step.
|
||||
// Alt let go before the button still ends the scrub with its undo step.
|
||||
let (at, _) = field(&mut u, "X");
|
||||
let press = |pressed: bool, m: Modifiers, p: Pos2| Event::PointerButton { pos: p, button: egui::PointerButton::Primary, pressed, modifiers: m };
|
||||
u.frame_with(vec![Event::PointerMoved(at), press(true, alt, at)], alt);
|
||||
u.frame_with(vec![Event::PointerMoved(at)], alt);
|
||||
u.frame_with(vec![press(true, alt, at)], alt);
|
||||
for k in 1..=10 {
|
||||
u.frame_with(vec![Event::PointerMoved(pos2(at.x + 2.0 * k as f32, at.y))], alt);
|
||||
}
|
||||
@@ -1229,4 +1229,24 @@ fn alt_held_over_a_field_scrubs_it() {
|
||||
u.frame(vec![]);
|
||||
assert_eq!(geom(&u, a).0, 55.0, "twenty more");
|
||||
assert_eq!(undo_steps(&u), steps + 2, "committed when the button went up, without Alt");
|
||||
// Without Alt the field doesn't take the drag at all (a touch swipe over it is the panel's to
|
||||
// scroll): the press is a click of the field's, not a drag.
|
||||
let (at, _) = field(&mut u, "X");
|
||||
let field_id = Id::unique("pos_x").with("field");
|
||||
u.frame_with(vec![Event::PointerMoved(at)], Modifiers::NONE);
|
||||
u.frame_with(vec![press(true, Modifiers::NONE, at)], Modifiers::NONE);
|
||||
u.frame_with(vec![Event::PointerMoved(pos2(at.x + 10.0, at.y))], Modifiers::NONE);
|
||||
assert!(!u.ctx.is_being_dragged(field_id), "a plain press on the field isn't a drag of the field's");
|
||||
u.frame_with(vec![Event::PointerMoved(pos2(at.x + 10.0, at.y)), press(false, Modifiers::NONE, pos2(at.x + 10.0, at.y))], Modifiers::NONE);
|
||||
u.frame(vec![]);
|
||||
assert_eq!(geom(&u, a).0, 55.0, "nothing scrubbed");
|
||||
// With Alt held over it, the field does take the drag.
|
||||
let (at, _) = field(&mut u, "X");
|
||||
u.frame_with(vec![Event::PointerMoved(at)], alt);
|
||||
u.frame_with(vec![press(true, alt, at)], alt);
|
||||
u.frame_with(vec![Event::PointerMoved(pos2(at.x + 10.0, at.y))], alt);
|
||||
assert!(u.ctx.is_being_dragged(field_id), "with Alt the drag is the field's");
|
||||
u.frame_with(vec![Event::PointerMoved(pos2(at.x + 10.0, at.y)), press(false, alt, pos2(at.x + 10.0, at.y))], alt);
|
||||
u.frame(vec![]);
|
||||
assert_eq!(geom(&u, a).0, 65.0, "ten more");
|
||||
}
|
||||
@@ -268,15 +268,17 @@ fn number_field_impl(
|
||||
let mut editing: Option<String> = ui.data(|d| d.get_temp(editing_id));
|
||||
// Alt held over the field scrubs it too, as the label always does: "hover the input field
|
||||
// itself and hold down the modifier key" (Adjust alignment, rotation, position, and
|
||||
// dimensions). The field always senses drags (egui assigns a press by the frame before it, so
|
||||
// a sense that waits for Alt would miss a press that arrives with it); Alt as the drag begins
|
||||
// is what makes it a scrub, and that holds until the button is let go, Alt released or not.
|
||||
// dimensions). The field senses drags only while Alt is held, or while a scrub begun that way
|
||||
// goes on (Alt released or not), so a plain press or a touch swipe on it stays the scroll
|
||||
// area's; egui assigns a press by the frame before it, so Alt is held over the field before
|
||||
// the press, as a hand does. Alt as the drag begins is what makes it a scrub.
|
||||
let field_id = id.with("field");
|
||||
let field_resp = ui.interact(edit_rect, field_id, Sense::click_and_drag());
|
||||
let alt_now = ui.input(|i| i.modifiers.alt);
|
||||
let scrubbing_id = id.with("altscrub");
|
||||
let alt_scrub =
|
||||
editing.is_none() && if field_resp.drag_started() { alt_now } else { ui.data(|d| d.get_temp::<bool>(scrubbing_id)).unwrap_or(false) };
|
||||
let scrubbing = ui.data(|d| d.get_temp::<bool>(scrubbing_id)).unwrap_or(false);
|
||||
let field_sense = if editing.is_none() && (alt_now || scrubbing) { Sense::click_and_drag() } else { Sense::click() };
|
||||
let field_resp = ui.interact(edit_rect, field_id, field_sense);
|
||||
let alt_scrub = editing.is_none() && if field_resp.drag_started() { alt_now } else { scrubbing };
|
||||
ui.data_mut(|d| d.insert_temp(scrubbing_id, alt_scrub && field_resp.dragged() && !field_resp.drag_stopped()));
|
||||
a11y::number(&field_resp, lead.name(), value, suffix, empty.text());
|
||||
a11y::ring_around(ui, rect, &field_resp);
|
||||
|
||||
Reference in new issue
Block a user