Skip to main content

matrix_gui/
helper.rs

1//! Helper utilities for the matrix_gui framework.
2//!
3//! This module provides utility types and functions for handling optional
4//! styling parameters in the GUI framework. It includes:
5//!
6//! - [`OptionColor`]: Wrapper for optional color values with fallback to style defaults
7//! - [`OptionFont`]: Wrapper for optional font values with fallback to style defaults
8//! - [`OptionU8`]: Wrapper for optional numeric values with fallback to style defaults
9//!
10//! # Purpose
11//!
12//! These helper types are used throughout the framework to allow widgets to have
13//! optional styling parameters that fall back to default values from the global
14//! style configuration when not explicitly set.
15//!
16//! # Example
17//!
18//! ```rust
19//! use matrix_gui::prelude::*;
20//!
21//! // Create an optional color
22//! let mut color = OptionColor::none();
23//! color.set_color(Rgb565::RED);
24//! ```
25
26pub mod lw_geometry;
27pub mod lw_primitives;
28pub mod matrix_utils;
29
30use crate::{style::Style, ui_font::UiFont};
31use embedded_graphics::prelude::PixelColor;
32
33/// Wrapper for optional color values with style fallback.
34///
35/// This struct provides a convenient way to handle optional color parameters
36/// in widgets. When a color is not explicitly set, it falls back to the
37/// corresponding color from the global style configuration.
38///
39/// # Type Parameters
40///
41/// * `COL` - The pixel color type implementing [`PixelColor`]
42///
43/// # Example
44///
45/// ```rust
46/// use matrix_gui::prelude::*;
47///
48/// // Create with no color set
49/// let mut color = OptionColor::none();
50///
51/// // Set a specific color
52/// color.set_color(Rgb565::RED);
53/// ```
54#[derive(Debug)]
55pub struct OptionColor<COL> {
56    /// The optional color value.
57    pub color: Option<COL>,
58}
59
60impl<COL: PixelColor> OptionColor<COL> {
61    /// Creates a new `OptionColor` with no color set.
62    ///
63    /// # Returns
64    ///
65    /// A new `OptionColor` instance with `color` set to `None`.
66    pub const fn none() -> Self {
67        Self { color: None }
68    }
69
70    /// Sets the color value.
71    ///
72    /// # Arguments
73    ///
74    /// * `color` - The color to set.
75    pub const fn set_color(&mut self, color: COL) {
76        self.color = Some(color);
77    }
78
79    /// Returns the text color, falling back to the style default if not set.
80    ///
81    /// # Arguments
82    ///
83    /// * `style` - Reference to the style configuration.
84    ///
85    /// # Returns
86    ///
87    /// The set color if present, otherwise `style.text_color`.
88    pub fn text_color(&self, style: &Style<COL>) -> COL {
89        self.color.unwrap_or(style.text_color)
90    }
91
92    /// Returns the background color, falling back to the style default if not set.
93    ///
94    /// # Arguments
95    ///
96    /// * `style` - Reference to the style configuration.
97    ///
98    /// # Returns
99    ///
100    /// The set color if present, otherwise `style.background_color`.
101    pub fn background_color(&self, style: &Style<COL>) -> COL {
102        self.color.unwrap_or(style.background_color)
103    }
104
105    /// Returns the border color, falling back to the style default if not set.
106    ///
107    /// # Arguments
108    ///
109    /// * `style` - Reference to the style configuration.
110    ///
111    /// # Returns
112    ///
113    /// The set color if present, otherwise `style.border_color`.
114    pub fn border_color(&self, style: &Style<COL>) -> COL {
115        self.color.unwrap_or(style.border_color)
116    }
117}
118
119/// Converts an `Option<COL>` into an `OptionColor<COL>`.
120impl<COL: PixelColor> From<Option<COL>> for OptionColor<COL> {
121    fn from(color: Option<COL>) -> Self {
122        Self { color }
123    }
124}
125
126/// Wrapper for optional font values with style fallback.
127///
128/// This struct provides a convenient way to handle optional font parameters
129/// in widgets. When a font is not explicitly set, it falls back to the
130/// default font from the global style configuration.
131///
132/// # Type Parameters
133///
134/// * `'a` - The lifetime of the font reference
135///
136/// # Example
137///
138/// ```ignore
139/// use matrix_gui::prelude::*;
140///
141/// // Create with no font set
142/// let mut font = OptionFont::none();
143///
144/// // Get font with fallback to style
145/// let actual_font = font.font(&style);
146/// ```
147#[derive(Debug)]
148pub struct OptionFont<'a> {
149    /// The optional font value.
150    pub font: Option<UiFont<'a>>,
151}
152
153impl<'a> OptionFont<'a> {
154    /// Creates a new `OptionFont` with no font set.
155    ///
156    /// # Returns
157    ///
158    /// A new `OptionFont` instance with `font` set to `None`.
159    pub const fn none() -> Self {
160        Self { font: None }
161    }
162
163    /// Sets the font value.
164    ///
165    /// # Arguments
166    ///
167    /// * `font` - The font to set.
168    pub const fn set_font(&mut self, font: UiFont<'a>) {
169        self.font = Some(font);
170    }
171
172    /// Returns the font, falling back to the style default if not set.
173    ///
174    /// # Type Parameters
175    ///
176    /// * `COL` - The pixel color type implementing [`PixelColor`]
177    ///
178    /// # Arguments
179    ///
180    /// * `style` - Reference to the style configuration.
181    ///
182    /// # Returns
183    ///
184    /// The set font if present, otherwise `style.default_font`.
185    pub fn font<COL: PixelColor>(&self, style: &Style<COL>) -> UiFont<'a> {
186        self.font.unwrap_or(style.default_font)
187    }
188}
189
190/// Converts an `Option<UiFont<'a>>` into an `OptionFont<'a>`.
191impl<'a> From<Option<UiFont<'a>>> for OptionFont<'a> {
192    fn from(font: Option<UiFont<'a>>) -> Self {
193        Self { font }
194    }
195}
196
197/// Wrapper for optional numeric values with style fallback.
198///
199/// This struct provides a convenient way to handle optional numeric parameters
200/// in widgets, such as corner radius and border width. When a value is not
201/// explicitly set, it falls back to corresponding value from the global style
202/// configuration.
203///
204/// # Example
205///
206/// ```rust
207/// use matrix_gui::prelude::*;
208///
209/// // Create with no value set
210/// let mut value = OptionU8::none();
211///
212/// // Set a specific value
213/// value.set_value(5);
214/// ```
215#[derive(Debug)]
216pub struct OptionU8 {
217    /// The optional numeric value.
218    pub value: Option<u8>,
219}
220
221impl OptionU8 {
222    /// Creates a new `OptionU8` with no value set.
223    ///
224    /// # Returns
225    ///
226    /// A new `OptionU8` instance with `value` set to `None`.
227    pub const fn none() -> Self {
228        Self { value: None }
229    }
230
231    /// Sets the numeric value.
232    ///
233    /// # Arguments
234    ///
235    /// * `value` - The value to set.
236    pub const fn set_value(&mut self, value: u8) {
237        self.value = Some(value);
238    }
239
240    /// Returns the corner radius, falling back to the style default if not set.
241    ///
242    /// # Type Parameters
243    ///
244    /// * `COL` - The pixel color type implementing [`PixelColor`]
245    ///
246    /// # Arguments
247    ///
248    /// * `style` - Reference to the style configuration.
249    ///
250    /// # Returns
251    ///
252    /// The set value if present, otherwise `style.corner_radius` as `u32`.
253    pub fn corner_radius<COL: PixelColor>(&self, style: &Style<COL>) -> u32 {
254        self.value.unwrap_or(style.corner_radius.into()) as u32
255    }
256
257    /// Returns the border width, falling back to the style default if not set.
258    ///
259    /// # Type Parameters
260    ///
261    /// * `COL` - The pixel color type implementing [`PixelColor`]
262    ///
263    /// # Arguments
264    ///
265    /// * `style` - Reference to the style configuration.
266    ///
267    /// # Returns
268    ///
269    /// The set value if present, otherwise `style.border_width` as `u32`.
270    pub fn border_width<COL: PixelColor>(&self, style: &Style<COL>) -> u32 {
271        self.value.unwrap_or(style.border_width.into()) as u32
272    }
273}
274
275/// Converts an `Option<u8>` into an `OptionU8`.
276impl From<Option<u8>> for OptionU8 {
277    fn from(value: Option<u8>) -> Self {
278        Self { value }
279    }
280}