1use crate::core::layout;
3use crate::core::mouse;
4use crate::core::overlay;
5use crate::core::renderer;
6use crate::core::widget::{Operation, Tree};
7use crate::core::{
8 Clipboard, Element, Event, Layout, Length, Rectangle, Shell, Size, Vector,
9 Widget,
10};
11
12#[allow(missing_debug_implementations)]
21pub struct Stack<'a, Message, Theme = crate::Theme, Renderer = crate::Renderer>
22{
23 width: Length,
24 height: Length,
25 children: Vec<Element<'a, Message, Theme, Renderer>>,
26 clip: bool,
27}
28
29impl<'a, Message, Theme, Renderer> Stack<'a, Message, Theme, Renderer>
30where
31 Renderer: crate::core::Renderer,
32{
33 pub fn new() -> Self {
35 Self::from_vec(Vec::new())
36 }
37
38 pub fn with_capacity(capacity: usize) -> Self {
40 Self::from_vec(Vec::with_capacity(capacity))
41 }
42
43 pub fn with_children(
45 children: impl IntoIterator<Item = Element<'a, Message, Theme, Renderer>>,
46 ) -> Self {
47 let iterator = children.into_iter();
48
49 Self::with_capacity(iterator.size_hint().0).extend(iterator)
50 }
51
52 pub fn from_vec(
60 children: Vec<Element<'a, Message, Theme, Renderer>>,
61 ) -> Self {
62 Self {
63 width: Length::Shrink,
64 height: Length::Shrink,
65 children,
66 clip: false,
67 }
68 }
69
70 pub fn width(mut self, width: impl Into<Length>) -> Self {
72 self.width = width.into();
73 self
74 }
75
76 pub fn height(mut self, height: impl Into<Length>) -> Self {
78 self.height = height.into();
79 self
80 }
81
82 pub fn push(
84 mut self,
85 child: impl Into<Element<'a, Message, Theme, Renderer>>,
86 ) -> Self {
87 let child = child.into();
88
89 if self.children.is_empty() {
90 let child_size = child.as_widget().size_hint();
91
92 self.width = self.width.enclose(child_size.width);
93 self.height = self.height.enclose(child_size.height);
94 }
95
96 self.children.push(child);
97 self
98 }
99
100 pub fn push_maybe(
102 self,
103 child: Option<impl Into<Element<'a, Message, Theme, Renderer>>>,
104 ) -> Self {
105 if let Some(child) = child {
106 self.push(child)
107 } else {
108 self
109 }
110 }
111
112 pub fn extend(
114 self,
115 children: impl IntoIterator<Item = Element<'a, Message, Theme, Renderer>>,
116 ) -> Self {
117 children.into_iter().fold(self, Self::push)
118 }
119
120 pub fn clip(mut self, clip: bool) -> Self {
126 self.clip = clip;
127 self
128 }
129}
130
131impl<Message, Renderer> Default for Stack<'_, Message, Renderer>
132where
133 Renderer: crate::core::Renderer,
134{
135 fn default() -> Self {
136 Self::new()
137 }
138}
139
140impl<'a, Message, Theme, Renderer> Widget<Message, Theme, Renderer>
141 for Stack<'a, Message, Theme, Renderer>
142where
143 Renderer: crate::core::Renderer,
144{
145 fn children(&self) -> Vec<Tree> {
146 self.children.iter().map(Tree::new).collect()
147 }
148
149 fn diff(&self, tree: &mut Tree) {
150 tree.diff_children(&self.children);
151 }
152
153 fn size(&self) -> Size<Length> {
154 Size {
155 width: self.width,
156 height: self.height,
157 }
158 }
159
160 fn layout(
161 &mut self,
162 tree: &mut Tree,
163 renderer: &Renderer,
164 limits: &layout::Limits,
165 ) -> layout::Node {
166 let limits = limits.width(self.width).height(self.height);
167
168 if self.children.is_empty() {
169 return layout::Node::new(limits.resolve(
170 self.width,
171 self.height,
172 Size::ZERO,
173 ));
174 }
175
176 let base = self.children[0].as_widget_mut().layout(
177 &mut tree.children[0],
178 renderer,
179 &limits,
180 );
181
182 let size = limits.resolve(self.width, self.height, base.size());
183 let limits = layout::Limits::new(Size::ZERO, size);
184
185 let nodes = std::iter::once(base)
186 .chain(
187 self.children[1..]
188 .iter_mut()
189 .zip(&mut tree.children[1..])
190 .map(|(layer, tree)| {
191 layer.as_widget_mut().layout(tree, renderer, &limits)
192 }),
193 )
194 .collect();
195
196 layout::Node::with_children(size, nodes)
197 }
198
199 fn operate(
200 &mut self,
201 tree: &mut Tree,
202 layout: Layout<'_>,
203 renderer: &Renderer,
204 operation: &mut dyn Operation,
205 ) {
206 operation.container(None, layout.bounds(), &mut |operation| {
207 self.children
208 .iter_mut()
209 .zip(&mut tree.children)
210 .zip(layout.children())
211 .for_each(|((child, state), layout)| {
212 child
213 .as_widget_mut()
214 .operate(state, layout, renderer, operation);
215 });
216 });
217 }
218
219 fn update(
220 &mut self,
221 tree: &mut Tree,
222 event: &Event,
223 layout: Layout<'_>,
224 mut cursor: mouse::Cursor,
225 renderer: &Renderer,
226 clipboard: &mut dyn Clipboard,
227 shell: &mut Shell<'_, Message>,
228 viewport: &Rectangle,
229 ) {
230 let is_over = cursor.is_over(layout.bounds());
231 let end = self.children.len() - 1;
232
233 for (i, ((child, state), layout)) in self
234 .children
235 .iter_mut()
236 .rev()
237 .zip(tree.children.iter_mut().rev())
238 .zip(layout.children().rev())
239 .enumerate()
240 {
241 child.as_widget_mut().update(
242 state, event, layout, cursor, renderer, clipboard, shell,
243 viewport,
244 );
245
246 if shell.is_event_captured() {
247 return;
248 }
249
250 if i < end && is_over && !cursor.is_levitating() {
251 let interaction = child.as_widget().mouse_interaction(
252 state, layout, cursor, viewport, renderer,
253 );
254
255 if interaction != mouse::Interaction::None {
256 cursor = cursor.levitate();
257 }
258 }
259 }
260 }
261
262 fn mouse_interaction(
263 &self,
264 tree: &Tree,
265 layout: Layout<'_>,
266 cursor: mouse::Cursor,
267 viewport: &Rectangle,
268 renderer: &Renderer,
269 ) -> mouse::Interaction {
270 self.children
271 .iter()
272 .rev()
273 .zip(tree.children.iter().rev())
274 .zip(layout.children().rev())
275 .map(|((child, state), layout)| {
276 child.as_widget().mouse_interaction(
277 state, layout, cursor, viewport, renderer,
278 )
279 })
280 .find(|&interaction| interaction != mouse::Interaction::None)
281 .unwrap_or_default()
282 }
283
284 fn draw(
285 &self,
286 tree: &Tree,
287 renderer: &mut Renderer,
288 theme: &Theme,
289 style: &renderer::Style,
290 layout: Layout<'_>,
291 cursor: mouse::Cursor,
292 viewport: &Rectangle,
293 ) {
294 if let Some(clipped_viewport) = layout.bounds().intersection(viewport) {
295 let viewport = if self.clip {
296 &clipped_viewport
297 } else {
298 viewport
299 };
300
301 let layers_below = if cursor.is_over(layout.bounds()) {
302 self.children
303 .iter()
304 .rev()
305 .zip(tree.children.iter().rev())
306 .zip(layout.children().rev())
307 .position(|((layer, state), layout)| {
308 let interaction = layer.as_widget().mouse_interaction(
309 state, layout, cursor, viewport, renderer,
310 );
311
312 interaction != mouse::Interaction::None
313 })
314 .map(|i| self.children.len() - i - 1)
315 .unwrap_or_default()
316 } else {
317 0
318 };
319
320 let mut layers = self
321 .children
322 .iter()
323 .zip(&tree.children)
324 .zip(layout.children())
325 .enumerate();
326
327 let layers = layers.by_ref();
328
329 let mut draw_layer =
330 |i,
331 layer: &Element<'a, Message, Theme, Renderer>,
332 state,
333 layout,
334 cursor| {
335 if i > 0 {
336 renderer.with_layer(*viewport, |renderer| {
337 layer.as_widget().draw(
338 state, renderer, theme, style, layout, cursor,
339 viewport,
340 );
341 });
342 } else {
343 layer.as_widget().draw(
344 state, renderer, theme, style, layout, cursor,
345 viewport,
346 );
347 }
348 };
349
350 for (i, ((layer, state), layout)) in layers.take(layers_below) {
351 draw_layer(i, layer, state, layout, mouse::Cursor::Unavailable);
352 }
353
354 for (i, ((layer, state), layout)) in layers {
355 draw_layer(i, layer, state, layout, cursor);
356 }
357 }
358 }
359
360 fn overlay<'b>(
361 &'b mut self,
362 tree: &'b mut Tree,
363 layout: Layout<'b>,
364 renderer: &Renderer,
365 viewport: &Rectangle,
366 translation: Vector,
367 ) -> Option<overlay::Element<'b, Message, Theme, Renderer>> {
368 overlay::from_children(
369 &mut self.children,
370 tree,
371 layout,
372 renderer,
373 viewport,
374 translation,
375 )
376 }
377}
378
379impl<'a, Message, Theme, Renderer> From<Stack<'a, Message, Theme, Renderer>>
380 for Element<'a, Message, Theme, Renderer>
381where
382 Message: 'a,
383 Theme: 'a,
384 Renderer: crate::core::Renderer + 'a,
385{
386 fn from(stack: Stack<'a, Message, Theme, Renderer>) -> Self {
387 Self::new(stack)
388 }
389}