use iced::{Color, Theme, theme::Palette};
use once_cell::sync::Lazy;
use optional_struct::{Applicable, optional_struct};
use serde::Deserialize;
use crate::utils::{
color::{mk_color, mk_dark_color, mk_light_color},
file::get_theme_toml,
};
pub const OXITHEME: Lazy<ComputedOxiTheme> = Lazy::new(|| {
let default_theme = default_theme();
let theme_str_opt = get_theme_toml();
if let Err(_) = theme_str_opt {
return ComputedOxiTheme::from(default_theme);
};
let theme_opt = toml::from_str::<OptionalOxiTheme>(&theme_str_opt.unwrap());
let theme = if let Ok(theme) = theme_opt {
theme.build(default_theme)
} else {
default_theme
};
ComputedOxiTheme::from(theme)
});
pub fn get_derived_iced_theme() -> Theme {
let theme = OXITHEME;
let palette = Palette {
background: theme.base,
text: theme.text,
primary: theme.primary,
success: theme.good,
danger: theme.bad,
};
Theme::custom(String::from("OxiTheme"), palette)
}
fn default_theme() -> OxiTheme {
OxiTheme {
base: String::from("1e1e2e"),
mantle: String::from("181825"),
primary_bg: String::from("313244"),
secondary_bg: String::from("45475a"),
tertiary_bg: String::from("585b70"),
text: String::from("cdd6f4"),
text_muted: String::from("585b70"),
primary: String::from("89b4fa"),
secondary: String::from("b4befe"),
primary_contrast: String::from("ffffff"),
secondary_contrast: String::from("ffffff"),
good: String::from("a6e3a1"),
good_contrast: String::from("000000"),
bad: String::from("f38ba8"),
bad_contrast: String::from("ffffff"),
info: String::from("94e2d5"),
info_contrast: String::from("ffffff"),
warning: String::from("f9e2af"),
warning_contrast: String::from("ffffff"),
rose: String::from("f5e0dc"),
lavender: String::from("b4befe"),
blue: String::from("89b4fa"),
mauve: String::from("cba6f7"),
flamingo: String::from("f2cdcd"),
tint_amount: 0.04,
shade_amount: 0.08,
border_radius: 10,
border_color_weak: String::from("cdd6f4"),
border_color_strong: String::from("89b4fa"),
padding_xs: 4.0,
padding_sm: 8.0,
padding_md: 12.0,
padding_lg: 16.0,
padding_xl: 24.0,
padding_xxl: 32.0,
font_sm: 10.0,
font_md: 14.0,
font_lg: 18.0,
font_xl: 24.0,
font_xxl: 32.0,
}
}
#[optional_struct]
#[derive(Deserialize)]
#[allow(dead_code)]
pub struct OxiTheme {
pub base: String,
pub mantle: String,
pub primary_bg: String,
pub secondary_bg: String,
pub tertiary_bg: String,
pub text: String,
pub text_muted: String,
pub primary: String,
pub secondary: String,
pub primary_contrast: String,
pub secondary_contrast: String,
pub good: String,
pub good_contrast: String,
pub bad: String,
pub bad_contrast: String,
pub info: String,
pub info_contrast: String,
pub warning: String,
pub warning_contrast: String,
pub rose: String,
pub lavender: String,
pub blue: String,
pub mauve: String,
pub flamingo: String,
pub shade_amount: f32,
pub tint_amount: f32,
pub border_radius: u16,
pub border_color_weak: String,
pub border_color_strong: String,
pub padding_xs: f32,
pub padding_sm: f32,
pub padding_md: f32,
pub padding_lg: f32,
pub padding_xl: f32,
pub padding_xxl: f32,
pub font_sm: f32,
pub font_md: f32,
pub font_lg: f32,
pub font_xl: f32,
pub font_xxl: f32,
}
impl From<OxiTheme> for ComputedOxiTheme {
fn from(value: OxiTheme) -> Self {
Self {
base: mk_color(&value.base),
mantle: mk_color(&value.mantle),
mantle_hover: mk_light_color(&value.mantle, value.tint_amount),
mantle_active: mk_light_color(&value.mantle, value.shade_amount),
primary_bg: mk_color(&value.primary_bg),
primary_bg_hover: mk_light_color(&value.primary_bg, value.tint_amount),
primary_bg_active: mk_light_color(&value.primary_bg, value.shade_amount),
secondary_bg: mk_color(&value.secondary_bg),
secondary_bg_hover: mk_light_color(&value.secondary_bg, value.tint_amount),
secondary_bg_active: mk_light_color(&value.secondary_bg, value.shade_amount),
tertiary_bg: mk_color(&value.tertiary_bg),
tertiary_bg_hover: mk_light_color(&value.tertiary_bg, value.tint_amount),
tertiary_bg_active: mk_light_color(&value.tertiary_bg, value.shade_amount),
text: mk_color(&value.text),
text_muted: mk_color(&value.text_muted),
primary: mk_color(&value.primary),
primary_hover: mk_dark_color(&value.primary, value.tint_amount),
primary_active: mk_dark_color(&value.primary, value.shade_amount),
secondary: mk_color(&value.secondary),
secondary_hover: mk_dark_color(&value.secondary, value.tint_amount),
secondary_active: mk_dark_color(&value.secondary, value.shade_amount),
primary_contrast: mk_color(&value.primary_contrast),
secondary_contrast: mk_color(&value.secondary_contrast),
good: mk_color(&value.good),
good_hover: mk_dark_color(&value.good, value.tint_amount),
good_active: mk_dark_color(&value.good, value.tint_amount),
good_contrast: mk_color(&value.good_contrast),
bad: mk_color(&value.bad),
bad_hover: mk_dark_color(&value.bad, value.tint_amount),
bad_active: mk_dark_color(&value.bad, value.tint_amount),
bad_contrast: mk_color(&value.bad_contrast),
info: mk_color(&value.info),
info_hover: mk_dark_color(&value.info, value.tint_amount),
info_active: mk_dark_color(&value.info, value.tint_amount),
info_contrast: mk_color(&value.info_contrast),
warning: mk_color(&value.warning),
warning_hover: mk_dark_color(&value.warning, value.tint_amount),
warning_active: mk_dark_color(&value.warning, value.tint_amount),
warning_contrast: mk_color(&value.warning_contrast),
rose: mk_color(&value.rose),
lavender: mk_color(&value.lavender),
blue: mk_color(&value.blue),
mauve: mk_color(&value.mauve),
flamingo: mk_color(&value.flamingo),
shade_amount: value.shade_amount,
tint_amount: value.tint_amount,
border_radius: value.border_radius,
border_color_weak: mk_color(&value.border_color_weak),
border_color_strong: mk_color(&value.border_color_strong),
padding_xs: value.padding_xs,
padding_sm: value.padding_sm,
padding_md: value.padding_md,
padding_lg: value.padding_lg,
padding_xl: value.padding_xl,
padding_xxl: value.padding_xxl,
font_sm: value.font_sm,
font_md: value.font_md,
font_lg: value.font_lg,
font_xl: value.font_xl,
font_xxl: value.font_xxl,
}
}
}
#[allow(dead_code)]
pub struct ComputedOxiTheme {
pub base: Color,
pub mantle: Color,
pub mantle_hover: Color,
pub mantle_active: Color,
pub primary_bg: Color,
pub primary_bg_hover: Color,
pub primary_bg_active: Color,
pub secondary_bg: Color,
pub secondary_bg_hover: Color,
pub secondary_bg_active: Color,
pub tertiary_bg: Color,
pub tertiary_bg_hover: Color,
pub tertiary_bg_active: Color,
pub text: Color,
pub text_muted: Color,
pub primary: Color,
pub primary_hover: Color,
pub primary_active: Color,
pub secondary: Color,
pub secondary_hover: Color,
pub secondary_active: Color,
pub primary_contrast: Color,
pub secondary_contrast: Color,
pub good: Color,
pub good_hover: Color,
pub good_active: Color,
pub good_contrast: Color,
pub bad: Color,
pub bad_hover: Color,
pub bad_active: Color,
pub bad_contrast: Color,
pub info: Color,
pub info_hover: Color,
pub info_active: Color,
pub info_contrast: Color,
pub warning: Color,
pub warning_hover: Color,
pub warning_active: Color,
pub warning_contrast: Color,
pub rose: Color,
pub lavender: Color,
pub blue: Color,
pub mauve: Color,
pub flamingo: Color,
pub shade_amount: f32,
pub tint_amount: f32,
pub border_radius: u16,
pub border_color_weak: Color,
pub border_color_strong: Color,
pub padding_xs: f32,
pub padding_sm: f32,
pub padding_md: f32,
pub padding_lg: f32,
pub padding_xl: f32,
pub padding_xxl: f32,
pub font_sm: f32,
pub font_md: f32,
pub font_lg: f32,
pub font_xl: f32,
pub font_xxl: f32,
}