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