From 3f968b8c876b7c2351232856887fb9c3e3db3130 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 12 Nov 2020 00:09:52 +0100 Subject: Make `Widget::on_event` return an `event::Status` --- native/src/widget/scrollable.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'native/src/widget/scrollable.rs') diff --git a/native/src/widget/scrollable.rs b/native/src/widget/scrollable.rs index 60ec2d7d..19c3e582 100644 --- a/native/src/widget/scrollable.rs +++ b/native/src/widget/scrollable.rs @@ -1,7 +1,12 @@ //! Navigate an endless amount of content with a scrollbar. +use crate::column; +use crate::event::{self, Event}; +use crate::layout; +use crate::mouse; +use crate::overlay; use crate::{ - column, layout, mouse, overlay, Align, Clipboard, Column, Element, Event, - Hasher, Layout, Length, Point, Rectangle, Size, Vector, Widget, + Align, Clipboard, Column, Element, Hasher, Layout, Length, Point, + Rectangle, Size, Vector, Widget, }; use std::{f32, hash::Hash, u32}; @@ -184,7 +189,7 @@ where messages: &mut Vec, renderer: &Renderer, clipboard: Option<&dyn Clipboard>, - ) { + ) -> event::Status { let bounds = layout.bounds(); let is_mouse_over = bounds.contains(cursor_position); -- cgit From fd275a2fee4c7bbea0dbefc0dc68b340cc003ad4 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 12 Nov 2020 00:53:39 +0100 Subject: Implement event capturing for `Scrollable` --- native/src/widget/scrollable.rs | 89 ++++++++++++++++++++++++----------------- 1 file changed, 52 insertions(+), 37 deletions(-) (limited to 'native/src/widget/scrollable.rs') diff --git a/native/src/widget/scrollable.rs b/native/src/widget/scrollable.rs index 19c3e582..92671ddd 100644 --- a/native/src/widget/scrollable.rs +++ b/native/src/widget/scrollable.rs @@ -196,7 +196,49 @@ where let content = layout.children().next().unwrap(); let content_bounds = content.bounds(); - // TODO: Event capture. Nested scrollables should capture scroll events. + let offset = self.state.offset(bounds, content_bounds); + let scrollbar = renderer.scrollbar( + bounds, + content_bounds, + offset, + self.scrollbar_width, + self.scrollbar_margin, + self.scroller_width, + ); + let is_mouse_over_scrollbar = scrollbar + .as_ref() + .map(|scrollbar| scrollbar.is_mouse_over(cursor_position)) + .unwrap_or(false); + + let event_status = { + let cursor_position = if is_mouse_over && !is_mouse_over_scrollbar { + Point::new( + cursor_position.x, + cursor_position.y + + self.state.offset(bounds, content_bounds) as f32, + ) + } else { + // TODO: Make `cursor_position` an `Option` so we can encode + // cursor availability. + // This will probably happen naturally once we add multi-window + // support. + Point::new(cursor_position.x, -1.0) + }; + + self.content.on_event( + event.clone(), + content, + cursor_position, + messages, + renderer, + clipboard, + ) + }; + + if let event::Status::Captured = event_status { + return event::Status::Captured; + } + if is_mouse_over { match event { Event::Mouse(mouse::Event::WheelScrolled { delta }) => { @@ -209,31 +251,21 @@ where self.state.scroll(y, bounds, content_bounds); } } + + return event::Status::Captured; } _ => {} } } - let offset = self.state.offset(bounds, content_bounds); - let scrollbar = renderer.scrollbar( - bounds, - content_bounds, - offset, - self.scrollbar_width, - self.scrollbar_margin, - self.scroller_width, - ); - let is_mouse_over_scrollbar = scrollbar - .as_ref() - .map(|scrollbar| scrollbar.is_mouse_over(cursor_position)) - .unwrap_or(false); - if self.state.is_scroller_grabbed() { match event { Event::Mouse(mouse::Event::ButtonReleased( mouse::Button::Left, )) => { self.state.scroller_grabbed_at = None; + + return event::Status::Captured; } Event::Mouse(mouse::Event::CursorMoved { .. }) => { if let (Some(scrollbar), Some(scroller_grabbed_at)) = @@ -247,6 +279,8 @@ where bounds, content_bounds, ); + + return event::Status::Captured; } } _ => {} @@ -271,6 +305,8 @@ where self.state.scroller_grabbed_at = Some(scroller_grabbed_at); + + return event::Status::Captured; } } } @@ -278,28 +314,7 @@ where } } - let cursor_position = if is_mouse_over && !is_mouse_over_scrollbar { - Point::new( - cursor_position.x, - cursor_position.y - + self.state.offset(bounds, content_bounds) as f32, - ) - } else { - // TODO: Make `cursor_position` an `Option` so we can encode - // cursor availability. - // This will probably happen naturally once we add multi-window - // support. - Point::new(cursor_position.x, -1.0) - }; - - self.content.on_event( - event, - content, - cursor_position, - messages, - renderer, - clipboard, - ) + event::Status::Ignored } fn draw( -- cgit