use super::{Status, StyleFn};
use iced::{border::Radius, Background, Color, Theme};
#[derive(Clone, Copy, Debug)]
pub struct Style {
pub background: Option<Background>,
pub border_color: Option<Color>,
pub border_width: f32,
pub tab_label_background: Background,
pub tab_label_border_color: Color,
pub tab_label_border_width: f32,
pub icon_color: Color,
pub icon_background: Option<Background>,
pub icon_border_radius: Radius,
pub text_color: Color,
}
impl Default for Style {
fn default() -> Self {
Self {
background: None,
border_color: None,
border_width: 0.0,
tab_label_background: Background::Color([0.87, 0.87, 0.87].into()),
tab_label_border_color: [0.7, 0.7, 0.7].into(),
tab_label_border_width: 1.0,
icon_color: Color::BLACK,
icon_background: Some(Background::Color(Color::TRANSPARENT)),
icon_border_radius: 4.0.into(),
text_color: Color::BLACK,
}
}
}
pub trait Catalog {
type Class<'a>;
fn default<'a>() -> Self::Class<'a>;
fn style(&self, class: &Self::Class<'_>, status: Status) -> Style;
}
impl Catalog for Theme {
type Class<'a> = StyleFn<'a, Self, Style>;
fn default<'a>() -> Self::Class<'a> {
Box::new(primary)
}
fn style(&self, class: &Self::Class<'_>, status: Status) -> Style {
class(self, status)
}
}
#[must_use]
pub fn primary(theme: &Theme, status: Status) -> Style {
let mut base = Style::default();
let palette = theme.extended_palette();
base.text_color = palette.background.base.text;
match status {
Status::Disabled => {
base.tab_label_background = Background::Color(palette.background.strong.color);
}
Status::Hovered => {
base.tab_label_background = Background::Color(palette.primary.strong.color);
}
_ => {
base.tab_label_background = Background::Color(palette.primary.base.color);
}
}
base
}
#[must_use]
pub fn dark(_theme: &Theme, status: Status) -> Style {
let mut base = Style {
tab_label_background: Background::Color([0.1, 0.1, 0.1].into()),
tab_label_border_color: [0.3, 0.3, 0.3].into(),
icon_color: Color::WHITE,
text_color: Color::WHITE,
..Default::default()
};
if status == Status::Disabled {
base.tab_label_background = Background::Color([0.13, 0.13, 0.13].into());
}
base
}
#[must_use]
pub fn red(_theme: &Theme, status: Status) -> Style {
let mut base = Style {
tab_label_background: Background::Color([1.0, 0.0, 0.0].into()),
tab_label_border_color: Color::TRANSPARENT,
tab_label_border_width: 0.0,
icon_color: Color::WHITE,
text_color: Color::WHITE,
..Default::default()
};
if status == Status::Disabled {
base.tab_label_background = Background::Color([0.13, 0.13, 0.13].into());
base.icon_color = Color::BLACK;
base.text_color = Color::BLACK;
}
base
}
#[must_use]
pub fn blue(_theme: &Theme, status: Status) -> Style {
let mut base = Style {
tab_label_background: Background::Color([0.0, 0.0, 1.0].into()),
tab_label_border_color: [0.0, 0.0, 1.0].into(),
icon_color: Color::WHITE,
text_color: Color::WHITE,
..Default::default()
};
if status == Status::Disabled {
base.tab_label_background = Background::Color([0.5, 0.5, 1.0].into());
base.tab_label_border_color = [0.5, 0.5, 1.0].into();
}
base
}
#[must_use]
pub fn green(_theme: &Theme, status: Status) -> Style {
let mut base = Style {
tab_label_background: Color::WHITE.into(),
icon_color: [0.0, 0.5, 0.0].into(),
text_color: [0.0, 0.5, 0.0].into(),
..Default::default()
};
match status {
Status::Disabled => {
base.icon_color = [0.7, 0.7, 0.7].into();
base.text_color = [0.7, 0.7, 0.7].into();
base.tab_label_border_color = [0.7, 0.7, 0.7].into();
}
_ => {
base.tab_label_border_color = [0.0, 0.5, 0.0].into();
}
}
base
}
#[must_use]
pub fn purple(_theme: &Theme, status: Status) -> Style {
let mut base = Style {
tab_label_background: Color::WHITE.into(),
tab_label_border_color: Color::TRANSPARENT,
icon_color: [0.7, 0.0, 1.0].into(),
text_color: [0.7, 0.0, 1.0].into(),
..Default::default()
};
if status == Status::Disabled {
base.icon_color = Color::BLACK;
base.text_color = Color::BLACK;
}
base
}