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#[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 pub fn new() -> Self {
23 Self::default()
24 }
25
26 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 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}