iced_rizzen 0.14.0

Extra widgets for official releases of iced GUI library.
Documentation
// This file is part of `iced_rizzen` project. For the terms of use, please see the file
// called `LICENSE-BSD-3-Clause` at the top level of the `iced_rizzen` project's Git repository.

//! The style file for the cell grid widget.

#[doc(inline)]
#[allow(unused_imports)]
use super::cellgrid::CellGrid;

use crate::core::{Color, Theme};

/// The appearance of a scrollbar.
#[derive(Clone, Copy, PartialEq)]
pub struct Style {
    /// The default background [`Color`] of the grid.
    pub background: Color,
    /// The [`Color`] of the divider.
    pub grid_line: Color,
    /// The [`Color`] of the divider for page bounds.
    pub page_break: Color,
    /// The [`Color`] of the resizing indicator.
    pub resizing: Color,
    /// The background [`Color`] of the scrollbar area. If margins are specified
    /// for the scrollbars, this is the color that will be seen. Also used for
    /// filling the gap between scrollbars.
    pub scrollbar: Color,
    /// The [`Color`] of the rail.
    pub rail: Color,
    /// The end style of the rail.
    pub rail_ends: EndStyle,
    /// The [`Color`] of the scroller.
    pub scroller: Color,
    /// The end style of the scroller.
    pub scroller_ends: EndStyle,
    /// The [`Color`] of the scroller when mouse cursor hovers over.
    pub scroller_hover: Color,
}

// Background has no Default implementation.
impl Default for Style {
    fn default() -> Self {
        Self {
            background: Color::default(),
            grid_line: Color::default(),
            page_break: Color::default(),
            resizing: Color::default(),
            scrollbar: Color::default(),
            rail: Color::default(),
            rail_ends: EndStyle::default(),
            scroller: Color::default(),
            scroller_ends: EndStyle::default(),
            scroller_hover: Color::default(),
        }
    }
}

// Mirrors the Style struct, but all fields are Option.
#[derive(Default, Clone, Copy, PartialEq)]
pub(crate) struct StyleOptions {
    pub background: Option<Color>,
    pub grid_line: Option<Color>,
    pub page_break: Option<Color>,
    pub resizing: Option<Color>,
    pub scrollbar: Option<Color>,
    pub rail: Option<Color>,
    pub rail_ends: Option<EndStyle>,
    pub scroller: Option<Color>,
    pub scroller_ends: Option<EndStyle>,
    pub scroller_hover: Option<Color>,
}

/// The styling of the ends of rail or scroller.
#[derive(Clone, Copy, PartialEq)]
pub enum EndStyle {
    /// Sharp corners
    Sharp,
    /// Round ends.
    Round,
    /// Corners slightly rounded.
    ///
    /// Usually the corner radius is between 1.0 and 3.0 pixels.
    BluntCorners(f32),
    // Future variants using `Canvas` within the `draw()`
    // /// Pointed ends.
    // ///
    // /// Distance from the end where diamond style ends.
    // Pointed(f32),
    // /// The rail or scroller is diamond shaped.
    // Diamond,
}

impl Default for EndStyle {
    fn default() -> Self {
        EndStyle::Sharp
    }
}

/// The components of [`CellGrid`].
pub enum Component {
    /// The background of the grid area.
    Background,
    /// The optional grid lines.
    GridLines,
    /// The page break grid line.
    PageBreak,
    /// The scrollbar area.
    Scrollbar,
    /// The rail of the scrollbar.
    Rail,
    /// The scroller of the scrollbar.
    Scroller,
    /// The scroller of the scrollbar, when house hovers over.
    ScrollerHover,
    /// The resizing guide line.
    Resizing,
}

/// The theme catalog of a [`CellGrid`].
pub trait Catalog {
    /// The item class of this [`Catalog`].
    type Class<'a>;

    /// The default class produced by this [`Catalog`].
    fn default<'a>() -> <Self as Catalog>::Class<'a>;

    /// The [`Style`] of a class.
    fn style(&self, class: &<Self as Catalog>::Class<'_>) -> Style;
}

/// A styling function for a [`CellGrid`].
///
/// This is just a boxed closure: `Fn(&Theme) -> Style`.
pub type StyleFn<'a, Theme> = Box<dyn Fn(&Theme) -> Style + 'a>;

impl Catalog for Theme {
    type Class<'a> = StyleFn<'a, Self>;

    fn default<'a>() -> StyleFn<'a, Self> {
        Box::new(default)
    }

    fn style(&self, class: &StyleFn<'_, Self>) -> Style {
        class(self)
    }
}

/// The default style of a [`CellGrid`].
pub fn default(theme: &Theme) -> Style {
    let palette = theme.extended_palette();
    Style {
        background: palette.background.weak.color,
        grid_line: palette.primary.base.text,
        page_break: palette.primary.strong.color,
        resizing: palette.primary.base.text,
        scrollbar: palette.background.weakest.color,
        rail: palette.secondary.base.color,
        rail_ends: EndStyle::Sharp,
        scroller: palette.background.weak.color,
        scroller_ends: EndStyle::Sharp,
        scroller_hover: palette.primary.strong.color,
    }
}