Merge pull request #2142 from iced-rs/fix/overlay-composition
Fix `Overlay` composition
This commit is contained in:
commit
170db35891
12 changed files with 68 additions and 28 deletions
|
|
@ -11,7 +11,7 @@ use crate::mouse;
|
||||||
use crate::renderer;
|
use crate::renderer;
|
||||||
use crate::widget;
|
use crate::widget;
|
||||||
use crate::widget::Tree;
|
use crate::widget::Tree;
|
||||||
use crate::{Clipboard, Layout, Point, Rectangle, Shell, Size};
|
use crate::{Clipboard, Layout, Point, Rectangle, Shell, Size, Vector};
|
||||||
|
|
||||||
/// An interactive component that can be displayed on top of other widgets.
|
/// An interactive component that can be displayed on top of other widgets.
|
||||||
pub trait Overlay<Message, Renderer>
|
pub trait Overlay<Message, Renderer>
|
||||||
|
|
@ -29,6 +29,7 @@ where
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
bounds: Size,
|
bounds: Size,
|
||||||
position: Point,
|
position: Point,
|
||||||
|
translation: Vector,
|
||||||
) -> layout::Node;
|
) -> layout::Node;
|
||||||
|
|
||||||
/// Draws the [`Overlay`] using the associated `Renderer`.
|
/// Draws the [`Overlay`] using the associated `Renderer`.
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ use std::any::Any;
|
||||||
#[allow(missing_debug_implementations)]
|
#[allow(missing_debug_implementations)]
|
||||||
pub struct Element<'a, Message, Renderer> {
|
pub struct Element<'a, Message, Renderer> {
|
||||||
position: Point,
|
position: Point,
|
||||||
|
translation: Vector,
|
||||||
overlay: Box<dyn Overlay<Message, Renderer> + 'a>,
|
overlay: Box<dyn Overlay<Message, Renderer> + 'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -25,7 +26,11 @@ where
|
||||||
position: Point,
|
position: Point,
|
||||||
overlay: Box<dyn Overlay<Message, Renderer> + 'a>,
|
overlay: Box<dyn Overlay<Message, Renderer> + 'a>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self { position, overlay }
|
Self {
|
||||||
|
position,
|
||||||
|
overlay,
|
||||||
|
translation: Vector::ZERO,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the position of the [`Element`].
|
/// Returns the position of the [`Element`].
|
||||||
|
|
@ -36,6 +41,7 @@ where
|
||||||
/// Translates the [`Element`].
|
/// Translates the [`Element`].
|
||||||
pub fn translate(mut self, translation: Vector) -> Self {
|
pub fn translate(mut self, translation: Vector) -> Self {
|
||||||
self.position = self.position + translation;
|
self.position = self.position + translation;
|
||||||
|
self.translation = self.translation + translation;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -48,6 +54,7 @@ where
|
||||||
{
|
{
|
||||||
Element {
|
Element {
|
||||||
position: self.position,
|
position: self.position,
|
||||||
|
translation: self.translation,
|
||||||
overlay: Box::new(Map::new(self.overlay, f)),
|
overlay: Box::new(Map::new(self.overlay, f)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -59,8 +66,12 @@ where
|
||||||
bounds: Size,
|
bounds: Size,
|
||||||
translation: Vector,
|
translation: Vector,
|
||||||
) -> layout::Node {
|
) -> layout::Node {
|
||||||
self.overlay
|
self.overlay.layout(
|
||||||
.layout(renderer, bounds, self.position + translation)
|
renderer,
|
||||||
|
bounds,
|
||||||
|
self.position + translation,
|
||||||
|
self.translation + translation,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Processes a runtime [`Event`].
|
/// Processes a runtime [`Event`].
|
||||||
|
|
@ -154,8 +165,9 @@ where
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
bounds: Size,
|
bounds: Size,
|
||||||
position: Point,
|
position: Point,
|
||||||
|
translation: Vector,
|
||||||
) -> layout::Node {
|
) -> layout::Node {
|
||||||
self.content.layout(renderer, bounds, position)
|
self.content.layout(renderer, bounds, position, translation)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn operate(
|
fn operate(
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,9 @@ use crate::mouse;
|
||||||
use crate::overlay;
|
use crate::overlay;
|
||||||
use crate::renderer;
|
use crate::renderer;
|
||||||
use crate::widget;
|
use crate::widget;
|
||||||
use crate::{Clipboard, Event, Layout, Overlay, Point, Rectangle, Shell, Size};
|
use crate::{
|
||||||
|
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.
|
||||||
|
|
@ -64,10 +66,9 @@ where
|
||||||
&mut self,
|
&mut self,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
bounds: Size,
|
bounds: Size,
|
||||||
position: Point,
|
_position: Point,
|
||||||
|
translation: Vector,
|
||||||
) -> layout::Node {
|
) -> layout::Node {
|
||||||
let translation = position - Point::ORIGIN;
|
|
||||||
|
|
||||||
layout::Node::with_children(
|
layout::Node::with_children(
|
||||||
bounds,
|
bounds,
|
||||||
self.children
|
self.children
|
||||||
|
|
|
||||||
|
|
@ -231,6 +231,7 @@ mod modal {
|
||||||
use iced::mouse;
|
use iced::mouse;
|
||||||
use iced::{
|
use iced::{
|
||||||
BorderRadius, Color, Element, Event, Length, Point, Rectangle, Size,
|
BorderRadius, Color, Element, Event, Length, Point, Rectangle, Size,
|
||||||
|
Vector,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A widget that centers a modal element over some base element
|
/// A widget that centers a modal element over some base element
|
||||||
|
|
@ -413,6 +414,7 @@ mod modal {
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
_bounds: Size,
|
_bounds: Size,
|
||||||
position: Point,
|
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)
|
||||||
|
|
|
||||||
|
|
@ -511,6 +511,7 @@ mod toast {
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
bounds: Size,
|
bounds: Size,
|
||||||
position: Point,
|
position: Point,
|
||||||
|
_translation: Vector,
|
||||||
) -> layout::Node {
|
) -> layout::Node {
|
||||||
let limits = layout::Limits::new(Size::ZERO, bounds)
|
let limits = layout::Limits::new(Size::ZERO, bounds)
|
||||||
.width(Length::Fill)
|
.width(Length::Fill)
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,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;
|
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
|
/// An overlay container that displays nested overlays
|
||||||
#[allow(missing_debug_implementations)]
|
#[allow(missing_debug_implementations)]
|
||||||
|
|
@ -33,19 +35,18 @@ where
|
||||||
&mut self,
|
&mut self,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
bounds: Size,
|
bounds: Size,
|
||||||
position: Point,
|
_position: Point,
|
||||||
|
translation: Vector,
|
||||||
) -> layout::Node {
|
) -> layout::Node {
|
||||||
fn recurse<Message, Renderer>(
|
fn recurse<Message, Renderer>(
|
||||||
element: &mut overlay::Element<'_, Message, Renderer>,
|
element: &mut overlay::Element<'_, Message, Renderer>,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
bounds: Size,
|
bounds: Size,
|
||||||
position: Point,
|
translation: Vector,
|
||||||
) -> layout::Node
|
) -> layout::Node
|
||||||
where
|
where
|
||||||
Renderer: renderer::Renderer,
|
Renderer: renderer::Renderer,
|
||||||
{
|
{
|
||||||
let translation = position - Point::ORIGIN;
|
|
||||||
|
|
||||||
let node = element.layout(renderer, bounds, translation);
|
let node = element.layout(renderer, bounds, translation);
|
||||||
|
|
||||||
if let Some(mut nested) =
|
if let Some(mut nested) =
|
||||||
|
|
@ -55,7 +56,7 @@ where
|
||||||
node.size(),
|
node.size(),
|
||||||
vec![
|
vec![
|
||||||
node,
|
node,
|
||||||
recurse(&mut nested, renderer, bounds, position),
|
recurse(&mut nested, renderer, bounds, translation),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -63,7 +64,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
recurse(&mut self.overlay, renderer, bounds, position)
|
recurse(&mut self.overlay, renderer, bounds, translation)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Draws the [`Nested`] overlay using the associated `Renderer`.
|
/// Draws the [`Nested`] overlay using the associated `Renderer`.
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,9 @@ 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::{Clipboard, Element, Layout, Point, Rectangle, Shell, Size};
|
use crate::core::{
|
||||||
|
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`].
|
||||||
|
|
@ -199,7 +201,8 @@ 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 = overlay.layout(renderer, bounds, Point::ORIGIN);
|
let mut layout =
|
||||||
|
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() {
|
||||||
|
|
@ -253,8 +256,12 @@ where
|
||||||
overlay = manual_overlay.as_mut().unwrap();
|
overlay = manual_overlay.as_mut().unwrap();
|
||||||
|
|
||||||
shell.revalidate_layout(|| {
|
shell.revalidate_layout(|| {
|
||||||
layout =
|
layout = overlay.layout(
|
||||||
overlay.layout(renderer, bounds, Point::ORIGIN);
|
renderer,
|
||||||
|
bounds,
|
||||||
|
Point::ORIGIN,
|
||||||
|
Vector::ZERO,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -448,7 +455,12 @@ where
|
||||||
.map(overlay::Nested::new)
|
.map(overlay::Nested::new)
|
||||||
{
|
{
|
||||||
let overlay_layout = self.overlay.take().unwrap_or_else(|| {
|
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
|
let cursor = if cursor
|
||||||
|
|
@ -566,8 +578,12 @@ where
|
||||||
.map(overlay::Nested::new)
|
.map(overlay::Nested::new)
|
||||||
{
|
{
|
||||||
if self.overlay.is_none() {
|
if self.overlay.is_none() {
|
||||||
self.overlay =
|
self.overlay = Some(overlay.layout(
|
||||||
Some(overlay.layout(renderer, self.bounds, Point::ORIGIN));
|
renderer,
|
||||||
|
self.bounds,
|
||||||
|
Point::ORIGIN,
|
||||||
|
Vector::ZERO,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
overlay.operate(
|
overlay.operate(
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ use crate::core::widget::tree::{self, Tree};
|
||||||
use crate::core::widget::{self, Widget};
|
use crate::core::widget::{self, Widget};
|
||||||
use crate::core::Element;
|
use crate::core::Element;
|
||||||
use crate::core::{
|
use crate::core::{
|
||||||
self, Clipboard, Hasher, Length, Point, Rectangle, Shell, Size,
|
self, Clipboard, Hasher, Length, Point, Rectangle, Shell, Size, Vector,
|
||||||
};
|
};
|
||||||
use crate::runtime::overlay::Nested;
|
use crate::runtime::overlay::Nested;
|
||||||
|
|
||||||
|
|
@ -333,9 +333,10 @@ where
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
bounds: Size,
|
bounds: Size,
|
||||||
position: Point,
|
position: Point,
|
||||||
|
translation: Vector,
|
||||||
) -> layout::Node {
|
) -> layout::Node {
|
||||||
self.with_overlay_maybe(|overlay| {
|
self.with_overlay_maybe(|overlay| {
|
||||||
overlay.layout(renderer, bounds, position)
|
overlay.layout(renderer, bounds, position, translation)
|
||||||
})
|
})
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -577,9 +577,10 @@ where
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
bounds: Size,
|
bounds: Size,
|
||||||
position: Point,
|
position: Point,
|
||||||
|
translation: Vector,
|
||||||
) -> layout::Node {
|
) -> layout::Node {
|
||||||
self.with_overlay_maybe(|overlay| {
|
self.with_overlay_maybe(|overlay| {
|
||||||
overlay.layout(renderer, bounds, position)
|
overlay.layout(renderer, bounds, position, translation)
|
||||||
})
|
})
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,8 @@ use crate::core::renderer;
|
||||||
use crate::core::widget;
|
use crate::core::widget;
|
||||||
use crate::core::widget::tree::{self, Tree};
|
use crate::core::widget::tree::{self, Tree};
|
||||||
use crate::core::{
|
use crate::core::{
|
||||||
self, Clipboard, Element, Length, Point, Rectangle, Shell, Size, Widget,
|
self, Clipboard, Element, Length, Point, Rectangle, Shell, Size, Vector,
|
||||||
|
Widget,
|
||||||
};
|
};
|
||||||
use crate::horizontal_space;
|
use crate::horizontal_space;
|
||||||
use crate::runtime::overlay::Nested;
|
use crate::runtime::overlay::Nested;
|
||||||
|
|
@ -367,9 +368,10 @@ where
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
bounds: Size,
|
bounds: Size,
|
||||||
position: Point,
|
position: Point,
|
||||||
|
translation: Vector,
|
||||||
) -> layout::Node {
|
) -> layout::Node {
|
||||||
self.with_overlay_maybe(|overlay| {
|
self.with_overlay_maybe(|overlay| {
|
||||||
overlay.layout(renderer, bounds, position)
|
overlay.layout(renderer, bounds, position, translation)
|
||||||
})
|
})
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -236,6 +236,7 @@ where
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
bounds: Size,
|
bounds: Size,
|
||||||
position: Point,
|
position: Point,
|
||||||
|
_translation: Vector,
|
||||||
) -> layout::Node {
|
) -> layout::Node {
|
||||||
let space_below = bounds.height - (position.y + self.target_height);
|
let space_below = bounds.height - (position.y + self.target_height);
|
||||||
let space_above = position.y;
|
let space_above = position.y;
|
||||||
|
|
|
||||||
|
|
@ -325,6 +325,7 @@ where
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
bounds: Size,
|
bounds: Size,
|
||||||
position: Point,
|
position: Point,
|
||||||
|
_translation: Vector,
|
||||||
) -> layout::Node {
|
) -> layout::Node {
|
||||||
let viewport = Rectangle::with_size(bounds);
|
let viewport = Rectangle::with_size(bounds);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue