diff --git a/Cargo.toml b/Cargo.toml index f9680441..051e0581 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -114,7 +114,7 @@ members = [ [workspace.dependencies.iced] git = "https://github.com/iced-rs/iced.git" #rev = "8221794" -version = "0.9.0" +#version = "0.9.0" features = ["advanced", "lazy"] [workspace.dependencies.iced_aw] diff --git a/examples/floating_element/src/main.rs b/examples/floating_element/src/main.rs index 707febd5..753f82ee 100644 --- a/examples/floating_element/src/main.rs +++ b/examples/floating_element/src/main.rs @@ -59,7 +59,7 @@ impl Application for FloatingElementExample { match self { FloatingElementExample::Loading => { if let Message::Loaded(_) = message { - *self = FloatingElementExample::Loaded(State { lines: (0..3000).into_iter().map(|_| "This is a newly added line.".into()).collect() }) + *self = FloatingElementExample::Loaded(State { lines: (0..3000).map(|_| "This is a newly added line.".into()).collect() }) } } FloatingElementExample::Loaded(State { lines }) => { diff --git a/src/native/floating_element.rs b/src/native/floating_element.rs index 1d868f83..98355cc5 100644 --- a/src/native/floating_element.rs +++ b/src/native/floating_element.rs @@ -7,7 +7,7 @@ use iced_widget::core::{ mouse::{self, Cursor}, overlay, renderer, widget::{Operation, Tree}, - Clipboard, Element, Event, Layout, Length, Point, Rectangle, Shell, Widget, + Clipboard, Element, Event, Layout, Length, Rectangle, Shell, Widget, }; pub mod anchor; @@ -222,26 +222,14 @@ where if state.children.len() == 2 { let bounds = layout.bounds(); - let offset = match self.anchor { - Anchor::NorthWest => Point::new(0.0, 0.0), - Anchor::NorthEast => Point::new(bounds.width, 0.0), - Anchor::SouthWest => Point::new(0.0, bounds.height), - Anchor::SouthEast => Point::new(bounds.width, bounds.height), - Anchor::North => Point::new(bounds.width / 2.0, 0.0), - Anchor::East => Point::new(bounds.width, bounds.height / 2.0), - Anchor::South => Point::new(bounds.width / 2.0, bounds.height), - Anchor::West => Point::new(0.0, bounds.height / 2.0), - }; - - let position = Point::new(bounds.x + offset.x, bounds.y + offset.y); - Some(overlay::Element::new( - position, + bounds.position(), Box::new(FloatingElementOverlay::new( &mut state.children[1], &mut self.element, &self.anchor, &self.offset, + bounds, )), )) } else { diff --git a/src/native/overlay/floating_element.rs b/src/native/overlay/floating_element.rs index 3a59effe..361cb3c9 100644 --- a/src/native/overlay/floating_element.rs +++ b/src/native/overlay/floating_element.rs @@ -7,7 +7,7 @@ use iced_widget::core::{ mouse::{self, Cursor}, overlay, renderer, widget::Tree, - Clipboard, Element, Event, Layout, Point, Rectangle, Shell, Size, + Clipboard, Element, Event, Layout, Length, Point, Rectangle, Shell, Size }; use crate::native::floating_element::{Anchor, Offset}; @@ -24,6 +24,8 @@ pub struct FloatingElementOverlay<'a, 'b, Message, Renderer: core::Renderer> { anchor: &'b Anchor, /// The offset of the element. offset: &'b Offset, + /// The bounds of the underlay element. + underlay_bounds: Rectangle, } impl<'a, 'b, Message, Renderer> FloatingElementOverlay<'a, 'b, Message, Renderer> @@ -37,12 +39,14 @@ where element: &'b mut Element<'a, Message, Renderer>, anchor: &'b Anchor, offset: &'b Offset, + underlay_bounds: Rectangle, ) -> Self { FloatingElementOverlay { state, element, anchor, offset, + underlay_bounds, } } } @@ -52,68 +56,49 @@ impl<'a, 'b, Message, Renderer> core::Overlay where Renderer: core::Renderer, { - fn layout(&self, renderer: &Renderer, bounds: Size, position: Point) -> layout::Node { - let limits = layout::Limits::new(Size::ZERO, bounds); - let element = self.element.as_widget().layout(renderer, &limits); - - let size = match self.anchor { - Anchor::NorthWest | Anchor::North => Size::new( - position.x + self.offset.x + element.bounds().width, - position.y + self.offset.y + element.bounds().height, - ), - Anchor::NorthEast => Size::new( - position.x - self.offset.x, - position.y + self.offset.y + element.bounds().height, - ), - Anchor::SouthWest | Anchor::South => Size::new( - position.x + self.offset.x + element.bounds().width, - position.y - self.offset.y, - ), - Anchor::SouthEast => Size::new(position.x - self.offset.x, position.y - self.offset.y), - Anchor::East => Size::new( - position.x - self.offset.x, - position.y + element.bounds().height / 2.0, - ), - Anchor::West => Size::new( - position.x + self.offset.x + element.bounds().width, - position.y + element.bounds().height / 2.0, - ), - }; + fn layout(&self, renderer: &Renderer, _bounds: Size, position: Point) -> layout::Node { + // Constrain overlay to fit inside the underlay's bounds + let limits = layout::Limits::new(Size::ZERO, self.underlay_bounds.size()) + .width(Length::Fill) + .height(Length::Fill); + let mut node = self.element.as_widget().layout(renderer, &limits); let position = match self.anchor { Anchor::NorthWest => Point::new(position.x + self.offset.x, position.y + self.offset.y), Anchor::NorthEast => Point::new( - position.x - element.bounds().width - self.offset.x, - position.y + self.offset.y, + position.x + self.underlay_bounds.width - node.bounds().width - self.offset.x, + position.y + self.offset.y, ), Anchor::SouthWest => Point::new( position.x + self.offset.x, - position.y - element.bounds().height - self.offset.y, + position.y + self.underlay_bounds.height - node.bounds().height - self.offset.y, ), Anchor::SouthEast => Point::new( - position.x - element.bounds().width - self.offset.x, - position.y - element.bounds().height - self.offset.y, + position.x + self.underlay_bounds.width - node.bounds().width - self.offset.x, + position.y + self.underlay_bounds.height - node.bounds().height - self.offset.y, ), Anchor::North => Point::new( - position.x + self.offset.x - element.bounds().width / 2.0, + position.x + self.underlay_bounds.width / 2.0 - node.bounds().width / 2.0 + + self.offset.x, position.y + self.offset.y, ), Anchor::East => Point::new( - position.x - element.bounds().width - self.offset.x, - position.y - element.bounds().height / 2.0, + position.x + self.underlay_bounds.width - node.bounds().width - self.offset.x, + position.y + self.underlay_bounds.height / 2.0 - node.bounds().height / 2.0 + + self.offset.y, ), Anchor::South => Point::new( - position.x + self.offset.x - element.bounds().width / 2.0, - position.y - element.bounds().height - self.offset.y, + position.x + self.underlay_bounds.width / 2.0 - node.bounds().width / 2.0 + + self.offset.x, + position.y + self.underlay_bounds.height - node.bounds().height - self.offset.y, ), Anchor::West => Point::new( position.x + self.offset.x, - position.y - element.bounds().height / 2.0, + position.y + self.underlay_bounds.height / 2.0 - node.bounds().height / 2.0 + + self.offset.y, ), }; - //element.move_to(position); - let mut node = layout::Node::with_children(size, vec![element]); node.move_to(position); node } @@ -130,10 +115,7 @@ where self.element.as_widget_mut().on_event( self.state, event, - layout - .children() - .next() - .expect("Native: Layout should have a content layout."), + layout, cursor, renderer, clipboard, @@ -151,10 +133,7 @@ where ) -> mouse::Interaction { self.element.as_widget().mouse_interaction( self.state, - layout - .children() - .next() - .expect("Native: Layout should have a content layout."), + layout, cursor, viewport, renderer, @@ -175,10 +154,7 @@ where renderer, theme, style, - layout - .children() - .next() - .expect("Native: Layout should have a content layout."), + layout, cursor, &bounds, ); @@ -191,6 +167,6 @@ where ) -> Option> { self.element .as_widget_mut() - .overlay(self.state, layout.children().next()?, renderer) + .overlay(self.state, layout, renderer) } }