1use alloc::vec::Vec;
4
5pub mod element;
7
8pub use element::{Element, IntoElement};
9
10use crate::{Constraints, Length, RenderError, Renderer, TouchPhase, UiAction, WidgetId};
11use embedded_graphics::{pixelcolor::PixelColor, prelude::*, primitives::Rectangle};
12use zest_theme::Theme;
13
14pub trait Widget<C: PixelColor, M: Clone> {
16 fn measure(&mut self, constraints: Constraints) -> Size;
18
19 fn preferred_size(&self) -> (Length, Length) {
25 (Length::Fill, Length::Fill)
26 }
27
28 fn arrange(&mut self, rect: Rectangle);
30
31 fn rect(&self) -> Rectangle;
33
34 fn handle_touch(&mut self, point: Point, phase: TouchPhase) -> Option<M>;
36
37 fn mark_pressed(&mut self, point: Point) {
40 let _ = point;
41 }
42
43 fn widget_id(&self) -> Option<WidgetId> {
45 None
46 }
47
48 fn is_focusable(&self) -> bool {
50 false
51 }
52
53 fn collect_focusable(&self, out: &mut Vec<WidgetId>) {
55 if self.is_focusable()
56 && let Some(id) = self.widget_id()
57 {
58 out.push(id);
59 }
60 }
61
62 fn sync_focus(&mut self, focused: Option<WidgetId>) {
64 let _ = focused;
65 }
66
67 fn handle_action(&mut self, action: UiAction) -> Option<M> {
69 let _ = action;
70 None
71 }
72
73 fn route_action(&mut self, target: WidgetId, action: UiAction) -> Option<M> {
75 if self.widget_id() == Some(target) {
76 self.handle_action(action)
77 } else {
78 None
79 }
80 }
81
82 fn navigate_focus(&self, target: WidgetId, action: UiAction) -> Option<WidgetId> {
84 let _ = (target, action);
85 None
86 }
87
88 fn focus_rect(&self, target: WidgetId) -> Option<Rectangle> {
90 if self.widget_id() == Some(target) {
91 Some(self.rect())
92 } else {
93 None
94 }
95 }
96
97 fn focus_at(&self, point: Point) -> Option<WidgetId> {
99 let _ = point;
100 None
101 }
102
103 fn draw<'t>(
105 &self,
106 renderer: &mut dyn Renderer<C>,
107 theme: &Theme<'t, C>,
108 ) -> Result<(), RenderError>;
109}