mirror of
https://github.com/storytold/effectcraft.git
synced 2026-11-07 12:13:22 +00:00
#1190: a move after the release in the same frame does not carry the checkbox drag
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RDvxCS8xcR28VArjzn1x7U
This commit is contained in:
@@ -484,18 +484,26 @@ fn drag_toggle(ui: &Ui, response: &Response, value: Option<bool>) -> Option<bool
|
||||
{
|
||||
return Some(target);
|
||||
}
|
||||
// Whether the button is held, tracked in event order: a move after a release in the same frame is no drag.
|
||||
// Before the first button event it is held exactly when that event is a release (or, with none, when it is down).
|
||||
let mut held = match steps.iter().find(|(step, _)| *step != Step::Move) {
|
||||
Some((step, _)) => *step == Step::Release,
|
||||
None => down,
|
||||
};
|
||||
let mut press_seen = false;
|
||||
for (step, over) in steps {
|
||||
match step {
|
||||
Step::Press => {
|
||||
press_seen = true;
|
||||
held = true;
|
||||
if drag.target.is_none() && over {
|
||||
drag.target = Some(!on);
|
||||
drag.visited.insert(response.id);
|
||||
return Some(!on);
|
||||
}
|
||||
}
|
||||
Step::Move if press_seen || down => match drag.target {
|
||||
Step::Release => held = false,
|
||||
Step::Move if held => match drag.target {
|
||||
Some(target) if over => {
|
||||
if drag.visited.insert(response.id) && on != target {
|
||||
return Some(target);
|
||||
@@ -1113,6 +1121,24 @@ mod tests {
|
||||
assert_eq!((values[0], values[1]), (Some(true), Some(true)), "a crossing before the release still takes the state");
|
||||
}
|
||||
|
||||
/// A move that arrives after the release, in the frame of the click, is the pointer travelling without the button:
|
||||
/// it must not carry the gesture onto the checkbox it ends over.
|
||||
#[test]
|
||||
fn a_move_after_the_release_in_the_same_frame_paints_nothing() {
|
||||
let (a, b) = (28.0, 58.0);
|
||||
let ctx = egui::Context::default();
|
||||
let mut values = [Some(false); 5];
|
||||
values[2] = None;
|
||||
checkbox_frame(&ctx, &mut values, vec![]);
|
||||
let mut events = vec![moved(a)];
|
||||
events.extend(button(a, true));
|
||||
events.extend(button(a, false));
|
||||
events.push(moved(b));
|
||||
checkbox_frame(&ctx, &mut values, events);
|
||||
checkbox_frame(&ctx, &mut values, vec![]);
|
||||
assert_eq!((values[0], values[1]), (Some(true), Some(false)), "the clicked one changes, the one moved onto afterwards does not");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn checkbox_click_and_keyboard_toggle_once_and_drag_must_start_on_a_checkbox() {
|
||||
let ctx = egui::Context::default();
|
||||
|
||||
Reference in New Issue
Block a user