1use crate::ConfigAction;
9use crate::theme::ColorsSrgb;
10use std::collections::BTreeMap;
11use std::time::Duration;
12
13#[derive(Clone, Debug)]
15#[non_exhaustive]
16pub enum ThemeConfigMsg {
17 SetActiveTheme(String),
19 SetActiveScheme(String),
21 AddScheme(String, ColorsSrgb),
23 RemoveScheme(String),
25 FadeDurationMs(u32),
27}
28
29#[derive(Clone, Debug, PartialEq)]
31#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
32pub struct ThemeConfig {
33 #[cfg_attr(feature = "serde", serde(default))]
35 pub active_theme: String,
36
37 #[cfg_attr(feature = "serde", serde(default = "defaults::default_scheme"))]
39 pub active_scheme: String,
40
41 #[cfg_attr(feature = "serde", serde(default = "defaults::color_schemes"))]
45 pub color_schemes: BTreeMap<String, ColorsSrgb>,
46
47 #[cfg_attr(feature = "serde", serde(default = "defaults::cursor_blink_rate_ms"))]
49 pub cursor_blink_rate_ms: u32,
50
51 #[cfg_attr(feature = "serde", serde(default = "defaults::transition_fade_ms"))]
53 pub transition_fade_ms: u32,
54}
55
56impl Default for ThemeConfig {
57 fn default() -> Self {
58 ThemeConfig {
59 active_theme: "".to_string(),
60 active_scheme: defaults::default_scheme(),
61 color_schemes: defaults::color_schemes(),
62 cursor_blink_rate_ms: defaults::cursor_blink_rate_ms(),
63 transition_fade_ms: defaults::transition_fade_ms(),
64 }
65 }
66}
67
68impl ThemeConfig {
69 pub(super) fn change_config(&mut self, msg: ThemeConfigMsg) -> ConfigAction {
70 match msg {
71 ThemeConfigMsg::SetActiveTheme(theme) => self.set_active_theme(theme),
72 ThemeConfigMsg::SetActiveScheme(scheme) => self.set_active_scheme(scheme),
73 ThemeConfigMsg::AddScheme(scheme, colors) => self.add_scheme(scheme, colors),
74 ThemeConfigMsg::RemoveScheme(scheme) => self.remove_scheme(&scheme),
75 ThemeConfigMsg::FadeDurationMs(dur) => {
76 self.transition_fade_ms = dur;
77 ConfigAction::THEME
78 }
79 }
80 }
81}
82
83impl ThemeConfig {
84 pub fn set_active_theme(&mut self, theme: impl ToString) -> ConfigAction {
89 let theme = theme.to_string();
90 if self.active_theme == theme {
91 ConfigAction::empty()
92 } else {
93 self.active_theme = theme;
94 ConfigAction::THEME_SWITCH
95 }
96 }
97
98 #[inline]
102 pub fn active_scheme(&self) -> &str {
103 &self.active_scheme
104 }
105
106 pub fn set_active_scheme(&mut self, scheme: impl ToString) -> ConfigAction {
110 let scheme = scheme.to_string();
111 if self.color_schemes.keys().any(|k| *k == scheme) {
112 self.active_scheme = scheme.to_string();
113 ConfigAction::THEME
114 } else {
115 ConfigAction::empty()
116 }
117 }
118
119 #[inline]
121 pub fn color_schemes(&self) -> impl Iterator<Item = (&str, &ColorsSrgb)> {
122 self.color_schemes.iter().map(|(s, t)| (s.as_str(), t))
123 }
124
125 #[inline]
127 pub fn get_color_scheme(&self, name: &str) -> Option<&ColorsSrgb> {
128 self.color_schemes.get(name)
129 }
130
131 #[inline]
133 pub fn get_active_scheme(&self) -> &ColorsSrgb {
134 self.color_schemes
135 .get(&self.active_scheme)
136 .unwrap_or(&ColorsSrgb::LIGHT)
137 }
138
139 pub fn add_scheme(&mut self, scheme: impl ToString, colors: ColorsSrgb) -> ConfigAction {
141 self.color_schemes.insert(scheme.to_string(), colors);
142 ConfigAction::empty()
143 }
144
145 pub fn remove_scheme(&mut self, scheme: &str) -> ConfigAction {
147 self.color_schemes.remove(scheme);
148 if scheme == self.active_scheme {
149 ConfigAction::THEME
150 } else {
151 ConfigAction::empty()
152 }
153 }
154
155 #[inline]
157 pub fn cursor_blink_rate(&self) -> Duration {
158 Duration::from_millis(self.cursor_blink_rate_ms as u64)
159 }
160
161 #[inline]
163 pub fn transition_fade_duration(&self) -> Duration {
164 Duration::from_millis(self.transition_fade_ms as u64)
165 }
166}
167
168mod defaults {
169 use super::*;
170
171 pub fn default_scheme() -> String {
172 "light".to_string()
173 }
174
175 pub fn color_schemes() -> BTreeMap<String, ColorsSrgb> {
176 let mut schemes = BTreeMap::new();
177 schemes.insert("light".to_string(), ColorsSrgb::LIGHT);
178 schemes.insert("dark".to_string(), ColorsSrgb::DARK);
179 schemes.insert("blue".to_string(), ColorsSrgb::BLUE);
180 schemes
181 }
182
183 pub fn cursor_blink_rate_ms() -> u32 {
184 600
185 }
186
187 pub fn transition_fade_ms() -> u32 {
188 150
189 }
190}