1use crate::layout;
2use crate::mouse;
3use crate::overlay;
4use crate::renderer;
5use crate::shell;
6use crate::widget;
7use crate::widget::tree::{self, Tree};
8use crate::{Border, Color, Event, Layout, Length, Rectangle, Shell, Size, Vector, Widget};
9
10use std::borrow::{Borrow, BorrowMut};
11
12pub struct Element<'a, Message, Theme, Renderer> {
22 widget: Box<dyn Widget<Message, Theme, Renderer> + 'a>,
23}
24
25impl<'a, Message, Theme, Renderer> Element<'a, Message, Theme, Renderer> {
26 pub fn new(widget: impl Widget<Message, Theme, Renderer> + 'a) -> Self
28 where
29 Renderer: crate::Renderer,
30 {
31 Self {
32 widget: Box::new(widget),
33 }
34 }
35
36 pub fn as_widget(&self) -> &dyn Widget<Message, Theme, Renderer> {
38 self.widget.as_ref()
39 }
40
41 pub fn as_widget_mut(&mut self) -> &mut dyn Widget<Message, Theme, Renderer> {
43 self.widget.as_mut()
44 }
45
46 pub fn map<B>(self, f: impl Fn(Message) -> B + 'a) -> Element<'a, B, Theme, Renderer>
186 where
187 Message: 'a,
188 Theme: 'a,
189 Renderer: crate::Renderer + 'a,
190 B: 'a,
191 {
192 Element::new(Map::new(self.widget, f))
193 }
194
195 pub fn explain<C: Into<Color>>(self, color: C) -> Element<'a, Message, Theme, Renderer>
202 where
203 Message: 'a,
204 Theme: 'a,
205 Renderer: crate::Renderer + 'a,
206 {
207 Element {
208 widget: Box::new(Explain::new(self, color.into())),
209 }
210 }
211}
212
213impl<'a, Message, Theme, Renderer> Borrow<dyn Widget<Message, Theme, Renderer> + 'a>
214 for Element<'a, Message, Theme, Renderer>
215{
216 fn borrow(&self) -> &(dyn Widget<Message, Theme, Renderer> + 'a) {
217 self.widget.borrow()
218 }
219}
220
221impl<'a, Message, Theme, Renderer> Borrow<dyn Widget<Message, Theme, Renderer> + 'a>
222 for &Element<'a, Message, Theme, Renderer>
223{
224 fn borrow(&self) -> &(dyn Widget<Message, Theme, Renderer> + 'a) {
225 self.widget.borrow()
226 }
227}
228
229impl<'a, Message, Theme, Renderer> Borrow<dyn Widget<Message, Theme, Renderer> + 'a>
230 for &mut Element<'a, Message, Theme, Renderer>
231{
232 fn borrow(&self) -> &(dyn Widget<Message, Theme, Renderer> + 'a) {
233 self.widget.borrow()
234 }
235}
236
237impl<'a, Message, Theme, Renderer> BorrowMut<dyn Widget<Message, Theme, Renderer> + 'a>
238 for Element<'a, Message, Theme, Renderer>
239{
240 fn borrow_mut(&mut self) -> &mut (dyn Widget<Message, Theme, Renderer> + 'a) {
241 self.widget.borrow_mut()
242 }
243}
244
245impl<'a, Message, Theme, Renderer> BorrowMut<dyn Widget<Message, Theme, Renderer> + 'a>
246 for &mut Element<'a, Message, Theme, Renderer>
247{
248 fn borrow_mut(&mut self) -> &mut (dyn Widget<Message, Theme, Renderer> + 'a) {
249 self.widget.borrow_mut()
250 }
251}
252
253struct Map<'a, A, B, Theme, Renderer> {
254 widget: Box<dyn Widget<A, Theme, Renderer> + 'a>,
255 mapper: Box<dyn Fn(A) -> B + 'a>,
256}
257
258impl<'a, A, B, Theme, Renderer> Map<'a, A, B, Theme, Renderer> {
259 pub fn new<F>(
260 widget: Box<dyn Widget<A, Theme, Renderer> + 'a>,
261 mapper: F,
262 ) -> Map<'a, A, B, Theme, Renderer>
263 where
264 F: 'a + Fn(A) -> B,
265 {
266 Map {
267 widget,
268 mapper: Box::new(mapper),
269 }
270 }
271}
272
273impl<'a, A, B, Theme, Renderer> Widget<B, Theme, Renderer> for Map<'a, A, B, Theme, Renderer>
274where
275 Renderer: crate::Renderer + 'a,
276 A: 'a,
277 B: 'a,
278{
279 fn tag(&self) -> tree::Tag {
280 self.widget.tag()
281 }
282
283 fn state(&self) -> tree::State {
284 self.widget.state()
285 }
286
287 fn diff(&mut self, tree: &mut Tree) {
288 self.widget.diff(tree);
289 }
290
291 fn size(&self) -> Size<Length> {
292 self.widget.size()
293 }
294
295 fn layout(
296 &mut self,
297 tree: &mut Tree,
298 renderer: &Renderer,
299 limits: &layout::Limits,
300 ) -> layout::Node {
301 self.widget.layout(tree, renderer, limits)
302 }
303
304 fn operate(
305 &mut self,
306 tree: &mut Tree,
307 layout: Layout<'_>,
308 viewport: &Rectangle,
309 renderer: &Renderer,
310 operation: &mut dyn widget::Operation,
311 ) {
312 self.widget
313 .operate(tree, layout, viewport, renderer, operation);
314 }
315
316 fn update(
317 &mut self,
318 tree: &mut Tree,
319 event: &Event,
320 layout: Layout<'_>,
321 cursor: mouse::Cursor,
322 renderer: &Renderer,
323 shell: &mut Shell<'_, B>,
324 viewport: &Rectangle,
325 ) {
326 let mut local_messages = shell::Bus::new();
327 let mut local_shell = shell.local(&mut local_messages);
328
329 self.widget.update(
330 tree,
331 event,
332 layout,
333 cursor,
334 renderer,
335 &mut local_shell,
336 viewport,
337 );
338
339 shell.merge(local_shell, &self.mapper);
340 }
341
342 fn draw(
343 &self,
344 tree: &Tree,
345 renderer: &mut Renderer,
346 theme: &Theme,
347 style: &renderer::Style,
348 layout: Layout<'_>,
349 cursor: mouse::Cursor,
350 viewport: &Rectangle,
351 ) {
352 self.widget
353 .draw(tree, renderer, theme, style, layout, cursor, viewport);
354 }
355
356 fn mouse_interaction(
357 &self,
358 tree: &Tree,
359 layout: Layout<'_>,
360 cursor: mouse::Cursor,
361 viewport: &Rectangle,
362 renderer: &Renderer,
363 ) -> mouse::Interaction {
364 self.widget
365 .mouse_interaction(tree, layout, cursor, viewport, renderer)
366 }
367
368 fn overlay<'b>(
369 &'b mut self,
370 tree: &'b mut Tree,
371 layout: Layout<'b>,
372 renderer: &Renderer,
373 viewport: &Rectangle,
374 translation: Vector,
375 ) -> Vec<overlay::Element<'b, B, Theme, Renderer>> {
376 let mapper = &self.mapper;
377
378 self.widget
379 .overlay(tree, layout, renderer, viewport, translation)
380 .into_iter()
381 .map(move |overlay| overlay.map(mapper))
382 .collect()
383 }
384}
385
386struct Explain<'a, Message, Theme, Renderer: crate::Renderer> {
387 element: Element<'a, Message, Theme, Renderer>,
388 color: Color,
389}
390
391impl<'a, Message, Theme, Renderer> Explain<'a, Message, Theme, Renderer>
392where
393 Renderer: crate::Renderer,
394{
395 fn new(element: Element<'a, Message, Theme, Renderer>, color: Color) -> Self {
396 Explain { element, color }
397 }
398}
399
400impl<Message, Theme, Renderer> Widget<Message, Theme, Renderer>
401 for Explain<'_, Message, Theme, Renderer>
402where
403 Renderer: crate::Renderer,
404{
405 fn size(&self) -> Size<Length> {
406 self.element.widget.size()
407 }
408
409 fn tag(&self) -> tree::Tag {
410 self.element.widget.tag()
411 }
412
413 fn state(&self) -> tree::State {
414 self.element.widget.state()
415 }
416
417 fn diff(&mut self, tree: &mut Tree) {
418 self.element.widget.diff(tree);
419 }
420
421 fn layout(
422 &mut self,
423 tree: &mut Tree,
424 renderer: &Renderer,
425 limits: &layout::Limits,
426 ) -> layout::Node {
427 self.element.widget.layout(tree, renderer, limits)
428 }
429
430 fn operate(
431 &mut self,
432 tree: &mut Tree,
433 layout: Layout<'_>,
434 viewport: &Rectangle,
435 renderer: &Renderer,
436 operation: &mut dyn widget::Operation,
437 ) {
438 self.element
439 .widget
440 .operate(tree, layout, viewport, renderer, operation);
441 }
442
443 fn update(
444 &mut self,
445 tree: &mut Tree,
446 event: &Event,
447 layout: Layout<'_>,
448 cursor: mouse::Cursor,
449 renderer: &Renderer,
450 shell: &mut Shell<'_, Message>,
451 viewport: &Rectangle,
452 ) {
453 self.element
454 .widget
455 .update(tree, event, layout, cursor, renderer, shell, viewport);
456 }
457
458 fn draw(
459 &self,
460 tree: &Tree,
461 renderer: &mut Renderer,
462 theme: &Theme,
463 style: &renderer::Style,
464 layout: Layout<'_>,
465 cursor: mouse::Cursor,
466 viewport: &Rectangle,
467 ) {
468 fn explain_layout<Renderer: crate::Renderer>(
469 renderer: &mut Renderer,
470 color: Color,
471 layout: Layout<'_>,
472 ) {
473 renderer.fill_quad(
474 renderer::Quad {
475 bounds: layout.bounds(),
476 border: Border {
477 color,
478 width: 1.0,
479 ..Border::default()
480 },
481 ..renderer::Quad::default()
482 },
483 Color::TRANSPARENT,
484 );
485
486 for child in layout.children() {
487 explain_layout(renderer, color, child);
488 }
489 }
490
491 self.element
492 .widget
493 .draw(tree, renderer, theme, style, layout, cursor, viewport);
494
495 renderer.with_layer(Rectangle::INFINITE, |renderer| {
496 explain_layout(renderer, self.color, layout);
497 });
498 }
499
500 fn mouse_interaction(
501 &self,
502 tree: &Tree,
503 layout: Layout<'_>,
504 cursor: mouse::Cursor,
505 viewport: &Rectangle,
506 renderer: &Renderer,
507 ) -> mouse::Interaction {
508 self.element
509 .widget
510 .mouse_interaction(tree, layout, cursor, viewport, renderer)
511 }
512
513 fn overlay<'b>(
514 &'b mut self,
515 tree: &'b mut Tree,
516 layout: Layout<'b>,
517 renderer: &Renderer,
518 viewport: &Rectangle,
519 translation: Vector,
520 ) -> Vec<overlay::Element<'b, Message, Theme, Renderer>> {
521 self.element
522 .widget
523 .overlay(tree, layout, renderer, viewport, translation)
524 }
525}
526
527impl<'a, T, Message, Theme, Renderer> From<Option<T>> for Element<'a, Message, Theme, Renderer>
528where
529 T: Into<Self>,
530 Renderer: crate::Renderer,
531{
532 fn from(value: Option<T>) -> Self {
533 value
534 .map(T::into)
535 .unwrap_or_else(|| Element::new(widget::Void))
536 }
537}
538
539impl<'a, Message, Theme, Renderer> From<widget::Void> for Element<'a, Message, Theme, Renderer>
540where
541 Renderer: crate::Renderer,
542{
543 fn from(void: widget::Void) -> Self {
544 Element::new(void)
545 }
546}