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