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#[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 pub fn new(
21 overlay: Box<dyn Overlay<Message, Theme, Renderer> + 'a>,
22 ) -> Self {
23 Self { overlay }
24 }
25
26 pub fn as_overlay(&self) -> &dyn Overlay<Message, Theme, Renderer> {
28 self.overlay.as_ref()
29 }
30
31 pub fn as_overlay_mut(
33 &mut self,
34 ) -> &mut dyn Overlay<Message, Theme, Renderer> {
35 self.overlay.as_mut()
36 }
37
38 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}