use ratatui::style::Color;
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub enum ColorMode {
#[default]
TrueColor,
Indexed256,
}
#[derive(Debug, Clone, Copy)]
pub struct Palette {
pub accent: Color,
pub green: Color,
pub light_green: Color,
pub red: Color,
pub white: Color,
pub gray: Color,
pub dim_gray: Color,
pub mid_gray: Color,
pub description_gray: Color,
pub light_gray: Color,
pub cyan: Color,
pub magenta: Color,
pub blue: Color,
pub bg_dark: Color,
pub vram_green: Color,
pub vram_yellow: Color,
pub vram_red: Color,
}
impl Palette {
pub const TRUECOLOR: Self = Self {
accent: Color::Rgb(255, 203, 107),
green: Color::Rgb(166, 227, 161),
light_green: Color::Rgb(80, 220, 140),
red: Color::Rgb(243, 139, 168),
white: Color::Rgb(205, 214, 244),
gray: Color::Rgb(100, 116, 139),
dim_gray: Color::Rgb(137, 180, 250),
mid_gray: Color::Rgb(99, 110, 125),
description_gray: Color::Rgb(176, 190, 197),
light_gray: Color::Rgb(115, 130, 155),
cyan: Color::Rgb(129, 229, 249),
magenta: Color::Rgb(203, 166, 247),
blue: Color::Rgb(137, 180, 250),
bg_dark: Color::Rgb(17, 24, 39),
vram_green: Color::Rgb(74, 222, 128),
vram_yellow: Color::Rgb(251, 191, 36),
vram_red: Color::Rgb(248, 113, 113),
};
pub const INDEXED: Self = Self {
accent: Color::Indexed(215),
green: Color::Indexed(120),
light_green: Color::Indexed(84),
red: Color::Indexed(210),
white: Color::Indexed(189),
gray: Color::Indexed(66),
dim_gray: Color::Indexed(147),
mid_gray: Color::Indexed(60),
description_gray: Color::Indexed(103),
light_gray: Color::Indexed(67),
cyan: Color::Indexed(123),
magenta: Color::Indexed(183),
blue: Color::Indexed(147),
bg_dark: Color::Rgb(17, 24, 39),
vram_green: Color::Indexed(49),
vram_yellow: Color::Indexed(214),
vram_red: Color::Indexed(209),
};
}
static PALETTE: std::sync::OnceLock<Palette> = std::sync::OnceLock::new();
pub fn init(mode: ColorMode) {
PALETTE.get_or_init(|| match mode {
ColorMode::TrueColor => Palette::TRUECOLOR,
ColorMode::Indexed256 => Palette::INDEXED,
});
}
pub fn detect_color_mode() -> ColorMode {
let colorterm = std::env::var("COLORTERM").unwrap_or_default();
let term = std::env::var("TERM").unwrap_or_default();
let term_program = std::env::var("TERM_PROGRAM").unwrap_or_default();
if colorterm.contains("truecolor") || colorterm.contains("24bit") {
return ColorMode::TrueColor;
}
if term.contains("256color") || term.contains("256colour") {
return ColorMode::TrueColor;
}
if term_program.contains("Apple_Terminal") {
return ColorMode::TrueColor;
}
ColorMode::TrueColor
}
pub fn get() -> Palette {
*PALETTE.get_or_init(|| match detect_color_mode() {
ColorMode::TrueColor => Palette::TRUECOLOR,
ColorMode::Indexed256 => Palette::INDEXED,
})
}
pub fn accent() -> Color { get().accent }
pub fn green() -> Color { get().green }
pub fn light_green() -> Color { get().light_green }
pub fn red() -> Color { get().red }
pub fn white() -> Color { get().white }
pub fn gray() -> Color { get().gray }
pub fn dim_gray() -> Color { get().dim_gray }
pub fn mid_gray() -> Color { get().mid_gray }
pub fn description_gray() -> Color { get().description_gray }
pub fn light_gray() -> Color { get().light_gray }
pub fn cyan() -> Color { get().cyan }
pub fn magenta() -> Color { get().magenta }
pub fn blue() -> Color { get().blue }
pub fn bg_dark() -> Color { get().bg_dark }
pub fn vram_green() -> Color { get().vram_green }
pub fn vram_yellow() -> Color { get().vram_yellow }
pub fn vram_red() -> Color { get().vram_red }
pub fn black() -> Color { Color::Black }