theme2.rs

  1mod default;
  2mod registry;
  3mod scale;
  4mod settings;
  5mod themes;
  6
  7pub use default::*;
  8pub use registry::*;
  9pub use scale::*;
 10pub use settings::*;
 11
 12use gpui2::{AppContext, HighlightStyle, Hsla, SharedString};
 13use settings2::Settings;
 14use std::sync::Arc;
 15
 16#[derive(Debug, Clone, PartialEq)]
 17pub enum Appearance {
 18    Light,
 19    Dark,
 20}
 21
 22pub fn init(cx: &mut AppContext) {
 23    cx.set_global(ThemeRegistry::default());
 24    ThemeSettings::register(cx);
 25}
 26
 27pub fn active_theme<'a>(cx: &'a AppContext) -> &'a Arc<Theme> {
 28    &ThemeSettings::get_global(cx).active_theme
 29}
 30
 31pub fn theme(cx: &AppContext) -> Arc<Theme> {
 32    active_theme(cx).clone()
 33}
 34
 35pub struct Theme {
 36    pub metadata: ThemeMetadata,
 37
 38    pub transparent: Hsla,
 39    pub mac_os_traffic_light_red: Hsla,
 40    pub mac_os_traffic_light_yellow: Hsla,
 41    pub mac_os_traffic_light_green: Hsla,
 42    pub border: Hsla,
 43    pub border_variant: Hsla,
 44    pub border_focused: Hsla,
 45    pub border_transparent: Hsla,
 46    /// The background color of an elevated surface, like a modal, tooltip or toast.
 47    pub elevated_surface: Hsla,
 48    pub surface: Hsla,
 49    /// Window background color of the base app
 50    pub background: Hsla,
 51    /// Default background for elements like filled buttons,
 52    /// text fields, checkboxes, radio buttons, etc.
 53    /// - TODO: Map to step 3.
 54    pub filled_element: Hsla,
 55    /// The background color of a hovered element, like a button being hovered
 56    /// with a mouse, or hovered on a touch screen.
 57    /// - TODO: Map to step 4.
 58    pub filled_element_hover: Hsla,
 59    /// The background color of an active element, like a button being pressed,
 60    /// or tapped on a touch screen.
 61    /// - TODO: Map to step 5.
 62    pub filled_element_active: Hsla,
 63    /// The background color of a selected element, like a selected tab,
 64    /// a button toggled on, or a checkbox that is checked.
 65    pub filled_element_selected: Hsla,
 66    pub filled_element_disabled: Hsla,
 67    pub ghost_element: Hsla,
 68    /// The background color of a hovered element with no default background,
 69    /// like a ghost-style button or an interactable list item.
 70    /// - TODO: Map to step 3.
 71    pub ghost_element_hover: Hsla,
 72    /// - TODO: Map to step 4.
 73    pub ghost_element_active: Hsla,
 74    pub ghost_element_selected: Hsla,
 75    pub ghost_element_disabled: Hsla,
 76    pub text: Hsla,
 77    pub text_muted: Hsla,
 78    pub text_placeholder: Hsla,
 79    pub text_disabled: Hsla,
 80    pub text_accent: Hsla,
 81    pub icon_muted: Hsla,
 82    pub syntax: SyntaxTheme,
 83
 84    pub status_bar: Hsla,
 85    pub title_bar: Hsla,
 86    pub toolbar: Hsla,
 87    pub tab_bar: Hsla,
 88    /// The background of the editor
 89    pub editor: Hsla,
 90    pub editor_subheader: Hsla,
 91    pub editor_active_line: Hsla,
 92    pub terminal: Hsla,
 93    pub image_fallback_background: Hsla,
 94
 95    pub git_created: Hsla,
 96    pub git_modified: Hsla,
 97    pub git_deleted: Hsla,
 98    pub git_conflict: Hsla,
 99    pub git_ignored: Hsla,
100    pub git_renamed: Hsla,
101
102    pub players: [PlayerTheme; 8],
103}
104
105#[derive(Clone)]
106pub struct SyntaxTheme {
107    pub highlights: Vec<(String, HighlightStyle)>,
108}
109
110impl SyntaxTheme {
111    // TOOD: Get this working with `#[cfg(test)]`. Why isn't it?
112    pub fn new_test(colors: impl IntoIterator<Item = (&'static str, Hsla)>) -> Self {
113        SyntaxTheme {
114            highlights: colors
115                .into_iter()
116                .map(|(key, color)| {
117                    (
118                        key.to_owned(),
119                        HighlightStyle {
120                            color: Some(color),
121                            ..Default::default()
122                        },
123                    )
124                })
125                .collect(),
126        }
127    }
128
129    pub fn get(&self, name: &str) -> HighlightStyle {
130        self.highlights
131            .iter()
132            .find_map(|entry| if entry.0 == name { Some(entry.1) } else { None })
133            .unwrap_or_default()
134    }
135
136    pub fn color(&self, name: &str) -> Hsla {
137        self.get(name).color.unwrap_or_default()
138    }
139}
140
141#[derive(Clone, Copy)]
142pub struct PlayerTheme {
143    pub cursor: Hsla,
144    pub selection: Hsla,
145}
146
147#[derive(Clone)]
148pub struct ThemeMetadata {
149    pub name: SharedString,
150    pub is_light: bool,
151}
152
153pub struct Editor {
154    pub syntax: Arc<SyntaxTheme>,
155}