iced_core/overlay/
element.rs

1pub use crate::Overlay;
2
3use crate::layout;
4use crate::mouse;
5use crate::renderer;
6use crate::widget;
7use crate::{Clipboard, Event, Layout, Shell, Size};
8
9/// A generic [`Overlay`].
10pub struct Element<'a, Message, Theme, Renderer> {
11    overlay: Box<dyn Overlay<Message, Theme, Renderer> + 'a>,
12}
13
14impl<'a, Message, Theme, Renderer> Element<'a, Message, Theme, Renderer>
15where
16    Renderer: crate::Renderer,
17{
18    /// Creates a new [`Element`] containing the given [`Overlay`].
19    pub fn new(overlay: Box<dyn Overlay<Message, Theme, Renderer> + 'a>) -> Self {
20        Self { overlay }
21    }
22
23    /// Returns a reference to the [`Overlay`] of the [`Element`],
24    pub fn as_overlay(&self) -> &dyn Overlay<Message, Theme, Renderer> {
25        self.overlay.as_ref()
26    }
27
28    /// Returns a mutable reference to the [`Overlay`] of the [`Element`],
29    pub fn as_overlay_mut(&mut self) -> &mut dyn Overlay<Message, Theme, Renderer> {
30        self.overlay.as_mut()
31    }
32
33    /// Applies a transformation to the produced message of the [`Element`].
34    pub fn map<B>(self, f: &'a dyn Fn(Message) -> B) -> Element<'a, B, Theme, Renderer>
35    where
36        Message: 'a,
37        Theme: 'a,
38        Renderer: 'a,
39        B: 'a,
40    {
41        Element {
42            overlay: Box::new(Map::new(self.overlay, f)),
43        }
44    }
45}
46
47struct Map<'a, A, B, Theme, Renderer> {
48    content: Box<dyn Overlay<A, Theme, Renderer> + 'a>,
49    mapper: &'a dyn Fn(A) -> B,
50}
51
52impl<'a, A, B, Theme, Renderer> Map<'a, A, B, Theme, Renderer> {
53    pub fn new(
54        content: Box<dyn Overlay<A, Theme, Renderer> + 'a>,
55        mapper: &'a dyn Fn(A) -> B,
56    ) -> Map<'a, A, B, Theme, Renderer> {
57        Map { content, mapper }
58    }
59}
60
61impl<A, B, Theme, Renderer> Overlay<B, Theme, Renderer> for Map<'_, A, B, Theme, Renderer>
62where
63    Renderer: crate::Renderer,
64{
65    fn layout(&mut self, renderer: &Renderer, bounds: Size) -> layout::Node {
66        self.content.layout(renderer, bounds)
67    }
68
69    fn operate(
70        &mut self,
71        layout: Layout<'_>,
72        renderer: &Renderer,
73        operation: &mut dyn widget::Operation,
74    ) {
75        self.content.operate(layout, renderer, operation);
76    }
77
78    fn update(
79        &mut self,
80        event: &Event,
81        layout: Layout<'_>,
82        cursor: mouse::Cursor,
83        renderer: &Renderer,
84        clipboard: &mut dyn Clipboard,
85        shell: &mut Shell<'_, B>,
86    ) {
87        let mut local_messages = Vec::new();
88        let mut local_shell = Shell::new(&mut local_messages);
89
90        self.content
91            .update(event, layout, cursor, renderer, clipboard, &mut local_shell);
92
93        shell.merge(local_shell, self.mapper);
94    }
95
96    fn mouse_interaction(
97        &self,
98        layout: Layout<'_>,
99        cursor: mouse::Cursor,
100        renderer: &Renderer,
101    ) -> mouse::Interaction {
102        self.content.mouse_interaction(layout, cursor, renderer)
103    }
104
105    fn draw(
106        &self,
107        renderer: &mut Renderer,
108        theme: &Theme,
109        style: &renderer::Style,
110        layout: Layout<'_>,
111        cursor: mouse::Cursor,
112    ) {
113        self.content.draw(renderer, theme, style, layout, cursor);
114    }
115
116    fn overlay<'a>(
117        &'a mut self,
118        layout: Layout<'a>,
119        renderer: &Renderer,
120    ) -> Option<Element<'a, B, Theme, Renderer>> {
121        self.content
122            .overlay(layout, renderer)
123            .map(|overlay| overlay.map(self.mapper))
124    }
125}