1use std::ops::{Deref, DerefMut};
9
10pub use drying_paint::Watched;
11use drying_paint::{Watcher, WatcherId};
12
13use crate::adapter::Adaptable;
14use crate::dims::{Dim, Rect};
15use crate::graphics::DrawContext;
16use crate::platform::{DefaultRenderPlatform, RenderPlatform};
17use crate::pointer::PointerEvent;
18
19mod anon;
20mod content;
21mod graphic;
22mod init;
23mod internal;
24pub mod layout;
25mod receivers;
26mod rect;
27
28use internal::WidgetInternal;
29use receivers::{
30 DrawChildReceiver, DrawGraphicBeforeReceiver, DrawGraphicOrderedReceiver,
31 DrawGraphicUnorderedReceiver, FindWidgetReceiver,
32 PointerEventChildReceiver,
33};
34
35pub use anon::AnonWidget;
36pub use content::WidgetContent;
37pub use graphic::WidgetGraphic;
38pub use init::WidgetInit;
39pub use internal::WidgetExtra;
40pub use receivers::{WidgetChildReceiver, WidgetGraphicReceiver};
41pub use rect::WidgetRect;
42
43pub(crate) type FindWidgetCallback<'a, P> =
44 Option<Box<dyn FnOnce(&mut dyn AnonWidget<P>) + 'a>>;
45
46pub struct Widget<T, P = DefaultRenderPlatform>
48where
49 P: RenderPlatform + ?Sized,
50 T: WidgetContent<P> + ?Sized,
51{
52 watcher: Watcher<WidgetInternal<P, T>>,
53}
54
55impl<T, P, Data> Adaptable<Data> for Widget<T, P>
56where
57 P: RenderPlatform,
58 T: WidgetContent<P> + Adaptable<Data>,
59{
60 fn adapt(&mut self, data: &Data) {
61 self.watcher.data_mut().content.adapt(data);
62 }
63
64 fn from(data: &Data) -> Self {
65 Widget::create_from(data)
66 }
67}
68
69impl<T, P> Default for Widget<T, P>
70where
71 P: RenderPlatform,
72 T: WidgetContent<P> + Default + ?Sized,
73{
74 fn default() -> Self {
75 Self {
76 watcher: Default::default(),
77 }
78 }
79}
80
81impl<T, P> Deref for Widget<T, P>
82where
83 P: RenderPlatform + ?Sized,
84 T: WidgetContent<P>,
85{
86 type Target = T;
87 fn deref(&self) -> &T {
88 &self.watcher.data().content
89 }
90}
91
92impl<T, P> DerefMut for Widget<T, P>
93where
94 P: RenderPlatform + ?Sized,
95 T: WidgetContent<P>,
96{
97 fn deref_mut(&mut self) -> &mut T {
98 &mut self.watcher.data_mut().content
99 }
100}
101
102impl<P, T> Widget<T, P>
103where
104 P: RenderPlatform + ?Sized,
105 T: WidgetContent<P>,
106{
107 pub fn create_from<Data>(data: &Data) -> Self
110 where
111 T: Adaptable<Data>,
112 {
113 Widget {
114 watcher: Watcher::create(WidgetInternal {
115 rect: WidgetRect::default(),
116 content: Adaptable::from(data),
117 _platform: Default::default(),
118 }),
119 }
120 }
121
122 pub fn create_with_rect<Data, R>(data: &Data, rect: &R) -> Self
125 where
126 T: Adaptable<Data>,
127 R: Rect,
128 {
129 Widget {
130 watcher: Watcher::create(WidgetInternal {
131 rect: WidgetRect::external_from(rect),
132 content: Adaptable::from(data),
133 _platform: Default::default(),
134 }),
135 }
136 }
137
138 pub fn id(this: &Self) -> WidgetId {
142 WidgetId {
143 id: this.watcher.id(),
144 }
145 }
146
147 pub(crate) fn draw(this: &mut Self, ctx: &mut DrawContext<P>) {
148 let wid_int = this.watcher.data_mut();
149 let content = &mut wid_int.content;
150 content.graphics(DrawGraphicBeforeReceiver { ctx });
151 content.children(DrawChildReceiver { ctx });
152 let mut num_ordered = 0;
153 content.graphics(DrawGraphicUnorderedReceiver {
154 ctx,
155 num_ordered: &mut num_ordered,
156 });
157 for target in (0..num_ordered).rev() {
158 content.graphics(DrawGraphicOrderedReceiver {
159 ctx,
160 target,
161 current: 0,
162 });
163 }
164 }
165
166 pub(crate) fn find_widget(
167 this: &mut Self,
168 id: &WidgetId,
169 func: &mut FindWidgetCallback<P>,
170 ) {
171 if let Some(f) = func.take() {
172 if Widget::id(this) == *id {
173 f(this);
174 } else {
175 *func = Some(f);
176 let content: &mut T = this;
177 content.children(FindWidgetReceiver { id, func });
178 }
179 }
180 }
181
182 pub(crate) fn pointer_event(
183 this: &mut Self,
184 event: &mut PointerEvent,
185 ) -> bool {
186 let id = Widget::id(this);
187 let wid_int = this.watcher.data_mut();
188 let mut extra = WidgetExtra {
189 id,
190 rect: &mut wid_int.rect,
191 };
192 T::pointer_event_before(&mut wid_int.content, &mut extra, event)
193 || {
194 let mut handled_by_child = false;
195 wid_int.content.children(PointerEventChildReceiver {
196 event,
197 handled: &mut handled_by_child,
198 });
199 handled_by_child
200 }
201 || T::pointer_event(&mut wid_int.content, &mut extra, event)
202 }
203
204 pub(crate) fn pointer_event_self(
205 this: &mut Self,
206 event: &mut PointerEvent,
207 ) -> bool {
208 let id = Widget::id(this);
209 let wid_int = this.watcher.data_mut();
210 let mut extra = WidgetExtra {
211 id,
212 rect: &mut wid_int.rect,
213 };
214 T::pointer_event(&mut wid_int.content, &mut extra, event)
215 }
216}
217
218impl<P, T> Widget<T, P>
219where
220 P: RenderPlatform,
221 T: WidgetContent<P> + Default,
222{
223 pub fn default_with_rect<R: Rect>(rect: &R) -> Self {
225 Widget {
226 watcher: Watcher::create(WidgetInternal {
227 rect: WidgetRect::external_from(rect),
228 content: Default::default(),
229 _platform: Default::default(),
230 }),
231 }
232 }
233}
234
235impl<P, T> Rect for Widget<T, P>
236where
237 P: RenderPlatform + ?Sized,
238 T: WidgetContent<P>,
239{
240 fn x(&self) -> Dim {
241 self.watcher.data().rect.x()
242 }
243 fn y(&self) -> Dim {
244 self.watcher.data().rect.y()
245 }
246
247 fn x_mut<F, R>(&mut self, f: F) -> R
248 where
249 F: FnOnce(&mut Dim) -> R,
250 {
251 self.watcher.data_mut().rect.external_x_mut(f)
252 }
253
254 fn y_mut<F, R>(&mut self, f: F) -> R
255 where
256 F: FnOnce(&mut Dim) -> R,
257 {
258 self.watcher.data_mut().rect.external_y_mut(f)
259 }
260}
261
262#[derive(Clone, Debug, PartialEq, Eq)]
267pub struct WidgetId {
268 id: WatcherId,
269}
270
271impl<P, T> From<&Widget<T, P>> for WidgetId
272where
273 P: RenderPlatform,
274 T: WidgetContent<P>,
275{
276 fn from(widget: &Widget<T, P>) -> Self {
277 widget.id()
278 }
279}
280
281impl From<&mut WidgetExtra<'_>> for WidgetId {
282 fn from(extra: &mut WidgetExtra) -> Self {
283 extra.id()
284 }
285}