Remove position from overlay::Element

This commit is contained in:
Héctor Ramón Jiménez 2024-02-01 01:08:21 +01:00
parent 7bbe450217
commit 738aa47547
No known key found for this signature in database
GPG key ID: 7CC46565708259A7
27 changed files with 230 additions and 283 deletions

View file

@ -446,11 +446,12 @@ where
tree: &'b mut Tree, tree: &'b mut Tree,
layout: Layout<'_>, layout: Layout<'_>,
renderer: &Renderer, renderer: &Renderer,
translation: Vector,
) -> Option<overlay::Element<'b, B, Theme, Renderer>> { ) -> Option<overlay::Element<'b, B, Theme, Renderer>> {
let mapper = &self.mapper; let mapper = &self.mapper;
self.widget self.widget
.overlay(tree, layout, renderer) .overlay(tree, layout, renderer, translation)
.map(move |overlay| overlay.map(mapper)) .map(move |overlay| overlay.map(mapper))
} }
} }
@ -596,7 +597,10 @@ where
state: &'b mut Tree, state: &'b mut Tree,
layout: Layout<'_>, layout: Layout<'_>,
renderer: &Renderer, renderer: &Renderer,
translation: Vector,
) -> Option<overlay::Element<'b, Message, Theme, Renderer>> { ) -> Option<overlay::Element<'b, Message, Theme, Renderer>> {
self.element.widget.overlay(state, layout, renderer) self.element
.widget
.overlay(state, layout, renderer, translation)
} }
} }

View file

