iced-yoda/core/src/overlay/group.rs

182 lines
4.8 KiB
Rust
Raw Normal View History

2023-01-17 10:01:17 -08:00
use crate::layout;
use crate::mouse;
use crate::overlay;
use crate::renderer;
use crate::widget;
use crate::{Clipboard, Event, Layout, Overlay, Point, Rectangle, Shell, Size};
2023-01-17 10:01:17 -08:00
/// An [`Overlay`] container that displays multiple overlay [`overlay::Element`]
/// children.
2023-01-17 10:01:17 -08:00
#[allow(missing_debug_implementations)]
pub struct Group<'a, Message, Theme, Renderer> {
children: Vec<overlay::Element<'a, Message, Theme, Renderer>>,
2023-01-17 10:01:17 -08:00
}
impl<'a, Message, Theme, Renderer> Group<'a, Message, Theme, Renderer>
2023-01-17 10:01:17 -08:00
where
Message: 'a,
Theme: 'a,
Renderer: 'a + crate::Renderer,
2023-01-17 10:01:17 -08:00
{
/// Creates an empty [`Group`].
pub fn new() -> Self {
Self::default()
}
/// Creates a [`Group`] with the given elements.
pub fn with_children(
children: Vec<overlay::Element<'a, Message, Theme, Renderer>>,
2023-01-17 10:01:17 -08:00
) -> Self {
Group { children }
}
/// Adds an [`overlay::Element`] to the [`Group`].
pub fn push(
mut self,
child: impl Into<overlay::Element<'a, Message, Theme, Renderer>>,
2023-01-17 10:01:17 -08:00
) -> Self {
self.children.push(child.into());
self
}
/// Turns the [`Group`] into an overlay [`overlay::Element`].
pub fn overlay(self) -> overlay::Element<'a, Message, Theme, Renderer> {
overlay::Element::new(Box::new(self))
2023-01-17 10:01:17 -08:00
}
}
impl<'a, Message, Theme, Renderer> Default
for Group<'a, Message, Theme, Renderer>
2023-01-17 10:01:17 -08:00
where
Message: 'a,
Theme: 'a,
Renderer: 'a + crate::Renderer,
2023-01-17 10:01:17 -08:00
{
fn default() -> Self {
Self::with_children(Vec::new())
}
}
impl<'a, Message, Theme, Renderer> Overlay<Message, Theme, Renderer>
for Group<'a, Message, Theme, Renderer>
2023-01-17 10:01:17 -08:00
where
Renderer: crate::Renderer,
{
fn layout(&mut self, renderer: &Renderer, bounds: Size) -> layout::Node {
2023-01-17 10:01:17 -08:00
layout::Node::with_children(
bounds,
self.children
.iter_mut()
.map(|child| child.layout(renderer, bounds))
2023-01-17 10:01:17 -08:00
.collect(),
)
}
2024-11-06 00:02:46 +01:00
fn update(
2023-01-17 10:01:17 -08:00
&mut self,
event: Event,
layout: Layout<'_>,
2023-06-08 20:11:59 +02:00
cursor: mouse::Cursor,
2023-01-17 10:01:17 -08:00
renderer: &Renderer,
clipboard: &mut dyn Clipboard,
shell: &mut Shell<'_, Message>,
) {
for (child, layout) in self.children.iter_mut().zip(layout.children()) {
2024-11-06 00:02:46 +01:00
child.update(
event.clone(),
layout,
cursor,
renderer,
clipboard,
shell,
);
}
2023-01-17 10:01:17 -08:00
}
fn draw(
&self,
renderer: &mut Renderer,
theme: &Theme,
2023-01-17 10:01:17 -08:00
style: &renderer::Style,
layout: Layout<'_>,
2023-06-08 20:11:59 +02:00
cursor: mouse::Cursor,
2023-01-17 10:01:17 -08:00
) {
for (child, layout) in self.children.iter().zip(layout.children()) {
2023-06-08 20:11:59 +02:00
child.draw(renderer, theme, style, layout, cursor);
2023-01-17 10:01:17 -08:00
}
}
fn mouse_interaction(
&self,
layout: Layout<'_>,
2023-06-08 20:11:59 +02:00
cursor: mouse::Cursor,
2023-01-17 10:01:17 -08:00
viewport: &Rectangle,
renderer: &Renderer,
) -> mouse::Interaction {
self.children
.iter()
.zip(layout.children())
.map(|(child, layout)| {
2023-06-08 20:11:59 +02:00
child.mouse_interaction(layout, cursor, viewport, renderer)
2023-01-17 10:01:17 -08:00
})
.max()
.unwrap_or_default()
}
fn operate(
&mut self,
layout: Layout<'_>,
renderer: &Renderer,
operation: &mut dyn widget::Operation,
2023-01-17 10:01:17 -08:00
) {
operation.container(None, layout.bounds(), &mut |operation| {
2023-01-17 10:01:17 -08:00
self.children.iter_mut().zip(layout.children()).for_each(
|(child, layout)| {
child.operate(layout, renderer, operation);
},
);
2023-01-17 10:01:17 -08:00
});
}
fn is_over(
&self,
layout: Layout<'_>,
renderer: &Renderer,
cursor_position: Point,
) -> bool {
self.children
.iter()
.zip(layout.children())
.any(|(child, layout)| {
child.is_over(layout, renderer, cursor_position)
})
}
fn overlay<'b>(
&'b mut self,
layout: Layout<'_>,
renderer: &Renderer,
) -> Option<overlay::Element<'b, Message, Theme, Renderer>> {
let children = self
.children
.iter_mut()
.zip(layout.children())
.filter_map(|(child, layout)| child.overlay(layout, renderer))
.collect::<Vec<_>>();
(!children.is_empty()).then(|| Group::with_children(children).overlay())
}
2023-01-17 10:01:17 -08:00
}
impl<'a, Message, Theme, Renderer> From<Group<'a, Message, Theme, Renderer>>
for overlay::Element<'a, Message, Theme, Renderer>
2023-01-17 10:01:17 -08:00
where
Message: 'a,
Theme: 'a,
Renderer: 'a + crate::Renderer,
2023-01-17 10:01:17 -08:00
{
fn from(group: Group<'a, Message, Theme, Renderer>) -> Self {
2023-01-17 10:01:17 -08:00
group.overlay()
}
}