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