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::widget;
7use crate::{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        shell: &mut Shell<'_, B>,
85    ) {
86        let mut local_messages = Vec::new();
87        let mut local_shell = Shell::new(&mut local_messages);
88
89        self.content
90            .update(event, layout, cursor, renderer, &mut local_shell);
91
92        shell.merge(local_shell, self.mapper);
93    }
94
95    fn mouse_interaction(
96        &self,
97        layout: Layout<'_>,
98        cursor: mouse::Cursor,
99        renderer: &Renderer,
100    ) -> mouse::Interaction {
101        self.content.mouse_interaction(layout, cursor, renderer)
102    }
103
104    fn draw(
105        &self,
106        renderer: &mut Renderer,
107        theme: &Theme,
108        style: &renderer::Style,
109        layout: Layout<'_>,
110        cursor: mouse::Cursor,
111    ) {
112        self.content.draw(renderer, theme, style, layout, cursor);
113    }
114
115    fn overlay<'a>(
116        &'a mut self,
117        layout: Layout<'a>,
118        renderer: &Renderer,
119    ) -> Option<Element<'a, B, Theme, Renderer>> {
120        self.content
121            .overlay(layout, renderer)
122            .map(|overlay| overlay.map(self.mapper))
123    }
124}