Don't consume unused scroll events (#2397)
* Initial Commit * Update scrollable.rs * Use `let _ = ` instead of `_ =` for consistency --------- Co-authored-by: Héctor Ramón Jiménez <hector@hecrj.dev>
This commit is contained in:
parent
67e181ce7b
commit
fdcec03197
1 changed files with 49 additions and 43 deletions
|
|
@ -435,15 +435,17 @@ where
|
||||||
|
|
||||||
state.scroll(delta, self.direction, bounds, content_bounds);
|
state.scroll(delta, self.direction, bounds, content_bounds);
|
||||||
|
|
||||||
notify_on_scroll(
|
event_status = if notify_on_scroll(
|
||||||
state,
|
state,
|
||||||
&self.on_scroll,
|
&self.on_scroll,
|
||||||
bounds,
|
bounds,
|
||||||
content_bounds,
|
content_bounds,
|
||||||
shell,
|
shell,
|
||||||
);
|
) {
|
||||||
|
event::Status::Captured
|
||||||
event_status = event::Status::Captured;
|
} else {
|
||||||
|
event::Status::Ignored
|
||||||
|
};
|
||||||
}
|
}
|
||||||
Event::Touch(event)
|
Event::Touch(event)
|
||||||
if state.scroll_area_touched_at.is_some()
|
if state.scroll_area_touched_at.is_some()
|
||||||
|
|
@ -481,7 +483,8 @@ where
|
||||||
state.scroll_area_touched_at =
|
state.scroll_area_touched_at =
|
||||||
Some(cursor_position);
|
Some(cursor_position);
|
||||||
|
|
||||||
notify_on_scroll(
|
// TODO: bubble up touch movements if not consumed.
|
||||||
|
let _ = notify_on_scroll(
|
||||||
state,
|
state,
|
||||||
&self.on_scroll,
|
&self.on_scroll,
|
||||||
bounds,
|
bounds,
|
||||||
|
|
@ -516,7 +519,7 @@ where
|
||||||
content_bounds,
|
content_bounds,
|
||||||
);
|
);
|
||||||
|
|
||||||
notify_on_scroll(
|
let _ = notify_on_scroll(
|
||||||
state,
|
state,
|
||||||
&self.on_scroll,
|
&self.on_scroll,
|
||||||
bounds,
|
bounds,
|
||||||
|
|
@ -554,7 +557,7 @@ where
|
||||||
|
|
||||||
state.y_scroller_grabbed_at = Some(scroller_grabbed_at);
|
state.y_scroller_grabbed_at = Some(scroller_grabbed_at);
|
||||||
|
|
||||||
notify_on_scroll(
|
let _ = notify_on_scroll(
|
||||||
state,
|
state,
|
||||||
&self.on_scroll,
|
&self.on_scroll,
|
||||||
bounds,
|
bounds,
|
||||||
|
|
@ -587,7 +590,7 @@ where
|
||||||
content_bounds,
|
content_bounds,
|
||||||
);
|
);
|
||||||
|
|
||||||
notify_on_scroll(
|
let _ = notify_on_scroll(
|
||||||
state,
|
state,
|
||||||
&self.on_scroll,
|
&self.on_scroll,
|
||||||
bounds,
|
bounds,
|
||||||
|
|
@ -625,7 +628,7 @@ where
|
||||||
|
|
||||||
state.x_scroller_grabbed_at = Some(scroller_grabbed_at);
|
state.x_scroller_grabbed_at = Some(scroller_grabbed_at);
|
||||||
|
|
||||||
notify_on_scroll(
|
let _ = notify_on_scroll(
|
||||||
state,
|
state,
|
||||||
&self.on_scroll,
|
&self.on_scroll,
|
||||||
bounds,
|
bounds,
|
||||||
|
|
@ -965,51 +968,54 @@ pub fn scroll_to<Message: 'static>(
|
||||||
Command::widget(operation::scrollable::scroll_to(id.0, offset))
|
Command::widget(operation::scrollable::scroll_to(id.0, offset))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns [`true`] if the viewport actually changed.
|
||||||
fn notify_on_scroll<Message>(
|
fn notify_on_scroll<Message>(
|
||||||
state: &mut State,
|
state: &mut State,
|
||||||
on_scroll: &Option<Box<dyn Fn(Viewport) -> Message + '_>>,
|
on_scroll: &Option<Box<dyn Fn(Viewport) -> Message + '_>>,
|
||||||
bounds: Rectangle,
|
bounds: Rectangle,
|
||||||
content_bounds: Rectangle,
|
content_bounds: Rectangle,
|
||||||
shell: &mut Shell<'_, Message>,
|
shell: &mut Shell<'_, Message>,
|
||||||
) {
|
) -> bool {
|
||||||
if let Some(on_scroll) = on_scroll {
|
if content_bounds.width <= bounds.width
|
||||||
if content_bounds.width <= bounds.width
|
&& content_bounds.height <= bounds.height
|
||||||
&& content_bounds.height <= bounds.height
|
{
|
||||||
{
|
return false;
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
let viewport = Viewport {
|
let viewport = Viewport {
|
||||||
offset_x: state.offset_x,
|
offset_x: state.offset_x,
|
||||||
offset_y: state.offset_y,
|
offset_y: state.offset_y,
|
||||||
bounds,
|
bounds,
|
||||||
content_bounds,
|
content_bounds,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Don't publish redundant viewports to shell
|
||||||
|
if let Some(last_notified) = state.last_notified {
|
||||||
|
let last_relative_offset = last_notified.relative_offset();
|
||||||
|
let current_relative_offset = viewport.relative_offset();
|
||||||
|
|
||||||
|
let last_absolute_offset = last_notified.absolute_offset();
|
||||||
|
let current_absolute_offset = viewport.absolute_offset();
|
||||||
|
|
||||||
|
let unchanged = |a: f32, b: f32| {
|
||||||
|
(a - b).abs() <= f32::EPSILON || (a.is_nan() && b.is_nan())
|
||||||
};
|
};
|
||||||
|
|
||||||
// Don't publish redundant viewports to shell
|
if unchanged(last_relative_offset.x, current_relative_offset.x)
|
||||||
if let Some(last_notified) = state.last_notified {
|
&& unchanged(last_relative_offset.y, current_relative_offset.y)
|
||||||
let last_relative_offset = last_notified.relative_offset();
|
&& unchanged(last_absolute_offset.x, current_absolute_offset.x)
|
||||||
let current_relative_offset = viewport.relative_offset();
|
&& unchanged(last_absolute_offset.y, current_absolute_offset.y)
|
||||||
|
{
|
||||||
let last_absolute_offset = last_notified.absolute_offset();
|
return false;
|
||||||
let current_absolute_offset = viewport.absolute_offset();
|
|
||||||
|
|
||||||
let unchanged = |a: f32, b: f32| {
|
|
||||||
(a - b).abs() <= f32::EPSILON || (a.is_nan() && b.is_nan())
|
|
||||||
};
|
|
||||||
|
|
||||||
if unchanged(last_relative_offset.x, current_relative_offset.x)
|
|
||||||
&& unchanged(last_relative_offset.y, current_relative_offset.y)
|
|
||||||
&& unchanged(last_absolute_offset.x, current_absolute_offset.x)
|
|
||||||
&& unchanged(last_absolute_offset.y, current_absolute_offset.y)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
shell.publish(on_scroll(viewport));
|
|
||||||
state.last_notified = Some(viewport);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(on_scroll) = on_scroll {
|
||||||
|
shell.publish(on_scroll(viewport));
|
||||||
|
}
|
||||||
|
state.last_notified = Some(viewport);
|
||||||
|
|
||||||
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue