mirror of
https://github.com/storytold/figcraft.git
synced 2026-11-09 00:17:58 +00:00
Scrub speed: a pointer gone from the window keeps its speed
egui reports the pointer gone (no hover position) with the button still down when it leaves the window during a scrub; the speed stayed at the last rise rather than falling back to 1x and announcing it. Test in field_tests. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
3d704ce4c0
commit
04d37b56b5
@@ -317,6 +317,26 @@ fn moving_up_or_down_while_scrubbing_changes_the_speed_and_says_so() {
|
||||
u.frame_with(vec![Event::PointerMoved(to), press(false, to)], shift);
|
||||
u.frame(vec![]);
|
||||
assert_eq!(geom(&u, a).0 - x0, 200.0, "ten points at 2x with Shift");
|
||||
// The pointer reported gone from the window (egui's PointerGone) with the button still down
|
||||
// keeps the speed it had: no notice of 1x, and the scrub goes on at 2x once it is back.
|
||||
let x0 = geom(&u, a).0;
|
||||
let from = label(&mut u, "X");
|
||||
let m = Modifiers::NONE;
|
||||
let press = |pressed, pos| Event::PointerButton { pos, button: egui::PointerButton::Primary, pressed, modifiers: m };
|
||||
u.frame_with(vec![Event::PointerMoved(from), press(true, from)], m);
|
||||
let up = pos2(from.x, from.y - 150.0);
|
||||
u.frame_with(vec![Event::PointerMoved(up)], m);
|
||||
u.frame_with(vec![Event::PointerMoved(pos2(up.x + 10.0, up.y))], m);
|
||||
assert!(toast(&u).contains("2x"), "{}", toast(&u));
|
||||
u.app.ui.toast = None;
|
||||
u.frame_with(vec![Event::PointerGone], m);
|
||||
u.frame_with(vec![Event::PointerMoved(pos2(up.x + 20.0, up.y))], m);
|
||||
u.frame_with(vec![Event::PointerMoved(pos2(up.x + 30.0, up.y))], m);
|
||||
assert!(toast(&u).is_empty(), "no notice while the pointer was gone or back at the same height: {}", toast(&u));
|
||||
let to = pos2(up.x + 30.0, up.y);
|
||||
u.frame_with(vec![Event::PointerMoved(to), press(false, to)], m);
|
||||
u.frame(vec![]);
|
||||
assert_eq!(geom(&u, a).0 - x0, 40.0, "ten points before and ten after the pointer was gone, at 2x both");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -168,7 +168,8 @@ pub(crate) fn scrub(ui: &Ui, id: Id, response: &Response, value: Option<f64>, st
|
||||
let scrub_id = id.with("scrub");
|
||||
if response.dragged() || response.drag_stopped() {
|
||||
let began = response.drag_started();
|
||||
let (v0, mut amount, last_speed): (f64, f64, &'static str) = ui.data(|d| d.get_temp(scrub_id)).filter(|_| !began).unwrap_or((v, 0.0, ""));
|
||||
let (v0, mut amount, last_speed, last_rise): (f64, f64, &'static str, f64) =
|
||||
ui.data(|d| d.get_temp(scrub_id)).filter(|_| !began).unwrap_or((v, 0.0, "", 0.0));
|
||||
let (dx, rise, shift, alt) = ui.input(|i| {
|
||||
let p = &i.pointer;
|
||||
// As it begins: all the way from the press (a drag is one only after a few points).
|
||||
@@ -178,10 +179,14 @@ pub(crate) fn scrub(ui: &Ui, id: Id, response: &Response, value: Option<f64>, st
|
||||
// does too. Elsewhere the scrub just stops there.
|
||||
let raw = p.motion().map_or(0.0, |m| m.x / i.pixels_per_point);
|
||||
let at_edge = moved == 0.0 && p.hover_pos().is_none_or(|at| at.x <= 1.0 || at.x >= i.content_rect().max.x - 1.0);
|
||||
// How far above where the scrub began the pointer is: the speed (`scrub_speed`).
|
||||
let rise = p.hover_pos().zip(p.press_origin()).map_or(0.0, |(at, from)| f64::from(from.y - at.y));
|
||||
// How far above where the scrub began the pointer is: the speed (`scrub_speed`);
|
||||
// None while the pointer is gone from the window.
|
||||
let rise = p.hover_pos().zip(p.press_origin()).map(|(at, from)| f64::from(from.y - at.y));
|
||||
(f64::from(if at_edge { raw } else { moved }), rise, i.modifiers.shift, i.modifiers.alt)
|
||||
});
|
||||
// Gone from the window (egui says so, the button still down), the pointer keeps the speed
|
||||
// it had rather than falling back to the usual one.
|
||||
let rise = rise.unwrap_or(last_rise);
|
||||
let (speed, notice) = scrub_speed(rise);
|
||||
// The frame the button goes up moves nothing: the scrub ends where the last one left it.
|
||||
if response.dragged() {
|
||||
@@ -190,7 +195,7 @@ pub(crate) fn scrub(ui: &Ui, id: Id, response: &Response, value: Option<f64>, st
|
||||
if notice != last_speed && !(last_speed.is_empty() && speed == 1.0) {
|
||||
ui.data_mut(|d| d.insert_temp(scrub_notice_id(), notice));
|
||||
}
|
||||
ui.data_mut(|d| d.insert_temp(scrub_id, (v0, amount, notice)));
|
||||
ui.data_mut(|d| d.insert_temp(scrub_id, (v0, amount, notice, rise)));
|
||||
}
|
||||
let quantum = if alt { step * 0.1 } else { step };
|
||||
return Some(FieldEdit::Scrub(scrubbed(v0, amount, quantum), response.drag_stopped()));
|
||||
|
||||
Reference in New Issue
Block a user