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/button.rs | 10 +++++++--- native/src/widget/checkbox.rs | 14 ++++++++++---- native/src/widget/column.rs | 12 +++++++----- native/src/widget/container.rs | 8 +++++--- native/src/widget/pane_grid.rs | 15 ++++++++++++--- native/src/widget/pane_grid/content.rs | 2 +- native/src/widget/pane_grid/title_bar.rs | 2 +- native/src/widget/pick_list.rs | 16 +++++++++++----- native/src/widget/radio.rs | 14 ++++++++++---- native/src/widget/row.rs | 12 +++++++----- native/src/widget/scrollable.rs | 11 ++++++++--- native/src/widget/slider.rs | 10 +++++++--- native/src/widget/text_input.rs | 14 +++++++++----- 13 files changed, 95 insertions(+), 45 deletions(-) (limited to 'native/src/widget') diff --git a/native/src/widget/button.rs b/native/src/widget/button.rs index 995ba7bc..4a2d82e9 100644 --- a/native/src/widget/button.rs +++ b/native/src/widget/button.rs @@ -4,9 +4,11 @@ //! //! [`Button`]: struct.Button.html //! [`State`]: struct.State.html +use crate::event::{self, Event}; +use crate::layout; +use crate::mouse; use crate::{ - layout, mouse, Clipboard, Element, Event, Hasher, Layout, Length, Point, - Rectangle, Widget, + Clipboard, Element, Hasher, Layout, Length, Point, Rectangle, Widget, }; use std::hash::Hash; @@ -184,7 +186,7 @@ where messages: &mut Vec, _renderer: &Renderer, _clipboard: Option<&dyn Clipboard>, - ) { + ) -> event::Status { match event { Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) => { if self.on_press.is_some() { @@ -209,6 +211,8 @@ where } _ => {} } + + event::Status::Ignored } fn draw( diff --git a/native/src/widget/checkbox.rs b/native/src/widget/checkbox.rs index e389427e..16a6a648 100644 --- a/native/src/widget/checkbox.rs +++ b/native/src/widget/checkbox.rs @@ -1,10 +1,14 @@ //! Show toggle controls using checkboxes. use std::hash::Hash; +use crate::event::{self, Event}; +use crate::layout; +use crate::mouse; +use crate::row; +use crate::text; use crate::{ - layout, mouse, row, text, Align, Clipboard, Element, Event, Hasher, - HorizontalAlignment, Layout, Length, Point, Rectangle, Row, Text, - VerticalAlignment, Widget, + Align, Clipboard, Element, Hasher, HorizontalAlignment, Layout, Length, + Point, Rectangle, Row, Text, VerticalAlignment, Widget, }; /// A box that can be checked. @@ -161,7 +165,7 @@ where messages: &mut Vec, _renderer: &Renderer, _clipboard: Option<&dyn Clipboard>, - ) { + ) -> event::Status { match event { Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) => { let mouse_over = layout.bounds().contains(cursor_position); @@ -172,6 +176,8 @@ where } _ => {} } + + event::Status::Ignored } fn draw( diff --git a/native/src/widget/column.rs b/native/src/widget/column.rs index e874ad42..425bd33f 100644 --- a/native/src/widget/column.rs +++ b/native/src/widget/column.rs @@ -1,11 +1,11 @@ //! Distribute content vertically. use std::hash::Hash; +use crate::event::{self, Event}; use crate::layout; use crate::overlay; use crate::{ - Align, Clipboard, Element, Event, Hasher, Layout, Length, Point, Rectangle, - Widget, + Align, Clipboard, Element, Hasher, Layout, Length, Point, Rectangle, Widget, }; use std::u32; @@ -162,19 +162,21 @@ where messages: &mut Vec, renderer: &Renderer, clipboard: Option<&dyn Clipboard>, - ) { + ) -> event::Status { self.children.iter_mut().zip(layout.children()).for_each( |(child, layout)| { - child.widget.on_event( + let _ = child.widget.on_event( event.clone(), layout, cursor_position, messages, renderer, clipboard, - ) + ); }, ); + + event::Status::Ignored } fn draw( diff --git a/native/src/widget/container.rs b/native/src/widget/container.rs index 5b04d699..419060db 100644 --- a/native/src/widget/container.rs +++ b/native/src/widget/container.rs @@ -1,9 +1,11 @@ //! Decorate content and apply alignment. use std::hash::Hash; +use crate::event::{self, Event}; +use crate::layout; +use crate::overlay; use crate::{ - layout, overlay, Align, Clipboard, Element, Event, Hasher, Layout, Length, - Point, Rectangle, Widget, + Align, Clipboard, Element, Hasher, Layout, Length, Point, Rectangle, Widget, }; use std::u32; @@ -174,7 +176,7 @@ where messages: &mut Vec, renderer: &Renderer, clipboard: Option<&dyn Clipboard>, - ) { + ) -> event::Status { self.content.widget.on_event( event, layout.children().next().unwrap(), diff --git a/native/src/widget/pane_grid.rs b/native/src/widget/pane_grid.rs index 9d36bae6..aeeee299 100644 --- a/native/src/widget/pane_grid.rs +++ b/native/src/widget/pane_grid.rs @@ -28,9 +28,16 @@ pub use split::Split; pub use state::{Focus, State}; pub use title_bar::TitleBar; +use crate::container; +use crate::event::{self, Event}; +use crate::layout; +use crate::mouse; +use crate::overlay; +use crate::row; +use crate::text; use crate::{ - container, layout, mouse, overlay, row, text, Clipboard, Element, Event, - Hasher, Layout, Length, Point, Rectangle, Size, Vector, Widget, + Clipboard, Element, Hasher, Layout, Length, Point, Rectangle, Size, Vector, + Widget, }; /// A collection of panes distributed using either vertical or horizontal splits @@ -386,7 +393,7 @@ where messages: &mut Vec, renderer: &Renderer, clipboard: Option<&dyn Clipboard>, - ) { + ) -> event::Status { match event { Event::Mouse(mouse_event) => match mouse_event { mouse::Event::ButtonPressed(mouse::Button::Left) => { @@ -484,6 +491,8 @@ where ); } } + + event::Status::Ignored } fn draw( diff --git a/native/src/widget/pane_grid/content.rs b/native/src/widget/pane_grid/content.rs index 5bfbb9ed..dffc3a73 100644 --- a/native/src/widget/pane_grid/content.rs +++ b/native/src/widget/pane_grid/content.rs @@ -172,7 +172,7 @@ where layout }; - self.body.on_event( + let _ = self.body.on_event( event, body_layout, cursor_position, diff --git a/native/src/widget/pane_grid/title_bar.rs b/native/src/widget/pane_grid/title_bar.rs index 9dfb9ae4..eed7590d 100644 --- a/native/src/widget/pane_grid/title_bar.rs +++ b/native/src/widget/pane_grid/title_bar.rs @@ -254,7 +254,7 @@ where let _ = children.next(); let controls_layout = children.next().unwrap(); - controls.on_event( + let _ = controls.on_event( event, controls_layout, cursor_position, diff --git a/native/src/widget/pick_list.rs b/native/src/widget/pick_list.rs index e086e367..ee113e5e 100644 --- a/native/src/widget/pick_list.rs +++ b/native/src/widget/pick_list.rs @@ -1,9 +1,13 @@ //! Display a dropdown list of selectable values. +use crate::event::{self, Event}; +use crate::layout; +use crate::mouse; +use crate::overlay; +use crate::overlay::menu::{self, Menu}; +use crate::scrollable; +use crate::text; use crate::{ - layout, mouse, overlay, - overlay::menu::{self, Menu}, - scrollable, text, Clipboard, Element, Event, Hasher, Layout, Length, Point, - Rectangle, Size, Widget, + Clipboard, Element, Hasher, Layout, Length, Point, Rectangle, Size, Widget, }; use std::borrow::Cow; @@ -223,7 +227,7 @@ where messages: &mut Vec, _renderer: &Renderer, _clipboard: Option<&dyn Clipboard>, - ) { + ) -> event::Status { match event { Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) => { if *self.is_open { @@ -248,6 +252,8 @@ where } _ => {} } + + event::Status::Ignored } fn draw( diff --git a/native/src/widget/radio.rs b/native/src/widget/radio.rs index 06d3f846..6e74b404 100644 --- a/native/src/widget/radio.rs +++ b/native/src/widget/radio.rs @@ -1,8 +1,12 @@ //! Create choices using radio buttons. +use crate::event::{self, Event}; +use crate::layout; +use crate::mouse; +use crate::row; +use crate::text; use crate::{ - layout, mouse, row, text, Align, Clipboard, Element, Event, Hasher, - HorizontalAlignment, Layout, Length, Point, Rectangle, Row, Text, - VerticalAlignment, Widget, + Align, Clipboard, Element, Hasher, HorizontalAlignment, Layout, Length, + Point, Rectangle, Row, Text, VerticalAlignment, Widget, }; use std::hash::Hash; @@ -166,7 +170,7 @@ where messages: &mut Vec, _renderer: &Renderer, _clipboard: Option<&dyn Clipboard>, - ) { + ) -> event::Status { match event { Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) => { if layout.bounds().contains(cursor_position) { @@ -175,6 +179,8 @@ where } _ => {} } + + event::Status::Ignored } fn draw( diff --git a/native/src/widget/row.rs b/native/src/widget/row.rs index bc8a3df1..7d7595f7 100644 --- a/native/src/widget/row.rs +++ b/native/src/widget/row.rs @@ -1,9 +1,9 @@ //! Distribute content horizontally. +use crate::event::{self, Event}; use crate::layout; use crate::overlay; use crate::{ - Align, Clipboard, Element, Event, Hasher, Layout, Length, Point, Rectangle, - Widget, + Align, Clipboard, Element, Hasher, Layout, Length, Point, Rectangle, Widget, }; use std::hash::Hash; @@ -162,19 +162,21 @@ where messages: &mut Vec, renderer: &Renderer, clipboard: Option<&dyn Clipboard>, - ) { + ) -> event::Status { self.children.iter_mut().zip(layout.children()).for_each( |(child, layout)| { - child.widget.on_event( + let _ = child.widget.on_event( event.clone(), layout, cursor_position, messages, renderer, clipboard, - ) + ); }, ); + + event::Status::Ignored } fn draw( 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); diff --git a/native/src/widget/slider.rs b/native/src/widget/slider.rs index d6e366aa..51edd56d 100644 --- a/native/src/widget/slider.rs +++ b/native/src/widget/slider.rs @@ -4,9 +4,11 @@ //! //! [`Slider`]: struct.Slider.html //! [`State`]: struct.State.html +use crate::event::{self, Event}; +use crate::layout; +use crate::mouse; use crate::{ - layout, mouse, Clipboard, Element, Event, Hasher, Layout, Length, Point, - Rectangle, Size, Widget, + Clipboard, Element, Hasher, Layout, Length, Point, Rectangle, Size, Widget, }; use std::{hash::Hash, ops::RangeInclusive}; @@ -202,7 +204,7 @@ where messages: &mut Vec, _renderer: &Renderer, _clipboard: Option<&dyn Clipboard>, - ) { + ) -> event::Status { let mut change = || { let bounds = layout.bounds(); if cursor_position.x <= bounds.x { @@ -251,6 +253,8 @@ where }, _ => {} } + + event::Status::Ignored } fn draw( diff --git a/native/src/widget/text_input.rs b/native/src/widget/text_input.rs index 470e92ed..436f01ab 100644 --- a/native/src/widget/text_input.rs +++ b/native/src/widget/text_input.rs @@ -14,11 +14,13 @@ pub use value::Value; use editor::Editor; +use crate::event::{self, Event}; +use crate::keyboard; +use crate::layout; +use crate::mouse::{self, click}; +use crate::text; use crate::{ - keyboard, layout, - mouse::{self, click}, - text, Clipboard, Element, Event, Hasher, Layout, Length, Point, Rectangle, - Size, Widget, + Clipboard, Element, Hasher, Layout, Length, Point, Rectangle, Size, Widget, }; use std::u32; @@ -218,7 +220,7 @@ where messages: &mut Vec, renderer: &Renderer, clipboard: Option<&dyn Clipboard>, - ) { + ) -> event::Status { match event { Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) => { let is_clicked = layout.bounds().contains(cursor_position); @@ -489,6 +491,8 @@ where }, _ => {} } + + event::Status::Ignored } fn draw( -- cgit From a44cd072120cc059e8dc4633b33d902817f89834 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 12 Nov 2020 00:19:12 +0100 Subject: Implement event capturing for `Button` --- native/src/widget/button.rs | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'native/src/widget') diff --git a/native/src/widget/button.rs b/native/src/widget/button.rs index 4a2d82e9..466f6ac5 100644 --- a/native/src/widget/button.rs +++ b/native/src/widget/button.rs @@ -192,20 +192,25 @@ where if self.on_press.is_some() { let bounds = layout.bounds(); - self.state.is_pressed = bounds.contains(cursor_position); + if bounds.contains(cursor_position) { + self.state.is_pressed = true; + + return event::Status::Captured; + } } } Event::Mouse(mouse::Event::ButtonReleased(mouse::Button::Left)) => { if let Some(on_press) = self.on_press.clone() { let bounds = layout.bounds(); - let is_clicked = self.state.is_pressed - && bounds.contains(cursor_position); + if self.state.is_pressed { + self.state.is_pressed = false; - self.state.is_pressed = false; + if bounds.contains(cursor_position) { + messages.push(on_press); + } - if is_clicked { - messages.push(on_press); + return event::Status::Captured; } } } -- cgit From 04468a7147c38cd363cb545de0d9a9881ce071dd Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 12 Nov 2020 00:20:09 +0100 Subject: Implement event capturing for `Checkbox` --- native/src/widget/checkbox.rs | 2 ++ 1 file changed, 2 insertions(+) (limited to 'native/src/widget') diff --git a/native/src/widget/checkbox.rs b/native/src/widget/checkbox.rs index 16a6a648..42e52aef 100644 --- a/native/src/widget/checkbox.rs +++ b/native/src/widget/checkbox.rs @@ -172,6 +172,8 @@ where if mouse_over { messages.push((self.on_toggle)(!self.is_checked)); + + return event::Status::Captured; } } _ => {} -- cgit From 3bcee62beb36d9e186d8716c7660433fac071ed6 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 12 Nov 2020 00:30:06 +0100 Subject: Implement event capturing for `Column` --- native/src/widget/column.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'native/src/widget') diff --git a/native/src/widget/column.rs b/native/src/widget/column.rs index 425bd33f..42a9e734 100644 --- a/native/src/widget/column.rs +++ b/native/src/widget/column.rs @@ -163,20 +163,20 @@ where renderer: &Renderer, clipboard: Option<&dyn Clipboard>, ) -> event::Status { - self.children.iter_mut().zip(layout.children()).for_each( - |(child, layout)| { - let _ = child.widget.on_event( + self.children + .iter_mut() + .zip(layout.children()) + .map(|(child, layout)| { + child.widget.on_event( event.clone(), layout, cursor_position, messages, renderer, clipboard, - ); - }, - ); - - event::Status::Ignored + ) + }) + .fold(event::Status::Ignored, event::Status::merge) } fn draw( -- cgit From 31c509b2063907ad4907f248f82724c6fd641032 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 12 Nov 2020 00:40:00 +0100 Subject: Implement event capturing for `PaneGrid` --- native/src/widget/pane_grid.rs | 49 ++++++++++++++++++++------------ native/src/widget/pane_grid/content.rs | 13 ++++++--- native/src/widget/pane_grid/title_bar.rs | 13 +++++---- 3 files changed, 47 insertions(+), 28 deletions(-) (limited to 'native/src/widget') diff --git a/native/src/widget/pane_grid.rs b/native/src/widget/pane_grid.rs index aeeee299..43e752cb 100644 --- a/native/src/widget/pane_grid.rs +++ b/native/src/widget/pane_grid.rs @@ -249,7 +249,7 @@ where layout: Layout<'_>, cursor_position: Point, messages: &mut Vec, - ) { + ) -> event::Status { if let Some((_, on_resize)) = &self.on_resize { if let Some((split, _)) = self.state.picked_split() { let bounds = layout.bounds(); @@ -276,9 +276,13 @@ where }; messages.push(on_resize(ResizeEvent { split, ratio })); + + return event::Status::Captured; } } } + + event::Status::Ignored } } @@ -394,12 +398,16 @@ where renderer: &Renderer, clipboard: Option<&dyn Clipboard>, ) -> event::Status { + let mut event_status = event::Status::Ignored; + match event { Event::Mouse(mouse_event) => match mouse_event { mouse::Event::ButtonPressed(mouse::Button::Left) => { let bounds = layout.bounds(); if bounds.contains(cursor_position) { + event_status = event::Status::Captured; + match self.on_resize { Some((leeway, _)) => { let relative_cursor = Point::new( @@ -463,12 +471,17 @@ where } self.state.idle(); + + event_status = event::Status::Captured; } else if self.state.picked_split().is_some() { self.state.idle(); + + event_status = event::Status::Captured; } } mouse::Event::CursorMoved { .. } => { - self.trigger_resize(layout, cursor_position, messages); + event_status = + self.trigger_resize(layout, cursor_position, messages); } _ => {} }, @@ -476,23 +489,23 @@ where } if self.state.picked_pane().is_none() { - { - self.elements.iter_mut().zip(layout.children()).for_each( - |((_, pane), layout)| { - pane.on_event( - event.clone(), - layout, - cursor_position, - messages, - renderer, - clipboard, - ) - }, - ); - } + self.elements + .iter_mut() + .zip(layout.children()) + .map(|((_, pane), layout)| { + pane.on_event( + event.clone(), + layout, + cursor_position, + messages, + renderer, + clipboard, + ) + }) + .fold(event_status, event::Status::merge) + } else { + event::Status::Captured } - - event::Status::Ignored } fn draw( diff --git a/native/src/widget/pane_grid/content.rs b/native/src/widget/pane_grid/content.rs index dffc3a73..2dac7060 100644 --- a/native/src/widget/pane_grid/content.rs +++ b/native/src/widget/pane_grid/content.rs @@ -1,8 +1,9 @@ use crate::container; +use crate::event::{self, Event}; use crate::layout; use crate::overlay; use crate::pane_grid::{self, TitleBar}; -use crate::{Clipboard, Element, Event, Hasher, Layout, Point, Size}; +use crate::{Clipboard, Element, Hasher, Layout, Point, Size}; /// The content of a [`Pane`]. /// @@ -154,11 +155,13 @@ where messages: &mut Vec, renderer: &Renderer, clipboard: Option<&dyn Clipboard>, - ) { + ) -> event::Status { + let mut event_status = event::Status::Ignored; + let body_layout = if let Some(title_bar) = &mut self.title_bar { let mut children = layout.children(); - title_bar.on_event( + event_status = title_bar.on_event( event.clone(), children.next().unwrap(), cursor_position, @@ -172,7 +175,7 @@ where layout }; - let _ = self.body.on_event( + let body_status = self.body.on_event( event, body_layout, cursor_position, @@ -180,6 +183,8 @@ where renderer, clipboard, ); + + event_status.merge(body_status) } pub(crate) fn hash_layout(&self, state: &mut Hasher) { diff --git a/native/src/widget/pane_grid/title_bar.rs b/native/src/widget/pane_grid/title_bar.rs index eed7590d..f8ff43eb 100644 --- a/native/src/widget/pane_grid/title_bar.rs +++ b/native/src/widget/pane_grid/title_bar.rs @@ -1,8 +1,7 @@ +use crate::event::{self, Event}; use crate::layout; use crate::pane_grid; -use crate::{ - Clipboard, Element, Event, Hasher, Layout, Point, Rectangle, Size, -}; +use crate::{Clipboard, Element, Hasher, Layout, Point, Rectangle, Size}; /// The title bar of a [`Pane`]. /// @@ -245,7 +244,7 @@ where messages: &mut Vec, renderer: &Renderer, clipboard: Option<&dyn Clipboard>, - ) { + ) -> event::Status { if let Some(controls) = &mut self.controls { let mut children = layout.children(); let padded = children.next().unwrap(); @@ -254,14 +253,16 @@ where let _ = children.next(); let controls_layout = children.next().unwrap(); - let _ = controls.on_event( + controls.on_event( event, controls_layout, cursor_position, messages, renderer, clipboard, - ); + ) + } else { + event::Status::Ignored } } } -- cgit From 7ff95f3a884fc5f7ca7417408bd6d4ed47c4e9cc Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 12 Nov 2020 00:47:21 +0100 Subject: Implement event capturing for `PickList` --- native/src/widget/pick_list.rs | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'native/src/widget') diff --git a/native/src/widget/pick_list.rs b/native/src/widget/pick_list.rs index ee113e5e..113197f7 100644 --- a/native/src/widget/pick_list.rs +++ b/native/src/widget/pick_list.rs @@ -230,10 +230,12 @@ where ) -> event::Status { match event { Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) => { - if *self.is_open { + let event_status = if *self.is_open { // TODO: Encode cursor availability in the type system *self.is_open = cursor_position.x < 0.0 || cursor_position.y < 0.0; + + event::Status::Captured } else if layout.bounds().contains(cursor_position) { let selected = self.selected.as_ref(); @@ -242,18 +244,24 @@ where .options .iter() .position(|option| Some(option) == selected); - } + + event::Status::Captured + } else { + event::Status::Ignored + }; if let Some(last_selection) = self.last_selection.take() { messages.push((self.on_selected)(last_selection)); *self.is_open = false; + + event::Status::Captured + } else { + event_status } } - _ => {} + _ => event::Status::Ignored, } - - event::Status::Ignored } fn draw( -- cgit From 18172f80c96f48cc915b4c8281b9157acaa74b16 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 12 Nov 2020 00:47:58 +0100 Subject: Implement event capturing for `Radio` --- native/src/widget/radio.rs | 2 ++ 1 file changed, 2 insertions(+) (limited to 'native/src/widget') diff --git a/native/src/widget/radio.rs b/native/src/widget/radio.rs index 6e74b404..781fffb1 100644 --- a/native/src/widget/radio.rs +++ b/native/src/widget/radio.rs @@ -175,6 +175,8 @@ where Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) => { if layout.bounds().contains(cursor_position) { messages.push(self.on_click.clone()); + + return event::Status::Captured; } } _ => {} -- cgit From 451bf8dc841b8f60f2a5664b0e8000ad40dfe114 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 12 Nov 2020 00:48:40 +0100 Subject: Implement event capturing for `Row` --- native/src/widget/row.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'native/src/widget') diff --git a/native/src/widget/row.rs b/native/src/widget/row.rs index 7d7595f7..6b09d0c8 100644 --- a/native/src/widget/row.rs +++ b/native/src/widget/row.rs @@ -163,20 +163,20 @@ where renderer: &Renderer, clipboard: Option<&dyn Clipboard>, ) -> event::Status { - self.children.iter_mut().zip(layout.children()).for_each( - |(child, layout)| { - let _ = child.widget.on_event( + self.children + .iter_mut() + .zip(layout.children()) + .map(|(child, layout)| { + child.widget.on_event( event.clone(), layout, cursor_position, messages, renderer, clipboard, - ); - }, - ); - - event::Status::Ignored + ) + }) + .fold(event::Status::Ignored, event::Status::merge) } fn draw( -- 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') 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 From c361fe48c7a92662046dd13cb08cb2157e0577be Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 12 Nov 2020 00:56:50 +0100 Subject: Implement event capturing for `Slider` --- native/src/widget/slider.rs | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'native/src/widget') diff --git a/native/src/widget/slider.rs b/native/src/widget/slider.rs index 51edd56d..4e38fb86 100644 --- a/native/src/widget/slider.rs +++ b/native/src/widget/slider.rs @@ -234,6 +234,8 @@ where if layout.bounds().contains(cursor_position) { change(); self.state.is_dragging = true; + + return event::Status::Captured; } } mouse::Event::ButtonReleased(mouse::Button::Left) => { @@ -242,11 +244,15 @@ where messages.push(on_release); } self.state.is_dragging = false; + + return event::Status::Captured; } } mouse::Event::CursorMoved { .. } => { if self.state.is_dragging { change(); + + return event::Status::Captured; } } _ => {} -- cgit From bf6c65b5ad24595bbb12570e38118321f4b572ac Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 12 Nov 2020 01:11:09 +0100 Subject: Implement event capturing for `TextInput` --- native/src/widget/text_input.rs | 298 ++++++++++++++++++++++------------------ 1 file changed, 168 insertions(+), 130 deletions(-) (limited to 'native/src/widget') diff --git a/native/src/widget/text_input.rs b/native/src/widget/text_input.rs index 436f01ab..cf95e7e8 100644 --- a/native/src/widget/text_input.rs +++ b/native/src/widget/text_input.rs @@ -225,6 +225,9 @@ where Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) => { let is_clicked = layout.bounds().contains(cursor_position); + self.state.is_dragging = is_clicked; + self.state.is_focused = is_clicked; + if is_clicked { let text_layout = layout.children().next().unwrap(); let target = cursor_position.x - text_layout.bounds().x; @@ -282,10 +285,9 @@ where } self.state.last_click = Some(click); - } - self.state.is_dragging = is_clicked; - self.state.is_focused = is_clicked; + return event::Status::Captured; + } } Event::Mouse(mouse::Event::ButtonReleased(mouse::Button::Left)) => { self.state.is_dragging = false; @@ -316,6 +318,8 @@ where position, ); } + + return event::Status::Captured; } } Event::Keyboard(keyboard::Event::CharacterReceived(c)) @@ -330,165 +334,199 @@ where let message = (self.on_change)(editor.contents()); messages.push(message); + + return event::Status::Captured; } Event::Keyboard(keyboard::Event::KeyPressed { key_code, modifiers, - }) if self.state.is_focused => match key_code { - keyboard::KeyCode::Enter => { - if let Some(on_submit) = self.on_submit.clone() { - messages.push(on_submit); - } - } - keyboard::KeyCode::Backspace => { - if platform::is_jump_modifier_pressed(modifiers) - && self.state.cursor.selection(&self.value).is_none() - { - if self.is_secure { - let cursor_pos = self.state.cursor.end(&self.value); - self.state.cursor.select_range(0, cursor_pos); - } else { - self.state.cursor.select_left_by_words(&self.value); + }) if self.state.is_focused => { + match key_code { + keyboard::KeyCode::Enter => { + if let Some(on_submit) = self.on_submit.clone() { + messages.push(on_submit); } } + keyboard::KeyCode::Backspace => { + if platform::is_jump_modifier_pressed(modifiers) + && self + .state + .cursor + .selection(&self.value) + .is_none() + { + if self.is_secure { + let cursor_pos = + self.state.cursor.end(&self.value); + self.state.cursor.select_range(0, cursor_pos); + } else { + self.state + .cursor + .select_left_by_words(&self.value); + } + } - let mut editor = - Editor::new(&mut self.value, &mut self.state.cursor); + let mut editor = Editor::new( + &mut self.value, + &mut self.state.cursor, + ); - editor.backspace(); + editor.backspace(); - let message = (self.on_change)(editor.contents()); - messages.push(message); - } - keyboard::KeyCode::Delete => { - if platform::is_jump_modifier_pressed(modifiers) - && self.state.cursor.selection(&self.value).is_none() - { - if self.is_secure { - let cursor_pos = self.state.cursor.end(&self.value); - self.state - .cursor - .select_range(cursor_pos, self.value.len()); - } else { - self.state + let message = (self.on_change)(editor.contents()); + messages.push(message); + } + keyboard::KeyCode::Delete => { + if platform::is_jump_modifier_pressed(modifiers) + && self + .state .cursor - .select_right_by_words(&self.value); + .selection(&self.value) + .is_none() + { + if self.is_secure { + let cursor_pos = + self.state.cursor.end(&self.value); + self.state + .cursor + .select_range(cursor_pos, self.value.len()); + } else { + self.state + .cursor + .select_right_by_words(&self.value); + } } - } - let mut editor = - Editor::new(&mut self.value, &mut self.state.cursor); + let mut editor = Editor::new( + &mut self.value, + &mut self.state.cursor, + ); - editor.delete(); + editor.delete(); - let message = (self.on_change)(editor.contents()); - messages.push(message); - } - keyboard::KeyCode::Left => { - if platform::is_jump_modifier_pressed(modifiers) - && !self.is_secure - { - if modifiers.shift { - self.state.cursor.select_left_by_words(&self.value); + let message = (self.on_change)(editor.contents()); + messages.push(message); + } + keyboard::KeyCode::Left => { + if platform::is_jump_modifier_pressed(modifiers) + && !self.is_secure + { + if modifiers.shift { + self.state + .cursor + .select_left_by_words(&self.value); + } else { + self.state + .cursor + .move_left_by_words(&self.value); + } + } else if modifiers.shift { + self.state.cursor.select_left(&self.value) } else { - self.state.cursor.move_left_by_words(&self.value); + self.state.cursor.move_left(&self.value); } - } else if modifiers.shift { - self.state.cursor.select_left(&self.value) - } else { - self.state.cursor.move_left(&self.value); } - } - keyboard::KeyCode::Right => { - if platform::is_jump_modifier_pressed(modifiers) - && !self.is_secure - { - if modifiers.shift { - self.state - .cursor - .select_right_by_words(&self.value); + keyboard::KeyCode::Right => { + if platform::is_jump_modifier_pressed(modifiers) + && !self.is_secure + { + if modifiers.shift { + self.state + .cursor + .select_right_by_words(&self.value); + } else { + self.state + .cursor + .move_right_by_words(&self.value); + } + } else if modifiers.shift { + self.state.cursor.select_right(&self.value) } else { - self.state.cursor.move_right_by_words(&self.value); + self.state.cursor.move_right(&self.value); } - } else if modifiers.shift { - self.state.cursor.select_right(&self.value) - } else { - self.state.cursor.move_right(&self.value); - } - } - keyboard::KeyCode::Home => { - if modifiers.shift { - self.state.cursor.select_range( - self.state.cursor.start(&self.value), - 0, - ); - } else { - self.state.cursor.move_to(0); } - } - keyboard::KeyCode::End => { - if modifiers.shift { - self.state.cursor.select_range( - self.state.cursor.start(&self.value), - self.value.len(), - ); - } else { - self.state.cursor.move_to(self.value.len()); + keyboard::KeyCode::Home => { + if modifiers.shift { + self.state.cursor.select_range( + self.state.cursor.start(&self.value), + 0, + ); + } else { + self.state.cursor.move_to(0); + } } - } - keyboard::KeyCode::V => { - if platform::is_copy_paste_modifier_pressed(modifiers) { - if let Some(clipboard) = clipboard { - let content = match self.state.is_pasting.take() { - Some(content) => content, - None => { - let content: String = clipboard - .content() - .unwrap_or(String::new()) - .chars() - .filter(|c| !c.is_control()) - .collect(); - - Value::new(&content) - } - }; - - let mut editor = Editor::new( - &mut self.value, - &mut self.state.cursor, + keyboard::KeyCode::End => { + if modifiers.shift { + self.state.cursor.select_range( + self.state.cursor.start(&self.value), + self.value.len(), ); + } else { + self.state.cursor.move_to(self.value.len()); + } + } + keyboard::KeyCode::V => { + if platform::is_copy_paste_modifier_pressed(modifiers) { + if let Some(clipboard) = clipboard { + let content = match self.state.is_pasting.take() + { + Some(content) => content, + None => { + let content: String = clipboard + .content() + .unwrap_or(String::new()) + .chars() + .filter(|c| !c.is_control()) + .collect(); + + Value::new(&content) + } + }; - editor.paste(content.clone()); + let mut editor = Editor::new( + &mut self.value, + &mut self.state.cursor, + ); + + editor.paste(content.clone()); - let message = (self.on_change)(editor.contents()); - messages.push(message); + let message = + (self.on_change)(editor.contents()); + messages.push(message); - self.state.is_pasting = Some(content); + self.state.is_pasting = Some(content); + } + } else { + self.state.is_pasting = None; } - } else { - self.state.is_pasting = None; } - } - keyboard::KeyCode::A => { - if platform::is_copy_paste_modifier_pressed(modifiers) { - self.state.cursor.select_all(&self.value); + keyboard::KeyCode::A => { + if platform::is_copy_paste_modifier_pressed(modifiers) { + self.state.cursor.select_all(&self.value); + } } + keyboard::KeyCode::Escape => { + self.state.is_focused = false; + self.state.is_dragging = false; + self.state.is_pasting = None; + } + _ => {} } - keyboard::KeyCode::Escape => { - self.state.is_focused = false; - self.state.is_dragging = false; - self.state.is_pasting = None; - } - _ => {} - }, + + return event::Status::Captured; + } Event::Keyboard(keyboard::Event::KeyReleased { key_code, .. - }) => match key_code { - keyboard::KeyCode::V => { - self.state.is_pasting = None; + }) if self.state.is_focused => { + match key_code { + keyboard::KeyCode::V => { + self.state.is_pasting = None; + } + _ => {} } - _ => {} - }, + + return event::Status::Captured; + } _ => {} } -- cgit