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