Skip to main content

freya_code_editor/
editor_theme.rs

1use freya_components::{
2    define_theme,
3    theming::{
4        component_themes::Theme,
5        macros::Preference,
6    },
7};
8use freya_core::prelude::Color;
9
10use crate::editor_ui::CodeEditor;
11
12define_theme! {
13    for = CodeEditor; theme_field = theme;
14    pub Editor {
15        %[fields]
16        background: Color,
17        gutter_selected: Color,
18        gutter_unselected: Color,
19        line_selected_background: Color,
20        cursor: Color,
21        highlight: Color,
22        text: Color,
23        whitespace: Color,
24    }
25}
26
27define_theme! {
28    %[no_ext]
29    pub EditorSyntax {
30        %[fields]
31        text: Color,
32        whitespace: Color,
33        attribute: Color,
34        boolean: Color,
35        comment: Color,
36        constant: Color,
37        constructor: Color,
38        escape: Color,
39        function: Color,
40        function_macro: Color,
41        function_method: Color,
42        keyword: Color,
43        label: Color,
44        module: Color,
45        number: Color,
46        operator: Color,
47        property: Color,
48        punctuation: Color,
49        punctuation_bracket: Color,
50        punctuation_delimiter: Color,
51        punctuation_special: Color,
52        string: Color,
53        string_escape: Color,
54        string_special: Color,
55        tag: Color,
56        text_literal: Color,
57        text_reference: Color,
58        text_title: Color,
59        text_uri: Color,
60        text_emphasis: Color,
61        type_: Color,
62        variable: Color,
63        variable_builtin: Color,
64        variable_parameter: Color,
65    }
66}
67
68impl EditorTheme {
69    pub fn dark() -> Self {
70        Self {
71            background: Color::from_rgb(29, 32, 33),
72            gutter_selected: Color::from_rgb(235, 235, 235),
73            gutter_unselected: Color::from_rgb(135, 135, 135),
74            line_selected_background: Color::from_rgb(55, 55, 55),
75            cursor: Color::WHITE,
76            highlight: Color::from_rgb(80, 80, 80),
77            text: Color::WHITE,
78            whitespace: Color::from_af32rgb(0.2, 223, 191, 142),
79        }
80    }
81
82    pub fn light() -> Self {
83        Self {
84            background: Color::from_rgb(246, 248, 250),
85            gutter_selected: Color::from_rgb(36, 41, 46),
86            gutter_unselected: Color::from_rgb(140, 149, 159),
87            line_selected_background: Color::from_rgb(234, 238, 242),
88            cursor: Color::from_rgb(36, 41, 46),
89            highlight: Color::from_rgb(200, 225, 255),
90            text: Color::from_rgb(36, 41, 46),
91            whitespace: Color::from_af32rgb(0.3, 106, 115, 125),
92        }
93    }
94}
95
96impl EditorSyntaxTheme {
97    pub fn dark() -> Self {
98        Self {
99            text: Color::from_rgb(235, 219, 178),
100            whitespace: Color::from_af32rgb(0.2, 223, 191, 142),
101            attribute: Color::from_rgb(131, 165, 152),
102            boolean: Color::from_rgb(211, 134, 155),
103            comment: Color::from_rgb(146, 131, 116),
104            constant: Color::from_rgb(211, 134, 155),
105            constructor: Color::from_rgb(250, 189, 47),
106            escape: Color::from_rgb(254, 128, 25),
107            function: Color::from_rgb(152, 192, 124),
108            function_macro: Color::from_rgb(131, 165, 152),
109            function_method: Color::from_rgb(152, 192, 124),
110            keyword: Color::from_rgb(251, 73, 52),
111            label: Color::from_rgb(211, 134, 155),
112            module: Color::from_rgb(250, 189, 47),
113            number: Color::from_rgb(211, 134, 155),
114            operator: Color::from_rgb(104, 157, 96),
115            property: Color::from_rgb(152, 192, 124),
116            punctuation: Color::from_rgb(104, 157, 96),
117            punctuation_bracket: Color::from_rgb(254, 128, 25),
118            punctuation_delimiter: Color::from_rgb(104, 157, 96),
119            punctuation_special: Color::from_rgb(131, 165, 152),
120            string: Color::from_rgb(184, 187, 38),
121            string_escape: Color::from_rgb(254, 128, 25),
122            string_special: Color::from_rgb(184, 187, 38),
123            tag: Color::from_rgb(131, 165, 152),
124            text_literal: Color::from_rgb(235, 219, 178),
125            text_reference: Color::from_rgb(131, 165, 152),
126            text_title: Color::from_rgb(250, 189, 47),
127            text_uri: Color::from_rgb(104, 157, 96),
128            text_emphasis: Color::from_rgb(235, 219, 178),
129            type_: Color::from_rgb(250, 189, 47),
130            variable: Color::from_rgb(235, 219, 178),
131            variable_builtin: Color::from_rgb(211, 134, 155),
132            variable_parameter: Color::from_rgb(235, 219, 178),
133        }
134    }
135
136    pub fn light() -> Self {
137        Self {
138            text: Color::from_rgb(36, 41, 46),
139            whitespace: Color::from_af32rgb(0.3, 106, 115, 125),
140            attribute: Color::from_rgb(0, 92, 197),
141            boolean: Color::from_rgb(0, 92, 197),
142            comment: Color::from_rgb(106, 115, 125),
143            constant: Color::from_rgb(0, 92, 197),
144            constructor: Color::from_rgb(111, 66, 193),
145            escape: Color::from_rgb(227, 98, 9),
146            function: Color::from_rgb(111, 66, 193),
147            function_macro: Color::from_rgb(111, 66, 193),
148            function_method: Color::from_rgb(111, 66, 193),
149            keyword: Color::from_rgb(215, 58, 73),
150            label: Color::from_rgb(215, 58, 73),
151            module: Color::from_rgb(227, 98, 9),
152            number: Color::from_rgb(0, 92, 197),
153            operator: Color::from_rgb(215, 58, 73),
154            property: Color::from_rgb(0, 92, 197),
155            punctuation: Color::from_rgb(36, 41, 46),
156            punctuation_bracket: Color::from_rgb(36, 41, 46),
157            punctuation_delimiter: Color::from_rgb(36, 41, 46),
158            punctuation_special: Color::from_rgb(215, 58, 73),
159            string: Color::from_rgb(3, 47, 98),
160            string_escape: Color::from_rgb(227, 98, 9),
161            string_special: Color::from_rgb(3, 47, 98),
162            tag: Color::from_rgb(34, 134, 58),
163            text_literal: Color::from_rgb(3, 47, 98),
164            text_reference: Color::from_rgb(0, 92, 197),
165            text_title: Color::from_rgb(0, 92, 197),
166            text_uri: Color::from_rgb(3, 47, 98),
167            text_emphasis: Color::from_rgb(36, 41, 46),
168            type_: Color::from_rgb(111, 66, 193),
169            variable: Color::from_rgb(36, 41, 46),
170            variable_builtin: Color::from_rgb(0, 92, 197),
171            variable_parameter: Color::from_rgb(227, 98, 9),
172        }
173    }
174}
175
176impl Default for EditorTheme {
177    fn default() -> Self {
178        Self::light()
179    }
180}
181
182impl Default for EditorSyntaxTheme {
183    fn default() -> Self {
184        Self::light()
185    }
186}
187
188/// Wraps a resolved [`EditorTheme`] into a preference of `Specific` values.
189impl From<EditorTheme> for EditorThemePreference {
190    fn from(theme: EditorTheme) -> Self {
191        Self {
192            background: Preference::Specific(theme.background),
193            gutter_selected: Preference::Specific(theme.gutter_selected),
194            gutter_unselected: Preference::Specific(theme.gutter_unselected),
195            line_selected_background: Preference::Specific(theme.line_selected_background),
196            cursor: Preference::Specific(theme.cursor),
197            highlight: Preference::Specific(theme.highlight),
198            text: Preference::Specific(theme.text),
199            whitespace: Preference::Specific(theme.whitespace),
200        }
201    }
202}
203
204/// Registers code editor themes into a [`Theme`], e.g. `dark_theme().with_dark_code_editor()`.
205pub trait CodeEditorThemeExt {
206    fn with_dark_code_editor(self) -> Self;
207    fn with_light_code_editor(self) -> Self;
208}
209
210impl CodeEditorThemeExt for Theme {
211    fn with_dark_code_editor(mut self) -> Self {
212        self.set(
213            "code_editor",
214            EditorThemePreference::from(EditorTheme::dark()),
215        );
216        self.set("code_editor_syntax", EditorSyntaxTheme::dark());
217        self
218    }
219
220    fn with_light_code_editor(mut self) -> Self {
221        self.set(
222            "code_editor",
223            EditorThemePreference::from(EditorTheme::light()),
224        );
225        self.set("code_editor_syntax", EditorSyntaxTheme::light());
226        self
227    }
228}