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