1use crate::event;
2use crate::layout;
3use crate::mouse;
4use crate::overlay;
5use crate::renderer;
6use crate::widget;
7use crate::{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 shell: &mut Shell<'_, Message>,
158 ) {
159 fn recurse<Message, Theme, Renderer>(
160 element: &mut overlay::Element<'_, Message, Theme, Renderer>,
161 layout: Layout<'_>,
162 event: &Event,
163 cursor: mouse::Cursor,
164 renderer: &Renderer,
165 shell: &mut Shell<'_, Message>,
166 ) -> bool
167 where
168 Renderer: renderer::Renderer,
169 {
170 let mut layouts = layout.children();
171
172 if let Some(layout) = layouts.next() {
173 let overlay = element.as_overlay_mut();
174
175 let nested_is_over = if let Some((mut nested, nested_layout)) =
176 overlay.overlay(layout, renderer).zip(layouts.next())
177 {
178 recurse(&mut nested, nested_layout, event, cursor, renderer, shell)
179 } else {
180 false
181 };
182
183 if shell.event_status() == event::Status::Ignored {
184 let is_over = nested_is_over
185 || cursor
186 .position()
187 .map(|cursor_position| {
188 overlay.mouse_interaction(
189 layout,
190 mouse::Cursor::Available(cursor_position),
191 renderer,
192 ) != mouse::Interaction::None
193 })
194 .unwrap_or_default();
195
196 overlay.update(
197 event,
198 layout,
199 if nested_is_over {
200 mouse::Cursor::Unavailable
201 } else {
202 cursor
203 },
204 renderer,
205 shell,
206 );
207
208 is_over
209 } else {
210 nested_is_over
211 }
212 } else {
213 false
214 }
215 }
216
217 let _ = recurse(&mut self.overlay, layout, event, cursor, renderer, shell);
218 }
219
220 pub fn mouse_interaction(
222 &mut self,
223 layout: Layout<'_>,
224 cursor: mouse::Cursor,
225 renderer: &Renderer,
226 ) -> mouse::Interaction {
227 fn recurse<Message, Theme, Renderer>(
228 element: &mut overlay::Element<'_, Message, Theme, Renderer>,
229 layout: Layout<'_>,
230 cursor: mouse::Cursor,
231 renderer: &Renderer,
232 ) -> Option<mouse::Interaction>
233 where
234 Renderer: renderer::Renderer,
235 {
236 let mut layouts = layout.children();
237
238 let layout = layouts.next()?;
239 let overlay = element.as_overlay_mut();
240
241 Some(
242 overlay
243 .overlay(layout, renderer)
244 .zip(layouts.next())
245 .and_then(|(mut overlay, layout)| {
246 recurse(&mut overlay, layout, cursor, renderer)
247 })
248 .unwrap_or_else(|| overlay.mouse_interaction(layout, cursor, renderer)),
249 )
250 }
251
252 recurse(&mut self.overlay, layout, cursor, renderer).unwrap_or_default()
253 }
254}