use anyhow::Context;
use hjkl_theme::{Color, Theme};
use hjkl_theme_tui::ToRatatui;
use ratatui::style::{Color as RColor, Modifier, Style};
use std::path::Path;
pub struct UiTheme {
pub fg: RColor,
pub bg: RColor,
pub border: Style,
pub border_selected: Style,
pub title: Style,
pub dim: Style,
pub gauge_util: Style,
pub gauge_vram: Style,
pub spark_util: Style,
pub spark_power: Style,
pub temp_ok: Style,
pub temp_warn: Style,
pub temp_crit: Style,
pub accent: RColor,
}
pub fn load(path: Option<&Path>) -> anyhow::Result<UiTheme> {
let theme = match path {
Some(p) => hjkl_theme::loader::load_from_path(p)
.with_context(|| format!("loading theme {}", p.display()))?,
None => hjkl_theme::loader::default_theme(),
};
Ok(UiTheme::from_theme(&theme))
}
impl UiTheme {
fn from_theme(t: &Theme) -> Self {
let fg =
t.ui.foreground
.unwrap_or_else(|| pal(t, &["text"], Color::rgb(0xcd, 0xd6, 0xf4)));
let bg =
t.ui.background
.unwrap_or_else(|| pal(t, &["base"], Color::rgb(0x1e, 0x1e, 0x2e)));
let accent = pal(t, &["mauve", "blue"], Color::rgb(0xcb, 0xa6, 0xf7));
let green = pal(t, &["green"], Color::rgb(0xa6, 0xe3, 0xa1));
let yellow = pal(t, &["yellow", "peach"], Color::rgb(0xf9, 0xe2, 0xaf));
let red = pal(t, &["red"], Color::rgb(0xf3, 0x8b, 0xa8));
let blue = pal(t, &["blue", "sky"], Color::rgb(0x89, 0xb4, 0xfa));
let teal = pal(t, &["teal", "sky"], Color::rgb(0x94, 0xe2, 0xd5));
let dim = pal(t, &["overlay0", "surface2"], Color::rgb(0x6c, 0x70, 0x86));
Self {
fg: fg.to_ratatui(),
bg: bg.to_ratatui(),
border: Style::new().fg(dim.to_ratatui()),
border_selected: Style::new().fg(accent.to_ratatui()),
title: Style::new()
.fg(accent.to_ratatui())
.add_modifier(Modifier::BOLD),
dim: Style::new().fg(dim.to_ratatui()),
gauge_util: Style::new().fg(green.to_ratatui()),
gauge_vram: Style::new().fg(blue.to_ratatui()),
spark_util: Style::new().fg(green.to_ratatui()),
spark_power: Style::new().fg(teal.to_ratatui()),
temp_ok: Style::new().fg(green.to_ratatui()),
temp_warn: Style::new().fg(yellow.to_ratatui()),
temp_crit: Style::new().fg(red.to_ratatui()),
accent: accent.to_ratatui(),
}
}
pub fn temp_style(&self, c: f64) -> Style {
if c >= 90.0 {
self.temp_crit
} else if c >= 75.0 {
self.temp_warn
} else {
self.temp_ok
}
}
}
fn pal(t: &Theme, names: &[&str], fallback: Color) -> Color {
names
.iter()
.find_map(|n| t.palette.get(*n).copied())
.unwrap_or(fallback)
}