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