@ -24,13 +24,7 @@ where
/// user interface. /// user interface.
/// ///
/// [`Node`]: layout::Node /// [`Node`]: layout::Node
fn layout( fn layout(&mut self, renderer: &Renderer, bounds: Size) -> layout::Node;
&mut self,
renderer: &Renderer,
bounds: Size,
position: Point,
translation: Vector,
) -> layout::Node;
/// Draws the [`Overlay`] using the associated `Renderer`. /// Draws the [`Overlay`] using the associated `Renderer`.
fn draw( fn draw(
@ -120,6 +114,7 @@ pub fn from_children<'a, Message, Theme, Renderer>(
tree: &'a mut Tree, tree: &'a mut Tree,
layout: Layout<'_>, layout: Layout<'_>,
renderer: &Renderer, renderer: &Renderer,
translation: Vector,
) -> Option<Element<'a, Message, Theme, Renderer>> ) -> Option<Element<'a, Message, Theme, Renderer>>
where where
Renderer: crate::Renderer, Renderer: crate::Renderer,
@ -129,7 +124,9 @@ where
.zip(&mut tree.children) .zip(&mut tree.children)
.zip(layout.children()) .zip(layout.children())
.filter_map(|((child, state), layout)| { .filter_map(|((child, state), layout)| {
child.as_widget_mut().overlay(state, layout, renderer) child
.as_widget_mut()
.overlay(state, layout, renderer, translation)
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();

View file

@ -12,8 +12,6 @@ use std::any::Any;
/// A generic [`Overlay`]. /// A generic [`Overlay`].
#[allow(missing_debug_implementations)] #[allow(missing_debug_implementations)]
pub struct Element<'a, Message, Theme, Renderer> { pub struct Element<'a, Message, Theme, Renderer> {
position: Point,
translation: Vector,
overlay: Box<dyn Overlay<Message, Theme, Renderer> + 'a>, overlay: Box<dyn Overlay<Message, Theme, Renderer> + 'a>,
} }
@ -23,26 +21,9 @@ where
{ {
/// Creates a new [`Element`] containing the given [`Overlay`]. /// Creates a new [`Element`] containing the given [`Overlay`].
pub fn new( pub fn new(
position: Point,
overlay: Box<dyn Overlay<Message, Theme, Renderer> + 'a>, overlay: Box<dyn Overlay<Message, Theme, Renderer> + 'a>,
) -> Self { ) -> Self {
Self { Self { overlay }
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
} }
/// Applies a transformation to the produced message of the [`Element`]. /// Applies a transformation to the produced message of the [`Element`].
@ -57,8 +38,6 @@ where
B: 'a, B: 'a,
{ {
Element { Element {
position: self.position,
translation: self.translation,
overlay: Box::new(Map::new(self.overlay, f)), overlay: Box::new(Map::new(self.overlay, f)),
} }
} }
@ -68,14 +47,8 @@ where
&mut self, &mut self,
renderer: &Renderer, renderer: &Renderer,
bounds: Size, bounds: Size,
translation: Vector,
) -> layout::Node { ) -> layout::Node {
self.overlay.layout( self.overlay.layout(renderer, bounds)
renderer,
bounds,
self.position + translation,
self.translation + translation,
)
} }
/// Processes a runtime [`Event`]. /// Processes a runtime [`Event`].
@ -165,14 +138,8 @@ impl<'a, A, B, Theme, Renderer> Overlay<B, Theme, Renderer>
where where
Renderer: crate::Renderer, Renderer: crate::Renderer,
{ {
fn layout( fn layout(&mut self, renderer: &Renderer, bounds: Size) -> layout::Node {
&mut self, self.content.layout(renderer, bounds)
renderer: &Renderer,
bounds: Size,
position: Point,
translation: Vector,
) -> layout::Node {
self.content.layout(renderer, bounds, position, translation)
} }
fn operate( fn operate(

View file

@ -4,9 +4,7 @@ use crate::mouse;
use crate::overlay; use crate::overlay;
use crate::renderer; use crate::renderer;
use crate::widget; use crate::widget;
use crate::{ use crate::{Clipboard, Event, Layout, Overlay, Point, Rectangle, Shell, Size};
Clipboard, Event, Layout, Overlay, Point, Rectangle, Shell, Size, Vector,
};
/// An [`Overlay`] container that displays multiple overlay [`overlay::Element`] /// An [`Overlay`] container that displays multiple overlay [`overlay::Element`]
/// children. /// children.
@ -44,7 +42,7 @@ where
/// Turns the [`Group`] into an overlay [`overlay::Element`]. /// Turns the [`Group`] into an overlay [`overlay::Element`].
pub fn overlay(self) -> overlay::Element<'a, Message, Theme, Renderer> { 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<Message, Theme, Renderer>
where where
Renderer: crate::Renderer, Renderer: crate::Renderer,
{ {
fn layout( fn layout(&mut self, renderer: &Renderer, bounds: Size) -> layout::Node {
&mut self,
renderer: &Renderer,
bounds: Size,
_position: Point,
translation: Vector,
) -> layout::Node {
layout::Node::with_children( layout::Node::with_children(
bounds, bounds,
self.children self.children
.iter_mut() .iter_mut()
.map(|child| child.layout(renderer, bounds, translation)) .map(|child| child.layout(renderer, bounds))
.collect(), .collect(),
) )
} }

View file

@ -15,7 +15,7 @@ use crate::layout::{self, Layout};
use crate::mouse; use crate::mouse;
use crate::overlay; use crate::overlay;
use crate::renderer; 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. /// A component that displays information and allows interaction.
/// ///
@ -146,6 +146,7 @@ where
_state: &'a mut Tree, _state: &'a mut Tree,
_layout: Layout<'_>, _layout: Layout<'_>,
_renderer: &Renderer, _renderer: &Renderer,
_translation: Vector,
) -> Option<overlay::Element<'a, Message, Theme, Renderer>> { ) -> Option<overlay::Element<'a, Message, Theme, Renderer>> {
None None
} }

View file

@ -346,16 +346,15 @@ mod modal {
state: &'b mut widget::Tree, state: &'b mut widget::Tree,
layout: Layout<'_>, layout: Layout<'_>,
_renderer: &Renderer, _renderer: &Renderer,
translation: Vector,
) -> Option<overlay::Element<'b, Message, Theme, Renderer>> { ) -> Option<overlay::Element<'b, Message, Theme, Renderer>> {
Some(overlay::Element::new( Some(overlay::Element::new(Box::new(Overlay {
layout.position(), position: layout.position() + translation,
Box::new(Overlay { content: &mut self.modal,
content: &mut self.modal, tree: &mut state.children[1],
tree: &mut state.children[1], size: layout.bounds().size(),
size: layout.bounds().size(), on_blur: self.on_blur.clone(),
on_blur: self.on_blur.clone(), })))
}),
))
} }
fn mouse_interaction( fn mouse_interaction(
@ -392,6 +391,7 @@ mod modal {
} }
struct Overlay<'a, 'b, Message, Theme, Renderer> { struct Overlay<'a, 'b, Message, Theme, Renderer> {
position: Point,
content: &'b mut Element<'a, Message, Theme, Renderer>, content: &'b mut Element<'a, Message, Theme, Renderer>,
tree: &'b mut widget::Tree, tree: &'b mut widget::Tree,
size: Size, size: Size,
@ -409,8 +409,6 @@ mod modal {
&mut self, &mut self,
renderer: &Renderer, renderer: &Renderer,
_bounds: Size, _bounds: Size,
position: Point,
_translation: Vector,
) -> layout::Node { ) -> layout::Node {
let limits = layout::Limits::new(Size::ZERO, self.size) let limits = layout::Limits::new(Size::ZERO, self.size)
.width(Length::Fill) .width(Length::Fill)
@ -423,7 +421,7 @@ mod modal {
.align(Alignment::Center, Alignment::Center, limits.max()); .align(Alignment::Center, Alignment::Center, limits.max());
layout::Node::with_children(self.size, vec![child]) layout::Node::with_children(self.size, vec![child])
.move_to(position) .move_to(self.position)
} }
fn on_event( fn on_event(
@ -530,6 +528,7 @@ mod modal {
self.tree, self.tree,
layout.children().next().unwrap(), layout.children().next().unwrap(),
renderer, renderer,
Vector::ZERO,
) )
} }
} }

View file

@ -456,6 +456,7 @@ mod toast {
state: &'b mut Tree, state: &'b mut Tree,
layout: Layout<'_>, layout: Layout<'_>,
renderer: &Renderer, renderer: &Renderer,
translation: Vector,
) -> Option<overlay::Element<'b, Message, Theme, Renderer>> { ) -> Option<overlay::Element<'b, Message, Theme, Renderer>> {
let instants = state.state.downcast_mut::<Vec<Option<Instant>>>(); let instants = state.state.downcast_mut::<Vec<Option<Instant>>>();
@ -465,19 +466,18 @@ mod toast {
&mut content_state[0], &mut content_state[0],
layout, layout,
renderer, renderer,
translation,
); );
let toasts = (!self.toasts.is_empty()).then(|| { let toasts = (!self.toasts.is_empty()).then(|| {
overlay::Element::new( overlay::Element::new(Box::new(Overlay {
layout.bounds().position(), position: layout.bounds().position() + translation,
Box::new(Overlay { toasts: &mut self.toasts,
toasts: &mut self.toasts, state: toasts_state,
state: toasts_state, instants,
instants, on_close: &self.on_close,
on_close: &self.on_close, timeout_secs: self.timeout_secs,
timeout_secs: self.timeout_secs, }))
}),
)
}); });
let overlays = let overlays =
content.into_iter().chain(toasts).collect::<Vec<_>>(); content.into_iter().chain(toasts).collect::<Vec<_>>();
@ -488,6 +488,7 @@ mod toast {
} }
struct Overlay<'a, 'b, Message> { struct Overlay<'a, 'b, Message> {
position: Point,
toasts: &'b mut [Element<'a, Message>], toasts: &'b mut [Element<'a, Message>],
state: &'b mut [Tree], state: &'b mut [Tree],
instants: &'b mut [Option<Instant>], instants: &'b mut [Option<Instant>],
@ -502,8 +503,6 @@ mod toast {
&mut self, &mut self,
renderer: &Renderer, renderer: &Renderer,
bounds: Size, bounds: Size,
position: Point,
_translation: Vector,
) -> layout::Node { ) -> layout::Node {
let limits = layout::Limits::new(Size::ZERO, bounds); let limits = layout::Limits::new(Size::ZERO, bounds);
@ -519,7 +518,7 @@ mod toast {
self.toasts, self.toasts,
self.state, self.state,
) )
.translate(Vector::new(position.x, position.y)) .translate(Vector::new(self.position.x, self.position.y))
} }
fn on_event( fn on_event(

View file

@ -4,9 +4,7 @@ use crate::core::mouse;
use crate::core::overlay; use crate::core::overlay;
use crate::core::renderer; use crate::core::renderer;
use crate::core::widget; use crate::core::widget;
use crate::core::{ use crate::core::{Clipboard, Event, Layout, Point, Rectangle, Shell, Size};
Clipboard, Event, Layout, Point, Rectangle, Shell, Size, Vector,
};
/// An overlay container that displays nested overlays /// An overlay container that displays nested overlays
#[allow(missing_debug_implementations)] #[allow(missing_debug_implementations)]
@ -25,11 +23,6 @@ where
Self { overlay: element } 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. /// Returns the layout [`Node`] of the [`Nested`] overlay.
/// ///
/// [`Node`]: layout::Node /// [`Node`]: layout::Node
@ -37,36 +30,30 @@ where
&mut self, &mut self,
renderer: &Renderer, renderer: &Renderer,
bounds: Size, bounds: Size,
_position: Point,
translation: Vector,
) -> layout::Node { ) -> layout::Node {
fn recurse<Message, Theme, Renderer>( fn recurse<Message, Theme, Renderer>(
element: &mut overlay::Element<'_, Message, Theme, Renderer>, element: &mut overlay::Element<'_, Message, Theme, Renderer>,
renderer: &Renderer, renderer: &Renderer,
bounds: Size, bounds: Size,
translation: Vector,
) -> layout::Node ) -> layout::Node
where where
Renderer: renderer::Renderer, Renderer: renderer::Renderer,
{ {
let node = element.layout(renderer, bounds, translation); let node = element.layout(renderer, bounds);
if let Some(mut nested) = if let Some(mut nested) =
element.overlay(Layout::new(&node), renderer) element.overlay(Layout::new(&node), renderer)
{ {
layout::Node::with_children( layout::Node::with_children(
node.size(), node.size(),
vec![ vec![node, recurse(&mut nested, renderer, bounds)],
node,
recurse(&mut nested, renderer, bounds, translation),
],
) )
} else { } else {
layout::Node::with_children(node.size(), vec![node]) 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`. /// Draws the [`Nested`] overlay using the associated `Renderer`.

View file

@ -5,9 +5,7 @@ use crate::core::mouse;
use crate::core::renderer; use crate::core::renderer;
use crate::core::widget; use crate::core::widget;
use crate::core::window; use crate::core::window;
use crate::core::{ use crate::core::{Clipboard, Element, Layout, Rectangle, Shell, Size, Vector};
Clipboard, Element, Layout, Point, Rectangle, Shell, Size, Vector,
};
use crate::overlay; use crate::overlay;
/// A set of interactive graphical elements with a specific [`Layout`]. /// A set of interactive graphical elements with a specific [`Layout`].
@ -193,7 +191,12 @@ where
let mut manual_overlay = ManuallyDrop::new( let mut manual_overlay = ManuallyDrop::new(
self.root self.root
.as_widget_mut() .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), .map(overlay::Nested::new),
); );
@ -201,8 +204,7 @@ where
let bounds = self.bounds; let bounds = self.bounds;
let mut overlay = manual_overlay.as_mut().unwrap(); let mut overlay = manual_overlay.as_mut().unwrap();
let mut layout = let mut layout = overlay.layout(renderer, bounds);
overlay.layout(renderer, bounds, Point::ORIGIN, Vector::ZERO);
let mut event_statuses = Vec::new(); let mut event_statuses = Vec::new();
for event in events.iter().cloned() { for event in events.iter().cloned() {
@ -245,6 +247,7 @@ where
&mut self.state, &mut self.state,
Layout::new(&self.base), Layout::new(&self.base),
renderer, renderer,
Vector::ZERO,
) )
.map(overlay::Nested::new), .map(overlay::Nested::new),
); );
@ -256,12 +259,7 @@ where
overlay = manual_overlay.as_mut().unwrap(); overlay = manual_overlay.as_mut().unwrap();
shell.revalidate_layout(|| { shell.revalidate_layout(|| {
layout = overlay.layout( layout = overlay.layout(renderer, bounds);
renderer,
bounds,
Point::ORIGIN,
Vector::ZERO,
);
}); });
} }
@ -451,17 +449,18 @@ where
let base_cursor = if let Some(mut overlay) = self let base_cursor = if let Some(mut overlay) = self
.root .root
.as_widget_mut() .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) .map(overlay::Nested::new)
{ {
let overlay_layout = self.overlay.take().unwrap_or_else(|| { let overlay_layout = self
overlay.layout( .overlay
renderer, .take()
self.bounds, .unwrap_or_else(|| overlay.layout(renderer, self.bounds));
Point::ORIGIN,
Vector::ZERO,
)
});
let cursor = if cursor let cursor = if cursor
.position() .position()
@ -520,7 +519,12 @@ where
.as_ref() .as_ref()
.and_then(|layout| { .and_then(|layout| {
root.as_widget_mut() 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(overlay::Nested::new)
.map(|mut overlay| { .map(|mut overlay| {
let overlay_interaction = overlay.mouse_interaction( let overlay_interaction = overlay.mouse_interaction(
@ -574,16 +578,16 @@ where
if let Some(mut overlay) = self if let Some(mut overlay) = self
.root .root
.as_widget_mut() .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) .map(overlay::Nested::new)
{ {
if self.overlay.is_none() { if self.overlay.is_none() {
self.overlay = Some(overlay.layout( self.overlay = Some(overlay.layout(renderer, self.bounds));
renderer,
self.bounds,
Point::ORIGIN,
Vector::ZERO,
));
} }
overlay.operate( overlay.operate(

View file

@ -11,7 +11,7 @@ use crate::core::widget::tree::{self, Tree};
use crate::core::widget::Operation; use crate::core::widget::Operation;
use crate::core::{ use crate::core::{
Background, Clipboard, Color, Element, Layout, Length, Padding, Rectangle, Background, Clipboard, Color, Element, Layout, Length, Padding, Rectangle,
Shell, Size, Widget, Shell, Size, Vector, Widget,
}; };
pub use crate::style::button::{Appearance, StyleSheet}; pub use crate::style::button::{Appearance, StyleSheet};
@ -271,11 +271,13 @@ where
tree: &'b mut Tree, tree: &'b mut Tree,
layout: Layout<'_>, layout: Layout<'_>,
renderer: &Renderer, renderer: &Renderer,
translation: Vector,
) -> Option<overlay::Element<'b, Message, Theme, Renderer>> { ) -> Option<overlay::Element<'b, Message, Theme, Renderer>> {
self.content.as_widget_mut().overlay( self.content.as_widget_mut().overlay(
&mut tree.children[0], &mut tree.children[0],
layout.children().next().unwrap(), layout.children().next().unwrap(),
renderer, renderer,
translation,
) )
} }
} }

View file

@ -7,7 +7,7 @@ use crate::core::renderer;
use crate::core::widget::{Operation, Tree}; use crate::core::widget::{Operation, Tree};
use crate::core::{ use crate::core::{
Alignment, Clipboard, Element, Layout, Length, Padding, Pixels, Rectangle, Alignment, Clipboard, Element, Layout, Length, Padding, Pixels, Rectangle,
Shell, Size, Widget, Shell, Size, Vector, Widget,
}; };
/// A container that distributes its contents vertically. /// A container that distributes its contents vertically.
@ -259,8 +259,15 @@ where
tree: &'b mut Tree, tree: &'b mut Tree,
layout: Layout<'_>, layout: Layout<'_>,
renderer: &Renderer, renderer: &Renderer,
translation: Vector,
) -> Option<overlay::Element<'b, Message, Theme, Renderer>> { ) -> Option<overlay::Element<'b, Message, Theme, Renderer>> {
overlay::from_children(&mut self.children, tree, layout, renderer) overlay::from_children(
&mut self.children,
tree,
layout,
renderer,
translation,
)
} }
} }

View file

@ -10,7 +10,7 @@ use crate::core::text;
use crate::core::time::Instant; use crate::core::time::Instant;
use crate::core::widget::{self, Widget}; use crate::core::widget::{self, Widget};
use crate::core::{ use crate::core::{
Clipboard, Element, Length, Padding, Rectangle, Shell, Size, Clipboard, Element, Length, Padding, Rectangle, Shell, Size, Vector,
}; };
use crate::overlay::menu; use crate::overlay::menu;
use crate::text::LineHeight; use crate::text::LineHeight;
@ -657,6 +657,7 @@ where
tree: &'b mut widget::Tree, tree: &'b mut widget::Tree,
layout: Layout<'_>, layout: Layout<'_>,
_renderer: &Renderer, _renderer: &Renderer,
translation: Vector,
) -> Option<overlay::Element<'b, Message, Theme, Renderer>> { ) -> Option<overlay::Element<'b, Message, Theme, Renderer>> {
let is_focused = { let is_focused = {
let text_input_state = tree.children[0] let text_input_state = tree.children[0]
@ -705,7 +706,7 @@ where
menu = menu.text_size(size); menu = menu.text_size(size);
} }
Some(menu.overlay(layout.position(), bounds.height)) Some(menu.overlay(layout.position() + translation, bounds.height))
} else { } else {
None None
} }

View file

@ -279,11 +279,13 @@ where
tree: &'b mut Tree, tree: &'b mut Tree,
layout: Layout<'_>, layout: Layout<'_>,
renderer: &Renderer, renderer: &Renderer,
translation: Vector,
) -> Option<overlay::Element<'b, Message, Theme, Renderer>> { ) -> Option<overlay::Element<'b, Message, Theme, Renderer>> {
self.content.as_widget_mut().overlay( self.content.as_widget_mut().overlay(
tree, tree,
layout.children().next().unwrap(), layout.children().next().unwrap(),
renderer, renderer,
translation,
) )
} }
} }

View file

@ -8,7 +8,7 @@ use crate::core::widget::tree::{self, Tree};
use crate::core::widget::Operation; use crate::core::widget::Operation;
use crate::core::{ use crate::core::{
Alignment, Clipboard, Element, Layout, Length, Padding, Pixels, Rectangle, Alignment, Clipboard, Element, Layout, Length, Padding, Pixels, Rectangle,
Shell, Size, Widget, Shell, Size, Vector, Widget,
}; };
/// A container that distributes its contents vertically. /// A container that distributes its contents vertically.
@ -316,8 +316,15 @@ where
tree: &'b mut Tree, tree: &'b mut Tree,
layout: Layout<'_>, layout: Layout<'_>,
renderer: &Renderer, renderer: &Renderer,
translation: Vector,
) -> Option<overlay::Element<'b, Message, Theme, Renderer>> { ) -> Option<overlay::Element<'b, Message, Theme, Renderer>> {
overlay::from_children(&mut self.children, tree, layout, renderer) overlay::from_children(
&mut self.children,
tree,
layout,
renderer,
translation,
)
} }
} }

View file

@ -259,6 +259,7 @@ where
tree: &'b mut Tree, tree: &'b mut Tree,
layout: Layout<'_>, layout: Layout<'_>,
renderer: &Renderer, renderer: &Renderer,
translation: Vector,
) -> Option<overlay::Element<'_, Message, Theme, Renderer>> { ) -> Option<overlay::Element<'_, Message, Theme, Renderer>> {
let overlay = Overlay(Some( let overlay = Overlay(Some(
InnerBuilder { InnerBuilder {
@ -275,18 +276,14 @@ where
overlay_builder: |element, tree| { overlay_builder: |element, tree| {
element element
.as_widget_mut() .as_widget_mut()
.overlay(tree, layout, renderer) .overlay(tree, layout, renderer, translation)
.map(|overlay| RefCell::new(Nested::new(overlay))) .map(|overlay| RefCell::new(Nested::new(overlay)))
}, },
} }
.build(), .build(),
)); ));
let has_overlay = Some(overlay::Element::new(Box::new(overlay)))
overlay.with_overlay_maybe(|overlay| overlay.position());
has_overlay
.map(|position| overlay::Element::new(position, Box::new(overlay)))
} }
} }
@ -339,17 +336,9 @@ impl<'a, Message, Theme, Renderer> overlay::Overlay<Message, Theme, Renderer>
where where
Renderer: core::Renderer, Renderer: core::Renderer,
{ {
fn layout( fn layout(&mut self, renderer: &Renderer, bounds: Size) -> layout::Node {
&mut self, self.with_overlay_maybe(|overlay| overlay.layout(renderer, bounds))
renderer: &Renderer, .unwrap_or_default()
bounds: Size,
position: Point,
translation: Vector,
) -> layout::Node {
self.with_overlay_maybe(|overlay| {
overlay.layout(renderer, bounds, position, translation)
})
.unwrap_or_default()
} }
fn draw( fn draw(

View file

@ -462,6 +462,7 @@ where
tree: &'b mut Tree, tree: &'b mut Tree,
layout: Layout<'_>, layout: Layout<'_>,
renderer: &Renderer, renderer: &Renderer,
translation: Vector,
) -> Option<overlay::Element<'b, Message, Theme, Renderer>> { ) -> Option<overlay::Element<'b, Message, Theme, Renderer>> {
self.rebuild_element_if_necessary(); self.rebuild_element_if_necessary();
let tree = tree let tree = tree
@ -486,6 +487,7 @@ where
&mut tree.children[0], &mut tree.children[0],
layout, layout,
renderer, renderer,
translation,
) )
.map(|overlay| { .map(|overlay| {
RefCell::new(Nested::new(overlay)) RefCell::new(Nested::new(overlay))
@ -497,18 +499,9 @@ where
.build(), .build(),
)); ));
let has_overlay = overlay.0.as_ref().unwrap().with_overlay(|overlay| { Some(overlay::Element::new(Box::new(OverlayInstance {
overlay.as_ref().map(|nested| nested.borrow().position()) overlay: Some(overlay),
}); })))
has_overlay.map(|position| {
overlay::Element::new(
position,
Box::new(OverlayInstance {
overlay: Some(overlay),
}),
)
})
} }
} }
@ -582,17 +575,9 @@ where
Renderer: core::Renderer, Renderer: core::Renderer,
S: 'static + Default, S: 'static + Default,
{ {
fn layout( fn layout(&mut self, renderer: &Renderer, bounds: Size) -> layout::Node {
&mut self, self.with_overlay_maybe(|overlay| overlay.layout(renderer, bounds))
renderer: &Renderer, .unwrap_or_default()
bounds: Size,
position: Point,
translation: Vector,
) -> layout::Node {
self.with_overlay_maybe(|overlay| {
overlay.layout(renderer, bounds, position, translation)
})
.unwrap_or_default()
} }
fn draw( fn draw(

View file

@ -279,6 +279,7 @@ where
tree: &'b mut Tree, tree: &'b mut Tree,
layout: Layout<'_>, layout: Layout<'_>,
renderer: &Renderer, renderer: &Renderer,
translation: Vector,
) -> Option<overlay::Element<'b, Message, Theme, Renderer>> { ) -> Option<overlay::Element<'b, Message, Theme, Renderer>> {
use std::ops::DerefMut; use std::ops::DerefMut;
@ -309,17 +310,13 @@ where
element element
.as_widget_mut() .as_widget_mut()
.overlay(tree, content_layout, renderer) .overlay(tree, content_layout, renderer, translation)
.map(|overlay| RefCell::new(Nested::new(overlay))) .map(|overlay| RefCell::new(Nested::new(overlay)))
}, },
} }
.build(); .build();
let has_overlay = Some(overlay::Element::new(Box::new(overlay)))
overlay.with_overlay_maybe(|overlay| overlay.position());
has_overlay
.map(|position| overlay::Element::new(position, Box::new(overlay)))
} }
} }
@ -375,17 +372,9 @@ impl<'a, 'b, Message, Theme, Renderer>
where where
Renderer: core::Renderer, Renderer: core::Renderer,
{ {
fn layout( fn layout(&mut self, renderer: &Renderer, bounds: Size) -> layout::Node {
&mut self, self.with_overlay_maybe(|overlay| overlay.layout(renderer, bounds))
renderer: &Renderer, .unwrap_or_default()
bounds: Size,
position: Point,
translation: Vector,
) -> layout::Node {
self.with_overlay_maybe(|overlay| {
overlay.layout(renderer, bounds, position, translation)
})
.unwrap_or_default()
} }
fn draw( fn draw(

View file

@ -8,7 +8,7 @@ use crate::core::renderer;
use crate::core::touch; use crate::core::touch;
use crate::core::widget::{tree, Operation, Tree}; use crate::core::widget::{tree, Operation, Tree};
use crate::core::{ 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. /// Emit messages on mouse events.
@ -217,11 +217,13 @@ where
tree: &'b mut Tree, tree: &'b mut Tree,
layout: Layout<'_>, layout: Layout<'_>,
renderer: &Renderer, renderer: &Renderer,
translation: Vector,
) -> Option<overlay::Element<'b, Message, Theme, Renderer>> { ) -> Option<overlay::Element<'b, Message, Theme, Renderer>> {
self.content.as_widget_mut().overlay( self.content.as_widget_mut().overlay(
&mut tree.children[0], &mut tree.children[0],
layout, layout,
renderer, renderer,
translation,
) )
} }
} }

View file

@ -134,10 +134,11 @@ where
position: Point, position: Point,
target_height: f32, target_height: f32,
) -> overlay::Element<'a, Message, Theme, Renderer> { ) -> overlay::Element<'a, Message, Theme, Renderer> {
overlay::Element::new( overlay::Element::new(Box::new(Overlay::new(
position, position,
Box::new(Overlay::new(self, target_height)), self,
) target_height,
)))
} }
} }
@ -167,6 +168,7 @@ where
Theme: StyleSheet + container::StyleSheet, Theme: StyleSheet + container::StyleSheet,
Renderer: crate::core::Renderer, Renderer: crate::core::Renderer,
{ {
position: Point,
state: &'a mut Tree, state: &'a mut Tree,
container: Container<'a, Message, Theme, Renderer>, container: Container<'a, Message, Theme, Renderer>,
width: f32, width: f32,
@ -181,6 +183,7 @@ where
Renderer: text::Renderer + 'a, Renderer: text::Renderer + 'a,
{ {
pub fn new<T>( pub fn new<T>(
position: Point,
menu: Menu<'a, T, Message, Theme, Renderer>, menu: Menu<'a, T, Message, Theme, Renderer>,
target_height: f32, target_height: f32,
) -> Self ) -> Self
@ -218,6 +221,7 @@ where
state.tree.diff(&container as &dyn Widget<_, _, _>); state.tree.diff(&container as &dyn Widget<_, _, _>);
Self { Self {
position,
state: &mut state.tree, state: &mut state.tree,
container, container,
width, width,
@ -234,20 +238,15 @@ where
Theme: StyleSheet + container::StyleSheet, Theme: StyleSheet + container::StyleSheet,
Renderer: text::Renderer, Renderer: text::Renderer,
{ {
fn layout( fn layout(&mut self, renderer: &Renderer, bounds: Size) -> layout::Node {
&mut self, let space_below =
renderer: &Renderer, bounds.height - (self.position.y + self.target_height);
bounds: Size, let space_above = self.position.y;
position: Point,
_translation: Vector,
) -> layout::Node {
let space_below = bounds.height - (position.y + self.target_height);
let space_above = position.y;
let limits = layout::Limits::new( let limits = layout::Limits::new(
Size::ZERO, Size::ZERO,
Size::new( Size::new(
bounds.width - position.x, bounds.width - self.position.x,
if space_below > space_above { if space_below > space_above {
space_below space_below
} else { } else {
@ -261,9 +260,9 @@ where
let size = node.size(); let size = node.size();
node.move_to(if space_below > space_above { 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 { } else {
position - Vector::new(0.0, size.height) self.position - Vector::new(0.0, size.height)
}) })
} }

View file

@ -447,6 +447,7 @@ where
tree: &'b mut Tree, tree: &'b mut Tree,
layout: Layout<'_>, layout: Layout<'_>,
renderer: &Renderer, renderer: &Renderer,
translation: Vector,
) -> Option<overlay::Element<'_, Message, Theme, Renderer>> { ) -> Option<overlay::Element<'_, Message, Theme, Renderer>> {
let children = self let children = self
.contents .contents
@ -454,7 +455,7 @@ where
.zip(&mut tree.children) .zip(&mut tree.children)
.zip(layout.children()) .zip(layout.children())
.filter_map(|(((_, content), state), layout)| { .filter_map(|(((_, content), state), layout)| {
content.overlay(state, layout, renderer) content.overlay(state, layout, renderer, translation)
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();

View file

@ -5,7 +5,9 @@ use crate::core::mouse;
use crate::core::overlay; use crate::core::overlay;
use crate::core::renderer; use crate::core::renderer;
use crate::core::widget::{self, Tree}; 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}; use crate::pane_grid::{Draggable, TitleBar};
/// The content of a [`Pane`]. /// The content of a [`Pane`].
@ -330,6 +332,7 @@ where
tree: &'b mut Tree, tree: &'b mut Tree,
layout: Layout<'_>, layout: Layout<'_>,
renderer: &Renderer, renderer: &Renderer,
translation: Vector,
) -> Option<overlay::Element<'b, Message, Theme, Renderer>> { ) -> Option<overlay::Element<'b, Message, Theme, Renderer>> {
if let Some(title_bar) = self.title_bar.as_mut() { if let Some(title_bar) = self.title_bar.as_mut() {
let mut children = layout.children(); let mut children = layout.children();
@ -339,13 +342,18 @@ where
let body_state = states.next().unwrap(); let body_state = states.next().unwrap();
let title_bar_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), Some(overlay) => Some(overlay),
None => self.body.as_widget_mut().overlay( None => self.body.as_widget_mut().overlay(
body_state, body_state,
children.next()?, children.next()?,
renderer, renderer,
translation,
), ),
} }
} else { } else {
@ -353,6 +361,7 @@ where
&mut tree.children[0], &mut tree.children[0],
layout, layout,
renderer, renderer,
translation,
) )
} }
} }

View file

@ -6,7 +6,7 @@ use crate::core::overlay;
use crate::core::renderer; use crate::core::renderer;
use crate::core::widget::{self, Tree}; use crate::core::widget::{self, Tree};
use crate::core::{ 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`]. /// The title bar of a [`Pane`].
@ -405,6 +405,7 @@ where
tree: &'b mut Tree, tree: &'b mut Tree,
layout: Layout<'_>, layout: Layout<'_>,
renderer: &Renderer, renderer: &Renderer,
translation: Vector,
) -> Option<overlay::Element<'b, Message, Theme, Renderer>> { ) -> Option<overlay::Element<'b, Message, Theme, Renderer>> {
let mut children = layout.children(); let mut children = layout.children();
let padded = children.next()?; let padded = children.next()?;
@ -422,7 +423,7 @@ where
content content
.as_widget_mut() .as_widget_mut()
.overlay(title_state, title_layout, renderer) .overlay(title_state, title_layout, renderer, translation)
.or_else(move || { .or_else(move || {
controls.as_mut().and_then(|controls| { controls.as_mut().and_then(|controls| {
let controls_layout = children.next()?; let controls_layout = children.next()?;
@ -431,6 +432,7 @@ where
controls_state, controls_state,
controls_layout, controls_layout,
renderer, renderer,
translation,
) )
}) })
}) })

View file

@ -12,7 +12,7 @@ use crate::core::touch;
use crate::core::widget::tree::{self, Tree}; use crate::core::widget::tree::{self, Tree};
use crate::core::{ use crate::core::{
Clipboard, Element, Layout, Length, Padding, Pixels, Point, Rectangle, Clipboard, Element, Layout, Length, Padding, Pixels, Point, Rectangle,
Shell, Size, Widget, Shell, Size, Vector, Widget,
}; };
use crate::overlay::menu::{self, Menu}; use crate::overlay::menu::{self, Menu};
use crate::scrollable; use crate::scrollable;
@ -265,11 +265,13 @@ where
tree: &'b mut Tree, tree: &'b mut Tree,
layout: Layout<'_>, layout: Layout<'_>,
renderer: &Renderer, renderer: &Renderer,
translation: Vector,
) -> Option<overlay::Element<'b, Message, Theme, Renderer>> { ) -> Option<overlay::Element<'b, Message, Theme, Renderer>> {
let state = tree.state.downcast_mut::<State<Renderer::Paragraph>>(); let state = tree.state.downcast_mut::<State<Renderer::Paragraph>>();
overlay( overlay(
layout, layout,
translation,
state, state,
self.padding, self.padding,
self.text_size, self.text_size,
@ -573,6 +575,7 @@ pub fn mouse_interaction(
/// Returns the current overlay of a [`PickList`]. /// Returns the current overlay of a [`PickList`].
pub fn overlay<'a, T, Message, Theme, Renderer>( pub fn overlay<'a, T, Message, Theme, Renderer>(
layout: Layout<'_>, layout: Layout<'_>,
translation: Vector,
state: &'a mut State<Renderer::Paragraph>, state: &'a mut State<Renderer::Paragraph>,
padding: Padding, padding: Padding,
text_size: Option<Pixels>, text_size: Option<Pixels>,
@ -617,7 +620,7 @@ where
menu = menu.text_size(text_size); menu = menu.text_size(text_size);
} }
Some(menu.overlay(layout.position(), bounds.height)) Some(menu.overlay(layout.position() + translation, bounds.height))
} else { } else {
None None
} }

View file

@ -7,7 +7,7 @@ use crate::core::renderer;
use crate::core::widget::{Operation, Tree}; use crate::core::widget::{Operation, Tree};
use crate::core::{ use crate::core::{
Alignment, Clipboard, Element, Length, Padding, Pixels, Rectangle, Shell, Alignment, Clipboard, Element, Length, Padding, Pixels, Rectangle, Shell,
Size, Widget, Size, Vector, Widget,
}; };
/// A container that distributes its contents horizontally. /// A container that distributes its contents horizontally.
@ -248,8 +248,15 @@ where
tree: &'b mut Tree, tree: &'b mut Tree,
layout: Layout<'_>, layout: Layout<'_>,
renderer: &Renderer, renderer: &Renderer,
translation: Vector,
) -> Option<overlay::Element<'b, Message, Theme, Renderer>> { ) -> Option<overlay::Element<'b, Message, Theme, Renderer>> {
overlay::from_children(&mut self.children, tree, layout, renderer) overlay::from_children(
&mut self.children,
tree,
layout,
renderer,
translation,
)
} }
} }

View file

@ -385,25 +385,24 @@ where
tree: &'b mut Tree, tree: &'b mut Tree,
layout: Layout<'_>, layout: Layout<'_>,
renderer: &Renderer, renderer: &Renderer,
translation: Vector,
) -> Option<overlay::Element<'b, Message, Theme, Renderer>> { ) -> Option<overlay::Element<'b, Message, Theme, Renderer>> {
self.content let bounds = layout.bounds();
.as_widget_mut() let content_layout = layout.children().next().unwrap();
.overlay( let content_bounds = content_layout.bounds();
&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::<State>()
.translation(self.direction, bounds, content_bounds);
overlay.translate(Vector::new(-translation.x, -translation.y)) let offset = tree.state.downcast_ref::<State>().translation(
}) self.direction,
bounds,
content_bounds,
);
self.content.as_widget_mut().overlay(
&mut tree.children[0],
layout.children().next().unwrap(),
renderer,
translation - offset,
)
} }
} }

