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 pressed.
 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 pressed.
 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    /// Color used to accent some debugger elements
113    /// Is used by breakpoints
114    pub debugger_accent: Hsla,
115
116    // ===
117    // UI Elements
118    // ===
119    pub status_bar_background: Hsla,
120    pub title_bar_background: Hsla,
121    pub title_bar_inactive_background: Hsla,
122    pub toolbar_background: Hsla,
123    pub tab_bar_background: Hsla,
124    pub tab_inactive_background: Hsla,
125    pub tab_active_background: Hsla,
126    pub search_match_background: Hsla,
127    pub panel_background: Hsla,
128    pub panel_focused_border: Hsla,
129    pub panel_indent_guide: Hsla,
130    pub panel_indent_guide_hover: Hsla,
131    pub panel_indent_guide_active: Hsla,
132    pub pane_focused_border: Hsla,
133    pub pane_group_border: Hsla,
134    /// The color of the scrollbar thumb.
135    pub scrollbar_thumb_background: Hsla,
136    /// The color of the scrollbar thumb when hovered over.
137    pub scrollbar_thumb_hover_background: Hsla,
138    /// The border color of the scrollbar thumb.
139    pub scrollbar_thumb_border: Hsla,
140    /// The background color of the scrollbar track.
141    pub scrollbar_track_background: Hsla,
142    /// The border color of the scrollbar track.
143    pub scrollbar_track_border: Hsla,
144
145    // ===
146    // Editor
147    // ===
148    pub editor_foreground: Hsla,
149    pub editor_background: Hsla,
150    pub editor_gutter_background: Hsla,
151    pub editor_subheader_background: Hsla,
152    pub editor_active_line_background: Hsla,
153    pub editor_highlighted_line_background: Hsla,
154    /// Line color of the line a debugger is currently stopped at
155    pub editor_debugger_active_line_background: Hsla,
156    /// Text Color. Used for the text of the line number in the editor gutter.
157    pub editor_line_number: Hsla,
158    /// Text Color. Used for the text of the line number in the editor gutter when the line is highlighted.
159    pub editor_active_line_number: Hsla,
160    /// Text Color. Used for the text of the line number in the editor gutter when the line is hovered over.
161    pub editor_hover_line_number: Hsla,
162    /// Text Color. Used to mark invisible characters in the editor.
163    ///
164    /// Example: spaces, tabs, carriage returns, etc.
165    pub editor_invisible: Hsla,
166    pub editor_wrap_guide: Hsla,
167    pub editor_active_wrap_guide: Hsla,
168    pub editor_indent_guide: Hsla,
169    pub editor_indent_guide_active: Hsla,
170    /// Read-access of a symbol, like reading a variable.
171    ///
172    /// A document highlight is a range inside a text document which deserves
173    /// special attention. Usually a document highlight is visualized by changing
174    /// the background color of its range.
175    pub editor_document_highlight_read_background: Hsla,
176    /// Read-access of a symbol, like reading a variable.
177    ///
178    /// A document highlight is a range inside a text document which deserves
179    /// special attention. Usually a document highlight is visualized by changing
180    /// the background color of its range.
181    pub editor_document_highlight_write_background: Hsla,
182    /// Highlighted brackets background color.
183    ///
184    /// Matching brackets in the cursor scope are highlighted with this background color.
185    pub editor_document_highlight_bracket_background: Hsla,
186
187    // ===
188    // Terminal
189    // ===
190    /// Terminal layout background color.
191    pub terminal_background: Hsla,
192    /// Terminal foreground color.
193    pub terminal_foreground: Hsla,
194    /// Bright terminal foreground color.
195    pub terminal_bright_foreground: Hsla,
196    /// Dim terminal foreground color.
197    pub terminal_dim_foreground: Hsla,
198    /// Terminal ANSI background color.
199    pub terminal_ansi_background: Hsla,
200    /// Black ANSI terminal color.
201    pub terminal_ansi_black: Hsla,
202    /// Bright black ANSI terminal color.
203    pub terminal_ansi_bright_black: Hsla,
204    /// Dim black ANSI terminal color.
205    pub terminal_ansi_dim_black: Hsla,
206    /// Red ANSI terminal color.
207    pub terminal_ansi_red: Hsla,
208    /// Bright red ANSI terminal color.
209    pub terminal_ansi_bright_red: Hsla,
210    /// Dim red ANSI terminal color.
211    pub terminal_ansi_dim_red: Hsla,
212    /// Green ANSI terminal color.
213    pub terminal_ansi_green: Hsla,
214    /// Bright green ANSI terminal color.
215    pub terminal_ansi_bright_green: Hsla,
216    /// Dim green ANSI terminal color.
217    pub terminal_ansi_dim_green: Hsla,
218    /// Yellow ANSI terminal color.
219    pub terminal_ansi_yellow: Hsla,
220    /// Bright yellow ANSI terminal color.
221    pub terminal_ansi_bright_yellow: Hsla,
222    /// Dim yellow ANSI terminal color.
223    pub terminal_ansi_dim_yellow: Hsla,
224    /// Blue ANSI terminal color.
225    pub terminal_ansi_blue: Hsla,
226    /// Bright blue ANSI terminal color.
227    pub terminal_ansi_bright_blue: Hsla,
228    /// Dim blue ANSI terminal color.
229    pub terminal_ansi_dim_blue: Hsla,
230    /// Magenta ANSI terminal color.
231    pub terminal_ansi_magenta: Hsla,
232    /// Bright magenta ANSI terminal color.
233    pub terminal_ansi_bright_magenta: Hsla,
234    /// Dim magenta ANSI terminal color.
235    pub terminal_ansi_dim_magenta: Hsla,
236    /// Cyan ANSI terminal color.
237    pub terminal_ansi_cyan: Hsla,
238    /// Bright cyan ANSI terminal color.
239    pub terminal_ansi_bright_cyan: Hsla,
240    /// Dim cyan ANSI terminal color.
241    pub terminal_ansi_dim_cyan: Hsla,
242    /// White ANSI terminal color.
243    pub terminal_ansi_white: Hsla,
244    /// Bright white ANSI terminal color.
245    pub terminal_ansi_bright_white: Hsla,
246    /// Dim white ANSI terminal color.
247    pub terminal_ansi_dim_white: Hsla,
248
249    /// Represents a link text hover color.
250    pub link_text_hover: Hsla,
251
252    /// Represents an added entry or hunk in vcs, like git.
253    pub version_control_added: Hsla,
254    /// Represents a deleted entry in version control systems.
255    pub version_control_deleted: Hsla,
256    /// Represents a modified entry in version control systems.
257    pub version_control_modified: Hsla,
258    /// Represents a renamed entry in version control systems.
259    pub version_control_renamed: Hsla,
260    /// Represents a conflicting entry in version control systems.
261    pub version_control_conflict: Hsla,
262    /// Represents an ignored entry in version control systems.
263    pub version_control_ignored: Hsla,
264
265    /// Represents the "ours" region of a merge conflict.
266    pub version_control_conflict_ours_background: Hsla,
267    /// Represents the "theirs" region of a merge conflict.
268    pub version_control_conflict_theirs_background: Hsla,
269    pub version_control_conflict_ours_marker_background: Hsla,
270    pub version_control_conflict_theirs_marker_background: Hsla,
271    pub version_control_conflict_divider_background: Hsla,
272}
273
274#[derive(EnumIter, Debug, Clone, Copy, AsRefStr)]
275#[strum(serialize_all = "snake_case")]
276pub enum ThemeColorField {
277    Border,
278    BorderVariant,
279    BorderFocused,
280    BorderSelected,
281    BorderTransparent,
282    BorderDisabled,
283    ElevatedSurfaceBackground,
284    SurfaceBackground,
285    Background,
286    ElementBackground,
287    ElementHover,
288    ElementActive,
289    ElementSelected,
290    ElementDisabled,
291    DropTargetBackground,
292    GhostElementBackground,
293    GhostElementHover,
294    GhostElementActive,
295    GhostElementSelected,
296    GhostElementDisabled,
297    Text,
298    TextMuted,
299    TextPlaceholder,
300    TextDisabled,
301    TextAccent,
302    Icon,
303    IconMuted,
304    IconDisabled,
305    IconPlaceholder,
306    IconAccent,
307    StatusBarBackground,
308    TitleBarBackground,
309    TitleBarInactiveBackground,
310    ToolbarBackground,
311    TabBarBackground,
312    TabInactiveBackground,
313    TabActiveBackground,
314    SearchMatchBackground,
315    PanelBackground,
316    PanelFocusedBorder,
317    PanelIndentGuide,
318    PanelIndentGuideHover,
319    PanelIndentGuideActive,
320    PaneFocusedBorder,
321    PaneGroupBorder,
322    ScrollbarThumbBackground,
323    ScrollbarThumbHoverBackground,
324    ScrollbarThumbBorder,
325    ScrollbarTrackBackground,
326    ScrollbarTrackBorder,
327    EditorForeground,
328    EditorBackground,
329    EditorGutterBackground,
330    EditorSubheaderBackground,
331    EditorActiveLineBackground,
332    EditorHighlightedLineBackground,
333    EditorLineNumber,
334    EditorActiveLineNumber,
335    EditorInvisible,
336    EditorWrapGuide,
337    EditorActiveWrapGuide,
338    EditorIndentGuide,
339    EditorIndentGuideActive,
340    EditorDocumentHighlightReadBackground,
341    EditorDocumentHighlightWriteBackground,
342    EditorDocumentHighlightBracketBackground,
343    TerminalBackground,
344    TerminalForeground,
345    TerminalBrightForeground,
346    TerminalDimForeground,
347    TerminalAnsiBackground,
348    TerminalAnsiBlack,
349    TerminalAnsiBrightBlack,
350    TerminalAnsiDimBlack,
351    TerminalAnsiRed,
352    TerminalAnsiBrightRed,
353    TerminalAnsiDimRed,
354    TerminalAnsiGreen,
355    TerminalAnsiBrightGreen,
356    TerminalAnsiDimGreen,
357    TerminalAnsiYellow,
358    TerminalAnsiBrightYellow,
359    TerminalAnsiDimYellow,
360    TerminalAnsiBlue,
361    TerminalAnsiBrightBlue,
362    TerminalAnsiDimBlue,
363    TerminalAnsiMagenta,
364    TerminalAnsiBrightMagenta,
365    TerminalAnsiDimMagenta,
366    TerminalAnsiCyan,
367    TerminalAnsiBrightCyan,
368    TerminalAnsiDimCyan,
369    TerminalAnsiWhite,
370    TerminalAnsiBrightWhite,
371    TerminalAnsiDimWhite,
372    LinkTextHover,
373    VersionControlAdded,
374    VersionControlDeleted,
375    VersionControlModified,
376    VersionControlRenamed,
377    VersionControlConflict,
378    VersionControlIgnored,
379}
380
381impl ThemeColors {
382    pub fn color(&self, field: ThemeColorField) -> Hsla {
383        match field {
384            ThemeColorField::Border => self.border,
385            ThemeColorField::BorderVariant => self.border_variant,
386            ThemeColorField::BorderFocused => self.border_focused,
387            ThemeColorField::BorderSelected => self.border_selected,
388            ThemeColorField::BorderTransparent => self.border_transparent,
389            ThemeColorField::BorderDisabled => self.border_disabled,
390            ThemeColorField::ElevatedSurfaceBackground => self.elevated_surface_background,
391            ThemeColorField::SurfaceBackground => self.surface_background,
392            ThemeColorField::Background => self.background,
393            ThemeColorField::ElementBackground => self.element_background,
394            ThemeColorField::ElementHover => self.element_hover,
395            ThemeColorField::ElementActive => self.element_active,
396            ThemeColorField::ElementSelected => self.element_selected,
397            ThemeColorField::ElementDisabled => self.element_disabled,
398            ThemeColorField::DropTargetBackground => self.drop_target_background,
399            ThemeColorField::GhostElementBackground => self.ghost_element_background,
400            ThemeColorField::GhostElementHover => self.ghost_element_hover,
401            ThemeColorField::GhostElementActive => self.ghost_element_active,
402            ThemeColorField::GhostElementSelected => self.ghost_element_selected,
403            ThemeColorField::GhostElementDisabled => self.ghost_element_disabled,
404            ThemeColorField::Text => self.text,
405            ThemeColorField::TextMuted => self.text_muted,
406            ThemeColorField::TextPlaceholder => self.text_placeholder,
407            ThemeColorField::TextDisabled => self.text_disabled,
408            ThemeColorField::TextAccent => self.text_accent,
409            ThemeColorField::Icon => self.icon,
410            ThemeColorField::IconMuted => self.icon_muted,
411            ThemeColorField::IconDisabled => self.icon_disabled,
412            ThemeColorField::IconPlaceholder => self.icon_placeholder,
413            ThemeColorField::IconAccent => self.icon_accent,
414            ThemeColorField::StatusBarBackground => self.status_bar_background,
415            ThemeColorField::TitleBarBackground => self.title_bar_background,
416            ThemeColorField::TitleBarInactiveBackground => self.title_bar_inactive_background,
417            ThemeColorField::ToolbarBackground => self.toolbar_background,
418            ThemeColorField::TabBarBackground => self.tab_bar_background,
419            ThemeColorField::TabInactiveBackground => self.tab_inactive_background,
420            ThemeColorField::TabActiveBackground => self.tab_active_background,
421            ThemeColorField::SearchMatchBackground => self.search_match_background,
422            ThemeColorField::PanelBackground => self.panel_background,
423            ThemeColorField::PanelFocusedBorder => self.panel_focused_border,
424            ThemeColorField::PanelIndentGuide => self.panel_indent_guide,
425            ThemeColorField::PanelIndentGuideHover => self.panel_indent_guide_hover,
426            ThemeColorField::PanelIndentGuideActive => self.panel_indent_guide_active,
427            ThemeColorField::PaneFocusedBorder => self.pane_focused_border,
428            ThemeColorField::PaneGroupBorder => self.pane_group_border,
429            ThemeColorField::ScrollbarThumbBackground => self.scrollbar_thumb_background,
430            ThemeColorField::ScrollbarThumbHoverBackground => self.scrollbar_thumb_hover_background,
431            ThemeColorField::ScrollbarThumbBorder => self.scrollbar_thumb_border,
432            ThemeColorField::ScrollbarTrackBackground => self.scrollbar_track_background,
433            ThemeColorField::ScrollbarTrackBorder => self.scrollbar_track_border,
434            ThemeColorField::EditorForeground => self.editor_foreground,
435            ThemeColorField::EditorBackground => self.editor_background,
436            ThemeColorField::EditorGutterBackground => self.editor_gutter_background,
437            ThemeColorField::EditorSubheaderBackground => self.editor_subheader_background,
438            ThemeColorField::EditorActiveLineBackground => self.editor_active_line_background,
439            ThemeColorField::EditorHighlightedLineBackground => {
440                self.editor_highlighted_line_background
441            }
442            ThemeColorField::EditorLineNumber => self.editor_line_number,
443            ThemeColorField::EditorActiveLineNumber => self.editor_active_line_number,
444            ThemeColorField::EditorInvisible => self.editor_invisible,
445            ThemeColorField::EditorWrapGuide => self.editor_wrap_guide,
446            ThemeColorField::EditorActiveWrapGuide => self.editor_active_wrap_guide,
447            ThemeColorField::EditorIndentGuide => self.editor_indent_guide,
448            ThemeColorField::EditorIndentGuideActive => self.editor_indent_guide_active,
449            ThemeColorField::EditorDocumentHighlightReadBackground => {
450                self.editor_document_highlight_read_background
451            }
452            ThemeColorField::EditorDocumentHighlightWriteBackground => {
453                self.editor_document_highlight_write_background
454            }
455            ThemeColorField::EditorDocumentHighlightBracketBackground => {
456                self.editor_document_highlight_bracket_background
457            }
458            ThemeColorField::TerminalBackground => self.terminal_background,
459            ThemeColorField::TerminalForeground => self.terminal_foreground,
460            ThemeColorField::TerminalBrightForeground => self.terminal_bright_foreground,
461            ThemeColorField::TerminalDimForeground => self.terminal_dim_foreground,
462            ThemeColorField::TerminalAnsiBackground => self.terminal_ansi_background,
463            ThemeColorField::TerminalAnsiBlack => self.terminal_ansi_black,
464            ThemeColorField::TerminalAnsiBrightBlack => self.terminal_ansi_bright_black,
465            ThemeColorField::TerminalAnsiDimBlack => self.terminal_ansi_dim_black,
466            ThemeColorField::TerminalAnsiRed => self.terminal_ansi_red,
467            ThemeColorField::TerminalAnsiBrightRed => self.terminal_ansi_bright_red,
468            ThemeColorField::TerminalAnsiDimRed => self.terminal_ansi_dim_red,
469            ThemeColorField::TerminalAnsiGreen => self.terminal_ansi_green,
470            ThemeColorField::TerminalAnsiBrightGreen => self.terminal_ansi_bright_green,
471            ThemeColorField::TerminalAnsiDimGreen => self.terminal_ansi_dim_green,
472            ThemeColorField::TerminalAnsiYellow => self.terminal_ansi_yellow,
473            ThemeColorField::TerminalAnsiBrightYellow => self.terminal_ansi_bright_yellow,
474            ThemeColorField::TerminalAnsiDimYellow => self.terminal_ansi_dim_yellow,
475            ThemeColorField::TerminalAnsiBlue => self.terminal_ansi_blue,
476            ThemeColorField::TerminalAnsiBrightBlue => self.terminal_ansi_bright_blue,
477            ThemeColorField::TerminalAnsiDimBlue => self.terminal_ansi_dim_blue,
478            ThemeColorField::TerminalAnsiMagenta => self.terminal_ansi_magenta,
479            ThemeColorField::TerminalAnsiBrightMagenta => self.terminal_ansi_bright_magenta,
480            ThemeColorField::TerminalAnsiDimMagenta => self.terminal_ansi_dim_magenta,
481            ThemeColorField::TerminalAnsiCyan => self.terminal_ansi_cyan,
482            ThemeColorField::TerminalAnsiBrightCyan => self.terminal_ansi_bright_cyan,
483            ThemeColorField::TerminalAnsiDimCyan => self.terminal_ansi_dim_cyan,
484            ThemeColorField::TerminalAnsiWhite => self.terminal_ansi_white,
485            ThemeColorField::TerminalAnsiBrightWhite => self.terminal_ansi_bright_white,
486            ThemeColorField::TerminalAnsiDimWhite => self.terminal_ansi_dim_white,
487            ThemeColorField::LinkTextHover => self.link_text_hover,
488            ThemeColorField::VersionControlAdded => self.version_control_added,
489            ThemeColorField::VersionControlDeleted => self.version_control_deleted,
490            ThemeColorField::VersionControlModified => self.version_control_modified,
491            ThemeColorField::VersionControlRenamed => self.version_control_renamed,
492            ThemeColorField::VersionControlConflict => self.version_control_conflict,
493            ThemeColorField::VersionControlIgnored => self.version_control_ignored,
494        }
495    }
496
497    pub fn iter(&self) -> impl Iterator<Item = (ThemeColorField, Hsla)> + '_ {
498        ThemeColorField::iter().map(move |field| (field, self.color(field)))
499    }
500
501    pub fn to_vec(&self) -> Vec<(ThemeColorField, Hsla)> {
502        self.iter().collect()
503    }
504}
505
506pub fn all_theme_colors(cx: &mut App) -> Vec<(Hsla, SharedString)> {
507    let theme = cx.theme();
508    ThemeColorField::iter()
509        .map(|field| {
510            let color = theme.colors().color(field);
511            let name = field.as_ref().to_string();
512            (color, SharedString::from(name))
513        })
514        .collect()
515}
516
517#[derive(Refineable, Clone, PartialEq)]
518pub struct ThemeStyles {
519    /// The background appearance of the window.
520    pub window_background_appearance: WindowBackgroundAppearance,
521    pub system: SystemColors,
522    /// An array of colors used for theme elements that iterate through a series of colors.
523    ///
524    /// Example: Player colors, rainbow brackets and indent guides, etc.
525    pub accents: AccentColors,
526
527    #[refineable]
528    pub colors: ThemeColors,
529
530    #[refineable]
531    pub status: StatusColors,
532
533    pub player: PlayerColors,
534
535    pub syntax: Arc<SyntaxTheme>,
536}
537
538#[cfg(test)]
539mod tests {
540    use serde_json::json;
541
542    use super::*;
543
544    #[test]
545    fn override_a_single_theme_color() {
546        let mut colors = ThemeColors::light();
547
548        let magenta: Hsla = gpui::rgb(0xff00ff).into();
549
550        assert_ne!(colors.text, magenta);
551
552        let overrides = ThemeColorsRefinement {
553            text: Some(magenta),
554            ..Default::default()
555        };
556
557        colors.refine(&overrides);
558
559        assert_eq!(colors.text, magenta);
560    }
561
562    #[test]
563    fn override_multiple_theme_colors() {
564        let mut colors = ThemeColors::light();
565
566        let magenta: Hsla = gpui::rgb(0xff00ff).into();
567        let green: Hsla = gpui::rgb(0x00ff00).into();
568
569        assert_ne!(colors.text, magenta);
570        assert_ne!(colors.background, green);
571
572        let overrides = ThemeColorsRefinement {
573            text: Some(magenta),
574            background: Some(green),
575            ..Default::default()
576        };
577
578        colors.refine(&overrides);
579
580        assert_eq!(colors.text, magenta);
581        assert_eq!(colors.background, green);
582    }
583
584    #[test]
585    fn deserialize_theme_colors_refinement_from_json() {
586        let colors: ThemeColorsRefinement = serde_json::from_value(json!({
587            "background": "#ff00ff",
588            "text": "#ff0000"
589        }))
590        .unwrap();
591
592        assert_eq!(colors.background, Some(gpui::rgb(0xff00ff).into()));
593        assert_eq!(colors.text, Some(gpui::rgb(0xff0000).into()));
594    }
595}