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