faststep 0.1.0

UIKit-inspired embedded UI framework built on embedded-graphics
Documentation
use embedded_graphics::pixelcolor::Rgb565;

/// Global semantic palette and sizing metrics used across widgets.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct FsTheme {
    /// Background color for full-screen surfaces.
    pub background: Rgb565,
    /// Primary card and panel surface color.
    pub surface: Rgb565,
    /// Secondary surface used for separators and contrast.
    pub surface_alt: Rgb565,
    /// Accent color for primary actions and emphasis.
    pub accent: Rgb565,
    /// Default foreground color for strong text.
    pub text_primary: Rgb565,
    /// Secondary foreground color for supporting text.
    pub text_secondary: Rgb565,
    /// Foreground color to render on accent surfaces.
    pub text_on_accent: Rgb565,
    /// Semantic success color.
    pub success: Rgb565,
    /// Semantic warning color.
    pub warning: Rgb565,
    /// Semantic danger or destructive color.
    pub danger: Rgb565,
    /// Foreground color to render on danger surfaces.
    pub text_on_danger: Rgb565,
    /// Base dimming color used for overlays.
    pub dim: Rgb565,
    /// Height of the tab bar container.
    pub tab_bar_height: u32,
    /// Outer margin used when presenting modals.
    pub modal_margin: u32,
}

impl FsTheme {
    /// Returns the default neutral light palette.
    pub const fn neutral_light() -> Self {
        Self {
            background: Rgb565::new(31, 63, 31),
            surface: Rgb565::new(29, 59, 29),
            surface_alt: Rgb565::new(26, 53, 26),
            accent: Rgb565::new(5, 24, 29),
            text_primary: Rgb565::new(4, 10, 4),
            text_secondary: Rgb565::new(10, 21, 10),
            text_on_accent: Rgb565::new(31, 63, 31),
            success: Rgb565::new(7, 40, 12),
            warning: Rgb565::new(31, 43, 5),
            danger: Rgb565::new(26, 13, 10),
            text_on_danger: Rgb565::new(31, 63, 31),
            dim: Rgb565::new(0, 0, 0),
            tab_bar_height: 72,
            modal_margin: 44,
        }
    }

    /// Overrides the neutral surface colors.
    pub const fn with_neutral_surfaces(
        mut self,
        background: Rgb565,
        surface: Rgb565,
        surface_alt: Rgb565,
    ) -> Self {
        self.background = background;
        self.surface = surface;
        self.surface_alt = surface_alt;
        self
    }

    /// Overrides the primary and secondary text colors.
    pub const fn with_text_colors(mut self, text_primary: Rgb565, text_secondary: Rgb565) -> Self {
        self.text_primary = text_primary;
        self.text_secondary = text_secondary;
        self
    }

    /// Overrides the accent color pair.
    pub const fn with_accent(mut self, accent: Rgb565, text_on_accent: Rgb565) -> Self {
        self.accent = accent;
        self.text_on_accent = text_on_accent;
        self
    }

    /// Overrides the semantic success, warning, and danger colors.
    pub const fn with_status_colors(
        mut self,
        success: Rgb565,
        warning: Rgb565,
        danger: Rgb565,
        text_on_danger: Rgb565,
    ) -> Self {
        self.success = success;
        self.warning = warning;
        self.danger = danger;
        self.text_on_danger = text_on_danger;
        self
    }

    /// Overrides the dimming base color.
    pub const fn with_dim(mut self, dim: Rgb565) -> Self {
        self.dim = dim;
        self
    }

    /// Overrides common widget metrics.
    pub const fn with_metrics(mut self, tab_bar_height: u32, modal_margin: u32) -> Self {
        self.tab_bar_height = tab_bar_height;
        self.modal_margin = modal_margin;
        self
    }
}

impl Default for FsTheme {
    fn default() -> Self {
        Self::neutral_light()
    }
}