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