iced_core/overlay/
group.rs

1use crate::layout;
2use crate::mouse;
3use crate::overlay;
4use crate::renderer;
5use crate::widget;
6use crate::{Clipboard, Event, Layout, Overlay, Shell, Size};
7
8/// An [`Overlay`] container that displays multiple overlay [`overlay::Element`]
9/// children.
10#[allow(missing_debug_implementations)]
11pub struct Group<'a, Message, Theme, Renderer> {
12    children: Vec<overlay::Element<'a, Message, Theme, Renderer>>,
13}
14
15impl<'a, Message, Theme, Renderer> Group<'a, Message, Theme, Renderer>
16where
17    Message: 'a,
18    Theme: 'a,
19    Renderer: 'a + crate::Renderer,
20{
21    /// Creates an empty [`Group`].
22    pub fn new() -> Self {
23        Self::default()
24    }
25
26    /// Creates a [`Group`] with the given elements.
27    pub fn with_children(
28        mut children: Vec<overlay::Element<'a, Message, Theme, Renderer>>,
29    ) -> Self {
30        use std::cmp;
31
32        children.sort_unstable_by(|a, b| {
33            a.as_overlay()
34                .index()
35                .partial_cmp(&b.as_overlay().index())
36                .unwrap_or(cmp::Ordering::Equal)
37        });
38
39        Group { children }
40    }
41
42    /// Turns the [`Group`] into an overlay [`overlay::Element`].
43    pub fn overlay(self) -> overlay::Element<'a, Message, Theme, Renderer> {
44        overlay::Element::new(Box::new(self))
45    }
46}
47
48impl<'a, Message, Theme, Renderer> Default
49    for Group<'a, Message, Theme, Renderer>
50where
51    Message: 'a,
52    Theme: 'a,
53    Renderer: 'a + crate::Renderer,
54{
55    fn default() -> Self {
56        Self::with_children(Vec::new())
57    }
58}
59
60impl<Message, Theme, Renderer> Overlay<Message, Theme, Renderer>
61    for Group<'_, Message, Theme, Renderer>
62where
63    Renderer: crate::Renderer,
64{
65    fn layout(&mut self, renderer: &Renderer, bounds: Size) -> layout::Node {
66        layout::Node::with_children(
67            bounds,
68            self.children
69                .iter_mut()
70                .map(|child| child.as_overlay_mut().layout(renderer, bounds))
71                .collect(),
72        )
73    }
74
75    fn update(
76        &mut self,
77        event: &Event,
78        layout: Layout<'_>,
79        cursor: mouse::Cursor,
80        renderer: &Renderer,
81        clipboard: &mut dyn Clipboard,
82        shell: &mut Shell<'_, Message>,
83    ) {
84        for (child, layout) in self.children.iter_mut().zip(layout.children()) {
85            child
86                .as_overlay_mut()
87                .update(event, layout, cursor, renderer, clipboard, shell);
88        }
89    }
90
91    fn draw(
92        &self,
93        renderer: &mut Renderer,
94        theme: &Theme,
95        style: &renderer::Style,
96        layout: Layout<'_>,
97        cursor: mouse::Cursor,
98    ) {
99        for (child, layout) in self.children.iter().zip(layout.children()) {
100            child
101                .as_overlay()
102                .draw(renderer, theme, style, layout, cursor);
103        }
104    }
105
106    fn mouse_interaction(
107        &self,
108        layout: Layout<'_>,
109        cursor: mouse::Cursor,
110        renderer: &Renderer,
111    ) -> mouse::Interaction {
112        self.children
113            .iter()
114            .zip(layout.children())
115            .map(|(child, layout)| {
116                child
117                    .as_overlay()
118                    .mouse_interaction(layout, cursor, renderer)
119            })
120            .max()
121            .unwrap_or_default()
122    }
123
124    fn operate(
125        &mut self,
126        layout: Layout<'_>,
127        renderer: &Renderer,
128        operation: &mut dyn widget::Operation,
129    ) {
130        operation.container(None, layout.bounds(), &mut |operation| {
131            self.children.iter_mut().zip(layout.children()).for_each(
132                |(child, layout)| {
133                    child.as_overlay_mut().operate(layout, renderer, operation);
134                },
135            );
136        });
137    }
138
139    fn overlay<'a>(
140        &'a mut self,
141        layout: Layout<'a>,
142        renderer: &Renderer,
143    ) -> Option<overlay::Element<'a, Message, Theme, Renderer>> {
144        let children = self
145            .children
146            .iter_mut()
147            .zip(layout.children())
148            .filter_map(|(child, layout)| {
149                child.as_overlay_mut().overlay(layout, renderer)
150            })
151            .collect::<Vec<_>>();
152
153        (!children.is_empty()).then(|| Group::with_children(children).overlay())
154    }
155
156    fn index(&self) -> f32 {
157        self.children
158            .first()
159            .map(|child| child.as_overlay().index())
160            .unwrap_or(1.0)
161    }
162}
163
164impl<'a, Message, Theme, Renderer> From<Group<'a, Message, Theme, Renderer>>
165    for overlay::Element<'a, Message, Theme, Renderer>
166where
167    Message: 'a,
168    Theme: 'a,
169    Renderer: 'a + crate::Renderer,
170{
171    fn from(group: Group<'a, Message, Theme, Renderer>) -> Self {
172        group.overlay()
173    }
174}