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}