1mod default_colors;
2mod default_theme;
3mod one_themes;
4mod registry;
5mod scale;
6mod settings;
7mod styles;
8#[cfg(not(feature = "importing-themes"))]
9mod themes;
10mod user_theme;
11
12use std::sync::Arc;
13
14use ::settings::Settings;
15pub use default_colors::*;
16pub use default_theme::*;
17pub use registry::*;
18pub use scale::*;
19pub use settings::*;
20pub use styles::*;
21#[cfg(not(feature = "importing-themes"))]
22pub use themes::*;
23pub use user_theme::*;
24
25use gpui::{AppContext, Hsla, SharedString};
26use serde::Deserialize;
27
28#[derive(Debug, PartialEq, Clone, Copy, Deserialize)]
29pub enum Appearance {
30 Light,
31 Dark,
32}
33
34impl Appearance {
35 pub fn is_light(&self) -> bool {
36 match self {
37 Self::Light => true,
38 Self::Dark => false,
39 }
40 }
41}
42
43#[derive(Debug, PartialEq, Eq, Clone, Copy)]
44pub enum LoadThemes {
45 /// Only load the base theme.
46 ///
47 /// No user themes will be loaded.
48 JustBase,
49
50 /// Load all of the built-in themes.
51 All,
52}
53
54pub fn init(themes_to_load: LoadThemes, cx: &mut AppContext) {
55 cx.set_global(ThemeRegistry::default());
56
57 match themes_to_load {
58 LoadThemes::JustBase => (),
59 LoadThemes::All => cx.global_mut::<ThemeRegistry>().load_user_themes(),
60 }
61
62 ThemeSettings::register(cx);
63}
64
65pub trait ActiveTheme {
66 fn theme(&self) -> &Arc<Theme>;
67}
68
69impl ActiveTheme for AppContext {
70 fn theme(&self) -> &Arc<Theme> {
71 &ThemeSettings::get_global(self).active_theme
72 }
73}
74
75// impl<'a> ActiveTheme for WindowContext<'a> {
76// fn theme(&self) -> &Arc<Theme> {
77// &ThemeSettings::get_global(self.app()).active_theme
78// }
79// }
80
81pub struct ThemeFamily {
82 pub id: String,
83 pub name: SharedString,
84 pub author: SharedString,
85 pub themes: Vec<Theme>,
86 pub scales: ColorScales,
87}
88
89impl ThemeFamily {}
90
91pub struct Theme {
92 pub id: String,
93 pub name: SharedString,
94 pub appearance: Appearance,
95 pub styles: ThemeStyles,
96}
97
98impl Theme {
99 /// Returns the [`SystemColors`] for the theme.
100 #[inline(always)]
101 pub fn system(&self) -> &SystemColors {
102 &self.styles.system
103 }
104
105 /// Returns the [`PlayerColors`] for the theme.
106 #[inline(always)]
107 pub fn players(&self) -> &PlayerColors {
108 &self.styles.player
109 }
110
111 /// Returns the [`ThemeColors`] for the theme.
112 #[inline(always)]
113 pub fn colors(&self) -> &ThemeColors {
114 &self.styles.colors
115 }
116
117 /// Returns the [`SyntaxTheme`] for the theme.
118 #[inline(always)]
119 pub fn syntax(&self) -> &Arc<SyntaxTheme> {
120 &self.styles.syntax
121 }
122
123 /// Returns the [`StatusColors`] for the theme.
124 #[inline(always)]
125 pub fn status(&self) -> &StatusColors {
126 &self.styles.status
127 }
128
129 /// Returns the color for the syntax node with the given name.
130 #[inline(always)]
131 pub fn syntax_color(&self, name: &str) -> Hsla {
132 self.syntax().color(name)
133 }
134
135 /// Returns the [`DiagnosticStyle`] for the theme.
136 #[inline(always)]
137 pub fn diagnostic_style(&self) -> DiagnosticStyle {
138 DiagnosticStyle {
139 error: self.status().error,
140 warning: self.status().warning,
141 info: self.status().info,
142 hint: self.status().info,
143 ignored: self.status().ignored,
144 }
145 }
146
147 /// Returns the [`Appearance`] for the theme.
148 #[inline(always)]
149 pub fn appearance(&self) -> Appearance {
150 self.appearance
151 }
152}
153
154#[derive(Clone, Debug, Default)]
155pub struct DiagnosticStyle {
156 pub error: Hsla,
157 pub warning: Hsla,
158 pub info: Hsla,
159 pub hint: Hsla,
160 pub ignored: Hsla,
161}
162
163pub fn color_alpha(color: Hsla, alpha: f32) -> Hsla {
164 let mut color = color;
165 color.a = alpha;
166 color
167}