colors.rs

  1#![allow(missing_docs)]
  2
  3use gpui::{App, Hsla, SharedString, WindowBackgroundAppearance};
  4use refineable::Refineable;
  5use std::sync::Arc;
  6use strum::{AsRefStr, EnumIter, IntoEnumIterator};
  7
  8use crate::{
  9    AccentColors, ActiveTheme, PlayerColors, StatusColors, StatusColorsRefinement, SyntaxTheme,
 10    SystemColors,
 11};
 12
 13#[derive(Refineable, Clone, Debug, PartialEq)]
 14#[refineable(Debug, serde::Deserialize)]
 15pub struct ThemeColors {
 16    /// Border color. Used for most borders, is usually a high contrast color.
 17    pub border: Hsla,
 18    /// Border color. Used for deemphasized borders, like a visual divider between two sections
 19    pub border_variant: Hsla,
 20    /// Border color. Used for focused elements, like keyboard focused list item.
 21    pub border_focused: Hsla,
 22    /// Border color. Used for selected elements, like an active search filter or selected checkbox.
 23    pub border_selected: Hsla,
 24    /// Border color. Used for transparent borders. Used for placeholder borders when an element gains a border on state change.
 25    pub border_transparent: Hsla,
 26    /// Border color. Used for disabled elements, like a disabled input or button.
 27    pub border_disabled: Hsla,
 28    /// Border color. Used for elevated surfaces, like a context menu, popup, or dialog.
 29    pub elevated_surface_background: Hsla,
 30    /// Background Color. Used for grounded surfaces like a panel or tab.
 31    pub surface_background: Hsla,
 32    /// Background Color. Used for the app background and blank panels or windows.
 33    pub background: Hsla,
 34    /// Background Color. Used for the background of an element that should have a different background than the surface it's on.
 35    ///
 36    /// Elements might include: Buttons, Inputs, Checkboxes, Radio Buttons...
 37    ///
 38    /// For an element that should have the same background as the surface it's on, use `ghost_element_background`.
 39    pub element_background: Hsla,
 40    /// Background Color. Used for the hover state of an element that should have a different background than the surface it's on.
 41    ///
 42    /// Hover states are triggered by the mouse entering an element, or a finger touching an element on a touch screen.
 43    pub element_hover: Hsla,
 44    /// Background Color. Used for the active state of an element that should have a different background than the surface it's on.
 45    ///
 46    /// Active states are triggered by the mouse button being pressed down on an element, or the Return button or other activator being pressd.
 47    pub element_active: Hsla,
 48    /// Background Color. Used for the selected state of an element that should have a different background than the surface it's on.
 49    ///
 50    /// Selected states are triggered by the element being selected (or "activated") by the user.
 51    ///
 52    /// This could include a selected checkbox, a toggleable button that is toggled on, etc.
 53    pub element_selected: Hsla,
 54    /// Background Color. Used for the disabled state of an element that should have a different background than the surface it's on.
 55    ///
 56    /// Disabled states are shown when a user cannot interact with an element, like a disabled button or input.
 57    pub element_disabled: Hsla,
 58    /// Background Color. Used for the area that shows where a dragged element will be dropped.
 59    pub drop_target_background: Hsla,
 60    /// Used for the background of a ghost element that should have the same background as the surface it's on.
 61    ///
 62    /// Elements might include: Buttons, Inputs, Checkboxes, Radio Buttons...
 63    ///
 64    /// For an element that should have a different background than the surface it's on, use `element_background`.
 65    pub ghost_element_background: Hsla,
 66    /// Background Color. Used for the hover state of a ghost element that should have the same background as the surface it's on.
 67    ///
 68    /// Hover states are triggered by the mouse entering an element, or a finger touching an element on a touch screen.
 69    pub ghost_element_hover: Hsla,
 70    /// Background Color. Used for the active state of a ghost element that should have the same background as the surface it's on.
 71    ///
 72    /// Active states are triggered by the mouse button being pressed down on an element, or the Return button or other activator being pressd.
 73    pub ghost_element_active: Hsla,
 74    /// Background Color. Used for the selected state of a ghost element that should have the same background as the surface it's on.
 75    ///
 76    /// Selected states are triggered by the element being selected (or "activated") by the user.
 77    ///
 78    /// This could include a selected checkbox, a toggleable button that is toggled on, etc.
 79    pub ghost_element_selected: Hsla,
 80    /// Background Color. Used for the disabled state of a ghost element that should have the same background as the surface it's on.
 81    ///
 82    /// Disabled states are shown when a user cannot interact with an element, like a disabled button or input.
 83    pub ghost_element_disabled: Hsla,
 84    /// Text Color. Default text color used for most text.
 85    pub text: Hsla,
 86    /// Text Color. Color of muted or deemphasized text. It is a subdued version of the standard text color.
 87    pub text_muted: Hsla,
 88    /// Text Color. Color of the placeholder text typically shown in input fields to guide the user to enter valid data.
 89    pub text_placeholder: Hsla,
 90    /// Text Color. Color used for text denoting disabled elements. Typically, the color is faded or grayed out to emphasize the disabled state.
 91    pub text_disabled: Hsla,
 92    /// Text Color. Color used for emphasis or highlighting certain text, like an active filter or a matched character in a search.
 93    pub text_accent: Hsla,
 94    /// Fill Color. Used for the default fill color of an icon.
 95    pub icon: Hsla,
 96    /// Fill Color. Used for the muted or deemphasized fill color of an icon.
 97    ///
 98    /// This might be used to show an icon in an inactive pane, or to deemphasize a series of icons to give them less visual weight.
 99    pub icon_muted: Hsla,
100    /// Fill Color. Used for the disabled fill color of an icon.
101    ///
102    /// Disabled states are shown when a user cannot interact with an element, like a icon button.
103    pub icon_disabled: Hsla,
104    /// Fill Color. Used for the placeholder fill color of an icon.
105    ///
106    /// This might be used to show an icon in an input that disappears when the user enters text.
107    pub icon_placeholder: Hsla,
108    /// Fill Color. Used for the accent fill color of an icon.
109    ///
110    /// This might be used to show when a toggleable icon button is selected.
111    pub icon_accent: Hsla,
112
113    // ===
114    // UI Elements
115    // ===
116    pub status_bar_background: Hsla,
117    pub title_bar_background: Hsla,
118    pub title_bar_inactive_background: Hsla,
119    pub toolbar_background: Hsla,
120    pub tab_bar_background: Hsla,
121    pub tab_inactive_background: Hsla,
122    pub tab_active_background: Hsla,
123    pub search_match_background: Hsla,
124    pub panel_background: Hsla,
125    pub panel_focused_border: Hsla,
126    pub panel_indent_guide: Hsla,
127    pub panel_indent_guide_hover: Hsla,
128    pub panel_indent_guide_active: Hsla,
129    pub pane_focused_border: Hsla,
130    pub pane_group_border: Hsla,
131    /// The color of the scrollbar thumb.
132    pub scrollbar_thumb_background: Hsla,
133    /// The color of the scrollbar thumb when hovered over.
134    pub scrollbar_thumb_hover_background: Hsla,
135    /// The border color of the scrollbar thumb.
136    pub scrollbar_thumb_border: Hsla,
137    /// The background color of the scrollbar track.
138    pub scrollbar_track_background: Hsla,
139    /// The border color of the scrollbar track.
140    pub scrollbar_track_border: Hsla,
141
142    // ===
143    // Editor
144    // ===
145    pub editor_foreground: Hsla,
146    pub editor_background: Hsla,
147    pub editor_gutter_background: Hsla,
148    pub editor_subheader_background: Hsla,
149    pub editor_active_line_background: Hsla,
150    pub editor_highlighted_line_background: Hsla,
151    /// Text Color. Used for the text of the line number in the editor gutter.
152    pub editor_line_number: Hsla,
153    /// Text Color. Used for the text of the line number in the editor gutter when the line is highlighted.
154    pub editor_active_line_number: Hsla,
155    /// Text Color. Used for the text of the line number in the editor gutter when the line is hovered over.
156    pub editor_hover_line_number: Hsla,
157    /// Text Color. Used to mark invisible characters in the editor.
158    ///
159    /// Example: spaces, tabs, carriage returns, etc.
160    pub editor_invisible: Hsla,
161    pub editor_wrap_guide: Hsla,
162    pub editor_active_wrap_guide: Hsla,
163    pub editor_indent_guide: Hsla,
164    pub editor_indent_guide_active: Hsla,
165    /// Read-access of a symbol, like reading a variable.
166    ///
167    /// A document highlight is a range inside a text document which deserves
168    /// special attention. Usually a document highlight is visualized by changing
169    /// the background color of its range.
170    pub editor_document_highlight_read_background: Hsla,
171    /// Read-access of a symbol, like reading a variable.
172    ///
173    /// A document highlight is a range inside a text document which deserves
174    /// special attention. Usually a document highlight is visualized by changing
175    /// the background color of its range.
176    pub editor_document_highlight_write_background: Hsla,
177    /// Highlighted brackets background color.
178    ///
179    /// Matching brackets in the cursor scope are highlighted with this background color.
180    pub editor_document_highlight_bracket_background: Hsla,
181
182    // ===
183    // Terminal
184    // ===
185    /// Terminal layout background color.
186    pub terminal_background: Hsla,
187    /// Terminal foreground color.
188    pub terminal_foreground: Hsla,
189    /// Bright terminal foreground color.
190    pub terminal_bright_foreground: Hsla,
191    /// Dim terminal foreground color.
192    pub terminal_dim_foreground: Hsla,
193    /// Terminal ANSI background color.
194    pub terminal_ansi_background: Hsla,
195    /// Black ANSI terminal color.
196    pub terminal_ansi_black: Hsla,
197    /// Bright black ANSI terminal color.
198    pub terminal_ansi_bright_black: Hsla,
199    /// Dim black ANSI terminal color.
200    pub terminal_ansi_dim_black: Hsla,
201    /// Red ANSI terminal color.
202    pub terminal_ansi_red: Hsla,
203    /// Bright red ANSI terminal color.
204    pub terminal_ansi_bright_red: Hsla,
205    /// Dim red ANSI terminal color.
206    pub terminal_ansi_dim_red: Hsla,
207    /// Green ANSI terminal color.
208    pub terminal_ansi_green: Hsla,
209    /// Bright green ANSI terminal color.
210    pub terminal_ansi_bright_green: Hsla,
211    /// Dim green ANSI terminal color.
212    pub terminal_ansi_dim_green: Hsla,
213    /// Yellow ANSI terminal color.
214    pub terminal_ansi_yellow: Hsla,
215    /// Bright yellow ANSI terminal color.
216    pub terminal_ansi_bright_yellow: Hsla,
217    /// Dim yellow ANSI terminal color.
218    pub terminal_ansi_dim_yellow: Hsla,
219    /// Blue ANSI terminal color.
220    pub terminal_ansi_blue: Hsla,
221    /// Bright blue ANSI terminal color.
222    pub terminal_ansi_bright_blue: Hsla,
223    /// Dim blue ANSI terminal color.
224    pub terminal_ansi_dim_blue: Hsla,
225    /// Magenta ANSI terminal color.
226    pub terminal_ansi_magenta: Hsla,
227    /// Bright magenta ANSI terminal color.
228    pub terminal_ansi_bright_magenta: Hsla,
229    /// Dim magenta ANSI terminal color.
230    pub terminal_ansi_dim_magenta: Hsla,
231    /// Cyan ANSI terminal color.
232    pub terminal_ansi_cyan: Hsla,
233    /// Bright cyan ANSI terminal color.
234    pub terminal_ansi_bright_cyan: Hsla,
235    /// Dim cyan ANSI terminal color.
236    pub terminal_ansi_dim_cyan: Hsla,
237    /// White ANSI terminal color.
238    pub terminal_ansi_white: Hsla,
239    /// Bright white ANSI terminal color.
240    pub terminal_ansi_bright_white: Hsla,
241    /// Dim white ANSI terminal color.
242    pub terminal_ansi_dim_white: Hsla,
243
244    /// Represents a link text hover color.
245    pub link_text_hover: Hsla,
246
247    /// Represents an added entry or hunk in vcs, like git.
248    pub version_control_added: Hsla,
249    /// Represents the line background of an added entry or hunk in vcs, like git.
250    pub version_control_added_background: Hsla,
251    /// Represents a deleted entry in version control systems.
252    pub version_control_deleted: Hsla,
253    /// Represents the background color for deleted entries in version control systems.
254    pub version_control_deleted_background: Hsla,
255    /// Represents a modified entry in version control systems.
256    pub version_control_modified: Hsla,
257    /// Represents the background color for modified entries in version control systems.
258    pub version_control_modified_background: Hsla,
259    /// Represents a renamed entry in version control systems.
260    pub version_control_renamed: Hsla,
261    /// Represents a conflicting entry in version control systems.
262    pub version_control_conflict: Hsla,
263    /// Represents the background color for conflicting entries in version control systems.
264    pub version_control_conflict_background: Hsla,
265    /// Represents an ignored entry in version control systems.
266    pub version_control_ignored: Hsla,
267}
268
269#[derive(EnumIter, Debug, Clone, Copy, AsRefStr)]
270#[strum(serialize_all = "snake_case")]
271pub enum ThemeColorField {
272    Border,
273    BorderVariant,
274    BorderFocused,
275    BorderSelected,
276    BorderTransparent,
277    BorderDisabled,
278    ElevatedSurfaceBackground,
279    SurfaceBackground,
280    Background,
281    ElementBackground,
282    ElementHover,
283    ElementActive,
284    ElementSelected,
285    ElementDisabled,
286    DropTargetBackground,
287    GhostElementBackground,
288    GhostElementHover,
289    GhostElementActive,
290    GhostElementSelected,
291    GhostElementDisabled,
292    Text,
293    TextMuted,
294    TextPlaceholder,
295    TextDisabled,
296    TextAccent,
297    Icon,
298    IconMuted,
299    IconDisabled,
300    IconPlaceholder,
301    IconAccent,
302    StatusBarBackground,
303    TitleBarBackground,
304    TitleBarInactiveBackground,
305    ToolbarBackground,
306    TabBarBackground,
307    TabInactiveBackground,
308    TabActiveBackground,
309    SearchMatchBackground,
310    PanelBackground,
311    PanelFocusedBorder,
312    PanelIndentGuide,
313    PanelIndentGuideHover,
314    PanelIndentGuideActive,
315    PaneFocusedBorder,
316    PaneGroupBorder,
317    ScrollbarThumbBackground,
318    ScrollbarThumbHoverBackground,
319    ScrollbarThumbBorder,
320    ScrollbarTrackBackground,
321    ScrollbarTrackBorder,
322    EditorForeground,
323    EditorBackground,
324    EditorGutterBackground,
325    EditorSubheaderBackground,
326    EditorActiveLineBackground,
327    EditorHighlightedLineBackground,
328    EditorLineNumber,
329    EditorActiveLineNumber,
330    EditorInvisible,
331    EditorWrapGuide,
332    EditorActiveWrapGuide,
333    EditorIndentGuide,
334    EditorIndentGuideActive,
335    EditorDocumentHighlightReadBackground,
336    EditorDocumentHighlightWriteBackground,
337    EditorDocumentHighlightBracketBackground,
338    TerminalBackground,
339    TerminalForeground,
340    TerminalBrightForeground,
341    TerminalDimForeground,
342    TerminalAnsiBackground,
343    TerminalAnsiBlack,
344    TerminalAnsiBrightBlack,
345    TerminalAnsiDimBlack,
346    TerminalAnsiRed,
347    TerminalAnsiBrightRed,
348    TerminalAnsiDimRed,
349    TerminalAnsiGreen,
350    TerminalAnsiBrightGreen,
351    TerminalAnsiDimGreen,
352    TerminalAnsiYellow,
353    TerminalAnsiBrightYellow,
354    TerminalAnsiDimYellow,
355    TerminalAnsiBlue,
356    TerminalAnsiBrightBlue,
357    TerminalAnsiDimBlue,
358    TerminalAnsiMagenta,
359    TerminalAnsiBrightMagenta,
360    TerminalAnsiDimMagenta,
361    TerminalAnsiCyan,
362    TerminalAnsiBrightCyan,
363    TerminalAnsiDimCyan,
364    TerminalAnsiWhite,
365    TerminalAnsiBrightWhite,
366    TerminalAnsiDimWhite,
367    LinkTextHover,
368    VersionControlAdded,
369    VersionControlAddedBackground,
370    VersionControlDeleted,
371    VersionControlDeletedBackground,
372    VersionControlModified,
373    VersionControlModifiedBackground,
374    VersionControlRenamed,
375    VersionControlConflict,
376    VersionControlConflictBackground,
377    VersionControlIgnored,
378}
379
380impl ThemeColors {
381    pub fn color(&self, field: ThemeColorField) -> Hsla {
382        match field {
383            ThemeColorField::Border => self.border,
384            ThemeColorField::BorderVariant => self.border_variant,
385            ThemeColorField::BorderFocused => self.border_focused,
386            ThemeColorField::BorderSelected => self.border_selected,
387            ThemeColorField::BorderTransparent => self.border_transparent,
388            ThemeColorField::BorderDisabled => self.border_disabled,
389            ThemeColorField::ElevatedSurfaceBackground => self.elevated_surface_background,
390            ThemeColorField::SurfaceBackground => self.surface_background,
391            ThemeColorField::Background => self.background,
392            ThemeColorField::ElementBackground => self.element_background,
393            ThemeColorField::ElementHover => self.element_hover,
394            ThemeColorField::ElementActive => self.element_active,
395            ThemeColorField::ElementSelected => self.element_selected,
396            ThemeColorField::ElementDisabled => self.element_disabled,
397            ThemeColorField::DropTargetBackground => self.drop_target_background,
398            ThemeColorField::GhostElementBackground => self.ghost_element_background,
399            ThemeColorField::GhostElementHover => self.ghost_element_hover,
400            ThemeColorField::GhostElementActive => self.ghost_element_active,
401            ThemeColorField::GhostElementSelected => self.ghost_element_selected,
402            ThemeColorField::GhostElementDisabled => self.ghost_element_disabled,
403            ThemeColorField::Text => self.text,
404            ThemeColorField::TextMuted => self.text_muted,
405            ThemeColorField::TextPlaceholder => self.text_placeholder,
406            ThemeColorField::TextDisabled => self.text_disabled,
407            ThemeColorField::TextAccent => self.text_accent,
408            ThemeColorField::Icon => self.icon,
409            ThemeColorField::IconMuted => self.icon_muted,
410            ThemeColorField::IconDisabled => self.icon_disabled,
411            ThemeColorField::IconPlaceholder => self.icon_placeholder,
412            ThemeColorField::IconAccent => self.icon_accent,
413            ThemeColorField::StatusBarBackground => self.status_bar_background,
414            ThemeColorField::TitleBarBackground => self.title_bar_background,
415            ThemeColorField::TitleBarInactiveBackground => self.title_bar_inactive_background,
416            ThemeColorField::ToolbarBackground => self.toolbar_background,
417            ThemeColorField::TabBarBackground => self.tab_bar_background,
418            ThemeColorField::TabInactiveBackground => self.tab_inactive_background,
419            ThemeColorField::TabActiveBackground => self.tab_active_background,
420            ThemeColorField::SearchMatchBackground => self.search_match_background,
421            ThemeColorField::PanelBackground => self.panel_background,
422            ThemeColorField::PanelFocusedBorder => self.panel_focused_border,
423            ThemeColorField::PanelIndentGuide => self.panel_indent_guide,
424            ThemeColorField::PanelIndentGuideHover => self.panel_indent_guide_hover,
425            ThemeColorField::PanelIndentGuideActive => self.panel_indent_guide_active,
426            ThemeColorField::PaneFocusedBorder => self.pane_focused_border,
427            ThemeColorField::PaneGroupBorder => self.pane_group_border,
428            ThemeColorField::ScrollbarThumbBackground => self.scrollbar_thumb_background,
429            ThemeColorField::ScrollbarThumbHoverBackground => self.scrollbar_thumb_hover_background,
430            ThemeColorField::ScrollbarThumbBorder => self.scrollbar_thumb_border,
431            ThemeColorField::ScrollbarTrackBackground => self.scrollbar_track_background,
432            ThemeColorField::ScrollbarTrackBorder => self.scrollbar_track_border,
433            ThemeColorField::EditorForeground => self.editor_foreground,
434            ThemeColorField::EditorBackground => self.editor_background,
435            ThemeColorField::EditorGutterBackground => self.editor_gutter_background,
436            ThemeColorField::EditorSubheaderBackground => self.editor_subheader_background,
437            ThemeColorField::EditorActiveLineBackground => self.editor_active_line_background,
438            ThemeColorField::EditorHighlightedLineBackground => {
439                self.editor_highlighted_line_background
440            }
441            ThemeColorField::EditorLineNumber => self.editor_line_number,
442            ThemeColorField::EditorActiveLineNumber => self.editor_active_line_number,
443            ThemeColorField::EditorInvisible => self.editor_invisible,
444            ThemeColorField::EditorWrapGuide => self.editor_wrap_guide,
445            ThemeColorField::EditorActiveWrapGuide => self.editor_active_wrap_guide,
446            ThemeColorField::EditorIndentGuide => self.editor_indent_guide,
447            ThemeColorField::EditorIndentGuideActive => self.editor_indent_guide_active,
448            ThemeColorField::EditorDocumentHighlightReadBackground => {
449                self.editor_document_highlight_read_background
450            }
451            ThemeColorField::EditorDocumentHighlightWriteBackground => {
452                self.editor_document_highlight_write_background
453            }
454            ThemeColorField::EditorDocumentHighlightBracketBackground => {
455                self.editor_document_highlight_bracket_background
456            }
457            ThemeColorField::TerminalBackground => self.terminal_background,
458            ThemeColorField::TerminalForeground => self.terminal_foreground,
459            ThemeColorField::TerminalBrightForeground => self.terminal_bright_foreground,
460            ThemeColorField::TerminalDimForeground => self.terminal_dim_foreground,
461            ThemeColorField::TerminalAnsiBackground => self.terminal_ansi_background,
462            ThemeColorField::TerminalAnsiBlack => self.terminal_ansi_black,
463            ThemeColorField::TerminalAnsiBrightBlack => self.terminal_ansi_bright_black,
464            ThemeColorField::TerminalAnsiDimBlack => self.terminal_ansi_dim_black,
465            ThemeColorField::TerminalAnsiRed => self.terminal_ansi_red,
466            ThemeColorField::TerminalAnsiBrightRed => self.terminal_ansi_bright_red,
467            ThemeColorField::TerminalAnsiDimRed => self.terminal_ansi_dim_red,
468            ThemeColorField::TerminalAnsiGreen => self.terminal_ansi_green,
469            ThemeColorField::TerminalAnsiBrightGreen => self.terminal_ansi_bright_green,
470            ThemeColorField::TerminalAnsiDimGreen => self.terminal_ansi_dim_green,
471            ThemeColorField::TerminalAnsiYellow => self.terminal_ansi_yellow,
472            ThemeColorField::TerminalAnsiBrightYellow => self.terminal_ansi_bright_yellow,
473            ThemeColorField::TerminalAnsiDimYellow => self.terminal_ansi_dim_yellow,
474            ThemeColorField::TerminalAnsiBlue => self.terminal_ansi_blue,
475            ThemeColorField::TerminalAnsiBrightBlue => self.terminal_ansi_bright_blue,
476            ThemeColorField::TerminalAnsiDimBlue => self.terminal_ansi_dim_blue,
477            ThemeColorField::TerminalAnsiMagenta => self.terminal_ansi_magenta,
478            ThemeColorField::TerminalAnsiBrightMagenta => self.terminal_ansi_bright_magenta,
479            ThemeColorField::TerminalAnsiDimMagenta => self.terminal_ansi_dim_magenta,
480            ThemeColorField::TerminalAnsiCyan => self.terminal_ansi_cyan,
481            ThemeColorField::TerminalAnsiBrightCyan => self.terminal_ansi_bright_cyan,
482            ThemeColorField::TerminalAnsiDimCyan => self.terminal_ansi_dim_cyan,
483            ThemeColorField::TerminalAnsiWhite => self.terminal_ansi_white,
484            ThemeColorField::TerminalAnsiBrightWhite => self.terminal_ansi_bright_white,
485            ThemeColorField::TerminalAnsiDimWhite => self.terminal_ansi_dim_white,
486            ThemeColorField::LinkTextHover => self.link_text_hover,
487            ThemeColorField::VersionControlAdded => self.version_control_added,
488            ThemeColorField::VersionControlAddedBackground => self.version_control_added_background,
489            ThemeColorField::VersionControlDeleted => self.version_control_deleted,
490            ThemeColorField::VersionControlDeletedBackground => {
491                self.version_control_deleted_background
492            }
493            ThemeColorField::VersionControlModified => self.version_control_modified,
494            ThemeColorField::VersionControlModifiedBackground => {
495                self.version_control_modified_background
496            }
497            ThemeColorField::VersionControlRenamed => self.version_control_renamed,
498            ThemeColorField::VersionControlConflict => self.version_control_conflict,
499            ThemeColorField::VersionControlConflictBackground => {
500                self.version_control_conflict_background
501            }
502            ThemeColorField::VersionControlIgnored => self.version_control_ignored,
503        }
504    }
505
506    pub fn iter(&self) -> impl Iterator<Item = (ThemeColorField, Hsla)> + '_ {
507        ThemeColorField::iter().map(move |field| (field, self.color(field)))
508    }
509
510    pub fn to_vec(&self) -> Vec<(ThemeColorField, Hsla)> {
511        self.iter().collect()
512    }
513}
514
515pub fn all_theme_colors(cx: &mut App) -> Vec<(Hsla, SharedString)> {
516    let theme = cx.theme();
517    ThemeColorField::iter()
518        .map(|field| {
519            let color = theme.colors().color(field);
520            let name = field.as_ref().to_string();
521            (color, SharedString::from(name))
522        })
523        .collect()
524}
525
526#[derive(Refineable, Clone, PartialEq)]
527pub struct ThemeStyles {
528    /// The background appearance of the window.
529    pub window_background_appearance: WindowBackgroundAppearance,
530    pub system: SystemColors,
531    /// An array of colors used for theme elements that iterate through a series of colors.
532    ///
533    /// Example: Player colors, rainbow brackets and indent guides, etc.
534    pub accents: AccentColors,
535
536    #[refineable]
537    pub colors: ThemeColors,
538
539    #[refineable]
540    pub status: StatusColors,
541
542    pub player: PlayerColors,
543
544    pub syntax: Arc<SyntaxTheme>,
545}
546
547#[cfg(test)]
548mod tests {
549    use serde_json::json;
550
551    use super::*;
552
553    #[test]
554    fn override_a_single_theme_color() {
555        let mut colors = ThemeColors::light();
556
557        let magenta: Hsla = gpui::rgb(0xff00ff).into();
558
559        assert_ne!(colors.text, magenta);
560
561        let overrides = ThemeColorsRefinement {
562            text: Some(magenta),
563            ..Default::default()
564        };
565
566        colors.refine(&overrides);
567
568        assert_eq!(colors.text, magenta);
569    }
570
571    #[test]
572    fn override_multiple_theme_colors() {
573        let mut colors = ThemeColors::light();
574
575        let magenta: Hsla = gpui::rgb(0xff00ff).into();
576        let green: Hsla = gpui::rgb(0x00ff00).into();
577
578        assert_ne!(colors.text, magenta);
579        assert_ne!(colors.background, green);
580
581        let overrides = ThemeColorsRefinement {
582            text: Some(magenta),
583            background: Some(green),
584            ..Default::default()
585        };
586
587        colors.refine(&overrides);
588
589        assert_eq!(colors.text, magenta);
590        assert_eq!(colors.background, green);
591    }
592
593    #[test]
594    fn deserialize_theme_colors_refinement_from_json() {
595        let colors: ThemeColorsRefinement = serde_json::from_value(json!({
596            "background": "#ff00ff",
597            "text": "#ff0000"
598        }))
599        .unwrap();
600
601        assert_eq!(colors.background, Some(gpui::rgb(0xff00ff).into()));
602        assert_eq!(colors.text, Some(gpui::rgb(0xff0000).into()));
603    }
604}