From dcc184b01b753dbecb500205391f6eaaa21c8683 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Fri, 25 Oct 2024 19:28:18 +0200 Subject: Replace `event::Status` in `Widget::on_event` with `Shell::capture_event` --- widget/src/pane_grid.rs | 49 +++++++++++++++++++++++-------------------------- 1 file changed, 23 insertions(+), 26 deletions(-) (limited to 'widget/src/pane_grid.rs') diff --git a/widget/src/pane_grid.rs b/widget/src/pane_grid.rs index b4ed4b64..29b7ac87 100644 --- a/widget/src/pane_grid.rs +++ b/widget/src/pane_grid.rs @@ -79,7 +79,6 @@ pub use state::State; pub use title_bar::TitleBar; use crate::container; -use crate::core::event::{self, Event}; use crate::core::layout; use crate::core::mouse; use crate::core::overlay::{self, Group}; @@ -88,7 +87,7 @@ use crate::core::touch; use crate::core::widget; use crate::core::widget::tree::{self, Tree}; use crate::core::{ - self, Background, Border, Clipboard, Color, Element, Layout, Length, + self, Background, Border, Clipboard, Color, Element, Event, Layout, Length, Pixels, Point, Rectangle, Shell, Size, Theme, Vector, Widget, }; @@ -433,9 +432,7 @@ where clipboard: &mut dyn Clipboard, shell: &mut Shell<'_, Message>, viewport: &Rectangle, - ) -> event::Status { - let mut event_status = event::Status::Ignored; - + ) { let Memory { action, .. } = tree.state.downcast_mut(); let node = self.internal.layout(); @@ -451,7 +448,7 @@ where let bounds = layout.bounds(); if let Some(cursor_position) = cursor.position_over(bounds) { - event_status = event::Status::Captured; + shell.capture_event(); match &self.on_resize { Some((leeway, _)) => { @@ -556,9 +553,9 @@ where } } - event_status = event::Status::Captured; + shell.capture_event(); } else if action.picked_split().is_some() { - event_status = event::Status::Captured; + shell.capture_event(); } *action = state::Action::Idle; @@ -600,7 +597,7 @@ where ratio, })); - event_status = event::Status::Captured; + shell.capture_event(); } } } @@ -611,7 +608,8 @@ where let picked_pane = action.picked_pane().map(|(pane, _)| pane); - self.panes + for (((pane, content), tree), layout) in self + .panes .iter() .copied() .zip(&mut self.contents) @@ -622,22 +620,21 @@ where .maximized() .map_or(true, |maximized| *pane == maximized) }) - .map(|(((pane, content), tree), layout)| { - let is_picked = picked_pane == Some(pane); - - content.on_event( - tree, - event.clone(), - layout, - cursor, - renderer, - clipboard, - shell, - viewport, - is_picked, - ) - }) - .fold(event_status, event::Status::merge) + { + let is_picked = picked_pane == Some(pane); + + content.on_event( + tree, + event.clone(), + layout, + cursor, + renderer, + clipboard, + shell, + viewport, + is_picked, + ); + } } fn mouse_interaction( -- cgit From f02bfc3f68322bea0c56283d76888714be401ec2 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Fri, 25 Oct 2024 22:06:06 +0200 Subject: Rename `Widget::on_event` to `update` --- widget/src/pane_grid.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'widget/src/pane_grid.rs') diff --git a/widget/src/pane_grid.rs b/widget/src/pane_grid.rs index 29b7ac87..a966627a 100644 --- a/widget/src/pane_grid.rs +++ b/widget/src/pane_grid.rs @@ -422,7 +422,7 @@ where }); } - fn on_event( + fn update( &mut self, tree: &mut Tree, event: Event, -- cgit From 4e47450c336a235fe26090665aca1cc7b4d23384 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Tue, 29 Oct 2024 15:55:47 +0100 Subject: Implement `reactive-rendering` for `pane_grid` --- widget/src/pane_grid.rs | 115 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 80 insertions(+), 35 deletions(-) (limited to 'widget/src/pane_grid.rs') diff --git a/widget/src/pane_grid.rs b/widget/src/pane_grid.rs index a966627a..691b0a93 100644 --- a/widget/src/pane_grid.rs +++ b/widget/src/pane_grid.rs @@ -86,6 +86,7 @@ use crate::core::renderer; use crate::core::touch; use crate::core::widget; use crate::core::widget::tree::{self, Tree}; +use crate::core::window; use crate::core::{ self, Background, Border, Clipboard, Color, Element, Event, Layout, Length, Pixels, Point, Rectangle, Shell, Size, Theme, Vector, Widget, @@ -166,6 +167,7 @@ pub struct PaneGrid< on_drag: Option Message + 'a>>, on_resize: Option<(f32, Box Message + 'a>)>, class: ::Class<'a>, + last_mouse_interaction: Option, } impl<'a, Message, Theme, Renderer> PaneGrid<'a, Message, Theme, Renderer> @@ -202,6 +204,7 @@ where on_drag: None, on_resize: None, class: ::default(), + last_mouse_interaction: None, } } @@ -292,6 +295,52 @@ where .then(|| self.on_drag.is_some()) .unwrap_or_default() } + + fn grid_interaction( + &self, + action: &state::Action, + layout: Layout<'_>, + cursor: mouse::Cursor, + ) -> Option { + if action.picked_pane().is_some() { + return Some(mouse::Interaction::Grabbing); + } + + let resize_leeway = self.on_resize.as_ref().map(|(leeway, _)| *leeway); + let node = self.internal.layout(); + + let resize_axis = + action.picked_split().map(|(_, axis)| axis).or_else(|| { + resize_leeway.and_then(|leeway| { + let cursor_position = cursor.position()?; + let bounds = layout.bounds(); + + let splits = + node.split_regions(self.spacing, bounds.size()); + + let relative_cursor = Point::new( + cursor_position.x - bounds.x, + cursor_position.y - bounds.y, + ); + + hovered_split( + splits.iter(), + self.spacing + leeway, + relative_cursor, + ) + .map(|(_, axis, _)| axis) + }) + }); + + if let Some(resize_axis) = resize_axis { + return Some(match resize_axis { + Axis::Horizontal => mouse::Interaction::ResizingVertically, + Axis::Vertical => mouse::Interaction::ResizingHorizontally, + }); + } + + None + } } #[derive(Default)] @@ -600,6 +649,8 @@ where shell.capture_event(); } } + } else if action.picked_pane().is_some() { + shell.request_redraw(); } } } @@ -635,6 +686,31 @@ where is_picked, ); } + + if shell.redraw_request() != Some(window::RedrawRequest::NextFrame) { + let interaction = self + .grid_interaction(action, layout, cursor) + .or_else(|| { + self.contents.iter().zip(layout.children()).find_map( + |(content, layout)| { + content.grid_interaction( + layout, + cursor, + on_drag.is_some(), + ) + }, + ) + }) + .unwrap_or(mouse::Interaction::None); + + if let Event::Window(window::Event::RedrawRequested(_now)) = event { + self.last_mouse_interaction = Some(interaction); + } else if self.last_mouse_interaction.is_some_and( + |last_mouse_interaction| last_mouse_interaction != interaction, + ) { + shell.request_redraw(); + } + } } fn mouse_interaction( @@ -647,41 +723,10 @@ where ) -> mouse::Interaction { let Memory { action, .. } = tree.state.downcast_ref(); - if action.picked_pane().is_some() { - return mouse::Interaction::Grabbing; - } - - let resize_leeway = self.on_resize.as_ref().map(|(leeway, _)| *leeway); - let node = self.internal.layout(); - - let resize_axis = - action.picked_split().map(|(_, axis)| axis).or_else(|| { - resize_leeway.and_then(|leeway| { - let cursor_position = cursor.position()?; - let bounds = layout.bounds(); - - let splits = - node.split_regions(self.spacing, bounds.size()); - - let relative_cursor = Point::new( - cursor_position.x - bounds.x, - cursor_position.y - bounds.y, - ); - - hovered_split( - splits.iter(), - self.spacing + leeway, - relative_cursor, - ) - .map(|(_, axis, _)| axis) - }) - }); - - if let Some(resize_axis) = resize_axis { - return match resize_axis { - Axis::Horizontal => mouse::Interaction::ResizingVertically, - Axis::Vertical => mouse::Interaction::ResizingHorizontally, - }; + if let Some(grid_interaction) = + self.grid_interaction(action, layout, cursor) + { + return grid_interaction; } self.panes -- cgit From e5f1e31a5c068fe992cab076661cb6e2d120bdf1 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Wed, 6 Nov 2024 00:02:46 +0100 Subject: Rename `Overlay::on_event` to `update` --- widget/src/pane_grid.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'widget/src/pane_grid.rs') diff --git a/widget/src/pane_grid.rs b/widget/src/pane_grid.rs index 691b0a93..9b87a2d3 100644 --- a/widget/src/pane_grid.rs +++ b/widget/src/pane_grid.rs @@ -674,7 +674,7 @@ where { let is_picked = picked_pane == Some(pane); - content.on_event( + content.update( tree, event.clone(), layout, -- cgit From 9511bfb971e8bb7e10f95f7d40d5e23c9197e5d6 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Wed, 6 Nov 2024 22:03:00 +0100 Subject: Fix event capturing order in `pane_grid` --- widget/src/pane_grid.rs | 79 +++++++++++++++++++++++++------------------------ 1 file changed, 41 insertions(+), 38 deletions(-) (limited to 'widget/src/pane_grid.rs') diff --git a/widget/src/pane_grid.rs b/widget/src/pane_grid.rs index 9b87a2d3..7b2956f3 100644 --- a/widget/src/pane_grid.rs +++ b/widget/src/pane_grid.rs @@ -491,6 +491,36 @@ where &None }; + let picked_pane = action.picked_pane().map(|(pane, _)| pane); + + for (((pane, content), tree), layout) in self + .panes + .iter() + .copied() + .zip(&mut self.contents) + .zip(&mut tree.children) + .zip(layout.children()) + .filter(|(((pane, _), _), _)| { + self.internal + .maximized() + .map_or(true, |maximized| *pane == maximized) + }) + { + let is_picked = picked_pane == Some(pane); + + content.update( + tree, + event.clone(), + layout, + cursor, + renderer, + clipboard, + shell, + viewport, + is_picked, + ); + } + match event { Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) | Event::Touch(touch::Event::FingerPressed { .. }) => { @@ -601,10 +631,6 @@ where } } } - - shell.capture_event(); - } else if action.picked_split().is_some() { - shell.capture_event(); } *action = state::Action::Idle; @@ -657,49 +683,26 @@ where _ => {} } - let picked_pane = action.picked_pane().map(|(pane, _)| pane); - - for (((pane, content), tree), layout) in self - .panes - .iter() - .copied() - .zip(&mut self.contents) - .zip(&mut tree.children) - .zip(layout.children()) - .filter(|(((pane, _), _), _)| { - self.internal - .maximized() - .map_or(true, |maximized| *pane == maximized) - }) - { - let is_picked = picked_pane == Some(pane); - - content.update( - tree, - event.clone(), - layout, - cursor, - renderer, - clipboard, - shell, - viewport, - is_picked, - ); - } - if shell.redraw_request() != Some(window::RedrawRequest::NextFrame) { let interaction = self .grid_interaction(action, layout, cursor) .or_else(|| { - self.contents.iter().zip(layout.children()).find_map( - |(content, layout)| { + self.panes + .iter() + .zip(&self.contents) + .zip(layout.children()) + .filter(|((&pane, _content), _layout)| { + self.internal + .maximized() + .map_or(true, |maximized| pane == maximized) + }) + .find_map(|((_pane, content), layout)| { content.grid_interaction( layout, cursor, on_drag.is_some(), ) - }, - ) + }) }) .unwrap_or(mouse::Interaction::None); -- cgit