1use crate::core::event;
2use crate::core::layout;
3use crate::core::mouse;
4use crate::core::overlay;
5use crate::core::renderer;
6use crate::core::widget;
7use crate::core::{Clipboard, Event, Layout, Shell, Size};
8
9#[allow(missing_debug_implementations)]
11pub struct Nested<'a, Message, Theme, Renderer> {
12 overlay: overlay::Element<'a, Message, Theme, Renderer>,
13}
14
15impl<'a, Message, Theme, Renderer> Nested<'a, Message, Theme, Renderer>
16where
17 Renderer: renderer::Renderer,
18{
19 pub fn new(
21 element: overlay::Element<'a, Message, Theme, Renderer>,
22 ) -> Self {
23 Self { overlay: element }
24 }
25
26 pub fn layout(
30 &mut self,
31 renderer: &Renderer,
32 bounds: Size,
33 ) -> layout::Node {
34 fn recurse<Message, Theme, Renderer>(
35 element: &mut overlay::Element<'_, Message, Theme, Renderer>,
36 renderer: &Renderer,
37 bounds: Size,
38 ) -> layout::Node
39 where
40 Renderer: renderer::Renderer,
41 {
42 let overlay = element.as_overlay_mut();
43 let node = overlay.layout(renderer, bounds);
44
45 let nested_node = overlay
46 .overlay(Layout::new(&node), renderer)
47 .as_mut()
48 .map(|nested| recurse(nested, renderer, bounds));
49
50 if let Some(nested_node) = nested_node {
51 layout::Node::with_children(
52 node.size(),
53 vec![node, nested_node],
54 )
55 } else {
56 layout::Node::with_children(node.size(), vec![node])
57 }
58 }
59
60 recurse(&mut self.overlay, renderer, bounds)
61 }
62
63 pub fn draw(
65 &mut self,
66 renderer: &mut Renderer,
67 theme: &Theme,
68 style: &renderer::Style,
69 layout: Layout<'_>,
70 cursor: mouse::Cursor,
71 ) {
72 fn recurse<Message, Theme, Renderer>(
73 element: &mut overlay::Element<'_, Message, Theme, Renderer>,
74 layout: Layout<'_>,
75 renderer: &mut Renderer,
76 theme: &Theme,
77 style: &renderer::Style,
78 cursor: mouse::Cursor,
79 ) where
80 Renderer: renderer::Renderer,
81 {
82 let mut layouts = layout.children();
83
84 if let Some(layout) = layouts.next() {
85 let nested_layout = layouts.next();
86 let overlay = element.as_overlay_mut();
87
88 let is_over = cursor
89 .position()
90 .zip(nested_layout)
91 .and_then(|(cursor_position, nested_layout)| {
92 overlay.overlay(layout, renderer).map(|nested| {
93 nested.as_overlay().mouse_interaction(
94 nested_layout.children().next().unwrap(),
95 mouse::Cursor::Available(cursor_position),
96 renderer,
97 ) != mouse::Interaction::None
98 })
99 })
100 .unwrap_or_default();
101
102 renderer.with_layer(layout.bounds(), |renderer| {
103 overlay.draw(
104 renderer,
105 theme,
106 style,
107 layout,
108 if is_over {
109 mouse::Cursor::Unavailable
110 } else {
111 cursor
112 },
113 );
114 });
115
116 if let Some((mut nested, nested_layout)) =
117 overlay.overlay(layout, renderer).zip(nested_layout)
118 {
119 recurse(
120 &mut nested,
121 nested_layout,
122 renderer,
123 theme,
124 style,
125 cursor,
126 );
127 }
128 }
129 }
130
131 recurse(&mut self.overlay, layout, renderer, theme, style, cursor);
132 }
133
134 pub fn operate(
136 &mut self,
137 layout: Layout<'_>,
138 renderer: &Renderer,
139 operation: &mut dyn widget::Operation,
140 ) {
141 fn recurse<Message, Theme, Renderer>(
142 element: &mut overlay::Element<'_, Message, Theme, Renderer>,
143 layout: Layout<'_>,
144 renderer: &Renderer,
145 operation: &mut dyn widget::Operation,
146 ) where
147 Renderer: renderer::Renderer,
148 {
149 let mut layouts = layout.children();
150
151 if let Some(layout) = layouts.next() {
152 let overlay = element.as_overlay_mut();
153
154 overlay.operate(layout, renderer, operation);
155
156 if let Some((mut nested, nested_layout)) =
157 overlay.overlay(layout, renderer).zip(layouts.next())
158 {
159 recurse(&mut nested, nested_layout, renderer, operation);
160 }
161 }
162 }
163
164 recurse(&mut self.overlay, layout, renderer, operation);
165 }
166
167 pub fn update(
169 &mut self,
170 event: &Event,
171 layout: Layout<'_>,
172 cursor: mouse::Cursor,
173 renderer: &Renderer,
174 clipboard: &mut dyn Clipboard,
175 shell: &mut Shell<'_, Message>,
176 ) {
177 fn recurse<Message, Theme, Renderer>(
178 element: &mut overlay::Element<'_, Message, Theme, Renderer>,
179 layout: Layout<'_>,
180 event: &Event,
181 cursor: mouse::Cursor,
182 renderer: &Renderer,
183 clipboard: &mut dyn Clipboard,
184 shell: &mut Shell<'_, Message>,
185 ) -> bool
186 where
187 Renderer: renderer::Renderer,
188 {
189 let mut layouts = layout.children();
190
191 if let Some(layout) = layouts.next() {
192 let overlay = element.as_overlay_mut();
193
194 let nested_is_over = if let Some((mut nested, nested_layout)) =
195 overlay.overlay(layout, renderer).zip(layouts.next())
196 {
197 recurse(
198 &mut nested,
199 nested_layout,
200 event,
201 cursor,
202 renderer,
203 clipboard,
204 shell,
205 )
206 } else {
207 false
208 };
209
210 if shell.event_status() == event::Status::Ignored {
211 let is_over = nested_is_over
212 || cursor
213 .position()
214 .map(|cursor_position| {
215 overlay.mouse_interaction(
216 layout,
217 mouse::Cursor::Available(cursor_position),
218 renderer,
219 ) != mouse::Interaction::None
220 })
221 .unwrap_or_default();
222
223 overlay.update(
224 event,
225 layout,
226 if nested_is_over {
227 mouse::Cursor::Unavailable
228 } else {
229 cursor
230 },
231 renderer,
232 clipboard,
233 shell,
234 );
235
236 is_over
237 } else {
238 nested_is_over
239 }
240 } else {
241 false
242 }
243 }
244
245 let _ = recurse(
246 &mut self.overlay,
247 layout,
248 event,
249 cursor,
250 renderer,
251 clipboard,
252 shell,
253 );
254 }
255
256 pub fn mouse_interaction(
258 &mut self,
259 layout: Layout<'_>,
260 cursor: mouse::Cursor,
261 renderer: &Renderer,
262 ) -> mouse::Interaction {
263 fn recurse<Message, Theme, Renderer>(
264 element: &mut overlay::Element<'_, Message, Theme, Renderer>,
265 layout: Layout<'_>,
266 cursor: mouse::Cursor,
267 renderer: &Renderer,
268 ) -> Option<mouse::Interaction>
269 where
270 Renderer: renderer::Renderer,
271 {
272 let mut layouts = layout.children();
273
274 let layout = layouts.next()?;
275 let overlay = element.as_overlay_mut();
276
277 Some(
278 overlay
279 .overlay(layout, renderer)
280 .zip(layouts.next())
281 .and_then(|(mut overlay, layout)| {
282 recurse(&mut overlay, layout, cursor, renderer)
283 })
284 .unwrap_or_else(|| {
285 overlay.mouse_interaction(layout, cursor, renderer)
286 }),
287 )
288 }
289
290 recurse(&mut self.overlay, layout, cursor, renderer).unwrap_or_default()
291 }
292}