From 9e934fe2a72d700e74f0a4601208a835dc4aec9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Fri, 2 May 2025 21:23:17 +0200 Subject: [PATCH] Remove now redundant `Overlay::is_over` The `mouse_interaction` method can be properly used now to encode hover status with the `None` and `Idle` variants. --- core/src/overlay.rs | 18 +-------- core/src/overlay/element.rs | 15 +------ core/src/overlay/group.rs | 21 +--------- examples/toast/src/main.rs | 32 ++++++++------- runtime/src/overlay/nested.rs | 76 +++++------------------------------ runtime/src/user_interface.rs | 54 ++++++++++++------------- widget/src/combo_box.rs | 13 +++--- widget/src/float.rs | 17 +------- widget/src/lazy.rs | 17 +------- widget/src/lazy/component.rs | 18 +-------- widget/src/lazy/responsive.rs | 15 +------ widget/src/overlay/menu.rs | 15 +++++-- widget/src/pick_list.rs | 8 +++- widget/src/themer.rs | 20 ++------- widget/src/tooltip.rs | 9 ----- 15 files changed, 92 insertions(+), 256 deletions(-) diff --git a/core/src/overlay.rs b/core/src/overlay.rs index 90d5731a..af9ae696 100644 --- a/core/src/overlay.rs +++ b/core/src/overlay.rs @@ -10,7 +10,7 @@ use crate::mouse; use crate::renderer; use crate::widget; use crate::widget::Tree; -use crate::{Clipboard, Event, Layout, Point, Rectangle, Shell, Size, Vector}; +use crate::{Clipboard, Event, Layout, Rectangle, Shell, Size, Vector}; /// An interactive component that can be displayed on top of other widgets. pub trait Overlay @@ -69,30 +69,16 @@ where /// Returns the current [`mouse::Interaction`] of the [`Overlay`]. /// - /// By default, it returns [`mouse::Interaction::Idle`]. + /// By default, it returns [`mouse::Interaction::None`]. fn mouse_interaction( &self, _layout: Layout<'_>, _cursor: mouse::Cursor, - _viewport: &Rectangle, _renderer: &Renderer, ) -> mouse::Interaction { mouse::Interaction::None } - /// Returns true if the cursor is over the [`Overlay`]. - /// - /// By default, it returns true if the bounds of the `layout` contain - /// the `cursor_position`. - fn is_over( - &self, - layout: Layout<'_>, - _renderer: &Renderer, - cursor_position: Point, - ) -> bool { - layout.bounds().contains(cursor_position) - } - /// Returns the nested overlay of the [`Overlay`], if there is any. fn overlay<'a>( &'a mut self, diff --git a/core/src/overlay/element.rs b/core/src/overlay/element.rs index f696d2d6..cf6d7360 100644 --- a/core/src/overlay/element.rs +++ b/core/src/overlay/element.rs @@ -4,7 +4,7 @@ use crate::layout; use crate::mouse; use crate::renderer; use crate::widget; -use crate::{Clipboard, Event, Layout, Point, Rectangle, Shell, Size}; +use crate::{Clipboard, Event, Layout, Shell, Size}; /// A generic [`Overlay`]. #[allow(missing_debug_implementations)] @@ -112,11 +112,9 @@ where &self, layout: Layout<'_>, cursor: mouse::Cursor, - viewport: &Rectangle, renderer: &Renderer, ) -> mouse::Interaction { - self.content - .mouse_interaction(layout, cursor, viewport, renderer) + self.content.mouse_interaction(layout, cursor, renderer) } fn draw( @@ -130,15 +128,6 @@ where self.content.draw(renderer, theme, style, layout, cursor); } - fn is_over( - &self, - layout: Layout<'_>, - renderer: &Renderer, - cursor_position: Point, - ) -> bool { - self.content.is_over(layout, renderer, cursor_position) - } - fn overlay<'a>( &'a mut self, layout: Layout<'_>, diff --git a/core/src/overlay/group.rs b/core/src/overlay/group.rs index a0afe3be..1009e60a 100644 --- a/core/src/overlay/group.rs +++ b/core/src/overlay/group.rs @@ -3,7 +3,7 @@ use crate::mouse; use crate::overlay; use crate::renderer; use crate::widget; -use crate::{Clipboard, Event, Layout, Overlay, Point, Rectangle, Shell, Size}; +use crate::{Clipboard, Event, Layout, Overlay, Shell, Size}; /// An [`Overlay`] container that displays multiple overlay [`overlay::Element`] /// children. @@ -107,7 +107,6 @@ where &self, layout: Layout<'_>, cursor: mouse::Cursor, - viewport: &Rectangle, renderer: &Renderer, ) -> mouse::Interaction { self.children @@ -116,7 +115,7 @@ where .map(|(child, layout)| { child .as_overlay() - .mouse_interaction(layout, cursor, viewport, renderer) + .mouse_interaction(layout, cursor, renderer) }) .max() .unwrap_or_default() @@ -137,22 +136,6 @@ where }); } - fn is_over( - &self, - layout: Layout<'_>, - renderer: &Renderer, - cursor_position: Point, - ) -> bool { - self.children - .iter() - .zip(layout.children()) - .any(|(child, layout)| { - child - .as_overlay() - .is_over(layout, renderer, cursor_position) - }) - } - fn overlay<'a>( &'a mut self, layout: Layout<'_>, diff --git a/examples/toast/src/main.rs b/examples/toast/src/main.rs index a58fb03a..f1a8cfa5 100644 --- a/examples/toast/src/main.rs +++ b/examples/toast/src/main.rs @@ -443,6 +443,7 @@ mod toast { let toasts = (!self.toasts.is_empty()).then(|| { overlay::Element::new(Box::new(Overlay { position: layout.bounds().position() + translation, + viewport: *viewport, toasts: &mut self.toasts, state: toasts_state, instants, @@ -460,6 +461,7 @@ mod toast { struct Overlay<'a, 'b, Message> { position: Point, + viewport: Rectangle, toasts: &'b mut [Element<'a, Message>], state: &'b mut [Tree], instants: &'b mut [Option], @@ -595,7 +597,6 @@ mod toast { &self, layout: Layout<'_>, cursor: mouse::Cursor, - viewport: &Rectangle, renderer: &Renderer, ) -> mouse::Interaction { self.toasts @@ -603,24 +604,25 @@ mod toast { .zip(self.state.iter()) .zip(layout.children()) .map(|((child, state), layout)| { - child.as_widget().mouse_interaction( - state, layout, cursor, viewport, renderer, - ) + child + .as_widget() + .mouse_interaction( + state, + layout, + cursor, + &self.viewport, + renderer, + ) + .max( + cursor + .is_over(layout.bounds()) + .then_some(mouse::Interaction::Idle) + .unwrap_or_default(), + ) }) .max() .unwrap_or_default() } - - fn is_over( - &self, - layout: Layout<'_>, - _renderer: &Renderer, - cursor_position: Point, - ) -> bool { - layout - .children() - .any(|layout| layout.bounds().contains(cursor_position)) - } } impl<'a, Message> From> for Element<'a, Message> diff --git a/runtime/src/overlay/nested.rs b/runtime/src/overlay/nested.rs index 0b7b1817..6a154eb6 100644 --- a/runtime/src/overlay/nested.rs +++ b/runtime/src/overlay/nested.rs @@ -4,7 +4,7 @@ use crate::core::mouse; use crate::core::overlay; use crate::core::renderer; use crate::core::widget; -use crate::core::{Clipboard, Event, Layout, Point, Rectangle, Shell, Size}; +use crate::core::{Clipboard, Event, Layout, Shell, Size}; /// An overlay container that displays nested overlays #[allow(missing_debug_implementations)] @@ -87,11 +87,11 @@ where .zip(nested_layout) .and_then(|(cursor_position, nested_layout)| { overlay.overlay(layout, renderer).map(|nested| { - nested.as_overlay().is_over( + nested.as_overlay().mouse_interaction( nested_layout.children().next().unwrap(), + mouse::Cursor::Available(cursor_position), renderer, - cursor_position, - ) + ) != mouse::Interaction::None }) }) .unwrap_or_default(); @@ -209,11 +209,11 @@ where || cursor .position() .map(|cursor_position| { - overlay.is_over( + overlay.mouse_interaction( layout, + mouse::Cursor::Available(cursor_position), renderer, - cursor_position, - ) + ) != mouse::Interaction::None }) .unwrap_or_default(); @@ -255,14 +255,12 @@ where &mut self, layout: Layout<'_>, cursor: mouse::Cursor, - viewport: &Rectangle, renderer: &Renderer, ) -> mouse::Interaction { fn recurse( element: &mut overlay::Element<'_, Message, Theme, Renderer>, layout: Layout<'_>, cursor: mouse::Cursor, - viewport: &Rectangle, renderer: &Renderer, ) -> Option where @@ -278,68 +276,14 @@ where .overlay(layout, renderer) .zip(layouts.next()) .and_then(|(mut overlay, layout)| { - recurse( - &mut overlay, - layout, - cursor, - viewport, - renderer, - ) + recurse(&mut overlay, layout, cursor, renderer) }) .unwrap_or_else(|| { - overlay.mouse_interaction( - layout, cursor, viewport, renderer, - ) + overlay.mouse_interaction(layout, cursor, renderer) }), ) } - recurse(&mut self.overlay, layout, cursor, viewport, renderer) - .unwrap_or_default() - } - - /// Returns true if the cursor is over the [`Nested`] overlay. - pub fn is_over( - &mut self, - layout: Layout<'_>, - renderer: &Renderer, - cursor_position: Point, - ) -> bool { - fn recurse( - element: &mut overlay::Element<'_, Message, Theme, Renderer>, - layout: Layout<'_>, - renderer: &Renderer, - cursor_position: Point, - ) -> bool - where - Renderer: renderer::Renderer, - { - let mut layouts = layout.children(); - - if let Some(layout) = layouts.next() { - let overlay = element.as_overlay_mut(); - - if overlay.is_over(layout, renderer, cursor_position) { - return true; - } - - if let Some((mut nested, nested_layout)) = - overlay.overlay(layout, renderer).zip(layouts.next()) - { - recurse( - &mut nested, - nested_layout, - renderer, - cursor_position, - ) - } else { - false - } - } else { - false - } - } - - recurse(&mut self.overlay, layout, renderer, cursor_position) + recurse(&mut self.overlay, layout, cursor, renderer).unwrap_or_default() } } diff --git a/runtime/src/user_interface.rs b/runtime/src/user_interface.rs index 2f3318ea..7fcf8a04 100644 --- a/runtime/src/user_interface.rs +++ b/runtime/src/user_interface.rs @@ -270,11 +270,11 @@ where .as_mut() .and_then(|overlay| { cursor.position().map(|cursor_position| { - overlay.is_over( + overlay.mouse_interaction( Layout::new(&layout), + mouse::Cursor::Available(cursor_position), renderer, - cursor_position, - ) + ) != mouse::Interaction::None }) }) .unwrap_or_default() @@ -439,7 +439,7 @@ where let viewport = Rectangle::with_size(self.bounds); - let base_cursor = if let Some(mut overlay) = self + let (base_cursor, overlay_interaction) = if let Some(mut overlay) = self .root .as_widget_mut() .overlay( @@ -456,27 +456,31 @@ where .take() .unwrap_or_else(|| overlay.layout(renderer, self.bounds)); - let cursor = if cursor - .position() - .map(|cursor_position| { - overlay.is_over( - Layout::new(&overlay_layout), - renderer, - cursor_position, - ) - }) - .unwrap_or_default() - { - mouse::Cursor::Unavailable - } else { - cursor + let (cursor, overlay_interaction) = { + let overlay_interaction = + cursor.position().map(|cursor_position| { + overlay.mouse_interaction( + Layout::new(&overlay_layout), + mouse::Cursor::Available(cursor_position), + renderer, + ) + }); + + match overlay_interaction { + Some(mouse::Interaction::None) | None => { + (cursor, mouse::Interaction::None) + } + Some(interaction) => { + (mouse::Cursor::Unavailable, interaction) + } + } }; self.overlay = Some(overlay_layout); - cursor + (cursor, overlay_interaction) } else { - cursor + (cursor, mouse::Interaction::None) }; self.root.as_widget().draw( @@ -522,13 +526,6 @@ where ) .map(overlay::Nested::new) .map(|mut overlay| { - let overlay_interaction = overlay.mouse_interaction( - Layout::new(layout), - cursor, - &viewport, - renderer, - ); - overlay.draw( renderer, theme, @@ -537,8 +534,7 @@ where cursor, ); - if overlay_interaction != mouse::Interaction::default() - { + if overlay_interaction != mouse::Interaction::None { overlay_interaction } else { base_interaction diff --git a/widget/src/combo_box.rs b/widget/src/combo_box.rs index 9ca92d03..5bf01eac 100644 --- a/widget/src/combo_box.rs +++ b/widget/src/combo_box.rs @@ -836,7 +836,7 @@ where tree: &'b mut widget::Tree, layout: Layout<'_>, _renderer: &Renderer, - _viewport: &Rectangle, + viewport: &Rectangle, translation: Vector, ) -> Option> { let is_focused = { @@ -889,12 +889,11 @@ where menu = menu.text_size(size); } - Some( - menu.overlay( - layout.position() + translation, - bounds.height, - ), - ) + Some(menu.overlay( + layout.position() + translation, + *viewport, + bounds.height, + )) } } else { None diff --git a/widget/src/float.rs b/widget/src/float.rs index aa6ae5f7..aa0121a8 100644 --- a/widget/src/float.rs +++ b/widget/src/float.rs @@ -8,8 +8,8 @@ use crate::core::renderer; use crate::core::widget; use crate::core::widget::tree; use crate::core::{ - Clipboard, Element, Event, Layout, Length, Point, Rectangle, Shadow, Shell, - Size, Transformation, Vector, Widget, + Clipboard, Element, Event, Layout, Length, Rectangle, Shadow, Shell, Size, + Transformation, Vector, Widget, }; /// A widget that can make its contents float over other widgets. @@ -298,18 +298,6 @@ where layout::Node::new(bounds.size()).move_to(bounds.position()) } - fn is_over( - &self, - layout: Layout<'_>, - _renderer: &Renderer, - cursor_position: Point, - ) -> bool { - self.float.opaque - && layout - .bounds() - .contains(cursor_position * self.transformation.inverse()) - } - fn update( &mut self, event: &Event, @@ -379,7 +367,6 @@ where &self, _layout: Layout<'_>, cursor: mouse::Cursor, - _viewport: &Rectangle, renderer: &Renderer, ) -> mouse::Interaction { self.float.content.as_widget().mouse_interaction( diff --git a/widget/src/lazy.rs b/widget/src/lazy.rs index eb8ccb12..b538b460 100644 --- a/widget/src/lazy.rs +++ b/widget/src/lazy.rs @@ -18,7 +18,7 @@ use crate::core::renderer; use crate::core::widget::tree::{self, Tree}; use crate::core::widget::{self, Widget}; use crate::core::{ - self, Clipboard, Event, Length, Point, Rectangle, Shell, Size, Vector, + self, Clipboard, Event, Length, Rectangle, Shell, Size, Vector, }; use crate::runtime::overlay::Nested; @@ -378,11 +378,10 @@ where &self, layout: Layout<'_>, cursor: mouse::Cursor, - viewport: &Rectangle, renderer: &Renderer, ) -> mouse::Interaction { self.with_overlay_maybe(|overlay| { - overlay.mouse_interaction(layout, cursor, viewport, renderer) + overlay.mouse_interaction(layout, cursor, renderer) }) .unwrap_or_default() } @@ -400,18 +399,6 @@ where overlay.update(event, layout, cursor, renderer, clipboard, shell); }); } - - fn is_over( - &self, - layout: Layout<'_>, - renderer: &Renderer, - cursor_position: Point, - ) -> bool { - self.with_overlay_maybe(|overlay| { - overlay.is_over(layout, renderer, cursor_position) - }) - .unwrap_or_default() - } } impl<'a, Message, Theme, Renderer, Dependency, View> diff --git a/widget/src/lazy/component.rs b/widget/src/lazy/component.rs index 4b9833c3..8bd04d64 100644 --- a/widget/src/lazy/component.rs +++ b/widget/src/lazy/component.rs @@ -7,8 +7,7 @@ use crate::core::renderer; use crate::core::widget; use crate::core::widget::tree::{self, Tree}; use crate::core::{ - self, Clipboard, Element, Length, Point, Rectangle, Shell, Size, Vector, - Widget, + self, Clipboard, Element, Length, Rectangle, Shell, Size, Vector, Widget, }; use crate::runtime::overlay::Nested; @@ -590,11 +589,10 @@ where &self, layout: Layout<'_>, cursor: mouse::Cursor, - viewport: &Rectangle, renderer: &Renderer, ) -> mouse::Interaction { self.with_overlay_maybe(|overlay| { - overlay.mouse_interaction(layout, cursor, viewport, renderer) + overlay.mouse_interaction(layout, cursor, renderer) }) .unwrap_or_default() } @@ -666,16 +664,4 @@ where shell.invalidate_layout(); } } - - fn is_over( - &self, - layout: Layout<'_>, - renderer: &Renderer, - cursor_position: Point, - ) -> bool { - self.with_overlay_maybe(|overlay| { - overlay.is_over(layout, renderer, cursor_position) - }) - .unwrap_or_default() - } } diff --git a/widget/src/lazy/responsive.rs b/widget/src/lazy/responsive.rs index f02c119e..4e90a178 100644 --- a/widget/src/lazy/responsive.rs +++ b/widget/src/lazy/responsive.rs @@ -416,11 +416,10 @@ where &self, layout: Layout<'_>, cursor: mouse::Cursor, - viewport: &Rectangle, renderer: &Renderer, ) -> mouse::Interaction { self.with_overlay_maybe(|overlay| { - overlay.mouse_interaction(layout, cursor, viewport, renderer) + overlay.mouse_interaction(layout, cursor, renderer) }) .unwrap_or_default() } @@ -449,18 +448,6 @@ where } } - fn is_over( - &self, - layout: Layout<'_>, - renderer: &Renderer, - cursor_position: Point, - ) -> bool { - self.with_overlay_maybe(|overlay| { - overlay.is_over(layout, renderer, cursor_position) - }) - .unwrap_or_default() - } - fn operate( &mut self, layout: Layout<'_>, diff --git a/widget/src/overlay/menu.rs b/widget/src/overlay/menu.rs index 3007ba89..7778768a 100644 --- a/widget/src/overlay/menu.rs +++ b/widget/src/overlay/menu.rs @@ -127,10 +127,12 @@ where pub fn overlay( self, position: Point, + viewport: Rectangle, target_height: f32, ) -> overlay::Element<'a, Message, Theme, Renderer> { overlay::Element::new(Box::new(Overlay::new( position, + viewport, self, target_height, ))) @@ -164,6 +166,7 @@ where Renderer: crate::core::Renderer, { position: Point, + viewport: Rectangle, state: &'a mut Tree, list: Scrollable<'a, Message, Theme, Renderer>, width: f32, @@ -180,6 +183,7 @@ where { pub fn new( position: Point, + viewport: Rectangle, menu: Menu<'a, 'b, T, Message, Theme, Renderer>, target_height: f32, ) -> Self @@ -218,6 +222,7 @@ where Self { position, + viewport, state: &mut state.tree, list, width, @@ -282,11 +287,15 @@ where &self, layout: Layout<'_>, cursor: mouse::Cursor, - viewport: &Rectangle, renderer: &Renderer, ) -> mouse::Interaction { - self.list - .mouse_interaction(self.state, layout, cursor, viewport, renderer) + self.list.mouse_interaction( + self.state, + layout, + cursor, + &self.viewport, + renderer, + ) } fn draw( diff --git a/widget/src/pick_list.rs b/widget/src/pick_list.rs index 4a9d1e2f..4f1d8262 100644 --- a/widget/src/pick_list.rs +++ b/widget/src/pick_list.rs @@ -690,7 +690,7 @@ where tree: &'b mut Tree, layout: Layout<'_>, renderer: &Renderer, - _viewport: &Rectangle, + viewport: &Rectangle, translation: Vector, ) -> Option> { let state = tree.state.downcast_mut::>(); @@ -722,7 +722,11 @@ where menu = menu.text_size(text_size); } - Some(menu.overlay(layout.position() + translation, bounds.height)) + Some(menu.overlay( + layout.position() + translation, + *viewport, + bounds.height, + )) } else { None } diff --git a/widget/src/themer.rs b/widget/src/themer.rs index 82b65486..f8b3cb29 100644 --- a/widget/src/themer.rs +++ b/widget/src/themer.rs @@ -6,8 +6,8 @@ use crate::core::renderer; use crate::core::widget::Operation; use crate::core::widget::tree::{self, Tree}; use crate::core::{ - Background, Clipboard, Color, Element, Event, Layout, Length, Point, - Rectangle, Shell, Size, Vector, Widget, + Background, Clipboard, Color, Element, Event, Layout, Length, Rectangle, + Shell, Size, Vector, Widget, }; use std::marker::PhantomData; @@ -248,25 +248,11 @@ where &self, layout: Layout<'_>, cursor: mouse::Cursor, - viewport: &Rectangle, renderer: &Renderer, ) -> mouse::Interaction { self.content .as_overlay() - .mouse_interaction(layout, cursor, viewport, renderer) - } - - fn is_over( - &self, - layout: Layout<'_>, - renderer: &Renderer, - cursor_position: Point, - ) -> bool { - self.content.as_overlay().is_over( - layout, - renderer, - cursor_position, - ) + .mouse_interaction(layout, cursor, renderer) } fn overlay<'b>( diff --git a/widget/src/tooltip.rs b/widget/src/tooltip.rs index ab6b8f14..8ef6280c 100644 --- a/widget/src/tooltip.rs +++ b/widget/src/tooltip.rs @@ -508,13 +508,4 @@ where &Rectangle::with_size(Size::INFINITY), ); } - - fn is_over( - &self, - _layout: Layout<'_>, - _renderer: &Renderer, - _cursor_position: Point, - ) -> bool { - false - } }