UI: reset the fractional wheel carry when the presentation changes

The leftover fraction of a wheel line is now stored with the active
document's uid and dropped when another presentation becomes active, so a
quarter line left in one deck can no longer turn a slide in another.

Test: 0.75 of a line in one presentation followed by 0.25 in a new one
does not turn the page; a whole line in the new one does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
kinower
2026-10-22 08:09:23 +02:00
co-authored by Claude Opus 5.5
parent 8ddb977733
commit e11c7e4d7e
2 changed files with 28 additions and 2 deletions
+7 -2
View File
@@ -177,13 +177,18 @@ pub fn show(app: &mut SlideApp, ui: &mut Ui) {
if overflow != egui::Vec2::ZERO {
offset -= wheel;
} else if !app.anim_preview_active() && app.session.tool.marquee.is_none() && !app.session.tool.dragging() {
// The leftover fraction belongs to one presentation: another one starts from zero.
let carry_id = ui.id().with("wheel_carry");
let mut carry: f32 = ui.data_mut(|d| d.get_temp(carry_id).unwrap_or_default());
let (carry_doc, mut carry): (Option<u64>, f32) = ui.data_mut(|d| d.get_temp(carry_id).unwrap_or_default());
let doc_uid = app.session.active().map(|d| d.uid);
if carry_doc != doc_uid {
carry = 0.0;
}
let wheel_step = app.session.active().and_then(|d| {
let current = d.selection.slide;
ui.input(|i| wheel_slide_target(&i.events, current, d.doc.slides.len(), &mut carry)).map(|target| (current, target))
});
ui.data_mut(|d| d.insert_temp(carry_id, carry));
ui.data_mut(|d| d.insert_temp(carry_id, (doc_uid, carry)));
if let Some((current, index)) = wheel_step {
if index != current {
let _ = app.run("slide.go", json!({"index": index}));
+21
View File
@@ -3383,6 +3383,27 @@ mod tests {
assert_eq!(slide_at(h.state()), 0, "a whole line back is one slide back");
}
/// A fraction of a line left over in one presentation does not carry into another.
#[test]
fn mouse_wheel_fraction_does_not_carry_into_another_presentation() {
let mut h = flick_harness();
h.state_mut().run("slide.new", json!({})).unwrap();
h.state_mut().run("slide.go", json!({"index": 0})).unwrap();
h.run_steps(1);
mouse_wheel(&mut h, &[-0.75]);
assert_eq!(slide_at(h.state()), 0);
h.state_mut().run("file.new", json!({})).unwrap();
h.state_mut().run("slide.new", json!({})).unwrap();
h.state_mut().run("slide.go", json!({"index": 0})).unwrap();
h.state_mut().ui.zoom = Some(0.4);
h.run_steps(2);
mouse_wheel(&mut h, &[-0.25]);
assert_eq!(slide_at(h.state()), 0, "a quarter line in the new presentation does not turn the page");
mouse_wheel(&mut h, &[-0.75]);
assert_eq!(slide_at(h.state()), 1, "a whole line in the new presentation does");
}
#[test]
fn mouse_wheel_over_a_zoomed_canvas_pans_and_outside_the_canvas_does_not_navigate() {
let mut h = flick_harness();