diff --git a/examples/scrollable/src/main.rs b/examples/scrollable/src/main.rs index 17b1fad2..0b183024 100644 --- a/examples/scrollable/src/main.rs +++ b/examples/scrollable/src/main.rs @@ -210,7 +210,8 @@ impl ScrollableDemo { .width(Fill) .height(Fill) .id(SCROLLABLE) - .on_scroll(Message::Scrolled), + .on_scroll(Message::Scrolled) + .auto_scroll(true), Direction::Horizontal => scrollable( row![ scroll_to_end_button(), @@ -236,7 +237,8 @@ impl ScrollableDemo { .width(Fill) .height(Fill) .id(SCROLLABLE) - .on_scroll(Message::Scrolled), + .on_scroll(Message::Scrolled) + .auto_scroll(true), Direction::Multi => scrollable( //horizontal content row![ @@ -283,7 +285,8 @@ impl ScrollableDemo { .width(Fill) .height(Fill) .id(SCROLLABLE) - .on_scroll(Message::Scrolled), + .on_scroll(Message::Scrolled) + .auto_scroll(true), }); let progress_bars: Element = match self.scrollable_direction { diff --git a/examples/styling/src/main.rs b/examples/styling/src/main.rs index 6ce72ad7..762657f9 100644 --- a/examples/styling/src/main.rs +++ b/examples/styling/src/main.rs @@ -131,7 +131,8 @@ impl Styling { "You did it!" ]) .width(Fill) - .height(Fill); + .height(Fill) + .auto_scroll(true); let check = checkbox(self.checkbox_value) .label("Check me!") diff --git a/examples/tour/src/main.rs b/examples/tour/src/main.rs index 9c229ac3..e611ece0 100644 --- a/examples/tour/src/main.rs +++ b/examples/tour/src/main.rs @@ -174,7 +174,8 @@ impl Tour { } else { content })) - .spacing(10); + .spacing(10) + .auto_scroll(true); center_y(scrollable).padding(10).into() } @@ -626,7 +627,7 @@ pub enum Layout { impl Default for Tour { fn default() -> Self { Self { - screen: Screen::Welcome, + screen: Screen::Scrollable, slider: 50, layout: Layout::Row, spacing: 20, diff --git a/widget/src/scrollable.rs b/widget/src/scrollable.rs index 913e5f3b..62871600 100644 --- a/widget/src/scrollable.rs +++ b/widget/src/scrollable.rs @@ -75,6 +75,7 @@ pub struct Scrollable< width: Length, height: Length, direction: Direction, + auto_scroll: bool, content: Element<'a, Message, Theme, Renderer>, on_scroll: Option Message + 'a>>, class: Theme::Class<'a>, @@ -103,6 +104,7 @@ where width: Length::Shrink, height: Length::Shrink, direction: direction.into(), + auto_scroll: false, content: content.into(), on_scroll: None, class: Theme::default(), @@ -225,6 +227,15 @@ where 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`]. #[must_use] pub fn style(mut self, style: impl Fn(&Theme, Status) -> Style + 'a) -> Self @@ -812,8 +823,10 @@ where if matches!(state.interaction, Interaction::AutoScrolling { .. }) && matches!( event, - Event::Mouse(mouse::Event::ButtonPressed(_)) - | Event::Touch(_) + Event::Mouse( + mouse::Event::ButtonPressed(_) + | mouse::Event::WheelScrolled { .. } + ) | Event::Touch(_) | Event::Keyboard(_) ) { @@ -881,7 +894,9 @@ where } Event::Mouse(mouse::Event::ButtonPressed( 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 { return; };