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 font_family_cache;
12mod one_themes;
13pub mod prelude;
14mod registry;
15mod scale;
16mod schema;
17mod settings;
18mod styles;
19
20use std::sync::Arc;
21
22use ::settings::{Settings, SettingsStore};
23pub use default_colors::*;
24pub use default_theme::*;
25pub use font_family_cache::*;
26pub use registry::*;
27pub use scale::*;
28pub use schema::*;
29pub use settings::*;
30pub use styles::*;
31
32use gpui::{
33 px, AppContext, AssetSource, Hsla, Pixels, SharedString, WindowAppearance,
34 WindowBackgroundAppearance,
35};
36use serde::Deserialize;
37
38#[derive(Debug, PartialEq, Clone, Copy, Deserialize)]
39pub enum Appearance {
40 Light,
41 Dark,
42}
43
44pub const CLIENT_SIDE_DECORATION_ROUNDING: Pixels = px(10.0);
45pub const CLIENT_SIDE_DECORATION_SHADOW: Pixels = px(10.0);
46
47impl Appearance {
48 pub fn is_light(&self) -> bool {
49 match self {
50 Self::Light => true,
51 Self::Dark => false,
52 }
53 }
54}
55
56impl From<WindowAppearance> for Appearance {
57 fn from(value: WindowAppearance) -> Self {
58 match value {
59 WindowAppearance::Dark | WindowAppearance::VibrantDark => Self::Dark,
60 WindowAppearance::Light | WindowAppearance::VibrantLight => Self::Light,
61 }
62 }
63}
64
65pub enum LoadThemes {
66 /// Only load the base theme.
67 ///
68 /// No user themes will be loaded.
69 JustBase,
70
71 /// Load all of the built-in themes.
72 All(Box<dyn AssetSource>),
73}
74
75pub fn init(themes_to_load: LoadThemes, cx: &mut AppContext) {
76 let (assets, load_user_themes) = match themes_to_load {
77 LoadThemes::JustBase => (Box::new(()) as Box<dyn AssetSource>, false),
78 LoadThemes::All(assets) => (assets, true),
79 };
80 ThemeRegistry::set_global(assets, cx);
81
82 if load_user_themes {
83 ThemeRegistry::global(cx).load_bundled_themes();
84 }
85
86 ThemeSettings::register(cx);
87 FontFamilyCache::init_global(cx);
88
89 let mut prev_buffer_font_size = ThemeSettings::get_global(cx).buffer_font_size;
90 cx.observe_global::<SettingsStore>(move |cx| {
91 let buffer_font_size = ThemeSettings::get_global(cx).buffer_font_size;
92 if buffer_font_size != prev_buffer_font_size {
93 prev_buffer_font_size = buffer_font_size;
94 reset_buffer_font_size(cx);
95 }
96 })
97 .detach();
98}
99
100pub trait ActiveTheme {
101 fn theme(&self) -> &Arc<Theme>;
102}
103
104impl ActiveTheme for AppContext {
105 fn theme(&self) -> &Arc<Theme> {
106 &ThemeSettings::get_global(self).active_theme
107 }
108}
109
110pub struct ThemeFamily {
111 pub id: String,
112 pub name: SharedString,
113 pub author: SharedString,
114 pub themes: Vec<Theme>,
115 pub scales: ColorScales,
116}
117
118impl ThemeFamily {}
119
120#[derive(Clone)]
121pub struct Theme {
122 pub id: String,
123 pub name: SharedString,
124 pub appearance: Appearance,
125 pub styles: ThemeStyles,
126}
127
128impl Theme {
129 /// Returns the [`SystemColors`] for the theme.
130 #[inline(always)]
131 pub fn system(&self) -> &SystemColors {
132 &self.styles.system
133 }
134
135 /// Returns the [`AccentColors`] for the theme.
136 #[inline(always)]
137 pub fn accents(&self) -> &AccentColors {
138 &self.styles.accents
139 }
140
141 /// Returns the [`PlayerColors`] for the theme.
142 #[inline(always)]
143 pub fn players(&self) -> &PlayerColors {
144 &self.styles.player
145 }
146
147 /// Returns the [`ThemeColors`] for the theme.
148 #[inline(always)]
149 pub fn colors(&self) -> &ThemeColors {
150 &self.styles.colors
151 }
152
153 /// Returns the [`SyntaxTheme`] for the theme.
154 #[inline(always)]
155 pub fn syntax(&self) -> &Arc<SyntaxTheme> {
156 &self.styles.syntax
157 }
158
159 /// Returns the [`StatusColors`] for the theme.
160 #[inline(always)]
161 pub fn status(&self) -> &StatusColors {
162 &self.styles.status
163 }
164
165 /// Returns the color for the syntax node with the given name.
166 #[inline(always)]
167 pub fn syntax_color(&self, name: &str) -> Hsla {
168 self.syntax().color(name)
169 }
170
171 /// Returns the [`Appearance`] for the theme.
172 #[inline(always)]
173 pub fn appearance(&self) -> Appearance {
174 self.appearance
175 }
176
177 /// Returns the [`WindowBackgroundAppearance`] for the theme.
178 #[inline(always)]
179 pub fn window_background_appearance(&self) -> WindowBackgroundAppearance {
180 self.styles.window_background_appearance
181 }
182}
183
184pub fn color_alpha(color: Hsla, alpha: f32) -> Hsla {
185 let mut color = color;
186 color.a = alpha;
187 color
188}