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
9pub 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 pub fn new(
20 overlay: Box<dyn Overlay<Message, Theme, Renderer> + 'a>,
21 ) -> Self {
22 Self { overlay }
23 }
24
25 pub fn as_overlay(&self) -> &dyn Overlay<Message, Theme, Renderer> {
27 self.overlay.as_ref()
28 }
29
30 pub fn as_overlay_mut(
32 &mut self,
33 ) -> &mut dyn Overlay<Message, Theme, Renderer> {
34 self.overlay.as_mut()
35 }
36
37 pub fn map<B>(
39 self,
40 f: &'a dyn Fn(Message) -> B,
41 ) -> Element<'a, B, Theme, Renderer>
42 where
43 Message: 'a,
44 Theme: 'a,
45 Renderer: 'a,
46 B: 'a,
47 {
48 Element {
49 overlay: Box::new(Map::new(self.overlay, f)),
50 }
51 }
52}
53
54struct Map<'a, A, B, Theme, Renderer> {
55 content: Box<dyn Overlay<A, Theme, Renderer> + 'a>,
56 mapper: &'a dyn Fn(A) -> B,
57}
58
59impl<'a, A, B, Theme, Renderer> Map<'a, A, B, Theme, Renderer> {
60 pub fn new(
61 content: Box<dyn Overlay<A, Theme, Renderer> + 'a>,
62 mapper: &'a dyn Fn(A) -> B,
63 ) -> Map<'a, A, B, Theme, Renderer> {
64 Map { content, mapper }
65 }
66}
67
68impl<A, B, Theme, Renderer> Overlay<B, Theme, Renderer>
69 for Map<'_, A, B, Theme, Renderer>
70where
71 Renderer: crate::Renderer,
72{
73 fn layout(&mut self, renderer: &Renderer, bounds: Size) -> layout::Node {
74 self.content.layout(renderer, bounds)
75 }
76
77 fn operate(
78 &mut self,
79 layout: Layout<'_>,
80 renderer: &Renderer,
81 operation: &mut dyn widget::Operation,
82 ) {
83 self.content.operate(layout, renderer, operation);
84 }
85
86 fn update(
87 &mut self,
88 event: &Event,
89 layout: Layout<'_>,
90 cursor: mouse::Cursor,
91 renderer: &Renderer,
92 clipboard: &mut dyn Clipboard,
93 shell: &mut Shell<'_, B>,
94 ) {
95 let mut local_messages = Vec::new();
96 let mut local_shell = Shell::new(&mut local_messages);
97
98 self.content.update(
99 event,
100 layout,
101 cursor,
102 renderer,
103 clipboard,
104 &mut local_shell,
105 );
106
107 shell.merge(local_shell, self.mapper);
108 }
109
110 fn mouse_interaction(
111 &self,
112 layout: Layout<'_>,
113 cursor: mouse::Cursor,
114 renderer: &Renderer,
115 ) -> mouse::Interaction {
116 self.content.mouse_interaction(layout, cursor, renderer)
117 }
118
119 fn draw(
120 &self,
121 renderer: &mut Renderer,
122 theme: &Theme,
123 style: &renderer::Style,
124 layout: Layout<'_>,
125 cursor: mouse::Cursor,
126 ) {
127 self.content.draw(renderer, theme, style, layout, cursor);
128 }
129
130 fn overlay<'a>(
131 &'a mut self,
132 layout: Layout<'a>,
133 renderer: &Renderer,
134 ) -> Option<Element<'a, B, Theme, Renderer>> {
135 self.content
136 .overlay(layout, renderer)
137 .map(|overlay| overlay.map(self.mapper))
138 }
139}