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