1pub mod operation;
3pub mod text;
4pub mod tree;
5
6mod element;
7mod id;
8
9pub use element::Element;
10pub use id::Id;
11pub use operation::Operation;
12pub use text::Text;
13pub use tree::Tree;
14
15use crate::layout::{self, Layout};
16use crate::mouse;
17use crate::overlay;
18use crate::renderer;
19use crate::shell;
20use crate::{Event, Length, Rectangle, Shell, Size, Vector};
21
22pub trait Widget<Message, Theme, Renderer>: Meta {
41 fn size(&self) -> Size<Length>;
43
44 fn tag(&self) -> tree::Tag {
48 tree::Tag::stateless()
49 }
50
51 fn state(&self) -> tree::State {
55 tree::State::None
56 }
57
58 fn diff(&mut self, tree: &mut Tree) {
60 tree.children.clear();
61 }
62
63 fn layout(&mut self, tree: &mut Tree, renderer: &Renderer, limits: &layout::Limits);
68
69 fn draw(
71 &self,
72 tree: &Tree,
73 renderer: &mut Renderer,
74 theme: &Theme,
75 style: &renderer::Style,
76 layout: Layout,
77 cursor: mouse::Cursor,
78 viewport: &Rectangle,
79 );
80
81 fn operate(
83 &mut self,
84 _tree: &mut Tree,
85 _layout: Layout,
86 _viewport: &Rectangle,
87 _renderer: &Renderer,
88 _operation: &mut dyn Operation,
89 ) {
90 }
91
92 fn update(
96 &mut self,
97 _tree: &mut Tree,
98 _event: &Event,
99 _layout: Layout,
100 _cursor: mouse::Cursor,
101 _renderer: &Renderer,
102 _shell: &mut Shell<'_, Message>,
103 _viewport: &Rectangle,
104 ) {
105 }
106
107 fn mouse_interaction(
111 &self,
112 _tree: &Tree,
113 _layout: Layout,
114 _cursor: mouse::Cursor,
115 _viewport: &Rectangle,
116 _renderer: &Renderer,
117 ) -> mouse::Interaction {
118 mouse::Interaction::None
119 }
120
121 fn overlay<'a>(
123 &'a mut self,
124 _tree: &'a mut Tree,
125 _layout: Layout,
126 _renderer: &Renderer,
127 _viewport: &Rectangle,
128 _translation: Vector,
129 _window: Size,
130 ) -> Vec<overlay::Element<'a, Message, Theme, Renderer>> {
131 Vec::new()
132 }
133
134 fn _map<F, B>(self, f: F) -> Map<Self, F, Message>
140 where
141 Self: Sized,
142 F: Fn(Message) -> B,
143 {
144 Map {
145 widget: self,
146 mapper: f,
147 _input: std::marker::PhantomData,
148 }
149 }
150
151 fn _boxed<'a>(self) -> Element<'a, Message, Theme, Renderer>
153 where
154 Self: Sized + 'a,
155 {
156 Element::new(self)
157 }
158}
159
160pub trait Meta {
162 fn is_void(&self) -> bool {
164 false
165 }
166}
167
168impl<T> Meta for &mut T
169where
170 T: Meta,
171{
172 fn is_void(&self) -> bool {
173 T::is_void(self)
174 }
175}
176
177impl<T, Message, Theme, Renderer> Widget<Message, Theme, Renderer> for &mut T
178where
179 Renderer: crate::Renderer,
180 T: Widget<Message, Theme, Renderer>,
181{
182 fn size(&self) -> Size<Length> {
183 T::size(self)
184 }
185
186 fn tag(&self) -> tree::Tag {
187 T::tag(self)
188 }
189
190 fn state(&self) -> tree::State {
191 T::state(self)
192 }
193
194 fn diff(&mut self, tree: &mut Tree) {
195 T::diff(self, tree);
196 }
197
198 fn layout(&mut self, tree: &mut Tree, renderer: &Renderer, limits: &layout::Limits) {
199 T::layout(self, tree, renderer, limits);
200 }
201
202 fn draw(
203 &self,
204 tree: &Tree,
205 renderer: &mut Renderer,
206 theme: &Theme,
207 style: &renderer::Style,
208 layout: Layout,
209 cursor: mouse::Cursor,
210 viewport: &Rectangle,
211 ) {
212 T::draw(self, tree, renderer, theme, style, layout, cursor, viewport);
213 }
214
215 fn operate(
216 &mut self,
217 tree: &mut Tree,
218 layout: Layout,
219 viewport: &Rectangle,
220 renderer: &Renderer,
221 operation: &mut dyn Operation,
222 ) {
223 T::operate(self, tree, layout, viewport, renderer, operation);
224 }
225
226 fn update(
227 &mut self,
228 tree: &mut Tree,
229 event: &Event,
230 layout: Layout,
231 cursor: mouse::Cursor,
232 renderer: &Renderer,
233 shell: &mut Shell<'_, Message>,
234 viewport: &Rectangle,
235 ) {
236 T::update(self, tree, event, layout, cursor, renderer, shell, viewport);
237 }
238
239 fn mouse_interaction(
240 &self,
241 tree: &Tree,
242 layout: Layout,
243 cursor: mouse::Cursor,
244 viewport: &Rectangle,
245 renderer: &Renderer,
246 ) -> mouse::Interaction {
247 T::mouse_interaction(self, tree, layout, cursor, viewport, renderer)
248 }
249
250 fn overlay<'a>(
251 &'a mut self,
252 tree: &'a mut Tree,
253 layout: Layout,
254 renderer: &Renderer,
255 viewport: &Rectangle,
256 translation: Vector,
257 window: Size,
258 ) -> Vec<overlay::Element<'a, Message, Theme, Renderer>> {
259 T::overlay(self, tree, layout, renderer, viewport, translation, window)
260 }
261}
262
263pub struct Void;
265
266impl Meta for Void {
267 fn is_void(&self) -> bool {
268 true
269 }
270}
271
272impl<Message, Theme, Renderer> Widget<Message, Theme, Renderer> for Void {
273 fn size(&self) -> Size<Length> {
274 Size {
275 width: Length::Shrink,
276 height: Length::Shrink,
277 }
278 }
279
280 fn layout(&mut self, _tree: &mut Tree, _renderer: &Renderer, _limits: &layout::Limits) {}
281
282 fn draw(
283 &self,
284 _tree: &Tree,
285 _renderer: &mut Renderer,
286 _theme: &Theme,
287 _style: &renderer::Style,
288 _layout: Layout,
289 _cursor: mouse::Cursor,
290 _viewport: &Rectangle,
291 ) {
292 }
293}
294
295pub struct Map<W, F, A> {
299 widget: W,
300 mapper: F,
301 _input: std::marker::PhantomData<A>,
302}
303
304impl<W, F, A> Meta for Map<W, F, A>
305where
306 W: Meta,
307{
308 fn is_void(&self) -> bool {
309 self.widget.is_void()
310 }
311}
312
313impl<W, A, B, F, Theme, Renderer> Widget<B, Theme, Renderer> for Map<W, F, A>
314where
315 W: Widget<A, Theme, Renderer>,
316 B: 'static,
317 F: Fn(A) -> B,
318 Theme: 'static,
319 Renderer: crate::Renderer + 'static,
320{
321 fn size(&self) -> Size<Length> {
322 self.widget.size()
323 }
324
325 fn tag(&self) -> tree::Tag {
326 self.widget.tag()
327 }
328
329 fn state(&self) -> tree::State {
330 self.widget.state()
331 }
332
333 fn diff(&mut self, tree: &mut Tree) {
334 self.widget.diff(tree);
335 }
336
337 fn layout(&mut self, tree: &mut Tree, renderer: &Renderer, limits: &layout::Limits) {
338 self.widget.layout(tree, renderer, limits);
339 }
340
341 fn operate(
342 &mut self,
343 tree: &mut Tree,
344 layout: Layout,
345 viewport: &Rectangle,
346 renderer: &Renderer,
347 operation: &mut dyn Operation,
348 ) {
349 self.widget
350 .operate(tree, layout, viewport, renderer, operation);
351 }
352
353 fn update(
354 &mut self,
355 tree: &mut Tree,
356 event: &Event,
357 layout: Layout,
358 cursor: mouse::Cursor,
359 renderer: &Renderer,
360 shell: &mut Shell<'_, B>,
361 viewport: &Rectangle,
362 ) {
363 let mut local_messages = shell::Bus::new();
364 let mut local_shell = shell.local(&mut local_messages);
365
366 self.widget.update(
367 tree,
368 event,
369 layout,
370 cursor,
371 renderer,
372 &mut local_shell,
373 viewport,
374 );
375
376 shell.merge(local_shell, &self.mapper);
377 }
378
379 fn draw(
380 &self,
381 tree: &Tree,
382 renderer: &mut Renderer,
383 theme: &Theme,
384 style: &renderer::Style,
385 layout: Layout,
386 cursor: mouse::Cursor,
387 viewport: &Rectangle,
388 ) {
389 self.widget
390 .draw(tree, renderer, theme, style, layout, cursor, viewport);
391 }
392
393 fn mouse_interaction(
394 &self,
395 tree: &Tree,
396 layout: Layout,
397 cursor: mouse::Cursor,
398 viewport: &Rectangle,
399 renderer: &Renderer,
400 ) -> mouse::Interaction {
401 self.widget
402 .mouse_interaction(tree, layout, cursor, viewport, renderer)
403 }
404
405 fn overlay<'b>(
406 &'b mut self,
407 tree: &'b mut Tree,
408 layout: Layout,
409 renderer: &Renderer,
410 viewport: &Rectangle,
411 translation: Vector,
412 window: Size,
413 ) -> Vec<overlay::Element<'b, B, Theme, Renderer>> {
414 let mapper = &self.mapper;
415
416 self.widget
417 .overlay(tree, layout, renderer, viewport, translation, window)
418 .into_iter()
419 .map(move |overlay| overlay.map(mapper))
420 .collect()
421 }
422}
423
424impl<T> Meta for Option<T>
425where
426 T: Meta,
427{
428 fn is_void(&self) -> bool {
429 self.is_none()
430 }
431}
432
433impl<T, Message, Theme, Renderer> Widget<Message, Theme, Renderer> for Option<T>
434where
435 T: Widget<Message, Theme, Renderer>,
436 Renderer: crate::Renderer,
437{
438 fn size(&self) -> Size<Length> {
439 let Some(widget) = self else {
440 return Size {
441 width: Length::Shrink,
442 height: Length::Shrink,
443 };
444 };
445
446 widget.size()
447 }
448
449 fn tag(&self) -> tree::Tag {
450 let Some(widget) = self else {
451 return tree::Tag::stateless();
452 };
453
454 widget.tag()
455 }
456
457 fn state(&self) -> tree::State {
458 let Some(widget) = self else {
459 return tree::State::None;
460 };
461
462 widget.state()
463 }
464
465 fn diff(&mut self, tree: &mut Tree) {
466 let Some(widget) = self else {
467 tree.children.clear();
468 return;
469 };
470
471 widget.diff(tree);
472 }
473
474 fn layout(&mut self, tree: &mut Tree, renderer: &Renderer, limits: &layout::Limits) {
475 let Some(widget) = self else {
476 return;
477 };
478
479 widget.layout(tree, renderer, limits);
480 }
481
482 fn draw(
483 &self,
484 tree: &Tree,
485 renderer: &mut Renderer,
486 theme: &Theme,
487 style: &renderer::Style,
488 layout: Layout,
489 cursor: mouse::Cursor,
490 viewport: &Rectangle,
491 ) {
492 let Some(widget) = self else {
493 return;
494 };
495
496 widget.draw(tree, renderer, theme, style, layout, cursor, viewport);
497 }
498
499 fn operate(
500 &mut self,
501 tree: &mut Tree,
502 layout: Layout,
503 viewport: &Rectangle,
504 renderer: &Renderer,
505 operation: &mut dyn Operation,
506 ) {
507 let Some(widget) = self else {
508 return;
509 };
510
511 widget.operate(tree, layout, viewport, renderer, operation);
512 }
513
514 fn update(
515 &mut self,
516 tree: &mut Tree,
517 event: &Event,
518 layout: Layout,
519 cursor: mouse::Cursor,
520 renderer: &Renderer,
521 shell: &mut Shell<'_, Message>,
522 viewport: &Rectangle,
523 ) {
524 let Some(widget) = self else {
525 return;
526 };
527
528 widget.update(tree, event, layout, cursor, renderer, shell, viewport);
529 }
530
531 fn mouse_interaction(
532 &self,
533 tree: &Tree,
534 layout: Layout,
535 cursor: mouse::Cursor,
536 viewport: &Rectangle,
537 renderer: &Renderer,
538 ) -> mouse::Interaction {
539 let Some(widget) = self else {
540 return mouse::Interaction::None;
541 };
542
543 widget.mouse_interaction(tree, layout, cursor, viewport, renderer)
544 }
545
546 fn overlay<'a>(
547 &'a mut self,
548 tree: &'a mut Tree,
549 layout: Layout,
550 renderer: &Renderer,
551 viewport: &Rectangle,
552 translation: Vector,
553 window: Size,
554 ) -> Vec<overlay::Element<'a, Message, Theme, Renderer>> {
555 let Some(widget) = self else {
556 return Vec::new();
557 };
558
559 widget.overlay(tree, layout, renderer, viewport, translation, window)
560 }
561}