Skip to main content

iced_core/overlay/
element.rs

1pub use crate::Overlay;
2
3use crate::mouse;
4use crate::renderer;
5use crate::shell;
6use crate::widget;
7use crate::{Event, Shell};
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 operate(&mut self, renderer: &Renderer, operation: &mut dyn widget::Operation) {
66        self.content.operate(renderer, operation);
67    }
68
69    fn update(
70        &mut self,
71        event: &Event,
72        cursor: mouse::Cursor,
73        renderer: &Renderer,
74        shell: &mut Shell<'_, B>,
75    ) {
76        let mut local_messages = shell::Bus::new();
77        let mut local_shell = shell.local(&mut local_messages);
78
79        self.content
80            .update(event, cursor, renderer, &mut local_shell);
81
82        shell.merge(local_shell, self.mapper);
83    }
84
85    fn mouse_interaction(&self, cursor: mouse::Cursor, renderer: &Renderer) -> mouse::Interaction {
86        self.content.mouse_interaction(cursor, renderer)
87    }
88
89    fn draw(
90        &self,
91        renderer: &mut Renderer,
92        theme: &Theme,
93        style: &renderer::Style,
94        cursor: mouse::Cursor,
95    ) {
96        self.content.draw(renderer, theme, style, cursor);
97    }
98
99    fn overlay<'a>(&'a mut self, renderer: &Renderer) -> Vec<Element<'a, B, Theme, Renderer>> {
100        self.content
101            .overlay(renderer)
102            .into_iter()
103            .map(|overlay| overlay.map(self.mapper))
104            .collect()
105    }
106
107    fn index(&self) -> f32 {
108        self.content.index()
109    }
110}