Skip to main content

iced_core/overlay/
element.rs

1pub use crate::Overlay;
2
3use crate::layout;
4use crate::mouse;
5use crate::renderer;
6use crate::shell;
7use crate::widget;
8use crate::{Event, Layout, Shell, Size};
9
10/// A generic [`Overlay`].
11pub struct Element<'a, Message, Theme, Renderer> {
12    overlay: Box<dyn Overlay<Message, Theme, Renderer> + 'a>,
13}
14
15impl<'a, Message, Theme, Renderer> Element<'a, Message, Theme, Renderer>
16where
17    Renderer: crate::Renderer,
18{
19    /// Creates a new [`Element`] containing the given [`Overlay`].
20    pub fn new(overlay: Box<dyn Overlay<Message, Theme, Renderer> + 'a>) -> Self {
21        Self { overlay }
22    }
23
24    /// Returns a reference to the [`Overlay`] of the [`Element`],
25    pub fn as_overlay(&self) -> &dyn Overlay<Message, Theme, Renderer> {
26        self.overlay.as_ref()
27    }
28
29    /// Returns a mutable reference to the [`Overlay`] of the [`Element`],
30    pub fn as_overlay_mut(&mut self) -> &mut dyn Overlay<Message, Theme, Renderer> {
31        self.overlay.as_mut()
32    }
33
34    /// Applies a transformation to the produced message of the [`Element`].
35    pub fn map<B>(self, f: &'a dyn Fn(Message) -> B) -> Element<'a, B, Theme, Renderer>
36    where
37        Message: 'a,
38        Theme: 'a,
39        Renderer: 'a,
40        B: 'a,
41    {
42        Element {
43            overlay: Box::new(Map::new(self.overlay, f)),
44        }
45    }
46}
47
48struct Map<'a, A, B, Theme, Renderer> {
49    content: Box<dyn Overlay<A, Theme, Renderer> + 'a>,
50    mapper: &'a dyn Fn(A) -> B,
51}
52
53impl<'a, A, B, Theme, Renderer> Map<'a, A, B, Theme, Renderer> {
54    pub fn new(
55        content: Box<dyn Overlay<A, Theme, Renderer> + 'a>,
56        mapper: &'a dyn Fn(A) -> B,
57    ) -> Map<'a, A, B, Theme, Renderer> {
58        Map { content, mapper }
59    }
60}
61
62impl<A, B, Theme, Renderer> Overlay<B, Theme, Renderer> for Map<'_, A, B, Theme, Renderer>
63where
64    Renderer: crate::Renderer,
65{
66    fn layout(&mut self, renderer: &Renderer, bounds: Size) -> layout::Node {
67        self.content.layout(renderer, bounds)
68    }
69
70    fn operate(
71        &mut self,
72        layout: Layout<'_>,
73        renderer: &Renderer,
74        operation: &mut dyn widget::Operation,
75    ) {
76        self.content.operate(layout, renderer, operation);
77    }
78
79    fn update(
80        &mut self,
81        event: &Event,
82        layout: Layout<'_>,
83        cursor: mouse::Cursor,
84        renderer: &Renderer,
85        shell: &mut Shell<'_, B>,
86    ) {
87        let mut local_messages = shell::Bus::new();
88        let mut local_shell = shell.local(&mut local_messages);
89
90        self.content
91            .update(event, layout, cursor, renderer, &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}