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}