1use crate::layout;
2use crate::mouse;
3use crate::overlay;
4use crate::renderer;
5use crate::widget;
6use crate::{Clipboard, Event, Layout, Overlay, Point, Rectangle, 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 children: Vec<overlay::Element<'a, Message, Theme, Renderer>>,
29 ) -> Self {
30 Group { children }
31 }
32
33 pub fn push(
35 mut self,
36 child: impl Into<overlay::Element<'a, Message, Theme, Renderer>>,
37 ) -> Self {
38 self.children.push(child.into());
39 self
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.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.update(event, layout, cursor, renderer, clipboard, shell);
86 }
87 }
88
89 fn draw(
90 &self,
91 renderer: &mut Renderer,
92 theme: &Theme,
93 style: &renderer::Style,
94 layout: Layout<'_>,
95 cursor: mouse::Cursor,
96 ) {
97 for (child, layout) in self.children.iter().zip(layout.children()) {
98 child.draw(renderer, theme, style, layout, cursor);
99 }
100 }
101
102 fn mouse_interaction(
103 &self,
104 layout: Layout<'_>,
105 cursor: mouse::Cursor,
106 viewport: &Rectangle,
107 renderer: &Renderer,
108 ) -> mouse::Interaction {
109 self.children
110 .iter()
111 .zip(layout.children())
112 .map(|(child, layout)| {
113 child.mouse_interaction(layout, cursor, viewport, renderer)
114 })
115 .max()
116 .unwrap_or_default()
117 }
118
119 fn operate(
120 &mut self,
121 layout: Layout<'_>,
122 renderer: &Renderer,
123 operation: &mut dyn widget::Operation,
124 ) {
125 operation.container(None, layout.bounds(), &mut |operation| {
126 self.children.iter_mut().zip(layout.children()).for_each(
127 |(child, layout)| {
128 child.operate(layout, renderer, operation);
129 },
130 );
131 });
132 }
133
134 fn is_over(
135 &self,
136 layout: Layout<'_>,
137 renderer: &Renderer,
138 cursor_position: Point,
139 ) -> bool {
140 self.children
141 .iter()
142 .zip(layout.children())
143 .any(|(child, layout)| {
144 child.is_over(layout, renderer, cursor_position)
145 })
146 }
147
148 fn overlay<'a>(
149 &'a mut self,
150 layout: Layout<'_>,
151 renderer: &Renderer,
152 ) -> Option<overlay::Element<'a, Message, Theme, Renderer>> {
153 let children = self
154 .children
155 .iter_mut()
156 .zip(layout.children())
157 .filter_map(|(child, layout)| child.overlay(layout, renderer))
158 .collect::<Vec<_>>();
159
160 (!children.is_empty()).then(|| Group::with_children(children).overlay())
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}