From 738aa47547818ebf57dc4f00099386a5a22a86d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 1 Feb 2024 01:08:21 +0100 Subject: [PATCH] Remove `position` from `overlay::Element` --- core/src/element.rs | 8 +++- core/src/overlay.rs | 13 +++---- core/src/overlay/element.rs | 41 ++------------------ core/src/overlay/group.rs | 16 ++------ core/src/widget.rs | 3 +- examples/modal/src/main.rs | 23 ++++++----- examples/toast/src/main.rs | 25 ++++++------ runtime/src/overlay/nested.rs | 21 ++-------- runtime/src/user_interface.rs | 62 ++++++++++++++++-------------- widget/src/button.rs | 4 +- widget/src/column.rs | 11 +++++- widget/src/combo_box.rs | 5 ++- widget/src/container.rs | 2 + widget/src/keyed/column.rs | 11 +++++- widget/src/lazy.rs | 23 +++-------- widget/src/lazy/component.rs | 31 ++++----------- widget/src/lazy/responsive.rs | 23 +++-------- widget/src/mouse_area.rs | 4 +- widget/src/overlay/menu.rs | 29 +++++++------- widget/src/pane_grid.rs | 3 +- widget/src/pane_grid/content.rs | 15 ++++++-- widget/src/pane_grid/title_bar.rs | 6 ++- widget/src/pick_list.rs | 7 +++- widget/src/row.rs | 11 +++++- widget/src/scrollable.rs | 35 ++++++++--------- widget/src/themer.rs | 19 +++------ widget/src/tooltip.rs | 64 ++++++++++++++++--------------- 27 files changed, 231 insertions(+), 284 deletions(-) diff --git a/core/src/element.rs b/core/src/element.rs index 71d0d873ac..8eea90ca98 100644 --- a/core/src/element.rs +++ b/core/src/element.rs @@ -446,11 +446,12 @@ where tree: &'b mut Tree, layout: Layout<'_>, renderer: &Renderer, + translation: Vector, ) -> Option> { let mapper = &self.mapper; self.widget - .overlay(tree, layout, renderer) + .overlay(tree, layout, renderer, translation) .map(move |overlay| overlay.map(mapper)) } } @@ -596,7 +597,10 @@ where state: &'b mut Tree, layout: Layout<'_>, renderer: &Renderer, + translation: Vector, ) -> Option> { - self.element.widget.overlay(state, layout, renderer) + self.element + .widget + .overlay(state, layout, renderer, translation) } } diff --git a/core/src/overlay.rs b/core/src/overlay.rs index 6b8cf2a66e..03076a30b2 100644 --- a/core/src/overlay.rs +++ b/core/src/overlay.rs @@ -24,13 +24,7 @@ where /// user interface. /// /// [`Node`]: layout::Node - fn layout( - &mut self, - renderer: &Renderer, - bounds: Size, - position: Point, - translation: Vector, - ) -> layout::Node; + fn layout(&mut self, renderer: &Renderer, bounds: Size) -> layout::Node; /// Draws the [`Overlay`] using the associated `Renderer`. fn draw( @@ -120,6 +114,7 @@ pub fn from_children<'a, Message, Theme, Renderer>( tree: &'a mut Tree, layout: Layout<'_>, renderer: &Renderer, + translation: Vector, ) -> Option> where Renderer: crate::Renderer, @@ -129,7 +124,9 @@ where .zip(&mut tree.children) .zip(layout.children()) .filter_map(|((child, state), layout)| { - child.as_widget_mut().overlay(state, layout, renderer) + child + .as_widget_mut() + .overlay(state, layout, renderer, translation) }) .collect::>(); diff --git a/core/src/overlay/element.rs b/core/src/overlay/element.rs index c34ab86289..695b88b3a5 100644 --- a/core/src/overlay/element.rs +++ b/core/src/overlay/element.rs @@ -12,8 +12,6 @@ use std::any::Any; /// A generic [`Overlay`]. #[allow(missing_debug_implementations)] pub struct Element<'a, Message, Theme, Renderer> { - position: Point, - translation: Vector, overlay: Box + 'a>, } @@ -23,26 +21,9 @@ where { /// Creates a new [`Element`] containing the given [`Overlay`]. pub fn new( - position: Point, overlay: Box + 'a>, ) -> Self { - Self { - position, - overlay, - translation: Vector::ZERO, - } - } - - /// Returns the position of the [`Element`]. - pub fn position(&self) -> Point { - self.position - } - - /// Translates the [`Element`]. - pub fn translate(mut self, translation: Vector) -> Self { - self.position = self.position + translation; - self.translation = self.translation + translation; - self + Self { overlay } } /// Applies a transformation to the produced message of the [`Element`]. @@ -57,8 +38,6 @@ where B: 'a, { Element { - position: self.position, - translation: self.translation, overlay: Box::new(Map::new(self.overlay, f)), } } @@ -68,14 +47,8 @@ where &mut self, renderer: &Renderer, bounds: Size, - translation: Vector, ) -> layout::Node { - self.overlay.layout( - renderer, - bounds, - self.position + translation, - self.translation + translation, - ) + self.overlay.layout(renderer, bounds) } /// Processes a runtime [`Event`]. @@ -165,14 +138,8 @@ impl<'a, A, B, Theme, Renderer> Overlay where Renderer: crate::Renderer, { - fn layout( - &mut self, - renderer: &Renderer, - bounds: Size, - position: Point, - translation: Vector, - ) -> layout::Node { - self.content.layout(renderer, bounds, position, translation) + fn layout(&mut self, renderer: &Renderer, bounds: Size) -> layout::Node { + self.content.layout(renderer, bounds) } fn operate( diff --git a/core/src/overlay/group.rs b/core/src/overlay/group.rs index 4e54a002c8..7e4bebd078 100644 --- a/core/src/overlay/group.rs +++ b/core/src/overlay/group.rs @@ -4,9 +4,7 @@ use crate::mouse; use crate::overlay; use crate::renderer; use crate::widget; -use crate::{ - Clipboard, Event, Layout, Overlay, Point, Rectangle, Shell, Size, Vector, -}; +use crate::{Clipboard, Event, Layout, Overlay, Point, Rectangle, Shell, Size}; /// An [`Overlay`] container that displays multiple overlay [`overlay::Element`] /// children. @@ -44,7 +42,7 @@ where /// Turns the [`Group`] into an overlay [`overlay::Element`]. pub fn overlay(self) -> overlay::Element<'a, Message, Theme, Renderer> { - overlay::Element::new(Point::ORIGIN, Box::new(self)) + overlay::Element::new(Box::new(self)) } } @@ -65,18 +63,12 @@ impl<'a, Message, Theme, Renderer> Overlay where Renderer: crate::Renderer, { - fn layout( - &mut self, - renderer: &Renderer, - bounds: Size, - _position: Point, - translation: Vector, - ) -> layout::Node { + fn layout(&mut self, renderer: &Renderer, bounds: Size) -> layout::Node { layout::Node::with_children( bounds, self.children .iter_mut() - .map(|child| child.layout(renderer, bounds, translation)) + .map(|child| child.layout(renderer, bounds)) .collect(), ) } diff --git a/core/src/widget.rs b/core/src/widget.rs index d5e2ec6fda..51326f1246 100644 --- a/core/src/widget.rs +++ b/core/src/widget.rs @@ -15,7 +15,7 @@ use crate::layout::{self, Layout}; use crate::mouse; use crate::overlay; use crate::renderer; -use crate::{Clipboard, Length, Rectangle, Shell, Size}; +use crate::{Clipboard, Length, Rectangle, Shell, Size, Vector}; /// A component that displays information and allows interaction. /// @@ -146,6 +146,7 @@ where _state: &'a mut Tree, _layout: Layout<'_>, _renderer: &Renderer, + _translation: Vector, ) -> Option> { None } diff --git a/examples/modal/src/main.rs b/examples/modal/src/main.rs index c2a4132c66..6fe951ee51 100644 --- a/examples/modal/src/main.rs +++ b/examples/modal/src/main.rs @@ -346,16 +346,15 @@ mod modal { state: &'b mut widget::Tree, layout: Layout<'_>, _renderer: &Renderer, + translation: Vector, ) -> Option> { - Some(overlay::Element::new( - layout.position(), - Box::new(Overlay { - content: &mut self.modal, - tree: &mut state.children[1], - size: layout.bounds().size(), - on_blur: self.on_blur.clone(), - }), - )) + Some(overlay::Element::new(Box::new(Overlay { + position: layout.position() + translation, + content: &mut self.modal, + tree: &mut state.children[1], + size: layout.bounds().size(), + on_blur: self.on_blur.clone(), + }))) } fn mouse_interaction( @@ -392,6 +391,7 @@ mod modal { } struct Overlay<'a, 'b, Message, Theme, Renderer> { + position: Point, content: &'b mut Element<'a, Message, Theme, Renderer>, tree: &'b mut widget::Tree, size: Size, @@ -409,8 +409,6 @@ mod modal { &mut self, renderer: &Renderer, _bounds: Size, - position: Point, - _translation: Vector, ) -> layout::Node { let limits = layout::Limits::new(Size::ZERO, self.size) .width(Length::Fill) @@ -423,7 +421,7 @@ mod modal { .align(Alignment::Center, Alignment::Center, limits.max()); layout::Node::with_children(self.size, vec![child]) - .move_to(position) + .move_to(self.position) } fn on_event( @@ -530,6 +528,7 @@ mod modal { self.tree, layout.children().next().unwrap(), renderer, + Vector::ZERO, ) } } diff --git a/examples/toast/src/main.rs b/examples/toast/src/main.rs index cc9875d94d..af29660a2c 100644 --- a/examples/toast/src/main.rs +++ b/examples/toast/src/main.rs @@ -456,6 +456,7 @@ mod toast { state: &'b mut Tree, layout: Layout<'_>, renderer: &Renderer, + translation: Vector, ) -> Option> { let instants = state.state.downcast_mut::>>(); @@ -465,19 +466,18 @@ mod toast { &mut content_state[0], layout, renderer, + translation, ); let toasts = (!self.toasts.is_empty()).then(|| { - overlay::Element::new( - layout.bounds().position(), - Box::new(Overlay { - toasts: &mut self.toasts, - state: toasts_state, - instants, - on_close: &self.on_close, - timeout_secs: self.timeout_secs, - }), - ) + overlay::Element::new(Box::new(Overlay { + position: layout.bounds().position() + translation, + toasts: &mut self.toasts, + state: toasts_state, + instants, + on_close: &self.on_close, + timeout_secs: self.timeout_secs, + })) }); let overlays = content.into_iter().chain(toasts).collect::>(); @@ -488,6 +488,7 @@ mod toast { } struct Overlay<'a, 'b, Message> { + position: Point, toasts: &'b mut [Element<'a, Message>], state: &'b mut [Tree], instants: &'b mut [Option], @@ -502,8 +503,6 @@ mod toast { &mut self, renderer: &Renderer, bounds: Size, - position: Point, - _translation: Vector, ) -> layout::Node { let limits = layout::Limits::new(Size::ZERO, bounds); @@ -519,7 +518,7 @@ mod toast { self.toasts, self.state, ) - .translate(Vector::new(position.x, position.y)) + .translate(Vector::new(self.position.x, self.position.y)) } fn on_event( diff --git a/runtime/src/overlay/nested.rs b/runtime/src/overlay/nested.rs index 60e2eb875e..ddb9532b9f 100644 --- a/runtime/src/overlay/nested.rs +++ b/runtime/src/overlay/nested.rs @@ -4,9 +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, Vector, -}; +use crate::core::{Clipboard, Event, Layout, Point, Rectangle, Shell, Size}; /// An overlay container that displays nested overlays #[allow(missing_debug_implementations)] @@ -25,11 +23,6 @@ where Self { overlay: element } } - /// Returns the position of the [`Nested`] overlay. - pub fn position(&self) -> Point { - self.overlay.position() - } - /// Returns the layout [`Node`] of the [`Nested`] overlay. /// /// [`Node`]: layout::Node @@ -37,36 +30,30 @@ where &mut self, renderer: &Renderer, bounds: Size, - _position: Point, - translation: Vector, ) -> layout::Node { fn recurse( element: &mut overlay::Element<'_, Message, Theme, Renderer>, renderer: &Renderer, bounds: Size, - translation: Vector, ) -> layout::Node where Renderer: renderer::Renderer, { - let node = element.layout(renderer, bounds, translation); + let node = element.layout(renderer, bounds); if let Some(mut nested) = element.overlay(Layout::new(&node), renderer) { layout::Node::with_children( node.size(), - vec![ - node, - recurse(&mut nested, renderer, bounds, translation), - ], + vec![node, recurse(&mut nested, renderer, bounds)], ) } else { layout::Node::with_children(node.size(), vec![node]) } } - recurse(&mut self.overlay, renderer, bounds, translation) + recurse(&mut self.overlay, renderer, bounds) } /// Draws the [`Nested`] overlay using the associated `Renderer`. diff --git a/runtime/src/user_interface.rs b/runtime/src/user_interface.rs index 054d56b781..08431cedfa 100644 --- a/runtime/src/user_interface.rs +++ b/runtime/src/user_interface.rs @@ -5,9 +5,7 @@ use crate::core::mouse; use crate::core::renderer; use crate::core::widget; use crate::core::window; -use crate::core::{ - Clipboard, Element, Layout, Point, Rectangle, Shell, Size, Vector, -}; +use crate::core::{Clipboard, Element, Layout, Rectangle, Shell, Size, Vector}; use crate::overlay; /// A set of interactive graphical elements with a specific [`Layout`]. @@ -193,7 +191,12 @@ where let mut manual_overlay = ManuallyDrop::new( self.root .as_widget_mut() - .overlay(&mut self.state, Layout::new(&self.base), renderer) + .overlay( + &mut self.state, + Layout::new(&self.base), + renderer, + Vector::ZERO, + ) .map(overlay::Nested::new), ); @@ -201,8 +204,7 @@ where let bounds = self.bounds; let mut overlay = manual_overlay.as_mut().unwrap(); - let mut layout = - overlay.layout(renderer, bounds, Point::ORIGIN, Vector::ZERO); + let mut layout = overlay.layout(renderer, bounds); let mut event_statuses = Vec::new(); for event in events.iter().cloned() { @@ -245,6 +247,7 @@ where &mut self.state, Layout::new(&self.base), renderer, + Vector::ZERO, ) .map(overlay::Nested::new), ); @@ -256,12 +259,7 @@ where overlay = manual_overlay.as_mut().unwrap(); shell.revalidate_layout(|| { - layout = overlay.layout( - renderer, - bounds, - Point::ORIGIN, - Vector::ZERO, - ); + layout = overlay.layout(renderer, bounds); }); } @@ -451,17 +449,18 @@ where let base_cursor = if let Some(mut overlay) = self .root .as_widget_mut() - .overlay(&mut self.state, Layout::new(&self.base), renderer) + .overlay( + &mut self.state, + Layout::new(&self.base), + renderer, + Vector::ZERO, + ) .map(overlay::Nested::new) { - let overlay_layout = self.overlay.take().unwrap_or_else(|| { - overlay.layout( - renderer, - self.bounds, - Point::ORIGIN, - Vector::ZERO, - ) - }); + let overlay_layout = self + .overlay + .take() + .unwrap_or_else(|| overlay.layout(renderer, self.bounds)); let cursor = if cursor .position() @@ -520,7 +519,12 @@ where .as_ref() .and_then(|layout| { root.as_widget_mut() - .overlay(&mut self.state, Layout::new(base), renderer) + .overlay( + &mut self.state, + Layout::new(base), + renderer, + Vector::ZERO, + ) .map(overlay::Nested::new) .map(|mut overlay| { let overlay_interaction = overlay.mouse_interaction( @@ -574,16 +578,16 @@ where if let Some(mut overlay) = self .root .as_widget_mut() - .overlay(&mut self.state, Layout::new(&self.base), renderer) + .overlay( + &mut self.state, + Layout::new(&self.base), + renderer, + Vector::ZERO, + ) .map(overlay::Nested::new) { if self.overlay.is_none() { - self.overlay = Some(overlay.layout( - renderer, - self.bounds, - Point::ORIGIN, - Vector::ZERO, - )); + self.overlay = Some(overlay.layout(renderer, self.bounds)); } overlay.operate( diff --git a/widget/src/button.rs b/widget/src/button.rs index 3b11e8a7aa..d16e8c6787 100644 --- a/widget/src/button.rs +++ b/widget/src/button.rs @@ -11,7 +11,7 @@ use crate::core::widget::tree::{self, Tree}; use crate::core::widget::Operation; use crate::core::{ Background, Clipboard, Color, Element, Layout, Length, Padding, Rectangle, - Shell, Size, Widget, + Shell, Size, Vector, Widget, }; pub use crate::style::button::{Appearance, StyleSheet}; @@ -271,11 +271,13 @@ where tree: &'b mut Tree, layout: Layout<'_>, renderer: &Renderer, + translation: Vector, ) -> Option> { self.content.as_widget_mut().overlay( &mut tree.children[0], layout.children().next().unwrap(), renderer, + translation, ) } } diff --git a/widget/src/column.rs b/widget/src/column.rs index faac0e48d8..1e9841eee8 100644 --- a/widget/src/column.rs +++ b/widget/src/column.rs @@ -7,7 +7,7 @@ use crate::core::renderer; use crate::core::widget::{Operation, Tree}; use crate::core::{ Alignment, Clipboard, Element, Layout, Length, Padding, Pixels, Rectangle, - Shell, Size, Widget, + Shell, Size, Vector, Widget, }; /// A container that distributes its contents vertically. @@ -259,8 +259,15 @@ where tree: &'b mut Tree, layout: Layout<'_>, renderer: &Renderer, + translation: Vector, ) -> Option> { - overlay::from_children(&mut self.children, tree, layout, renderer) + overlay::from_children( + &mut self.children, + tree, + layout, + renderer, + translation, + ) } } diff --git a/widget/src/combo_box.rs b/widget/src/combo_box.rs index 0103e9cd8c..e3862174ad 100644 --- a/widget/src/combo_box.rs +++ b/widget/src/combo_box.rs @@ -10,7 +10,7 @@ use crate::core::text; use crate::core::time::Instant; use crate::core::widget::{self, Widget}; use crate::core::{ - Clipboard, Element, Length, Padding, Rectangle, Shell, Size, + Clipboard, Element, Length, Padding, Rectangle, Shell, Size, Vector, }; use crate::overlay::menu; use crate::text::LineHeight; @@ -657,6 +657,7 @@ where tree: &'b mut widget::Tree, layout: Layout<'_>, _renderer: &Renderer, + translation: Vector, ) -> Option> { let is_focused = { let text_input_state = tree.children[0] @@ -705,7 +706,7 @@ where menu = menu.text_size(size); } - Some(menu.overlay(layout.position(), bounds.height)) + Some(menu.overlay(layout.position() + translation, bounds.height)) } else { None } diff --git a/widget/src/container.rs b/widget/src/container.rs index 78ec19788d..4eb4a5d9bb 100644 --- a/widget/src/container.rs +++ b/widget/src/container.rs @@ -279,11 +279,13 @@ where tree: &'b mut Tree, layout: Layout<'_>, renderer: &Renderer, + translation: Vector, ) -> Option> { self.content.as_widget_mut().overlay( tree, layout.children().next().unwrap(), renderer, + translation, ) } } diff --git a/widget/src/keyed/column.rs b/widget/src/keyed/column.rs index 6203d2c587..88a6e503c8 100644 --- a/widget/src/keyed/column.rs +++ b/widget/src/keyed/column.rs @@ -8,7 +8,7 @@ use crate::core::widget::tree::{self, Tree}; use crate::core::widget::Operation; use crate::core::{ Alignment, Clipboard, Element, Layout, Length, Padding, Pixels, Rectangle, - Shell, Size, Widget, + Shell, Size, Vector, Widget, }; /// A container that distributes its contents vertically. @@ -316,8 +316,15 @@ where tree: &'b mut Tree, layout: Layout<'_>, renderer: &Renderer, + translation: Vector, ) -> Option> { - overlay::from_children(&mut self.children, tree, layout, renderer) + overlay::from_children( + &mut self.children, + tree, + layout, + renderer, + translation, + ) } } diff --git a/widget/src/lazy.rs b/widget/src/lazy.rs index dda6162b27..eb663ea589 100644 --- a/widget/src/lazy.rs +++ b/widget/src/lazy.rs @@ -259,6 +259,7 @@ where tree: &'b mut Tree, layout: Layout<'_>, renderer: &Renderer, + translation: Vector, ) -> Option> { let overlay = Overlay(Some( InnerBuilder { @@ -275,18 +276,14 @@ where overlay_builder: |element, tree| { element .as_widget_mut() - .overlay(tree, layout, renderer) + .overlay(tree, layout, renderer, translation) .map(|overlay| RefCell::new(Nested::new(overlay))) }, } .build(), )); - let has_overlay = - overlay.with_overlay_maybe(|overlay| overlay.position()); - - has_overlay - .map(|position| overlay::Element::new(position, Box::new(overlay))) + Some(overlay::Element::new(Box::new(overlay))) } } @@ -339,17 +336,9 @@ impl<'a, Message, Theme, Renderer> overlay::Overlay where Renderer: core::Renderer, { - fn layout( - &mut self, - renderer: &Renderer, - bounds: Size, - position: Point, - translation: Vector, - ) -> layout::Node { - self.with_overlay_maybe(|overlay| { - overlay.layout(renderer, bounds, position, translation) - }) - .unwrap_or_default() + fn layout(&mut self, renderer: &Renderer, bounds: Size) -> layout::Node { + self.with_overlay_maybe(|overlay| overlay.layout(renderer, bounds)) + .unwrap_or_default() } fn draw( diff --git a/widget/src/lazy/component.rs b/widget/src/lazy/component.rs index 30b1efedd3..edecbdaa6e 100644 --- a/widget/src/lazy/component.rs +++ b/widget/src/lazy/component.rs @@ -462,6 +462,7 @@ where tree: &'b mut Tree, layout: Layout<'_>, renderer: &Renderer, + translation: Vector, ) -> Option> { self.rebuild_element_if_necessary(); let tree = tree @@ -486,6 +487,7 @@ where &mut tree.children[0], layout, renderer, + translation, ) .map(|overlay| { RefCell::new(Nested::new(overlay)) @@ -497,18 +499,9 @@ where .build(), )); - let has_overlay = overlay.0.as_ref().unwrap().with_overlay(|overlay| { - overlay.as_ref().map(|nested| nested.borrow().position()) - }); - - has_overlay.map(|position| { - overlay::Element::new( - position, - Box::new(OverlayInstance { - overlay: Some(overlay), - }), - ) - }) + Some(overlay::Element::new(Box::new(OverlayInstance { + overlay: Some(overlay), + }))) } } @@ -582,17 +575,9 @@ where Renderer: core::Renderer, S: 'static + Default, { - fn layout( - &mut self, - renderer: &Renderer, - bounds: Size, - position: Point, - translation: Vector, - ) -> layout::Node { - self.with_overlay_maybe(|overlay| { - overlay.layout(renderer, bounds, position, translation) - }) - .unwrap_or_default() + fn layout(&mut self, renderer: &Renderer, bounds: Size) -> layout::Node { + self.with_overlay_maybe(|overlay| overlay.layout(renderer, bounds)) + .unwrap_or_default() } fn draw( diff --git a/widget/src/lazy/responsive.rs b/widget/src/lazy/responsive.rs index 9875b24ef0..44312a2158 100644 --- a/widget/src/lazy/responsive.rs +++ b/widget/src/lazy/responsive.rs @@ -279,6 +279,7 @@ where tree: &'b mut Tree, layout: Layout<'_>, renderer: &Renderer, + translation: Vector, ) -> Option> { use std::ops::DerefMut; @@ -309,17 +310,13 @@ where element .as_widget_mut() - .overlay(tree, content_layout, renderer) + .overlay(tree, content_layout, renderer, translation) .map(|overlay| RefCell::new(Nested::new(overlay))) }, } .build(); - let has_overlay = - overlay.with_overlay_maybe(|overlay| overlay.position()); - - has_overlay - .map(|position| overlay::Element::new(position, Box::new(overlay))) + Some(overlay::Element::new(Box::new(overlay))) } } @@ -375,17 +372,9 @@ impl<'a, 'b, Message, Theme, Renderer> where Renderer: core::Renderer, { - fn layout( - &mut self, - renderer: &Renderer, - bounds: Size, - position: Point, - translation: Vector, - ) -> layout::Node { - self.with_overlay_maybe(|overlay| { - overlay.layout(renderer, bounds, position, translation) - }) - .unwrap_or_default() + fn layout(&mut self, renderer: &Renderer, bounds: Size) -> layout::Node { + self.with_overlay_maybe(|overlay| overlay.layout(renderer, bounds)) + .unwrap_or_default() } fn draw( diff --git a/widget/src/mouse_area.rs b/widget/src/mouse_area.rs index 62bb45d827..88f7d1260d 100644 --- a/widget/src/mouse_area.rs +++ b/widget/src/mouse_area.rs @@ -8,7 +8,7 @@ use crate::core::renderer; use crate::core::touch; use crate::core::widget::{tree, Operation, Tree}; use crate::core::{ - Clipboard, Element, Layout, Length, Rectangle, Shell, Size, Widget, + Clipboard, Element, Layout, Length, Rectangle, Shell, Size, Vector, Widget, }; /// Emit messages on mouse events. @@ -217,11 +217,13 @@ where tree: &'b mut Tree, layout: Layout<'_>, renderer: &Renderer, + translation: Vector, ) -> Option> { self.content.as_widget_mut().overlay( &mut tree.children[0], layout, renderer, + translation, ) } } diff --git a/widget/src/overlay/menu.rs b/widget/src/overlay/menu.rs index a7b7ec9406..8a4d6a98cd 100644 --- a/widget/src/overlay/menu.rs +++ b/widget/src/overlay/menu.rs @@ -134,10 +134,11 @@ where position: Point, target_height: f32, ) -> overlay::Element<'a, Message, Theme, Renderer> { - overlay::Element::new( + overlay::Element::new(Box::new(Overlay::new( position, - Box::new(Overlay::new(self, target_height)), - ) + self, + target_height, + ))) } } @@ -167,6 +168,7 @@ where Theme: StyleSheet + container::StyleSheet, Renderer: crate::core::Renderer, { + position: Point, state: &'a mut Tree, container: Container<'a, Message, Theme, Renderer>, width: f32, @@ -181,6 +183,7 @@ where Renderer: text::Renderer + 'a, { pub fn new( + position: Point, menu: Menu<'a, T, Message, Theme, Renderer>, target_height: f32, ) -> Self @@ -218,6 +221,7 @@ where state.tree.diff(&container as &dyn Widget<_, _, _>); Self { + position, state: &mut state.tree, container, width, @@ -234,20 +238,15 @@ where Theme: StyleSheet + container::StyleSheet, Renderer: text::Renderer, { - fn layout( - &mut self, - renderer: &Renderer, - bounds: Size, - position: Point, - _translation: Vector, - ) -> layout::Node { - let space_below = bounds.height - (position.y + self.target_height); - let space_above = position.y; + fn layout(&mut self, renderer: &Renderer, bounds: Size) -> layout::Node { + let space_below = + bounds.height - (self.position.y + self.target_height); + let space_above = self.position.y; let limits = layout::Limits::new( Size::ZERO, Size::new( - bounds.width - position.x, + bounds.width - self.position.x, if space_below > space_above { space_below } else { @@ -261,9 +260,9 @@ where let size = node.size(); node.move_to(if space_below > space_above { - position + Vector::new(0.0, self.target_height) + self.position + Vector::new(0.0, self.target_height) } else { - position - Vector::new(0.0, size.height) + self.position - Vector::new(0.0, size.height) }) } diff --git a/widget/src/pane_grid.rs b/widget/src/pane_grid.rs index c20d959a98..f76c608862 100644 --- a/widget/src/pane_grid.rs +++ b/widget/src/pane_grid.rs @@ -447,6 +447,7 @@ where tree: &'b mut Tree, layout: Layout<'_>, renderer: &Renderer, + translation: Vector, ) -> Option> { let children = self .contents @@ -454,7 +455,7 @@ where .zip(&mut tree.children) .zip(layout.children()) .filter_map(|(((_, content), state), layout)| { - content.overlay(state, layout, renderer) + content.overlay(state, layout, renderer, translation) }) .collect::>(); diff --git a/widget/src/pane_grid/content.rs b/widget/src/pane_grid/content.rs index 415dcc3ef0..dfe0fdcfbd 100644 --- a/widget/src/pane_grid/content.rs +++ b/widget/src/pane_grid/content.rs @@ -5,7 +5,9 @@ use crate::core::mouse; use crate::core::overlay; use crate::core::renderer; use crate::core::widget::{self, Tree}; -use crate::core::{Clipboard, Element, Layout, Point, Rectangle, Shell, Size}; +use crate::core::{ + Clipboard, Element, Layout, Point, Rectangle, Shell, Size, Vector, +}; use crate::pane_grid::{Draggable, TitleBar}; /// The content of a [`Pane`]. @@ -330,6 +332,7 @@ where tree: &'b mut Tree, layout: Layout<'_>, renderer: &Renderer, + translation: Vector, ) -> Option> { if let Some(title_bar) = self.title_bar.as_mut() { let mut children = layout.children(); @@ -339,13 +342,18 @@ where let body_state = states.next().unwrap(); let title_bar_state = states.next().unwrap(); - match title_bar.overlay(title_bar_state, title_bar_layout, renderer) - { + match title_bar.overlay( + title_bar_state, + title_bar_layout, + renderer, + translation, + ) { Some(overlay) => Some(overlay), None => self.body.as_widget_mut().overlay( body_state, children.next()?, renderer, + translation, ), } } else { @@ -353,6 +361,7 @@ where &mut tree.children[0], layout, renderer, + translation, ) } } diff --git a/widget/src/pane_grid/title_bar.rs b/widget/src/pane_grid/title_bar.rs index 3cca6b33da..5b57509b35 100644 --- a/widget/src/pane_grid/title_bar.rs +++ b/widget/src/pane_grid/title_bar.rs @@ -6,7 +6,7 @@ use crate::core::overlay; use crate::core::renderer; use crate::core::widget::{self, Tree}; use crate::core::{ - Clipboard, Element, Layout, Padding, Point, Rectangle, Shell, Size, + Clipboard, Element, Layout, Padding, Point, Rectangle, Shell, Size, Vector, }; /// The title bar of a [`Pane`]. @@ -405,6 +405,7 @@ where tree: &'b mut Tree, layout: Layout<'_>, renderer: &Renderer, + translation: Vector, ) -> Option> { let mut children = layout.children(); let padded = children.next()?; @@ -422,7 +423,7 @@ where content .as_widget_mut() - .overlay(title_state, title_layout, renderer) + .overlay(title_state, title_layout, renderer, translation) .or_else(move || { controls.as_mut().and_then(|controls| { let controls_layout = children.next()?; @@ -431,6 +432,7 @@ where controls_state, controls_layout, renderer, + translation, ) }) }) diff --git a/widget/src/pick_list.rs b/widget/src/pick_list.rs index 70b1d4c07a..475115c2c5 100644 --- a/widget/src/pick_list.rs +++ b/widget/src/pick_list.rs @@ -12,7 +12,7 @@ use crate::core::touch; use crate::core::widget::tree::{self, Tree}; use crate::core::{ Clipboard, Element, Layout, Length, Padding, Pixels, Point, Rectangle, - Shell, Size, Widget, + Shell, Size, Vector, Widget, }; use crate::overlay::menu::{self, Menu}; use crate::scrollable; @@ -265,11 +265,13 @@ where tree: &'b mut Tree, layout: Layout<'_>, renderer: &Renderer, + translation: Vector, ) -> Option> { let state = tree.state.downcast_mut::>(); overlay( layout, + translation, state, self.padding, self.text_size, @@ -573,6 +575,7 @@ pub fn mouse_interaction( /// Returns the current overlay of a [`PickList`]. pub fn overlay<'a, T, Message, Theme, Renderer>( layout: Layout<'_>, + translation: Vector, state: &'a mut State, padding: Padding, text_size: Option, @@ -617,7 +620,7 @@ where menu = menu.text_size(text_size); } - Some(menu.overlay(layout.position(), bounds.height)) + Some(menu.overlay(layout.position() + translation, bounds.height)) } else { None } diff --git a/widget/src/row.rs b/widget/src/row.rs index 89f610c990..7f8c335418 100644 --- a/widget/src/row.rs +++ b/widget/src/row.rs @@ -7,7 +7,7 @@ use crate::core::renderer; use crate::core::widget::{Operation, Tree}; use crate::core::{ Alignment, Clipboard, Element, Length, Padding, Pixels, Rectangle, Shell, - Size, Widget, + Size, Vector, Widget, }; /// A container that distributes its contents horizontally. @@ -248,8 +248,15 @@ where tree: &'b mut Tree, layout: Layout<'_>, renderer: &Renderer, + translation: Vector, ) -> Option> { - overlay::from_children(&mut self.children, tree, layout, renderer) + overlay::from_children( + &mut self.children, + tree, + layout, + renderer, + translation, + ) } } diff --git a/widget/src/scrollable.rs b/widget/src/scrollable.rs index 6e48cd1027..207b2539e1 100644 --- a/widget/src/scrollable.rs +++ b/widget/src/scrollable.rs @@ -385,25 +385,24 @@ where tree: &'b mut Tree, layout: Layout<'_>, renderer: &Renderer, + translation: Vector, ) -> Option> { - self.content - .as_widget_mut() - .overlay( - &mut tree.children[0], - layout.children().next().unwrap(), - renderer, - ) - .map(|overlay| { - let bounds = layout.bounds(); - let content_layout = layout.children().next().unwrap(); - let content_bounds = content_layout.bounds(); - let translation = tree - .state - .downcast_ref::() - .translation(self.direction, bounds, content_bounds); - - overlay.translate(Vector::new(-translation.x, -translation.y)) - }) + let bounds = layout.bounds(); + let content_layout = layout.children().next().unwrap(); + let content_bounds = content_layout.bounds(); + + let offset = tree.state.downcast_ref::().translation( + self.direction, + bounds, + content_bounds, + ); + + self.content.as_widget_mut().overlay( + &mut tree.children[0], + layout.children().next().unwrap(), + renderer, + translation - offset, + ) } } diff --git a/widget/src/themer.rs b/widget/src/themer.rs index ee96a49362..e6ca6cfea2 100644 --- a/widget/src/themer.rs +++ b/widget/src/themer.rs @@ -141,6 +141,7 @@ where tree: &'b mut Tree, layout: Layout<'_>, renderer: &Renderer, + translation: Vector, ) -> Option> { struct Overlay<'a, Message, Theme, Renderer> { theme: &'a Theme, @@ -157,14 +158,8 @@ where &mut self, renderer: &Renderer, bounds: Size, - position: Point, - translation: Vector, ) -> layout::Node { - self.content.layout( - renderer, - bounds, - translation + (position - Point::ORIGIN), - ) + self.content.layout(renderer, bounds) } fn draw( @@ -233,22 +228,18 @@ where theme: self.theme, content, }) - .map(|overlay| { - overlay::Element::new(Point::ORIGIN, Box::new(overlay)) - }) + .map(|overlay| overlay::Element::new(Box::new(overlay))) } } self.content .as_widget_mut() - .overlay(tree, layout, renderer) + .overlay(tree, layout, renderer, translation) .map(|content| Overlay { theme: &self.theme, content, }) - .map(|overlay| { - overlay::Element::new(Point::ORIGIN, Box::new(overlay)) - }) + .map(|overlay| overlay::Element::new(Box::new(overlay))) } } diff --git a/widget/src/tooltip.rs b/widget/src/tooltip.rs index 44cfc4b39e..87bec9323d 100644 --- a/widget/src/tooltip.rs +++ b/widget/src/tooltip.rs @@ -231,6 +231,7 @@ where tree: &'b mut widget::Tree, layout: Layout<'_>, renderer: &Renderer, + translation: Vector, ) -> Option> { let state = tree.state.downcast_ref::(); @@ -240,23 +241,22 @@ where children.next().unwrap(), layout, renderer, + translation, ); let tooltip = if let State::Hovered { cursor_position } = *state { - Some(overlay::Element::new( - layout.position(), - Box::new(Overlay { - tooltip: &self.tooltip, - state: children.next().unwrap(), - cursor_position, - content_bounds: layout.bounds(), - snap_within_viewport: self.snap_within_viewport, - position: self.position, - gap: self.gap, - padding: self.padding, - style: &self.style, - }), - )) + Some(overlay::Element::new(Box::new(Overlay { + position: layout.position() + translation, + tooltip: &self.tooltip, + state: children.next().unwrap(), + cursor_position, + content_bounds: layout.bounds(), + snap_within_viewport: self.snap_within_viewport, + positioning: self.position, + gap: self.gap, + padding: self.padding, + style: &self.style, + }))) } else { None }; @@ -317,12 +317,13 @@ where Theme: container::StyleSheet + widget::text::StyleSheet, Renderer: text::Renderer, { + position: Point, tooltip: &'b Text<'a, Theme, Renderer>, state: &'b mut widget::Tree, cursor_position: Point, content_bounds: Rectangle, snap_within_viewport: bool, - position: Position, + positioning: Position, gap: f32, padding: f32, style: &'b ::Style, @@ -335,13 +336,7 @@ where Theme: container::StyleSheet + widget::text::StyleSheet, Renderer: text::Renderer, { - fn layout( - &mut self, - renderer: &Renderer, - bounds: Size, - position: Point, - _translation: Vector, - ) -> layout::Node { + fn layout(&mut self, renderer: &Renderer, bounds: Size) -> layout::Node { let viewport = Rectangle::with_size(bounds); let text_layout = Widget::<(), Theme, Renderer>::layout( @@ -358,37 +353,44 @@ where ); let text_bounds = text_layout.bounds(); - let x_center = - position.x + (self.content_bounds.width - text_bounds.width) / 2.0; - let y_center = position.y + let x_center = self.position.x + + (self.content_bounds.width - text_bounds.width) / 2.0; + let y_center = self.position.y + (self.content_bounds.height - text_bounds.height) / 2.0; let mut tooltip_bounds = { - let offset = match self.position { + let offset = match self.positioning { Position::Top => Vector::new( x_center, - position.y - text_bounds.height - self.gap - self.padding, + self.position.y + - text_bounds.height + - self.gap + - self.padding, ), Position::Bottom => Vector::new( x_center, - position.y + self.position.y + self.content_bounds.height + self.gap + self.padding, ), Position::Left => Vector::new( - position.x - text_bounds.width - self.gap - self.padding, + self.position.x + - text_bounds.width + - self.gap + - self.padding, y_center, ), Position::Right => Vector::new( - position.x + self.position.x + self.content_bounds.width + self.gap + self.padding, y_center, ), Position::FollowCursor => { - let translation = position - self.content_bounds.position(); + let translation = + self.position - self.content_bounds.position(); Vector::new( self.cursor_position.x,