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