1pub use crate::Overlay;
2
3use crate::layout;
4use crate::mouse;
5use crate::renderer;
6use crate::widget;
7use crate::{Clipboard, Event, Layout, Point, Rectangle, 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 map<B>(
28 self,
29 f: &'a dyn Fn(Message) -> B,
30 ) -> Element<'a, B, Theme, Renderer>
31 where
32 Message: 'a,
33 Theme: 'a,
34 Renderer: 'a,
35 B: 'a,
36 {
37 Element {
38 overlay: Box::new(Map::new(self.overlay, f)),
39 }
40 }
41
42 pub fn layout(
44 &mut self,
45 renderer: &Renderer,
46 bounds: Size,
47 ) -> layout::Node {
48 self.overlay.layout(renderer, bounds)
49 }
50
51 pub fn update(
53 &mut self,
54 event: &Event,
55 layout: Layout<'_>,
56 cursor: mouse::Cursor,
57 renderer: &Renderer,
58 clipboard: &mut dyn Clipboard,
59 shell: &mut Shell<'_, Message>,
60 ) {
61 self.overlay
62 .update(event, layout, cursor, renderer, clipboard, shell);
63 }
64
65 pub fn mouse_interaction(
67 &self,
68 layout: Layout<'_>,
69 cursor: mouse::Cursor,
70 viewport: &Rectangle,
71 renderer: &Renderer,
72 ) -> mouse::Interaction {
73 self.overlay
74 .mouse_interaction(layout, cursor, viewport, renderer)
75 }
76
77 pub fn draw(
79 &self,
80 renderer: &mut Renderer,
81 theme: &Theme,
82 style: &renderer::Style,
83 layout: Layout<'_>,
84 cursor: mouse::Cursor,
85 ) {
86 self.overlay.draw(renderer, theme, style, layout, cursor);
87 }
88
89 pub fn operate(
91 &mut self,
92 layout: Layout<'_>,
93 renderer: &Renderer,
94 operation: &mut dyn widget::Operation,
95 ) {
96 self.overlay.operate(layout, renderer, operation);
97 }
98
99 pub fn is_over(
101 &self,
102 layout: Layout<'_>,
103 renderer: &Renderer,
104 cursor_position: Point,
105 ) -> bool {
106 self.overlay.is_over(layout, renderer, cursor_position)
107 }
108
109 pub fn overlay<'b>(
111 &'b mut self,
112 layout: Layout<'_>,
113 renderer: &Renderer,
114 ) -> Option<Element<'b, Message, Theme, Renderer>> {
115 self.overlay.overlay(layout, renderer)
116 }
117}
118
119struct Map<'a, A, B, Theme, Renderer> {
120 content: Box<dyn Overlay<A, Theme, Renderer> + 'a>,
121 mapper: &'a dyn Fn(A) -> B,
122}
123
124impl<'a, A, B, Theme, Renderer> Map<'a, A, B, Theme, Renderer> {
125 pub fn new(
126 content: Box<dyn Overlay<A, Theme, Renderer> + 'a>,
127 mapper: &'a dyn Fn(A) -> B,
128 ) -> Map<'a, A, B, Theme, Renderer> {
129 Map { content, mapper }
130 }
131}
132
133impl<A, B, Theme, Renderer> Overlay<B, Theme, Renderer>
134 for Map<'_, A, B, Theme, Renderer>
135where
136 Renderer: crate::Renderer,
137{
138 fn layout(&mut self, renderer: &Renderer, bounds: Size) -> layout::Node {
139 self.content.layout(renderer, bounds)
140 }
141
142 fn operate(
143 &mut self,
144 layout: Layout<'_>,
145 renderer: &Renderer,
146 operation: &mut dyn widget::Operation,
147 ) {
148 self.content.operate(layout, renderer, operation);
149 }
150
151 fn update(
152 &mut self,
153 event: &Event,
154 layout: Layout<'_>,
155 cursor: mouse::Cursor,
156 renderer: &Renderer,
157 clipboard: &mut dyn Clipboard,
158 shell: &mut Shell<'_, B>,
159 ) {
160 let mut local_messages = Vec::new();
161 let mut local_shell = Shell::new(&mut local_messages);
162
163 self.content.update(
164 event,
165 layout,
166 cursor,
167 renderer,
168 clipboard,
169 &mut local_shell,
170 );
171
172 shell.merge(local_shell, self.mapper);
173 }
174
175 fn mouse_interaction(
176 &self,
177 layout: Layout<'_>,
178 cursor: mouse::Cursor,
179 viewport: &Rectangle,
180 renderer: &Renderer,
181 ) -> mouse::Interaction {
182 self.content
183 .mouse_interaction(layout, cursor, viewport, renderer)
184 }
185
186 fn draw(
187 &self,
188 renderer: &mut Renderer,
189 theme: &Theme,
190 style: &renderer::Style,
191 layout: Layout<'_>,
192 cursor: mouse::Cursor,
193 ) {
194 self.content.draw(renderer, theme, style, layout, cursor);
195 }
196
197 fn is_over(
198 &self,
199 layout: Layout<'_>,
200 renderer: &Renderer,
201 cursor_position: Point,
202 ) -> bool {
203 self.content.is_over(layout, renderer, cursor_position)
204 }
205
206 fn overlay<'a>(
207 &'a mut self,
208 layout: Layout<'_>,
209 renderer: &Renderer,
210 ) -> Option<Element<'a, B, Theme, Renderer>> {
211 self.content
212 .overlay(layout, renderer)
213 .map(|overlay| overlay.map(self.mapper))
214 }
215}