mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-11-06 18:52:36 +00:00
fix(ui): prevent wheel lockup at edge in non-continuous view (#5713)
This commit is contained in:
1 parent
f47618f59b
commit
b31b40356d
3 files changed
+53
-1
No files matched your search
@@ -268,7 +268,11 @@ impl DocView {
|
|||||||
let Some(forward) = self.wheel.feed(unit, dy, phase, now, can_turn) else { return false };
|
let Some(forward) = self.wheel.feed(unit, dy, phase, now, can_turn) else { return false };
|
||||||
let before = self.current;
|
let before = self.current;
|
||||||
self.step_page(forward);
|
self.step_page(forward);
|
||||||
self.current != before
|
if self.current == before {
|
||||||
|
self.wheel.unturn();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
/// One wheel event in a non-continuous view whose page is taller than the window, where the
|
/// One wheel event in a non-continuous view whose page is taller than the window, where the
|
||||||
@@ -288,6 +292,7 @@ impl DocView {
|
|||||||
let before = self.current;
|
let before = self.current;
|
||||||
self.step_page(forward);
|
self.step_page(forward);
|
||||||
if self.current == before {
|
if self.current == before {
|
||||||
|
self.wheel.unturn();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if !forward {
|
if !forward {
|
||||||
|
|||||||
@@ -73,6 +73,11 @@ impl WheelPager {
|
|||||||
self.accum = 0.0;
|
self.accum = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Reset any turned state when a turn did not happen (e.g. at document boundary).
|
||||||
|
pub(crate) fn unturn(&mut self) {
|
||||||
|
self.turned = None;
|
||||||
|
}
|
||||||
|
|
||||||
/// Whether the current gesture already turned a page: the rest of it must not pan the page
|
/// Whether the current gesture already turned a page: the rest of it must not pan the page
|
||||||
/// just shown away from its top (or bottom).
|
/// just shown away from its top (or bottom).
|
||||||
pub(crate) fn gesture_turned(&self) -> bool {
|
pub(crate) fn gesture_turned(&self) -> bool {
|
||||||
|
|||||||
@@ -520,6 +520,48 @@ fn single_page_swipe_that_reaches_the_edge_does_not_turn_but_a_fresh_one_does()
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn single_page_wheel_at_last_page_bottom_edge_can_scroll_back_up() {
|
||||||
|
let mut h = harness_stepping(1.0 / 60.0, &[("layout", "single"), ("zoom", "200")]);
|
||||||
|
h.state_mut().views[0].go_to_page(2); // Go to last page of PAGES (3 pages)
|
||||||
|
h.run_steps(20);
|
||||||
|
let at = h.state().views[0].viewport_rect().center();
|
||||||
|
h.hover_at(at);
|
||||||
|
h.run_steps(4);
|
||||||
|
|
||||||
|
// Scroll to the bottom edge of page 3
|
||||||
|
let mut notches = 0;
|
||||||
|
let mut last = rect(&h, 2).expect("page 3 on screen").min.y;
|
||||||
|
let mut at_bottom = false;
|
||||||
|
while notches < 80 {
|
||||||
|
h.event(wheel(MouseWheelUnit::Line, -1.0, TouchPhase::Move));
|
||||||
|
h.run_steps(12);
|
||||||
|
notches += 1;
|
||||||
|
if let Some(r) = rect(&h, 2) {
|
||||||
|
if (r.min.y - last).abs() < 0.01 {
|
||||||
|
at_bottom = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
last = r.min.y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert!(at_bottom, "reached bottom edge of last page");
|
||||||
|
assert_eq!(h.state().views[0].current, 2, "remains on page 3");
|
||||||
|
|
||||||
|
// Push the wheel further against the bottom edge (cannot turn because it's the last page)
|
||||||
|
for _ in 0..5 {
|
||||||
|
h.event(wheel(MouseWheelUnit::Line, -1.0, TouchPhase::Move));
|
||||||
|
h.run_steps(12);
|
||||||
|
}
|
||||||
|
let bottom_y = rect(&h, 2).expect("page 3 on screen").min.y;
|
||||||
|
|
||||||
|
// Roll the wheel back up: the page must move away from the bottom edge (#5713)
|
||||||
|
h.event(wheel(MouseWheelUnit::Line, 1.0, TouchPhase::Move));
|
||||||
|
h.run_steps(12);
|
||||||
|
let after_up_y = rect(&h, 2).expect("page 3 on screen").min.y;
|
||||||
|
assert!(after_up_y > bottom_y, "scrolling up moves the page away from the bottom edge: {after_up_y} > {bottom_y}");
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn stepping_past_either_end_leaves_the_view_alone() {
|
fn stepping_past_either_end_leaves_the_view_alone() {
|
||||||
// Paging on past the first or last page must not jump the page back to its top.
|
// Paging on past the first or last page must not jump the page back to its top.
|
||||||
|
|||||||
Reference in new issue
Block a user