diff options
author | 2019-10-29 05:09:54 +0100 | |
---|---|---|
committer | 2019-10-29 05:09:54 +0100 | |
commit | 29588f604af66fb4911f791c0c402fccd30ba64b (patch) | |
tree | 09cfc0049cdb9f80616bbb925a1b24672f5d2d06 /native | |
parent | 9dabbf78857c3a60583227d3aa2fa6e030f085d0 (diff) | |
download | iced-29588f604af66fb4911f791c0c402fccd30ba64b.tar.gz iced-29588f604af66fb4911f791c0c402fccd30ba64b.tar.bz2 iced-29588f604af66fb4911f791c0c402fccd30ba64b.zip |
Implement scrollbar interactions! :tada:
Diffstat (limited to 'native')
-rw-r--r-- | native/src/widget/scrollable.rs | 65 |
1 files changed, 60 insertions, 5 deletions
diff --git a/native/src/widget/scrollable.rs b/native/src/widget/scrollable.rs index e52f3c3f..76d12124 100644 --- a/native/src/widget/scrollable.rs +++ b/native/src/widget/scrollable.rs @@ -1,6 +1,7 @@ use crate::{ - column, input::mouse, Element, Event, Hasher, Layout, Node, Point, - Rectangle, Style, Widget, + column, + input::{mouse, ButtonState}, + Element, Event, Hasher, Layout, Node, Point, Rectangle, Style, Widget, }; pub use iced_core::scrollable::State; @@ -54,18 +55,65 @@ where let content = layout.children().next().unwrap(); let content_bounds = content.bounds(); + let is_mouse_over_scrollbar = renderer.is_mouse_over_scrollbar( + bounds, + content_bounds, + cursor_position, + ); + + // TODO: Event capture. Nested scrollables should capture scroll events. if is_mouse_over { match event { Event::Mouse(mouse::Event::WheelScrolled { delta_y, .. }) => { - self.state.scroll(delta_y, bounds, content_bounds); + // TODO: Configurable speed (?) + self.state.scroll(delta_y * 15.0, bounds, content_bounds); + } + _ => {} + } + } + + if self.state.is_scrollbar_grabbed() || is_mouse_over_scrollbar { + match event { + Event::Mouse(mouse::Event::Input { + button: mouse::Button::Left, + state, + }) => match state { + ButtonState::Pressed => { + self.state.scroll_to( + cursor_position.y / (bounds.y + bounds.height), + bounds, + content_bounds, + ); + + self.state.scrollbar_grabbed_at = Some(cursor_position); + } + ButtonState::Released => { + self.state.scrollbar_grabbed_at = None; + } + }, + Event::Mouse(mouse::Event::CursorMoved { .. }) => { + if let Some(scrollbar_grabbed_at) = + self.state.scrollbar_grabbed_at + { + self.state.scroll( + scrollbar_grabbed_at.y - cursor_position.y, + bounds, + content_bounds, + ); + + self.state.scrollbar_grabbed_at = Some(cursor_position); + } } _ => {} } } - let cursor_position = if is_mouse_over { + let cursor_position = if is_mouse_over + && !(is_mouse_over_scrollbar + || self.state.scrollbar_grabbed_at.is_some()) + { Point::new( cursor_position.x, cursor_position.y @@ -73,7 +121,7 @@ where ) } else { // TODO: Make `cursor_position` an `Option<Point>` so we can encode - // cursor unavailability. + // cursor availability. // This will probably happen naturally once we add multi-window // support. Point::new(cursor_position.x, -1.0) @@ -118,6 +166,13 @@ where } pub trait Renderer: crate::Renderer + Sized { + fn is_mouse_over_scrollbar( + &self, + bounds: Rectangle, + content_bounds: Rectangle, + cursor_position: Point, + ) -> bool; + fn draw<Message>( &mut self, scrollable: &Scrollable<'_, Message, Self>, |