1use embedded_graphics_core::{draw_target::DrawTarget, pixelcolor::Rgb565};
2
3use crate::{geometry::Rect, render::RenderCtx};
4
5#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
6pub struct WidgetFlags(u16);
7
8impl WidgetFlags {
9 pub const HIDDEN: Self = Self(1 << 0);
10 pub const DISABLED: Self = Self(1 << 1);
11 pub const CLICKABLE: Self = Self(1 << 2);
12 pub const SCROLLABLE: Self = Self(1 << 3);
13 pub const FOCUSABLE: Self = Self(1 << 4);
14 pub const CLIP_CHILDREN: Self = Self(1 << 5);
15 pub const EVENT_BUBBLE: Self = Self(1 << 6);
16
17 pub const fn empty() -> Self {
18 Self(0)
19 }
20
21 pub const fn bits(self) -> u16 {
22 self.0
23 }
24
25 pub const fn from_bits(bits: u16) -> Self {
26 Self(bits)
27 }
28
29 pub const fn contains(self, flag: Self) -> bool {
30 self.0 & flag.0 == flag.0
31 }
32
33 pub fn insert(&mut self, flag: Self) {
34 self.0 |= flag.0;
35 }
36
37 pub fn remove(&mut self, flag: Self) {
38 self.0 &= !flag.0;
39 }
40
41 pub fn set(&mut self, flag: Self, enabled: bool) {
42 if enabled {
43 self.insert(flag);
44 } else {
45 self.remove(flag);
46 }
47 }
48}
49
50impl core::ops::BitOr for WidgetFlags {
51 type Output = Self;
52
53 fn bitor(self, rhs: Self) -> Self::Output {
54 Self(self.0 | rhs.0)
55 }
56}
57
58impl core::ops::BitOrAssign for WidgetFlags {
59 fn bitor_assign(&mut self, rhs: Self) {
60 self.0 |= rhs.0;
61 }
62}
63
64#[derive(Clone, Copy, Debug, PartialEq, Eq)]
65pub struct WidgetId(pub u16);
66
67impl WidgetId {
68 pub const fn new(raw: u16) -> Self {
69 Self(raw)
70 }
71
72 pub const fn raw(self) -> u16 {
73 self.0
74 }
75}
76
77pub trait StatefulWidget<State> {
78 fn render_stateful<D>(
79 &self,
80 area: Rect,
81 state: &mut State,
82 ctx: &mut RenderCtx<'_, D>,
83 ) -> Result<(), D::Error>
84 where
85 D: DrawTarget<Color = Rgb565>;
86}
87
88#[derive(Clone, Copy, Debug, PartialEq, Eq)]
89pub enum EventPhase {
90 Capture,
91 Target,
92 Bubble,
93}
94
95#[derive(Clone, Copy, Debug, PartialEq, Eq)]
96pub enum EventPolicy {
97 Continue,
98 Stop,
99}
100
101#[derive(Clone, Copy, Debug, PartialEq, Eq)]
102pub struct EventContext {
103 pub target: WidgetId,
104 pub current: WidgetId,
105 pub phase: EventPhase,
106}
107
108#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
109pub struct FocusGroupId(pub u8);
110
111impl FocusGroupId {
112 pub const ROOT: Self = Self(0);
113
114 pub const fn new(raw: u8) -> Self {
115 Self(raw)
116 }
117
118 pub const fn raw(self) -> u8 {
119 self.0
120 }
121}
122
123#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
124pub struct StyleClassId(pub u8);
125
126impl StyleClassId {
127 pub const NONE: Self = Self(0);
128
129 pub const fn new(raw: u8) -> Self {
130 Self(raw)
131 }
132
133 pub const fn raw(self) -> u8 {
134 self.0
135 }
136}
137
138#[derive(Clone, Copy, Debug, PartialEq, Eq)]
139pub struct MenuContract {
140 pub wrap_navigation: bool,
141 pub select_opens_dropdown: bool,
142 pub back_closes_dropdown: bool,
143 pub back_closes_notification_sheet: bool,
144 pub select_toggles_feed_expanded: bool,
145}
146
147impl Default for MenuContract {
148 fn default() -> Self {
149 Self {
150 wrap_navigation: true,
151 select_opens_dropdown: true,
152 back_closes_dropdown: true,
153 back_closes_notification_sheet: true,
154 select_toggles_feed_expanded: true,
155 }
156 }
157}
158
159#[derive(Clone, Copy, Debug, PartialEq, Eq)]
160pub enum PropertyKey {
161 Value,
162 Min,
163 Max,
164 Text,
165 Progress,
166 Selected,
167 State,
168 Offset,
169 Open,
170 Expanded,
171 Custom(u16),
172}
173
174#[derive(Clone, Debug, PartialEq)]
175pub enum PropertyValue<'a> {
176 Float(f32),
177 Int(i32),
178 Usize(usize),
179 Bool(bool),
180 Str(&'a str),
181 Char(char),
182}
183
184#[derive(Clone, Copy, Debug, PartialEq, Eq)]
185pub enum PropertyError {
186 NotFound,
187 ReadOnly,
188 TypeMismatch,
189}
190
191pub trait Widget {
192 fn render_widget_bounds(&self, _bounds: Rect, _style: &crate::style::Style) {}
193
194 fn handle_widget_event(
195 &mut self,
196 _event: &crate::input::UiEvent,
197 _ctx: &mut EventContext,
198 ) -> EventPolicy {
199 EventPolicy::Continue
200 }
201
202 fn get_property(&self, _key: PropertyKey) -> Option<PropertyValue<'_>> {
203 None
204 }
205
206 fn set_property<'a>(
207 &mut self,
208 _key: PropertyKey,
209 _val: PropertyValue<'a>,
210 ) -> Result<(), PropertyError> {
211 Err(PropertyError::NotFound)
212 }
213}