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