1use std::collections::HashMap;
6
7use ratatui::style::Style;
8
9use crate::TcaTheme;
10
11#[derive(Debug, Clone)]
13pub struct StyleSet {
14 pub name: String,
16 pub author: String,
18 pub is_dark: bool,
20 pub primary: Style,
22 pub secondary: Style,
24 pub muted: Style,
26 pub border: Style,
28 pub border_muted: Style,
30 pub selection: Style,
32 pub cursor: Style,
34 pub cursor_muted: Style,
36 pub error: Style,
38 pub warning: Style,
40 pub info: Style,
42 pub success: Style,
44 pub highlight: Style,
46 pub link: Style,
48 custom: HashMap<String, Style>,
50}
51
52impl StyleSet {
53 #[cfg(feature = "fs")]
57 pub fn from_name(name: &str) -> Self {
58 TcaTheme::from_name(name).into()
59 }
60
61 #[cfg(feature = "fs")]
67 pub fn from_default_light_cfg() -> Self {
68 TcaTheme::from_default_light_cfg().into()
69 }
70
71 pub fn insert_custom(&mut self, key: impl Into<String>, style: Style) {
73 self.custom.insert(key.into(), style);
74 }
75
76 pub fn get_custom(&self, key: &str) -> Option<&Style> {
78 self.custom.get(key)
79 }
80}
81
82impl From<TcaTheme> for StyleSet {
83 fn from(value: TcaTheme) -> Self {
84 StyleSet {
85 name: value.meta.name.clone(),
86 author: value.meta.author.clone(),
87 is_dark: value.meta.dark,
88 primary: Style::default()
89 .bg(value.ui.bg_primary)
90 .fg(value.ui.fg_primary),
91 secondary: Style::default()
92 .bg(value.ui.bg_secondary)
93 .fg(value.ui.fg_secondary),
94 muted: Style::default()
95 .bg(value.ui.bg_primary)
96 .fg(value.ui.fg_muted),
97 border: Style::default()
98 .bg(value.ui.bg_primary)
99 .fg(value.ui.border_primary),
100 border_muted: Style::default()
101 .bg(value.ui.bg_primary)
102 .fg(value.ui.border_muted),
103 selection: Style::default()
104 .bg(value.ui.selection_bg)
105 .fg(value.ui.selection_fg),
106 cursor: Style::default()
107 .bg(value.ui.bg_primary)
108 .fg(value.ui.cursor_primary),
109 cursor_muted: Style::default()
110 .bg(value.ui.bg_primary)
111 .fg(value.ui.cursor_muted),
112 error: Style::default()
113 .bg(value.ui.bg_primary)
114 .fg(value.semantic.error),
115 warning: Style::default()
116 .bg(value.ui.bg_primary)
117 .fg(value.semantic.warning),
118 info: Style::default()
119 .bg(value.ui.bg_primary)
120 .fg(value.semantic.info),
121 success: Style::default()
122 .bg(value.ui.bg_primary)
123 .fg(value.semantic.success),
124 highlight: Style::default()
125 .bg(value.ui.bg_primary)
126 .fg(value.semantic.highlight),
127 link: Style::default()
128 .bg(value.ui.bg_primary)
129 .fg(value.semantic.link),
130 custom: HashMap::default(),
131 }
132 }
133}
134
135impl From<&TcaTheme> for StyleSet {
136 fn from(value: &TcaTheme) -> Self {
137 value.clone().into()
138 }
139}
140
141#[cfg(feature = "fs")]
146impl Default for StyleSet {
147 fn default() -> Self {
148 TcaTheme::default().into()
149 }
150}
151
152#[cfg(feature = "fs")]
157#[derive(Debug)]
158pub struct StyleSetCursor(crate::theme::TcaThemeCursor);
159
160#[cfg(feature = "fs")]
161impl StyleSetCursor {
162 pub fn new(themes: impl IntoIterator<Item = TcaTheme>) -> Self {
164 Self(crate::theme::TcaThemeCursor::new(themes))
165 }
166
167 pub fn with_builtins() -> Self {
169 Self(crate::theme::TcaThemeCursor::with_builtins())
170 }
171
172 pub fn with_user_themes() -> Self {
174 Self(crate::theme::TcaThemeCursor::with_user_themes())
175 }
176
177 pub fn with_all_themes() -> Self {
179 Self(crate::theme::TcaThemeCursor::with_all_themes())
180 }
181
182 pub fn peek(&self) -> Option<StyleSet> {
184 self.0.peek().map(Into::into)
185 }
186
187 #[allow(clippy::should_implement_trait)]
189 pub fn next(&mut self) -> Option<StyleSet> {
190 self.0.next().map(Into::into)
191 }
192
193 pub fn prev(&mut self) -> Option<StyleSet> {
195 self.0.prev().map(Into::into)
196 }
197
198 pub fn set_current(&mut self, name: &str) -> Option<StyleSet> {
200 self.0.set_current(name).map(Into::into)
201 }
202
203 pub fn len(&self) -> usize {
205 self.0.len()
206 }
207
208 pub fn is_empty(&self) -> bool {
210 self.0.is_empty()
211 }
212}