Skip to main content

embedded_gui/
widget.rs

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}