iced_code_editor/
theme.rs1use iced::Color;
2
3#[derive(Debug, Clone, Copy)]
5pub struct Style {
6 pub background: Color,
8 pub text_color: Color,
10 pub gutter_background: Color,
12 pub gutter_border: Color,
14 pub line_number_color: Color,
16 pub scrollbar_background: Color,
18 pub scroller_color: Color,
20 pub current_line_highlight: Color,
22}
23
24pub trait Catalog {
26 type Class<'a>;
28
29 fn default<'a>() -> Self::Class<'a>;
31
32 fn style(&self, class: &Self::Class<'_>) -> Style;
34}
35
36pub type StyleFn<'a, Theme> = Box<dyn Fn(&Theme) -> Style + 'a>;
41
42impl Catalog for iced::Theme {
43 type Class<'a> = StyleFn<'a, Self>;
44
45 fn default<'a>() -> Self::Class<'a> {
46 Box::new(dark)
47 }
48
49 fn style(&self, class: &Self::Class<'_>) -> Style {
50 class(self)
51 }
52}
53
54pub fn dark(_theme: &iced::Theme) -> Style {
64 Style {
65 background: Color::from_rgb(0.05, 0.05, 0.07), text_color: Color::from_rgb(0.9, 0.9, 0.9), gutter_background: Color::from_rgb(0.08, 0.08, 0.10), gutter_border: Color::from_rgb(0.15, 0.15, 0.15), line_number_color: Color::from_rgb(0.5, 0.5, 0.5), scrollbar_background: Color::from_rgb(0.1, 0.1, 0.12), scroller_color: Color::from_rgb(0.3, 0.3, 0.35), current_line_highlight: Color::from_rgb(0.15, 0.15, 0.2), }
74}
75
76pub fn light(_theme: &iced::Theme) -> Style {
86 Style {
87 background: Color::from_rgb(1.0, 1.0, 1.0), text_color: Color::from_rgb(0.0, 0.0, 0.0), gutter_background: Color::from_rgb(0.953, 0.953, 0.953), gutter_border: Color::from_rgb(0.9, 0.9, 0.9), line_number_color: Color::from_rgb(0.522, 0.522, 0.522), scrollbar_background: Color::from_rgb(0.961, 0.961, 0.961), scroller_color: Color::from_rgb(0.784, 0.784, 0.784), current_line_highlight: Color::from_rgb(0.95, 0.95, 0.97), }
96}
97
98#[cfg(test)]
99mod tests {
100 use super::*;
101
102 #[test]
103 fn test_dark_theme_creation() {
104 let theme = iced::Theme::Dark;
105 let style = dark(&theme);
106
107 assert!(style.background.r < 0.1);
109 assert!(style.background.g < 0.1);
110 assert!(style.background.b < 0.1);
111
112 assert!(style.text_color.r > 0.8);
114 assert!(style.text_color.g > 0.8);
115 assert!(style.text_color.b > 0.8);
116 }
117
118 #[test]
119 fn test_dark_theme_gutter_colors() {
120 let theme = iced::Theme::Dark;
121 let style = dark(&theme);
122
123 assert!(style.gutter_background.r > style.background.r);
125 assert!(style.gutter_background.g > style.background.g);
126 assert!(style.gutter_background.b > style.background.b);
127
128 let line_num_r = style.line_number_color.r;
130 assert!(line_num_r > 0.4 && line_num_r < 0.6);
131 }
132
133 #[test]
134 fn test_dark_theme_scrollbar_colors() {
135 let theme = iced::Theme::Dark;
136 let style = dark(&theme);
137
138 assert!(style.scrollbar_background.r < style.scroller_color.r);
140 assert!(style.scrollbar_background.g < style.scroller_color.g);
141 assert!(style.scrollbar_background.b < style.scroller_color.b);
142
143 assert!(style.scroller_color.r > 0.2);
145 assert!(style.scroller_color.g > 0.2);
146 assert!(style.scroller_color.b > 0.2);
147 }
148
149 #[test]
150 fn test_style_copy() {
151 let theme = iced::Theme::Dark;
152 let style1 = dark(&theme);
153 let style2 = style1;
154
155 assert!(
157 (style1.background.r - style2.background.r).abs() < f32::EPSILON
158 );
159 assert!(
160 (style1.text_color.r - style2.text_color.r).abs() < f32::EPSILON
161 );
162 assert!(
163 (style1.gutter_background.r - style2.gutter_background.r).abs()
164 < f32::EPSILON
165 );
166 }
167
168 #[test]
169 fn test_catalog_default() {
170 let theme = iced::Theme::Dark;
171 let class = <iced::Theme as Catalog>::default();
172 let style = theme.style(&class);
173
174 assert!(style.background.r < 0.1);
176 assert!(style.text_color.r > 0.8);
177 }
178
179 #[test]
180 fn test_light_theme_creation() {
181 let theme = iced::Theme::Light;
182 let style = light(&theme);
183
184 assert!(style.background.r > 0.9);
186 assert!(style.background.g > 0.9);
187 assert!(style.background.b > 0.9);
188
189 assert!(style.text_color.r < 0.2);
191 assert!(style.text_color.g < 0.2);
192 assert!(style.text_color.b < 0.2);
193 }
194
195 #[test]
196 fn test_light_theme_gutter_colors() {
197 let theme = iced::Theme::Light;
198 let style = light(&theme);
199
200 assert!(style.gutter_background.r < style.background.r);
202 assert!(style.gutter_background.g < style.background.g);
203 assert!(style.gutter_background.b < style.background.b);
204
205 assert!(style.gutter_background.r > 0.9);
207
208 let line_num_r = style.line_number_color.r;
210 assert!(line_num_r > 0.4 && line_num_r < 0.6);
211 }
212
213 #[test]
214 fn test_light_theme_scrollbar_colors() {
215 let theme = iced::Theme::Light;
216 let style = light(&theme);
217
218 assert!(style.scrollbar_background.r > style.scroller_color.r);
220 assert!(style.scrollbar_background.g > style.scroller_color.g);
221 assert!(style.scrollbar_background.b > style.scroller_color.b);
222
223 assert!(style.scroller_color.r > 0.7);
225 assert!(style.scroller_color.g > 0.7);
226 assert!(style.scroller_color.b > 0.7);
227 }
228
229 #[test]
230 fn test_light_vs_dark_contrast() {
231 let light_style = light(&iced::Theme::Light);
232 let dark_style = dark(&iced::Theme::Dark);
233
234 assert!(light_style.background.r > dark_style.background.r);
236
237 assert!(light_style.text_color.r < dark_style.text_color.r);
239 }
240}