Add auto_scroll method to scrollable widget

This commit is contained in:
Héctor Ramón Jiménez 2025-11-28 06:08:20 +01:00
parent 71e57fe889
commit 519e7ae414
No known key found for this signature in database
GPG key ID: 7CC46565708259A7
4 changed files with 29 additions and 9 deletions

View file

@ -210,7 +210,8 @@ impl ScrollableDemo {
.width(Fill) .width(Fill)
.height(Fill) .height(Fill)
.id(SCROLLABLE) .id(SCROLLABLE)
.on_scroll(Message::Scrolled), .on_scroll(Message::Scrolled)
.auto_scroll(true),
Direction::Horizontal => scrollable( Direction::Horizontal => scrollable(
row![ row![
scroll_to_end_button(), scroll_to_end_button(),
@ -236,7 +237,8 @@ impl ScrollableDemo {
.width(Fill) .width(Fill)
.height(Fill) .height(Fill)
.id(SCROLLABLE) .id(SCROLLABLE)
.on_scroll(Message::Scrolled), .on_scroll(Message::Scrolled)
.auto_scroll(true),
Direction::Multi => scrollable( Direction::Multi => scrollable(
//horizontal content //horizontal content
row![ row![
@ -283,7 +285,8 @@ impl ScrollableDemo {
.width(Fill) .width(Fill)
.height(Fill) .height(Fill)
.id(SCROLLABLE) .id(SCROLLABLE)
.on_scroll(Message::Scrolled), .on_scroll(Message::Scrolled)
.auto_scroll(true),
}); });
let progress_bars: Element<Message> = match self.scrollable_direction { let progress_bars: Element<Message> = match self.scrollable_direction {

View file

@ -131,7 +131,8 @@ impl Styling {
"You did it!" "You did it!"
]) ])
.width(Fill) .width(Fill)
.height(Fill); .height(Fill)
.auto_scroll(true);
let check = checkbox(self.checkbox_value) let check = checkbox(self.checkbox_value)
.label("Check me!") .label("Check me!")

View file

@ -174,7 +174,8 @@ impl Tour {
} else { } else {
content content
})) }))
.spacing(10); .spacing(10)
.auto_scroll(true);
center_y(scrollable).padding(10).into() center_y(scrollable).padding(10).into()
} }
@ -626,7 +627,7 @@ pub enum Layout {
impl Default for Tour { impl Default for Tour {
fn default() -> Self { fn default() -> Self {
Self { Self {
screen: Screen::Welcome, screen: Screen::Scrollable,
slider: 50, slider: 50,
layout: Layout::Row, layout: Layout::Row,
spacing: 20, spacing: 20,

View file

@ -75,6 +75,7 @@ pub struct Scrollable<
width: Length, width: Length,
height: Length, height: Length,
direction: Direction, direction: Direction,
auto_scroll: bool,
content: Element<'a, Message, Theme, Renderer>, content: Element<'a, Message, Theme, Renderer>,
on_scroll: Option<Box<dyn Fn(Viewport) -> Message + 'a>>, on_scroll: Option<Box<dyn Fn(Viewport) -> Message + 'a>>,
class: Theme::Class<'a>, class: Theme::Class<'a>,
@ -103,6 +104,7 @@ where
width: Length::Shrink, width: Length::Shrink,
height: Length::Shrink, height: Length::Shrink,
direction: direction.into(), direction: direction.into(),
auto_scroll: false,
content: content.into(), content: content.into(),
on_scroll: None, on_scroll: None,
class: Theme::default(), class: Theme::default(),
@ -225,6 +227,15 @@ where
self self
} }
/// Sets whether the user should be allowed to auto-scroll the [`Scrollable`]
/// with the middle mouse button.
///
/// By default, it is disabled.
pub fn auto_scroll(mut self, auto_scroll: bool) -> Self {
self.auto_scroll = auto_scroll;
self
}
/// Sets the style of this [`Scrollable`]. /// Sets the style of this [`Scrollable`].
#[must_use] #[must_use]
pub fn style(mut self, style: impl Fn(&Theme, Status) -> Style + 'a) -> Self pub fn style(mut self, style: impl Fn(&Theme, Status) -> Style + 'a) -> Self
@ -812,8 +823,10 @@ where
if matches!(state.interaction, Interaction::AutoScrolling { .. }) if matches!(state.interaction, Interaction::AutoScrolling { .. })
&& matches!( && matches!(
event, event,
Event::Mouse(mouse::Event::ButtonPressed(_)) Event::Mouse(
| Event::Touch(_) mouse::Event::ButtonPressed(_)
| mouse::Event::WheelScrolled { .. }
) | Event::Touch(_)
| Event::Keyboard(_) | Event::Keyboard(_)
) )
{ {
@ -881,7 +894,9 @@ where
} }
Event::Mouse(mouse::Event::ButtonPressed( Event::Mouse(mouse::Event::ButtonPressed(
mouse::Button::Middle, mouse::Button::Middle,
)) if matches!(state.interaction, Interaction::None) => { )) if self.auto_scroll
&& matches!(state.interaction, Interaction::None) =>
{
let Some(origin) = cursor_over_scrollable else { let Some(origin) = cursor_over_scrollable else {
return; return;
}; };