use crate::render::palette::RgbColor;
#[derive(Clone, Debug)]
pub struct PanelStyle {
pub bg_color: RgbColor,
pub focus_color: RgbColor,
pub unfocus_color: RgbColor,
pub text_primary: RgbColor,
pub text_secondary: RgbColor,
pub border_color: RgbColor,
pub indicator_width: usize,
pub status_bar_bg: RgbColor,
pub notification_bg: RgbColor,
pub vertical_padding: usize,
pub accent_info: RgbColor,
pub accent_success: RgbColor,
pub accent_warning: RgbColor,
pub accent_error: RgbColor,
pub accent_active: RgbColor,
pub muted: RgbColor,
pub accent_modified: RgbColor,
pub cli_color: RgbColor,
pub focus_bg: RgbColor,
pub state_default: RgbColor,
pub accent_fps_good: RgbColor,
pub accent_fps_warn: RgbColor,
}
pub const GRUVBOX_DARK: PanelStyle = PanelStyle {
bg_color: RgbColor::new(0x28, 0x28, 0x28), focus_color: RgbColor::new(0xFA, 0xBD, 0x2F), unfocus_color: RgbColor::new(0x78, 0x5F, 0x26), text_primary: RgbColor::new(0xEB, 0xDB, 0xB2), text_secondary: RgbColor::new(0xB9, 0xAA, 0x8C), border_color: RgbColor::new(0x69, 0x63, 0x58), indicator_width: 0,
status_bar_bg: RgbColor::new(0x10, 0x12, 0x13), notification_bg: RgbColor::new(0x21, 0x26, 0x23), vertical_padding: 0,
accent_info: RgbColor::new(0x83, 0xA5, 0x98), accent_success: RgbColor::new(0xB8, 0xBB, 0x26), accent_warning: RgbColor::new(0xFA, 0xBD, 0x2F), accent_error: RgbColor::new(0xFB, 0x49, 0x34), accent_active: RgbColor::new(0xFA, 0xBD, 0x2F), muted: RgbColor::new(0x66, 0x5C, 0x54), accent_modified: RgbColor::new(0xFE, 0x80, 0x19), cli_color: RgbColor::new(204, 102, 102), focus_bg: RgbColor::new(34, 52, 40), state_default: RgbColor::new(0x66, 0x5C, 0x54), accent_fps_good: RgbColor::new(0x8E, 0xC0, 0x7C), accent_fps_warn: RgbColor::new(0xD7, 0x99, 0x21), };
pub const SLIME_DARK: PanelStyle = PanelStyle {
bg_color: RgbColor::new(0x0B, 0x10, 0x0E), focus_color: RgbColor::new(0x39, 0xD3, 0x53), unfocus_color: RgbColor::new(0x18, 0x48, 0x28), text_primary: RgbColor::new(0xBE, 0xE6, 0xCD), text_secondary: RgbColor::new(0x64, 0x9B, 0x76), border_color: RgbColor::new(0x1A, 0x38, 0x24), indicator_width: 0,
status_bar_bg: RgbColor::new(0x06, 0x0A, 0x08), notification_bg: RgbColor::new(0x0F, 0x1A, 0x13), vertical_padding: 0,
accent_info: RgbColor::new(0x00, 0xBC, 0xD4), accent_success: RgbColor::new(0x39, 0xD3, 0x53), accent_warning: RgbColor::new(0xFF, 0xB7, 0x00), accent_error: RgbColor::new(0xFF, 0x47, 0x57), accent_active: RgbColor::new(0x39, 0xD3, 0x53), muted: RgbColor::new(0x24, 0x3A, 0x2C), accent_modified: RgbColor::new(0xFF, 0xB7, 0x00), cli_color: RgbColor::new(0xFF, 0x47, 0x57), focus_bg: RgbColor::new(0x18, 0x48, 0x28), state_default: RgbColor::new(0x24, 0x3A, 0x2C), accent_fps_good: RgbColor::new(0x39, 0xD3, 0x53), accent_fps_warn: RgbColor::new(0xFF, 0xB7, 0x00), };
pub const NORD: PanelStyle = PanelStyle {
bg_color: RgbColor {
r: 46,
g: 52,
b: 64,
}, focus_color: RgbColor {
r: 136,
g: 192,
b: 208,
}, unfocus_color: RgbColor {
r: 67,
g: 76,
b: 94,
}, text_primary: RgbColor {
r: 236,
g: 239,
b: 244,
}, text_secondary: RgbColor {
r: 216,
g: 222,
b: 233,
}, border_color: RgbColor {
r: 59,
g: 66,
b: 82,
}, indicator_width: 0,
status_bar_bg: RgbColor {
r: 36,
g: 41,
b: 51,
}, notification_bg: RgbColor {
r: 42,
g: 47,
b: 59,
}, vertical_padding: 0,
accent_info: RgbColor {
r: 136,
g: 192,
b: 208,
}, accent_success: RgbColor {
r: 163,
g: 190,
b: 140,
}, accent_warning: RgbColor {
r: 235,
g: 203,
b: 139,
}, accent_error: RgbColor {
r: 191,
g: 97,
b: 106,
}, accent_active: RgbColor {
r: 136,
g: 192,
b: 208,
}, muted: RgbColor {
r: 76,
g: 86,
b: 106,
}, accent_modified: RgbColor {
r: 208,
g: 135,
b: 112,
}, cli_color: RgbColor {
r: 191,
g: 97,
b: 106,
}, focus_bg: RgbColor {
r: 67,
g: 76,
b: 94,
}, state_default: RgbColor {
r: 76,
g: 86,
b: 106,
}, accent_fps_good: RgbColor {
r: 163,
g: 190,
b: 140,
}, accent_fps_warn: RgbColor {
r: 235,
g: 203,
b: 139,
}, };
pub const CATPPUCCIN_MOCHA: PanelStyle = PanelStyle {
bg_color: RgbColor {
r: 30,
g: 30,
b: 46,
}, focus_color: RgbColor {
r: 203,
g: 166,
b: 247,
}, unfocus_color: RgbColor {
r: 62,
g: 53,
b: 86,
}, text_primary: RgbColor {
r: 205,
g: 214,
b: 244,
}, text_secondary: RgbColor {
r: 166,
g: 173,
b: 200,
}, border_color: RgbColor {
r: 54,
g: 58,
b: 79,
}, indicator_width: 0,
status_bar_bg: RgbColor {
r: 17,
g: 17,
b: 27,
}, notification_bg: RgbColor {
r: 24,
g: 24,
b: 37,
}, vertical_padding: 0,
accent_info: RgbColor {
r: 137,
g: 220,
b: 235,
}, accent_success: RgbColor {
r: 166,
g: 227,
b: 161,
}, accent_warning: RgbColor {
r: 249,
g: 226,
b: 175,
}, accent_error: RgbColor {
r: 243,
g: 139,
b: 168,
}, accent_active: RgbColor {
r: 203,
g: 166,
b: 247,
}, muted: RgbColor {
r: 88,
g: 91,
b: 112,
}, accent_modified: RgbColor {
r: 250,
g: 179,
b: 135,
}, cli_color: RgbColor {
r: 243,
g: 139,
b: 168,
}, focus_bg: RgbColor {
r: 62,
g: 53,
b: 86,
}, state_default: RgbColor {
r: 88,
g: 91,
b: 112,
}, accent_fps_good: RgbColor {
r: 166,
g: 227,
b: 161,
}, accent_fps_warn: RgbColor {
r: 249,
g: 226,
b: 175,
}, };
pub const TOKYO_NIGHT: PanelStyle = PanelStyle {
bg_color: RgbColor {
r: 26,
g: 27,
b: 38,
}, focus_color: RgbColor {
r: 122,
g: 162,
b: 247,
}, unfocus_color: RgbColor {
r: 41,
g: 46,
b: 66,
}, text_primary: RgbColor {
r: 192,
g: 202,
b: 245,
}, text_secondary: RgbColor {
r: 169,
g: 177,
b: 214,
}, border_color: RgbColor {
r: 41,
g: 46,
b: 66,
}, indicator_width: 0,
status_bar_bg: RgbColor {
r: 16,
g: 16,
b: 28,
}, notification_bg: RgbColor {
r: 22,
g: 22,
b: 36,
}, vertical_padding: 0,
accent_info: RgbColor {
r: 125,
g: 207,
b: 255,
}, accent_success: RgbColor {
r: 158,
g: 206,
b: 106,
}, accent_warning: RgbColor {
r: 224,
g: 175,
b: 104,
}, accent_error: RgbColor {
r: 247,
g: 118,
b: 142,
}, accent_active: RgbColor {
r: 187,
g: 154,
b: 247,
}, muted: RgbColor {
r: 86,
g: 95,
b: 137,
}, accent_modified: RgbColor {
r: 255,
g: 158,
b: 100,
}, cli_color: RgbColor {
r: 247,
g: 118,
b: 142,
}, focus_bg: RgbColor {
r: 41,
g: 46,
b: 66,
}, state_default: RgbColor {
r: 86,
g: 95,
b: 137,
}, accent_fps_good: RgbColor {
r: 158,
g: 206,
b: 106,
}, accent_fps_warn: RgbColor {
r: 224,
g: 175,
b: 104,
}, };
impl Default for PanelStyle {
fn default() -> Self {
GRUVBOX_DARK
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Theme {
GruvboxDark,
SlimeDark,
Nord,
CatppuccinMocha,
TokyoNight,
}
impl Theme {
pub fn name(&self) -> &'static str {
match self {
Theme::GruvboxDark => "GruvboxDark",
Theme::SlimeDark => "SlimeDark",
Theme::Nord => "Nord",
Theme::CatppuccinMocha => "CatppuccinMocha",
Theme::TokyoNight => "TokyoNight",
}
}
pub fn style(&self) -> PanelStyle {
match self {
Theme::GruvboxDark => GRUVBOX_DARK,
Theme::SlimeDark => SLIME_DARK,
Theme::Nord => NORD,
Theme::CatppuccinMocha => CATPPUCCIN_MOCHA,
Theme::TokyoNight => TOKYO_NIGHT,
}
}
}
pub const ALL_THEMES: [Theme; 5] = [
Theme::GruvboxDark,
Theme::SlimeDark,
Theme::Nord,
Theme::CatppuccinMocha,
Theme::TokyoNight,
];
#[cfg(test)]
mod token_tests {
use super::*;
#[test]
fn gruvbox_dark_has_new_tokens_matching_legacy_consts() {
assert_eq!(GRUVBOX_DARK.cli_color, RgbColor::new(204, 102, 102));
assert_eq!(GRUVBOX_DARK.focus_bg, RgbColor::new(34, 52, 40));
assert_eq!(GRUVBOX_DARK.state_default, GRUVBOX_DARK.muted);
}
#[test]
fn non_gruvbox_new_tokens_match_theme_aliases() {
for style in [SLIME_DARK, NORD, CATPPUCCIN_MOCHA, TOKYO_NIGHT] {
assert_eq!(style.focus_bg, style.unfocus_color);
assert_eq!(style.cli_color, style.accent_error);
assert_eq!(style.state_default, style.muted);
}
}
}