1pub use crate::{old_theme, ButtonVariant, ElementExt, Theme};
2use gpui2::{rgb, Hsla, WindowContext};
3use strum::EnumIter;
4
5#[derive(Clone, Copy)]
6pub struct PlayerThemeColors {
7 pub cursor: Hsla,
8 pub selection: Hsla,
9}
10
11impl std::fmt::Debug for PlayerThemeColors {
12 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13 f.debug_struct("PlayerThemeColors")
14 .field("cursor", &self.cursor.to_rgb().to_hex())
15 .field("selection", &self.selection.to_rgb().to_hex())
16 .finish()
17 }
18}
19
20impl PlayerThemeColors {
21 pub fn new(cx: &WindowContext, ix: usize) -> Self {
22 let theme = old_theme(cx);
23
24 if ix < theme.players.len() {
25 Self {
26 cursor: theme.players[ix].cursor,
27 selection: theme.players[ix].selection,
28 }
29 } else {
30 Self {
31 cursor: rgb::<Hsla>(0xff00ff),
32 selection: rgb::<Hsla>(0xff00ff),
33 }
34 }
35 }
36}
37
38#[derive(Clone, Copy)]
39pub struct SyntaxColor {
40 pub comment: Hsla,
41 pub string: Hsla,
42 pub function: Hsla,
43 pub keyword: Hsla,
44}
45
46impl std::fmt::Debug for SyntaxColor {
47 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
48 f.debug_struct("SyntaxColor")
49 .field("comment", &self.comment.to_rgb().to_hex())
50 .field("string", &self.string.to_rgb().to_hex())
51 .field("function", &self.function.to_rgb().to_hex())
52 .field("keyword", &self.keyword.to_rgb().to_hex())
53 .finish()
54 }
55}
56
57impl SyntaxColor {
58 pub fn new(cx: &WindowContext) -> Self {
59 let theme = old_theme(cx);
60
61 Self {
62 comment: theme
63 .syntax
64 .get("comment")
65 .cloned()
66 .unwrap_or_else(|| rgb::<Hsla>(0xff00ff)),
67 string: theme
68 .syntax
69 .get("string")
70 .cloned()
71 .unwrap_or_else(|| rgb::<Hsla>(0xff00ff)),
72 function: theme
73 .syntax
74 .get("function")
75 .cloned()
76 .unwrap_or_else(|| rgb::<Hsla>(0xff00ff)),
77 keyword: theme
78 .syntax
79 .get("keyword")
80 .cloned()
81 .unwrap_or_else(|| rgb::<Hsla>(0xff00ff)),
82 }
83 }
84}
85
86/// ThemeColor is the primary interface for coloring elements in the UI.
87///
88/// It is a mapping layer between semantic theme colors and colors from the reference library.
89///
90/// While we are between zed and zed2 we use this to map semantic colors to the old theme.
91#[derive(Clone, Copy)]
92pub struct ThemeColor {
93 pub transparent: Hsla,
94 pub mac_os_traffic_light_red: Hsla,
95 pub mac_os_traffic_light_yellow: Hsla,
96 pub mac_os_traffic_light_green: Hsla,
97 pub border: Hsla,
98 pub border_variant: Hsla,
99 pub border_focused: Hsla,
100 pub border_transparent: Hsla,
101 /// The background color of an elevated surface, like a modal, tooltip or toast.
102 pub elevated_surface: Hsla,
103 pub surface: Hsla,
104 /// Window background color of the base app
105 pub background: Hsla,
106 /// Default background for elements like filled buttons,
107 /// text fields, checkboxes, radio buttons, etc.
108 /// - TODO: Map to step 3.
109 pub filled_element: Hsla,
110 /// The background color of a hovered element, like a button being hovered
111 /// with a mouse, or hovered on a touch screen.
112 /// - TODO: Map to step 4.
113 pub filled_element_hover: Hsla,
114 /// The background color of an active element, like a button being pressed,
115 /// or tapped on a touch screen.
116 /// - TODO: Map to step 5.
117 pub filled_element_active: Hsla,
118 /// The background color of a selected element, like a selected tab,
119 /// a button toggled on, or a checkbox that is checked.
120 pub filled_element_selected: Hsla,
121 pub filled_element_disabled: Hsla,
122 pub ghost_element: Hsla,
123 /// The background color of a hovered element with no default background,
124 /// like a ghost-style button or an interactable list item.
125 /// - TODO: Map to step 3.
126 pub ghost_element_hover: Hsla,
127 /// - TODO: Map to step 4.
128 pub ghost_element_active: Hsla,
129 pub ghost_element_selected: Hsla,
130 pub ghost_element_disabled: Hsla,
131 pub text: Hsla,
132 pub text_muted: Hsla,
133 pub text_placeholder: Hsla,
134 pub text_disabled: Hsla,
135 pub text_accent: Hsla,
136 pub icon_muted: Hsla,
137 pub syntax: SyntaxColor,
138
139 pub status_bar: Hsla,
140 pub title_bar: Hsla,
141 pub toolbar: Hsla,
142 pub tab_bar: Hsla,
143 /// The background of the editor
144 pub editor: Hsla,
145 pub editor_subheader: Hsla,
146 pub editor_active_line: Hsla,
147 pub terminal: Hsla,
148 pub image_fallback_background: Hsla,
149
150 pub git_created: Hsla,
151 pub git_modified: Hsla,
152 pub git_deleted: Hsla,
153 pub git_conflict: Hsla,
154 pub git_ignored: Hsla,
155 pub git_renamed: Hsla,
156
157 pub players: [PlayerThemeColors; 8],
158}
159
160impl std::fmt::Debug for ThemeColor {
161 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
162 f.debug_struct("ThemeColor")
163 .field("transparent", &self.transparent.to_rgb().to_hex())
164 .field(
165 "mac_os_traffic_light_red",
166 &self.mac_os_traffic_light_red.to_rgb().to_hex(),
167 )
168 .field(
169 "mac_os_traffic_light_yellow",
170 &self.mac_os_traffic_light_yellow.to_rgb().to_hex(),
171 )
172 .field(
173 "mac_os_traffic_light_green",
174 &self.mac_os_traffic_light_green.to_rgb().to_hex(),
175 )
176 .field("border", &self.border.to_rgb().to_hex())
177 .field("border_variant", &self.border_variant.to_rgb().to_hex())
178 .field("border_focused", &self.border_focused.to_rgb().to_hex())
179 .field(
180 "border_transparent",
181 &self.border_transparent.to_rgb().to_hex(),
182 )
183 .field("elevated_surface", &self.elevated_surface.to_rgb().to_hex())
184 .field("surface", &self.surface.to_rgb().to_hex())
185 .field("background", &self.background.to_rgb().to_hex())
186 .field("filled_element", &self.filled_element.to_rgb().to_hex())
187 .field(
188 "filled_element_hover",
189 &self.filled_element_hover.to_rgb().to_hex(),
190 )
191 .field(
192 "filled_element_active",
193 &self.filled_element_active.to_rgb().to_hex(),
194 )
195 .field(
196 "filled_element_selected",
197 &self.filled_element_selected.to_rgb().to_hex(),
198 )
199 .field(
200 "filled_element_disabled",
201 &self.filled_element_disabled.to_rgb().to_hex(),
202 )
203 .field("ghost_element", &self.ghost_element.to_rgb().to_hex())
204 .field(
205 "ghost_element_hover",
206 &self.ghost_element_hover.to_rgb().to_hex(),
207 )
208 .field(
209 "ghost_element_active",
210 &self.ghost_element_active.to_rgb().to_hex(),
211 )
212 .field(
213 "ghost_element_selected",
214 &self.ghost_element_selected.to_rgb().to_hex(),
215 )
216 .field(
217 "ghost_element_disabled",
218 &self.ghost_element_disabled.to_rgb().to_hex(),
219 )
220 .field("text", &self.text.to_rgb().to_hex())
221 .field("text_muted", &self.text_muted.to_rgb().to_hex())
222 .field("text_placeholder", &self.text_placeholder.to_rgb().to_hex())
223 .field("text_disabled", &self.text_disabled.to_rgb().to_hex())
224 .field("text_accent", &self.text_accent.to_rgb().to_hex())
225 .field("icon_muted", &self.icon_muted.to_rgb().to_hex())
226 .field("syntax", &self.syntax)
227 .field("status_bar", &self.status_bar.to_rgb().to_hex())
228 .field("title_bar", &self.title_bar.to_rgb().to_hex())
229 .field("toolbar", &self.toolbar.to_rgb().to_hex())
230 .field("tab_bar", &self.tab_bar.to_rgb().to_hex())
231 .field("editor", &self.editor.to_rgb().to_hex())
232 .field("editor_subheader", &self.editor_subheader.to_rgb().to_hex())
233 .field(
234 "editor_active_line",
235 &self.editor_active_line.to_rgb().to_hex(),
236 )
237 .field("terminal", &self.terminal.to_rgb().to_hex())
238 .field(
239 "image_fallback_background",
240 &self.image_fallback_background.to_rgb().to_hex(),
241 )
242 .field("git_created", &self.git_created.to_rgb().to_hex())
243 .field("git_modified", &self.git_modified.to_rgb().to_hex())
244 .field("git_deleted", &self.git_deleted.to_rgb().to_hex())
245 .field("git_conflict", &self.git_conflict.to_rgb().to_hex())
246 .field("git_ignored", &self.git_ignored.to_rgb().to_hex())
247 .field("git_renamed", &self.git_renamed.to_rgb().to_hex())
248 .field("players", &self.players)
249 .finish()
250 }
251}
252
253/// Colors used exclusively for syntax highlighting.
254///
255/// For now we deserialize these from a theme.
256/// These will be defined statically in the new theme.
257#[derive(Default, PartialEq, EnumIter, Clone, Copy)]
258pub enum HighlightColor {
259 #[default]
260 Default,
261 Comment,
262 String,
263 Function,
264 Keyword,
265}
266
267impl HighlightColor {
268 pub fn hsla(&self, theme: &Theme) -> Hsla {
269 match self {
270 Self::Default => theme
271 .syntax
272 .get("primary")
273 .cloned()
274 .expect("Couldn't find `primary` in theme.syntax"),
275 Self::Comment => theme
276 .syntax
277 .get("comment")
278 .cloned()
279 .expect("Couldn't find `comment` in theme.syntax"),
280 Self::String => theme
281 .syntax
282 .get("string")
283 .cloned()
284 .expect("Couldn't find `string` in theme.syntax"),
285 Self::Function => theme
286 .syntax
287 .get("function")
288 .cloned()
289 .expect("Couldn't find `function` in theme.syntax"),
290 Self::Keyword => theme
291 .syntax
292 .get("keyword")
293 .cloned()
294 .expect("Couldn't find `keyword` in theme.syntax"),
295 }
296 }
297}