View file

@ -141,6 +141,7 @@ where
tree: &'b mut Tree, tree: &'b mut Tree,
layout: Layout<'_>, layout: Layout<'_>,
renderer: &Renderer, renderer: &Renderer,
translation: Vector,
) -> Option<overlay::Element<'b, Message, AnyTheme, Renderer>> { ) -> Option<overlay::Element<'b, Message, AnyTheme, Renderer>> {
struct Overlay<'a, Message, Theme, Renderer> { struct Overlay<'a, Message, Theme, Renderer> {
theme: &'a Theme, theme: &'a Theme,
@ -157,14 +158,8 @@ where
&mut self, &mut self,
renderer: &Renderer, renderer: &Renderer,
bounds: Size, bounds: Size,
position: Point,
translation: Vector,
) -> layout::Node { ) -> layout::Node {
self.content.layout( self.content.layout(renderer, bounds)
renderer,
bounds,
translation + (position - Point::ORIGIN),
)
} }
fn draw( fn draw(
@ -233,22 +228,18 @@ where
theme: self.theme, theme: self.theme,
content, content,
}) })
.map(|overlay| { .map(|overlay| overlay::Element::new(Box::new(overlay)))
overlay::Element::new(Point::ORIGIN, Box::new(overlay))
})
} }
} }
self.content self.content
.as_widget_mut() .as_widget_mut()
.overlay(tree, layout, renderer) .overlay(tree, layout, renderer, translation)
.map(|content| Overlay { .map(|content| Overlay {
theme: &self.theme, theme: &self.theme,
content, content,
}) })
.map(|overlay| { .map(|overlay| overlay::Element::new(Box::new(overlay)))
overlay::Element::new(Point::ORIGIN, Box::new(overlay))
})
} }
} }

