1use ratatui::prelude::*;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
6pub enum Theme {
7 Light,
8 Dark,
9}
10
11#[derive(Debug, Clone)]
13pub struct ThemeColors {
14 pub score_high: Color,
16 pub score_mid: Color,
17 pub score_low: Color,
18
19 pub bar_filled_high: Color,
21 pub bar_filled_mid: Color,
22 pub bar_filled_low: Color,
23 pub bar_empty: Color,
24
25 pub row_alt_bg: Color,
27 pub index_color: Color,
28
29 pub title_style: Style,
31 pub header_style: Style,
32 pub tab_active: Style,
33 pub row_selected: Style,
34
35 pub muted: Color,
37 pub title_color: Color,
38
39 pub tab_active_style: Style,
41 pub tab_inactive_style: Style,
42
43 pub status_bar_bg: Color,
45 pub status_key_color: Color,
46 pub flash_success: Color,
47 pub flash_error: Color,
48
49 pub divider_color: Color,
51
52 pub popup_border: Color,
54 pub popup_title: Style,
55 pub popup_bg: Color,
56
57 pub scrollbar_thumb: Color,
59 pub scrollbar_track: Color,
60
61 pub banner_bg: Color,
63 pub banner_fg: Color,
64 pub banner_key: Color,
65}
66
67impl ThemeColors {
68 pub fn new(theme: Theme) -> Self {
70 match theme {
71 Theme::Dark => Self::dark(),
72 Theme::Light => Self::light(),
73 }
74 }
75
76 pub fn dark() -> Self {
78 Self {
79 score_high: Color::Red,
80 score_mid: Color::Yellow,
81 score_low: Color::Green,
82 bar_filled_high: Color::Red,
83 bar_filled_mid: Color::Yellow,
84 bar_filled_low: Color::Green,
85 bar_empty: Color::DarkGray,
86 row_alt_bg: Color::Indexed(235),
87 index_color: Color::DarkGray,
88 title_style: Style::new().bold(),
89 header_style: Style::new().bold(),
90 tab_active: Style::new().reversed(),
91 row_selected: Style::new().reversed(),
92 muted: Color::Gray,
93 title_color: Color::Cyan,
94 tab_active_style: Style::new().fg(Color::Cyan).bold(),
95 tab_inactive_style: Style::new().fg(Color::DarkGray),
96 status_bar_bg: Color::Indexed(236),
97 status_key_color: Color::Cyan,
98 flash_success: Color::Green,
99 flash_error: Color::Red,
100 divider_color: Color::Indexed(238),
101 popup_border: Color::Cyan,
102 popup_title: Style::new().fg(Color::Cyan).bold(),
103 popup_bg: Color::Indexed(234),
104 scrollbar_thumb: Color::Indexed(244),
105 scrollbar_track: Color::Indexed(236),
106 banner_bg: Color::Rgb(50, 50, 120),
107 banner_fg: Color::White,
108 banner_key: Color::Yellow,
109 }
110 }
111
112 fn light() -> Self {
114 Self {
115 score_high: Color::Red,
117 score_mid: Color::Yellow,
118 score_low: Color::Green,
119 bar_filled_high: Color::Red,
120 bar_filled_mid: Color::Yellow,
121 bar_filled_low: Color::Green,
122 bar_empty: Color::Indexed(250), row_alt_bg: Color::Indexed(254), index_color: Color::Indexed(240), title_style: Style::new().bold(),
128 header_style: Style::new().bold(),
129 tab_active: Style::new().reversed(),
130 row_selected: Style::new().reversed(),
131 muted: Color::Indexed(244), title_color: Color::Blue, tab_active_style: Style::new().fg(Color::Blue).bold(),
136 tab_inactive_style: Style::new().fg(Color::Indexed(240)),
137 status_bar_bg: Color::Indexed(253), status_key_color: Color::Blue,
140 flash_success: Color::Green,
142 flash_error: Color::Red,
143 divider_color: Color::Indexed(250), popup_border: Color::Blue,
147 popup_title: Style::new().fg(Color::Blue).bold(),
148 popup_bg: Color::Indexed(255), scrollbar_thumb: Color::Indexed(240),
151 scrollbar_track: Color::Indexed(253),
152 banner_bg: Color::Rgb(180, 180, 230), banner_fg: Color::Black, banner_key: Color::Indexed(88), }
157 }
158
159 pub fn score_color(&self, score: f64, max_score: f64) -> Color {
161 let percentage = if max_score > 0.0 {
162 (score / max_score) * 100.0
163 } else {
164 0.0
165 };
166
167 if percentage >= 70.0 {
168 self.score_high
169 } else if percentage >= 40.0 {
170 self.score_mid
171 } else {
172 self.score_low
173 }
174 }
175}
176
177pub fn resolve_theme(config_theme: &str) -> Theme {
179 match config_theme {
180 "light" => Theme::Light,
181 "dark" => Theme::Dark,
182 "auto" => detect_terminal_theme(),
183 _ => Theme::Dark, }
185}
186
187fn detect_terminal_theme() -> Theme {
189 match terminal_light::luma() {
190 Ok(luma) if luma > 0.5 => Theme::Light,
191 _ => Theme::Dark, }
193}