1use crate::core::layout;
3use crate::core::mouse;
4use crate::core::overlay;
5use crate::core::renderer;
6use crate::core::widget::{Meta, Operation, Tree};
7use crate::core::{Event, Layout, Length, Rectangle, Shell, Size, Vector, Widget};
8
9pub struct Stack<W> {
21 width: Length,
22 height: Length,
23 children: Vec<W>,
24 clip: bool,
25 base_layer: usize,
26}
27
28impl<W> Stack<W> {
29 pub fn new() -> Self {
31 Self::from_vec(Vec::new())
32 }
33
34 pub fn with_capacity(capacity: usize) -> Self {
36 Self::from_vec(Vec::with_capacity(capacity))
37 }
38
39 pub fn with_children(children: impl IntoIterator<Item = W>) -> Self
41 where
42 W: Meta,
43 {
44 let iterator = children.into_iter();
45
46 Self::with_capacity(iterator.size_hint().0).extend(iterator)
47 }
48
49 pub fn from_vec(children: Vec<W>) -> Self {
51 Self {
52 width: Length::Fit,
53 height: Length::Fit,
54 children,
55 clip: false,
56 base_layer: 0,
57 }
58 }
59
60 pub fn width(mut self, width: impl Into<Length>) -> Self {
62 self.width = width.into();
63 self
64 }
65
66 pub fn height(mut self, height: impl Into<Length>) -> Self {
68 self.height = height.into();
69 self
70 }
71
72 pub fn push(mut self, child: impl Into<W>) -> Self
74 where
75 W: Meta,
76 {
77 let child = child.into();
78
79 if !child.is_void() {
80 self.children.push(child);
81 }
82
83 self
84 }
85
86 pub fn push_under(mut self, child: impl Into<W>) -> Self {
88 self.children.insert(0, child.into());
89 self.base_layer += 1;
90 self
91 }
92
93 pub fn extend(self, children: impl IntoIterator<Item = W>) -> Self
95 where
96 W: Meta,
97 {
98 children.into_iter().fold(self, Self::push)
99 }
100
101 pub fn clip(mut self, clip: bool) -> Self {
107 self.clip = clip;
108 self
109 }
110}
111
112impl<W> Default for Stack<W> {
113 fn default() -> Self {
114 Self::new()
115 }
116}
117
118impl<W> Meta for Stack<W> {}
119
120impl<W, Message, Theme, Renderer> Widget<Message, Theme, Renderer> for Stack<W>
121where
122 W: Widget<Message, Theme, Renderer>,
123 Renderer: crate::core::Renderer,
124{
125 fn diff(&mut self, tree: &mut Tree) {
126 tree.diff_children(&mut self.children);
127
128 if let Some(base) = self.children.get(self.base_layer) {
129 let size = base.size();
130
131 self.width = self.width.cross(size.width);
132 self.height = self.height.cross(size.height);
133 }
134 }
135
136 fn size(&self) -> Size<Length> {
137 Size {
138 width: self.width,
139 height: self.height,
140 }
141 }
142
143 fn layout(&mut self, tree: &mut Tree, renderer: &Renderer, limits: &layout::Limits) {
144 let limits = limits.width(self.width).height(self.height);
145
146 if self.children.len() <= self.base_layer {
147 tree.size = limits.resolve(self.width, self.height, Size::ZERO);
148 return;
149 }
150
151 self.children[self.base_layer].layout(
152 &mut tree.children[self.base_layer],
153 renderer,
154 &limits,
155 );
156
157 let size = limits.resolve(self.width, self.height, tree.children[self.base_layer].size);
158 let limits = layout::Limits::new(Size::ZERO, size);
159
160 let (under, above) = self.children.split_at_mut(self.base_layer);
161 let (tree_under, tree_above) = tree.children.split_at_mut(self.base_layer);
162
163 under.iter_mut().zip(tree_under).for_each(|(layer, tree)| {
164 layer.layout(tree, renderer, &limits);
165 });
166
167 above[1..]
168 .iter_mut()
169 .zip(&mut tree_above[1..])
170 .for_each(|(layer, tree)| layer.layout(tree, renderer, &limits));
171
172 tree.size = size;
173 }
174
175 fn operate(
176 &mut self,
177 tree: &mut Tree,
178 layout: Layout,
179 viewport: &Rectangle,
180 renderer: &Renderer,
181 operation: &mut dyn Operation,
182 ) {
183 operation.container(None, layout.bounds(), viewport);
184 operation.traverse(&mut |operation| {
185 self.children
186 .iter_mut()
187 .zip(layout.iter_mut(&mut tree.children))
188 .for_each(|(child, (layout, state))| {
189 child.operate(state, layout, viewport, renderer, operation);
190 });
191 });
192 }
193
194 fn update(
195 &mut self,
196 tree: &mut Tree,
197 event: &Event,
198 layout: Layout,
199 mut cursor: mouse::Cursor,
200 renderer: &Renderer,
201 shell: &mut Shell<'_, Message>,
202 viewport: &Rectangle,
203 ) {
204 if self.children.is_empty() {
205 return;
206 }
207
208 let is_over = cursor.is_over(layout.bounds());
209 let end = self.children.len() - 1;
210
211 for (i, (child, (layout, tree))) in self
212 .children
213 .iter_mut()
214 .rev()
215 .zip(layout.iter_mut(&mut tree.children).rev())
216 .enumerate()
217 {
218 child.update(tree, event, layout, cursor, renderer, shell, viewport);
219
220 if shell.is_event_captured() {
221 return;
222 }
223
224 if i < end && is_over && !cursor.is_levitating() {
225 let interaction = child.mouse_interaction(tree, layout, cursor, viewport, renderer);
226
227 if interaction != mouse::Interaction::None {
228 cursor = cursor.levitate();
229 }
230 }
231 }
232 }
233
234 fn mouse_interaction(
235 &self,
236 tree: &Tree,
237 layout: Layout,
238 cursor: mouse::Cursor,
239 viewport: &Rectangle,
240 renderer: &Renderer,
241 ) -> mouse::Interaction {
242 self.children
243 .iter()
244 .rev()
245 .zip(layout.iter(&tree.children).rev())
246 .map(|(child, (layout, tree))| {
247 child.mouse_interaction(tree, layout, cursor, viewport, renderer)
248 })
249 .find(|&interaction| interaction != mouse::Interaction::None)
250 .unwrap_or_default()
251 }
252
253 fn draw(
254 &self,
255 tree: &Tree,
256 renderer: &mut Renderer,
257 theme: &Theme,
258 style: &renderer::Style,
259 layout: Layout,
260 cursor: mouse::Cursor,
261 viewport: &Rectangle,
262 ) {
263 if let Some(clipped_viewport) = layout.bounds().intersection(viewport) {
264 let viewport = if self.clip {
265 &clipped_viewport
266 } else {
267 viewport
268 };
269
270 let layers_under = if cursor.is_over(layout.bounds()) {
271 self.children
272 .iter()
273 .rev()
274 .zip(layout.iter(&tree.children).rev())
275 .position(|(layer, (layout, tree))| {
276 let interaction =
277 layer.mouse_interaction(tree, layout, cursor, viewport, renderer);
278
279 interaction != mouse::Interaction::None
280 })
281 .map(|i| self.children.len() - i - 1)
282 .unwrap_or_default()
283 } else {
284 0
285 };
286
287 let mut layers = self
288 .children
289 .iter()
290 .zip(layout.iter(&tree.children))
291 .enumerate();
292
293 let layers = layers.by_ref();
294
295 let mut draw_layer = |i, layer: &W, tree, layout, cursor| {
296 if i > 0 {
297 renderer.with_layer(*viewport, |renderer| {
298 layer.draw(tree, renderer, theme, style, layout, cursor, viewport);
299 });
300 } else {
301 layer.draw(tree, renderer, theme, style, layout, cursor, viewport);
302 }
303 };
304
305 for (i, (layer, (layout, tree))) in layers.take(layers_under) {
306 draw_layer(i, layer, tree, layout, mouse::Cursor::Unavailable);
307 }
308
309 for (i, (layer, (layout, tree))) in layers {
310 draw_layer(i, layer, tree, layout, cursor);
311 }
312 }
313 }
314
315 fn overlay<'b>(
316 &'b mut self,
317 tree: &'b mut Tree,
318 layout: Layout,
319 renderer: &Renderer,
320 viewport: &Rectangle,
321 translation: Vector,
322 window: Size,
323 ) -> Vec<overlay::Element<'b, Message, Theme, Renderer>> {
324 overlay::from_children(
325 &mut self.children,
326 tree,
327 layout,
328 renderer,
329 viewport,
330 translation,
331 window,
332 )
333 }
334}