use std::collections::HashMap;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TextureKind {
Solid,
Glass, Frosted, Custom(u32), }
impl Default for TextureKind {
fn default() -> Self {
TextureKind::Solid
}
}
#[derive(Debug, Clone)]
pub struct StyleManager {
colors: HashMap<String, String>,
sizes: HashMap<String, f64>,
textures: HashMap<String, TextureKind>,
active_preset: Option<String>,
}
impl Default for StyleManager {
fn default() -> Self {
let mut sm = Self {
colors: HashMap::new(),
sizes: HashMap::new(),
textures: HashMap::new(),
active_preset: None,
};
sm.set_color("surface_0", "#08090B");
sm.set_color("surface", "#0E0E11");
sm.set_color("surface_raised", "#1C1D23");
sm.set_color("fg_0", "#F4F4F5");
sm.set_color("fg_1", "#D7D8DB");
sm.set_color("fg_2", "#878B91");
sm.set_color("fg_3", "#555860");
sm.set_color("accent", "#FBB26A");
sm.set_color("accent_hover", "#F9A04E");
sm.set_color("accent_dim", "rgba(251,178,106,0.12)");
sm.set_color("border", "rgba(255,255,255,0.06)");
sm.set_color("border_strong", "rgba(255,255,255,0.12)");
sm.set_color("ok", "#5CB87A");
sm.set_color("warn", "#E8A838");
sm.set_color("error", "#EB5757");
sm.set_size("button_radius", 6.0);
sm.set_size("button_padding", 8.0);
sm.set_size("button_font_size", 13.0);
sm.set_size("chrome_height", 30.0);
sm.set_size("modal_radius", 8.0);
sm.set_size("popup_radius", 6.0);
sm.set_size("toolbar_height", 40.0);
sm.set_texture("button_bg", TextureKind::Solid);
sm.set_texture("modal_bg", TextureKind::Solid);
sm.set_texture("chrome_bg", TextureKind::Solid);
sm.set_texture("popup_bg", TextureKind::Solid);
sm
}
}
impl StyleManager {
pub fn new() -> Self {
Self::default()
}
pub fn color(&self, key: &str) -> Option<&str> {
self.colors.get(key).map(|s| s.as_str())
}
pub fn color_or<'a>(&'a self, key: &str, fallback: &'a str) -> &'a str {
self.colors.get(key).map(|s| s.as_str()).unwrap_or(fallback)
}
pub fn color_or_owned(&self, key: &str, fallback: &str) -> String {
self.colors.get(key).map(|s| s.clone()).unwrap_or_else(|| fallback.to_string())
}
pub fn set_color(&mut self, key: impl Into<String>, value: impl Into<String>) {
self.colors.insert(key.into(), value.into());
}
pub fn size(&self, key: &str) -> Option<f64> {
self.sizes.get(key).copied()
}
pub fn size_or(&self, key: &str, fallback: f64) -> f64 {
self.size(key).unwrap_or(fallback)
}
pub fn set_size(&mut self, key: impl Into<String>, value: f64) {
self.sizes.insert(key.into(), value);
}
pub fn texture(&self, key: &str) -> TextureKind {
self.textures.get(key).copied().unwrap_or(TextureKind::Solid)
}
pub fn set_texture(&mut self, key: impl Into<String>, value: TextureKind) {
self.textures.insert(key.into(), value);
}
pub fn apply<P: Preset + ?Sized>(&mut self, preset: &P) {
preset.apply_to(self);
self.active_preset = None;
}
pub fn apply_named<P: Preset + ?Sized>(&mut self, preset: &P, name: impl Into<String>) {
preset.apply_to(self);
self.active_preset = Some(name.into());
}
pub fn active_preset(&self) -> Option<&str> {
self.active_preset.as_deref()
}
}
pub trait Preset {
fn apply_to(&self, sm: &mut StyleManager);
}
pub struct MirageDarkPreset;
impl Preset for MirageDarkPreset {
fn apply_to(&self, sm: &mut StyleManager) {
sm.set_color("surface_0", "#08090B");
sm.set_color("surface", "#0E0E11");
sm.set_color("surface_raised", "#1C1D23");
sm.set_color("fg_0", "#F4F4F5");
sm.set_color("fg_1", "#D7D8DB");
sm.set_color("fg_2", "#878B91");
sm.set_color("fg_3", "#555860");
sm.set_color("accent", "#FBB26A");
sm.set_color("accent_hover", "#F9A04E");
sm.set_color("accent_dim", "rgba(251,178,106,0.12)");
sm.set_color("border", "rgba(255,255,255,0.06)");
sm.set_color("border_strong", "rgba(255,255,255,0.12)");
sm.set_color("ok", "#5CB87A");
sm.set_color("warn", "#E8A838");
sm.set_color("error", "#EB5757");
}
}
pub struct MirageLightPreset;
impl Preset for MirageLightPreset {
fn apply_to(&self, sm: &mut StyleManager) {
sm.set_color("surface_0", "#E4E4E0");
sm.set_color("surface", "#F0F0EC");
sm.set_color("surface_raised", "#FFFFFF");
sm.set_color("fg_0", "#0A0A0A");
sm.set_color("fg_1", "#1F1F1F");
sm.set_color("fg_2", "#4A4A4A");
sm.set_color("fg_3", "#7A7A7A");
sm.set_color("accent", "#B85F00");
sm.set_color("accent_hover", "#9A4F00");
sm.set_color("accent_dim", "rgba(184,95,0,0.16)");
sm.set_color("border", "rgba(0,0,0,0.12)");
sm.set_color("border_strong", "rgba(0,0,0,0.22)");
sm.set_color("ok", "#1F6F30");
sm.set_color("warn", "#8C5208");
sm.set_color("error", "#A82828");
}
}