theme.rs

  1//! # Theme
  2//!
  3//! This crate provides the theme system for Zed.
  4//!
  5//! ## Overview
  6//!
  7//! A theme is a collection of colors used to build a consistent appearance for UI components across the application.
  8
  9mod default_colors;
 10mod default_theme;
 11mod one_themes;
 12pub mod prelude;
 13mod registry;
 14mod scale;
 15mod schema;
 16mod settings;
 17mod styles;
 18#[cfg(not(feature = "importing-themes"))]
 19mod themes;
 20mod user_theme;
 21
 22use std::sync::Arc;
 23
 24use ::settings::{Settings, SettingsStore};
 25pub use default_colors::*;
 26pub use default_theme::*;
 27pub use registry::*;
 28pub use scale::*;
 29pub use schema::*;
 30pub use settings::*;
 31pub use styles::*;
 32#[cfg(not(feature = "importing-themes"))]
 33pub use themes::*;
 34pub use user_theme::*;
 35
 36use gpui::{AppContext, Hsla, SharedString};
 37use serde::Deserialize;
 38
 39#[derive(Debug, PartialEq, Clone, Copy, Deserialize)]
 40pub enum Appearance {
 41    Light,
 42    Dark,
 43}
 44
 45impl Appearance {
 46    pub fn is_light(&self) -> bool {
 47        match self {
 48            Self::Light => true,
 49            Self::Dark => false,
 50        }
 51    }
 52}
 53
 54#[derive(Debug, PartialEq, Eq, Clone, Copy)]
 55pub enum LoadThemes {
 56    /// Only load the base theme.
 57    ///
 58    /// No user themes will be loaded.
 59    JustBase,
 60
 61    /// Load all of the built-in themes.
 62    All,
 63}
 64
 65pub fn init(themes_to_load: LoadThemes, cx: &mut AppContext) {
 66    cx.set_global(ThemeRegistry::default());
 67    match themes_to_load {
 68        LoadThemes::JustBase => (),
 69        LoadThemes::All => cx.global_mut::<ThemeRegistry>().load_user_themes(),
 70    }
 71    ThemeSettings::register(cx);
 72
 73    let mut prev_buffer_font_size = ThemeSettings::get_global(cx).buffer_font_size;
 74    cx.observe_global::<SettingsStore>(move |cx| {
 75        let buffer_font_size = ThemeSettings::get_global(cx).buffer_font_size;
 76        if buffer_font_size != prev_buffer_font_size {
 77            prev_buffer_font_size = buffer_font_size;
 78            reset_font_size(cx);
 79        }
 80    })
 81    .detach();
 82}
 83
 84pub trait ActiveTheme {
 85    fn theme(&self) -> &Arc<Theme>;
 86}
 87
 88impl ActiveTheme for AppContext {
 89    fn theme(&self) -> &Arc<Theme> {
 90        &ThemeSettings::get_global(self).active_theme
 91    }
 92}
 93
 94pub struct ThemeFamily {
 95    pub id: String,
 96    pub name: SharedString,
 97    pub author: SharedString,
 98    pub themes: Vec<Theme>,
 99    pub scales: ColorScales,
100}
101
102impl ThemeFamily {}
103
104#[derive(Clone)]
105pub struct Theme {
106    pub id: String,
107    pub name: SharedString,
108    pub appearance: Appearance,
109    pub styles: ThemeStyles,
110}
111
112impl Theme {
113    /// Returns the [`SystemColors`] for the theme.
114    #[inline(always)]
115    pub fn system(&self) -> &SystemColors {
116        &self.styles.system
117    }
118
119    /// Returns the [`PlayerColors`] for the theme.
120    #[inline(always)]
121    pub fn players(&self) -> &PlayerColors {
122        &self.styles.player
123    }
124
125    /// Returns the [`ThemeColors`] for the theme.
126    #[inline(always)]
127    pub fn colors(&self) -> &ThemeColors {
128        &self.styles.colors
129    }
130
131    /// Returns the [`SyntaxTheme`] for the theme.
132    #[inline(always)]
133    pub fn syntax(&self) -> &Arc<SyntaxTheme> {
134        &self.styles.syntax
135    }
136
137    /// Returns the [`StatusColors`] for the theme.
138    #[inline(always)]
139    pub fn status(&self) -> &StatusColors {
140        &self.styles.status
141    }
142
143    /// Returns the color for the syntax node with the given name.
144    #[inline(always)]
145    pub fn syntax_color(&self, name: &str) -> Hsla {
146        self.syntax().color(name)
147    }
148
149    /// Returns the [`Appearance`] for the theme.
150    #[inline(always)]
151    pub fn appearance(&self) -> Appearance {
152        self.appearance
153    }
154}
155
156pub fn color_alpha(color: Hsla, alpha: f32) -> Hsla {
157    let mut color = color;
158    color.a = alpha;
159    color
160}