Skip to content

Commit 716a11c

Browse files
hecrjKoranir
andcommitted
Notify all scrollable::Viewport changes
Co-authored-by: Daniel Yoon <101683475+Koranir@users.noreply.github.com>
1 parent c22559c commit 716a11c

1 file changed

Lines changed: 44 additions & 14 deletions

File tree

widget/src/scrollable.rs

Lines changed: 44 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use crate::core::touch;
1212
use crate::core::widget;
1313
use crate::core::widget::operation::{self, Operation};
1414
use crate::core::widget::tree::{self, Tree};
15+
use crate::core::window;
1516
use crate::core::{
1617
self, Background, Clipboard, Color, Element, Layout, Length, Padding,
1718
Pixels, Point, Rectangle, Shell, Size, Theme, Vector, Widget,
@@ -526,7 +527,7 @@ where
526527
content_bounds,
527528
);
528529

529-
let _ = notify_on_scroll(
530+
let _ = notify_scroll(
530531
state,
531532
&self.on_scroll,
532533
bounds,
@@ -564,7 +565,7 @@ where
564565

565566
state.y_scroller_grabbed_at = Some(scroller_grabbed_at);
566567

567-
let _ = notify_on_scroll(
568+
let _ = notify_scroll(
568569
state,
569570
&self.on_scroll,
570571
bounds,
@@ -597,7 +598,7 @@ where
597598
content_bounds,
598599
);
599600

600-
let _ = notify_on_scroll(
601+
let _ = notify_scroll(
601602
state,
602603
&self.on_scroll,
603604
bounds,
@@ -635,7 +636,7 @@ where
635636

636637
state.x_scroller_grabbed_at = Some(scroller_grabbed_at);
637638

638-
let _ = notify_on_scroll(
639+
let _ = notify_scroll(
639640
state,
640641
&self.on_scroll,
641642
bounds,
@@ -759,7 +760,7 @@ where
759760
content_bounds,
760761
);
761762

762-
if notify_on_scroll(
763+
if notify_scroll(
763764
state,
764765
&self.on_scroll,
765766
bounds,
@@ -807,7 +808,7 @@ where
807808
Some(cursor_position);
808809

809810
// TODO: bubble up touch movements if not consumed.
810-
let _ = notify_on_scroll(
811+
let _ = notify_scroll(
811812
state,
812813
&self.on_scroll,
813814
bounds,
@@ -821,6 +822,17 @@ where
821822

822823
event::Status::Captured
823824
}
825+
Event::Window(window::Event::RedrawRequested(_)) => {
826+
let _ = notify_viewport(
827+
state,
828+
&self.on_scroll,
829+
bounds,
830+
content_bounds,
831+
shell,
832+
);
833+
834+
event::Status::Ignored
835+
}
824836
_ => event::Status::Ignored,
825837
}
826838
}
@@ -1153,8 +1165,23 @@ pub fn scroll_by<T>(id: Id, offset: AbsoluteOffset) -> Task<T> {
11531165
)))
11541166
}
11551167

1156-
/// Returns [`true`] if the viewport actually changed.
1157-
fn notify_on_scroll<Message>(
1168+
fn notify_scroll<Message>(
1169+
state: &mut State,
1170+
on_scroll: &Option<Box<dyn Fn(Viewport) -> Message + '_>>,
1171+
bounds: Rectangle,
1172+
content_bounds: Rectangle,
1173+
shell: &mut Shell<'_, Message>,
1174+
) -> bool {
1175+
if notify_viewport(state, on_scroll, bounds, content_bounds, shell) {
1176+
state.last_scrolled = Some(Instant::now());
1177+
1178+
true
1179+
} else {
1180+
false
1181+
}
1182+
}
1183+
1184+
fn notify_viewport<Message>(
11581185
state: &mut State,
11591186
on_scroll: &Option<Box<dyn Fn(Viewport) -> Message + '_>>,
11601187
bounds: Rectangle,
@@ -1167,6 +1194,11 @@ fn notify_on_scroll<Message>(
11671194
return false;
11681195
}
11691196

1197+
let Some(on_scroll) = on_scroll else {
1198+
state.last_notified = None;
1199+
return false;
1200+
};
1201+
11701202
let viewport = Viewport {
11711203
offset_x: state.offset_x,
11721204
offset_y: state.offset_y,
@@ -1186,7 +1218,9 @@ fn notify_on_scroll<Message>(
11861218
(a - b).abs() <= f32::EPSILON || (a.is_nan() && b.is_nan())
11871219
};
11881220

1189-
if unchanged(last_relative_offset.x, current_relative_offset.x)
1221+
if last_notified.bounds == bounds
1222+
&& last_notified.content_bounds == content_bounds
1223+
&& unchanged(last_relative_offset.x, current_relative_offset.x)
11901224
&& unchanged(last_relative_offset.y, current_relative_offset.y)
11911225
&& unchanged(last_absolute_offset.x, current_absolute_offset.x)
11921226
&& unchanged(last_absolute_offset.y, current_absolute_offset.y)
@@ -1195,12 +1229,8 @@ fn notify_on_scroll<Message>(
11951229
}
11961230
}
11971231

1198-
if let Some(on_scroll) = on_scroll {
1199-
shell.publish(on_scroll(viewport));
1200-
}
1201-
1232+
shell.publish(on_scroll(viewport));
12021233
state.last_notified = Some(viewport);
1203-
state.last_scrolled = Some(Instant::now());
12041234

12051235
true
12061236
}

0 commit comments

Comments
 (0)