summaryrefslogtreecommitdiffstats
path: root/native
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2019-10-29 05:09:54 +0100
committerLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2019-10-29 05:09:54 +0100
commit29588f604af66fb4911f791c0c402fccd30ba64b (patch)
tree09cfc0049cdb9f80616bbb925a1b24672f5d2d06 /native
parent9dabbf78857c3a60583227d3aa2fa6e030f085d0 (diff)
downloadiced-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.rs65
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>,