View file

@ -231,6 +231,7 @@ where
tree: &'b mut widget::Tree, tree: &'b mut widget::Tree,
layout: Layout<'_>, layout: Layout<'_>,
renderer: &Renderer, renderer: &Renderer,
translation: Vector,
) -> Option<overlay::Element<'b, Message, Theme, Renderer>> { ) -> Option<overlay::Element<'b, Message, Theme, Renderer>> {
let state = tree.state.downcast_ref::<State>(); let state = tree.state.downcast_ref::<State>();
@ -240,23 +241,22 @@ where
children.next().unwrap(), children.next().unwrap(),
layout, layout,
renderer, renderer,
translation,
); );
let tooltip = if let State::Hovered { cursor_position } = *state { let tooltip = if let State::Hovered { cursor_position } = *state {
Some(overlay::Element::new( Some(overlay::Element::new(Box::new(Overlay {
layout.position(), position: layout.position() + translation,
Box::new(Overlay { tooltip: &self.tooltip,
tooltip: &self.tooltip, state: children.next().unwrap(),
state: children.next().unwrap(), cursor_position,
cursor_position, content_bounds: layout.bounds(),
content_bounds: layout.bounds(), snap_within_viewport: self.snap_within_viewport,
snap_within_viewport: self.snap_within_viewport, positioning: self.position,
position: self.position, gap: self.gap,
gap: self.gap, padding: self.padding,
padding: self.padding, style: &self.style,
style: &self.style, })))
}),
))
} else { } else {
None None
}; };
@ -317,12 +317,13 @@ where
Theme: container::StyleSheet + widget::text::StyleSheet, Theme: container::StyleSheet + widget::text::StyleSheet,
Renderer: text::Renderer, Renderer: text::Renderer,
{ {
position: Point,
tooltip: &'b Text<'a, Theme, Renderer>, tooltip: &'b Text<'a, Theme, Renderer>,
state: &'b mut widget::Tree, state: &'b mut widget::Tree,
cursor_position: Point, cursor_position: Point,
content_bounds: Rectangle, content_bounds: Rectangle,
snap_within_viewport: bool, snap_within_viewport: bool,
position: Position, positioning: Position,
gap: f32, gap: f32,
padding: f32, padding: f32,
style: &'b <Theme as container::StyleSheet>::Style, style: &'b <Theme as container::StyleSheet>::Style,
@ -335,13 +336,7 @@ where
Theme: container::StyleSheet + widget::text::StyleSheet, Theme: container::StyleSheet + widget::text::StyleSheet,
Renderer: text::Renderer, Renderer: text::Renderer,
{ {
fn layout( fn layout(&mut self, renderer: &Renderer, bounds: Size) -> layout::Node {
&mut self,
renderer: &Renderer,
bounds: Size,
position: Point,
_translation: Vector,
) -> layout::Node {
let viewport = Rectangle::with_size(bounds); let viewport = Rectangle::with_size(bounds);
let text_layout = Widget::<(), Theme, Renderer>::layout( let text_layout = Widget::<(), Theme, Renderer>::layout(
@ -358,37 +353,44 @@ where
); );
let text_bounds = text_layout.bounds(); let text_bounds = text_layout.bounds();
let x_center = let x_center = self.position.x
position.x + (self.content_bounds.width - text_bounds.width) / 2.0; + (self.content_bounds.width - text_bounds.width) / 2.0;
let y_center = position.y let y_center = self.position.y
+ (self.content_bounds.height - text_bounds.height) / 2.0; + (self.content_bounds.height - text_bounds.height) / 2.0;
let mut tooltip_bounds = { let mut tooltip_bounds = {
let offset = match self.position { let offset = match self.positioning {
Position::Top => Vector::new( Position::Top => Vector::new(
x_center, 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( Position::Bottom => Vector::new(
x_center, x_center,
position.y self.position.y
+ self.content_bounds.height + self.content_bounds.height
+ self.gap + self.gap
+ self.padding, + self.padding,
), ),
Position::Left => Vector::new( 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, y_center,
), ),
Position::Right => Vector::new( Position::Right => Vector::new(
position.x self.position.x
+ self.content_bounds.width + self.content_bounds.width
+ self.gap + self.gap
+ self.padding, + self.padding,
y_center, y_center,
), ),
Position::FollowCursor => { Position::FollowCursor => {
let translation = position - self.content_bounds.position(); let translation =
self.position - self.content_bounds.position();
Vector::new( Vector::new(
self.cursor_position.x, self.cursor_position.x,