diff --git a/core/src/overlay.rs b/core/src/overlay.rs index 6027d4c7e1..11360abc04 100644 --- a/core/src/overlay.rs +++ b/core/src/overlay.rs @@ -10,8 +10,9 @@ use crate::mouse; use crate::renderer; use crate::widget; use crate::widget::Tree; -use crate::{layout, IME}; -use crate::{Clipboard, Layout, Point, Rectangle, Shell, Size}; +use crate::{ + layout, Clipboard, Layout, Point, Rectangle, Shell, Size, Vector, IME, +}; /// An interactive component that can be displayed on top of other widgets. pub trait Overlay @@ -29,6 +30,7 @@ where renderer: &Renderer, bounds: Size, position: Point, + translation: Vector, ) -> layout::Node; /// Draws the [`Overlay`] using the associated `Renderer`. diff --git a/core/src/overlay/element.rs b/core/src/overlay/element.rs index 863a161fd6..691e2672b2 100644 --- a/core/src/overlay/element.rs +++ b/core/src/overlay/element.rs @@ -13,6 +13,7 @@ use std::any::Any; #[allow(missing_debug_implementations)] pub struct Element<'a, Message, Renderer> { position: Point, + translation: Vector, overlay: Box + 'a>, } @@ -25,7 +26,11 @@ where position: Point, overlay: Box + 'a>, ) -> Self { - Self { position, overlay } + Self { + position, + overlay, + translation: Vector::ZERO, + } } /// Returns the position of the [`Element`]. @@ -36,6 +41,7 @@ where /// Translates the [`Element`]. pub fn translate(mut self, translation: Vector) -> Self { self.position = self.position + translation; + self.translation = self.translation + translation; self } @@ -48,6 +54,7 @@ where { Element { position: self.position, + translation: self.translation, overlay: Box::new(Map::new(self.overlay, f)), } } @@ -59,8 +66,12 @@ where bounds: Size, translation: Vector, ) -> layout::Node { - self.overlay - .layout(renderer, bounds, self.position + translation) + self.overlay.layout( + renderer, + bounds, + self.position + translation, + self.translation + translation, + ) } /// Processes a runtime [`Event`]. @@ -155,8 +166,9 @@ where renderer: &Renderer, bounds: Size, position: Point, + translation: Vector, ) -> layout::Node { - self.content.layout(renderer, bounds, position) + self.content.layout(renderer, bounds, position, translation) } fn operate( diff --git a/core/src/overlay/group.rs b/core/src/overlay/group.rs index d0b87f934b..2932573665 100644 --- a/core/src/overlay/group.rs +++ b/core/src/overlay/group.rs @@ -4,8 +4,11 @@ use crate::mouse; use crate::overlay; use crate::renderer; use crate::widget; -use crate::IME; -use crate::{Clipboard, Event, Layout, Overlay, Point, Rectangle, Shell, Size}; + +use crate::{ + Clipboard, Event, Layout, Overlay, Point, Rectangle, Shell, Size, Vector, + IME, +}; /// An [`Overlay`] container that displays multiple overlay [`overlay::Element`] /// children. @@ -65,10 +68,9 @@ where &mut self, renderer: &Renderer, bounds: Size, - position: Point, + _position: Point, + translation: Vector, ) -> layout::Node { - let translation = position - Point::ORIGIN; - layout::Node::with_children( bounds, self.children diff --git a/examples/modal/src/main.rs b/examples/modal/src/main.rs index 9bb90ab021..785972647d 100644 --- a/examples/modal/src/main.rs +++ b/examples/modal/src/main.rs @@ -231,6 +231,7 @@ mod modal { use iced::mouse; use iced::{ BorderRadius, Color, Element, Event, Length, Point, Rectangle, Size, + Vector, }; /// A widget that centers a modal element over some base element @@ -415,6 +416,7 @@ mod modal { renderer: &Renderer, _bounds: Size, position: Point, + _translation: Vector, ) -> layout::Node { let limits = layout::Limits::new(Size::ZERO, self.size) .width(Length::Fill) diff --git a/examples/progress_bar/README.md b/examples/progress_bar/README.md index 1268ac6bee..a87829c627 100644 --- a/examples/progress_bar/README.md +++ b/examples/progress_bar/README.md @@ -5,7 +5,7 @@ A simple progress bar that can be filled by using a slider. The __[`main`]__ file contains all the code of the example.
- +
You can run it with `cargo run`: diff --git a/examples/toast/src/main.rs b/examples/toast/src/main.rs index 8935a9147f..3dd8c1f9af 100644 --- a/examples/toast/src/main.rs +++ b/examples/toast/src/main.rs @@ -513,6 +513,7 @@ mod toast { renderer: &Renderer, bounds: Size, position: Point, + _translation: Vector, ) -> layout::Node { let limits = layout::Limits::new(Size::ZERO, bounds) .width(Length::Fill) diff --git a/runtime/src/overlay/nested.rs b/runtime/src/overlay/nested.rs index 323423d2f6..805a015adf 100644 --- a/runtime/src/overlay/nested.rs +++ b/runtime/src/overlay/nested.rs @@ -6,7 +6,9 @@ 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, Point, Rectangle, Shell, Size, Vector, +}; /// An overlay container that displays nested overlays #[allow(missing_debug_implementations)] @@ -35,19 +37,18 @@ where &mut self, renderer: &Renderer, bounds: Size, - position: Point, + _position: Point, + translation: Vector, ) -> layout::Node { fn recurse( element: &mut overlay::Element<'_, Message, Renderer>, renderer: &Renderer, bounds: Size, - position: Point, + translation: Vector, ) -> layout::Node where Renderer: renderer::Renderer, { - let translation = position - Point::ORIGIN; - let node = element.layout(renderer, bounds, translation); if let Some(mut nested) = @@ -57,7 +58,7 @@ where node.size(), vec![ node, - recurse(&mut nested, renderer, bounds, position), + recurse(&mut nested, renderer, bounds, translation), ], ) } else { @@ -65,7 +66,7 @@ where } } - recurse(&mut self.overlay, renderer, bounds, position) + recurse(&mut self.overlay, renderer, bounds, translation) } /// Draws the [`Nested`] overlay using the associated `Renderer`. diff --git a/runtime/src/user_interface.rs b/runtime/src/user_interface.rs index 83d682c728..0ad928592e 100644 --- a/runtime/src/user_interface.rs +++ b/runtime/src/user_interface.rs @@ -7,7 +7,9 @@ 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}; +use crate::core::{ + Clipboard, Element, Layout, Point, Rectangle, Shell, Size, Vector, +}; use crate::overlay; /// A set of interactive graphical elements with a specific [`Layout`]. @@ -202,7 +204,8 @@ where let bounds = self.bounds; let mut overlay = manual_overlay.as_mut().unwrap(); - let mut layout = overlay.layout(renderer, bounds, Point::ORIGIN); + let mut layout = + overlay.layout(renderer, bounds, Point::ORIGIN, Vector::ZERO); let mut event_statuses = Vec::new(); for event in events.iter().cloned() { @@ -257,8 +260,12 @@ where overlay = manual_overlay.as_mut().unwrap(); shell.revalidate_layout(|| { - layout = - overlay.layout(renderer, bounds, Point::ORIGIN); + layout = overlay.layout( + renderer, + bounds, + Point::ORIGIN, + Vector::ZERO, + ); }); } @@ -456,7 +463,12 @@ where .map(overlay::Nested::new) { let overlay_layout = self.overlay.take().unwrap_or_else(|| { - overlay.layout(renderer, self.bounds, Point::ORIGIN) + overlay.layout( + renderer, + self.bounds, + Point::ORIGIN, + Vector::ZERO, + ) }); let cursor = if cursor @@ -574,8 +586,12 @@ where .map(overlay::Nested::new) { if self.overlay.is_none() { - self.overlay = - Some(overlay.layout(renderer, self.bounds, Point::ORIGIN)); + self.overlay = Some(overlay.layout( + renderer, + self.bounds, + Point::ORIGIN, + Vector::ZERO, + )); } overlay.operate( diff --git a/widget/src/lazy.rs b/widget/src/lazy.rs index 2a8351d2fe..87b3f4ad49 100644 --- a/widget/src/lazy.rs +++ b/widget/src/lazy.rs @@ -18,7 +18,7 @@ use crate::core::widget::tree::{self, Tree}; use crate::core::widget::{self, Widget}; use crate::core::Element; use crate::core::{ - self, Clipboard, Hasher, Length, Point, Rectangle, Shell, Size, IME, + self, Clipboard, Hasher, Length, Point, Rectangle, Shell, Size, Vector, IME, }; use crate::runtime::overlay::Nested; @@ -335,9 +335,10 @@ where renderer: &Renderer, bounds: Size, position: Point, + translation: Vector, ) -> layout::Node { self.with_overlay_maybe(|overlay| { - overlay.layout(renderer, bounds, position) + overlay.layout(renderer, bounds, position, translation) }) .unwrap_or_default() } diff --git a/widget/src/lazy/component.rs b/widget/src/lazy/component.rs index a9da38d17a..181e646d61 100644 --- a/widget/src/lazy/component.rs +++ b/widget/src/lazy/component.rs @@ -579,9 +579,10 @@ where renderer: &Renderer, bounds: Size, position: Point, + translation: Vector, ) -> layout::Node { self.with_overlay_maybe(|overlay| { - overlay.layout(renderer, bounds, position) + overlay.layout(renderer, bounds, position, translation) }) .unwrap_or_default() } diff --git a/widget/src/lazy/responsive.rs b/widget/src/lazy/responsive.rs index 954b3f490f..b6039afd94 100644 --- a/widget/src/lazy/responsive.rs +++ b/widget/src/lazy/responsive.rs @@ -6,8 +6,8 @@ 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, Widget, - IME, + self, Clipboard, Element, Length, Point, Rectangle, Shell, Size, Vector, + Widget, IME, }; use crate::horizontal_space; use crate::runtime::overlay::Nested; @@ -370,9 +370,10 @@ where renderer: &Renderer, bounds: Size, position: Point, + translation: Vector, ) -> layout::Node { self.with_overlay_maybe(|overlay| { - overlay.layout(renderer, bounds, position) + overlay.layout(renderer, bounds, position, translation) }) .unwrap_or_default() } diff --git a/widget/src/overlay/menu.rs b/widget/src/overlay/menu.rs index a485062bc1..f4d91317b9 100644 --- a/widget/src/overlay/menu.rs +++ b/widget/src/overlay/menu.rs @@ -237,6 +237,7 @@ where 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; diff --git a/widget/src/tooltip.rs b/widget/src/tooltip.rs index c37479736e..b3b7a29abc 100644 --- a/widget/src/tooltip.rs +++ b/widget/src/tooltip.rs @@ -160,11 +160,19 @@ where ) -> event::Status { let state = tree.state.downcast_mut::(); + let was_idle = *state == State::Idle; + *state = cursor .position_over(layout.bounds()) .map(|cursor_position| State::Hovered { cursor_position }) .unwrap_or_default(); + let is_idle = *state == State::Idle; + + if was_idle != is_idle { + shell.invalidate_layout(); + } + self.content.as_widget_mut().on_event( &mut tree.children[0], event, @@ -293,7 +301,7 @@ pub enum Position { Right, } -#[derive(Debug, Clone, Copy, Default)] +#[derive(Debug, Clone, Copy, PartialEq, Default)] enum State { #[default] Idle, @@ -329,6 +337,7 @@ where renderer: &Renderer, bounds: Size, position: Point, + _translation: Vector, ) -> layout::Node { let viewport = Rectangle::with_size(bounds);