1pub use gpui3::{
2 div, Element, IntoAnyElement, ParentElement, ScrollState, StyleHelpers, Styled, ViewContext,
3 WindowContext,
4};
5
6pub use crate::{theme, ButtonVariant, ElementExt, Theme};
7
8use gpui3::{hsla, rems, rgb, AbsoluteLength, Hsla};
9use strum::EnumIter;
10
11#[derive(Clone, Copy)]
12pub struct Token {
13 pub list_indent_depth: AbsoluteLength,
14 pub default_panel_size: AbsoluteLength,
15 pub state_hover_background: Hsla,
16 pub state_active_background: Hsla,
17}
18
19impl Default for Token {
20 fn default() -> Self {
21 Self {
22 list_indent_depth: AbsoluteLength::Rems(rems(0.3)),
23 default_panel_size: AbsoluteLength::Rems(rems(16.)),
24 state_hover_background: hsla(0.0, 0.0, 0.0, 0.08),
25 state_active_background: hsla(0.0, 0.0, 0.0, 0.16),
26 }
27 }
28}
29
30pub fn token() -> Token {
31 Token::default()
32}
33
34#[derive(Default)]
35pub struct SystemColor {
36 pub transparent: Hsla,
37 pub mac_os_traffic_light_red: Hsla,
38 pub mac_os_traffic_light_yellow: Hsla,
39 pub mac_os_traffic_light_green: Hsla,
40}
41
42impl SystemColor {
43 pub fn new() -> SystemColor {
44 SystemColor {
45 transparent: hsla(0.0, 0.0, 0.0, 0.0),
46 mac_os_traffic_light_red: rgb::<Hsla>(0xEC695E),
47 mac_os_traffic_light_yellow: rgb::<Hsla>(0xF4BF4F),
48 mac_os_traffic_light_green: rgb::<Hsla>(0x62C554),
49 }
50 }
51 pub fn color(&self) -> Hsla {
52 self.transparent
53 }
54}
55
56#[derive(Clone, Copy)]
57pub struct ThemeColor {
58 pub border: Hsla,
59 pub border_variant: Hsla,
60 pub border_focused: Hsla,
61 /// The background color of an elevated surface, like a modal, tooltip or toast.
62 pub elevated_surface: Hsla,
63 pub surface: Hsla,
64}
65
66impl ThemeColor {
67 pub fn new(cx: &WindowContext) -> Self {
68 let theme = theme(cx);
69
70 Self {
71 border: theme.lowest.base.default.border,
72 border_variant: theme.lowest.variant.default.border,
73 border_focused: theme.lowest.accent.default.border,
74 elevated_surface: theme.middle.base.default.background,
75 surface: theme.middle.base.default.background,
76 }
77 }
78}
79
80#[derive(Default, PartialEq, EnumIter, Clone, Copy)]
81pub enum HighlightColor {
82 #[default]
83 Default,
84 Comment,
85 String,
86 Function,
87 Keyword,
88}
89
90impl HighlightColor {
91 pub fn hsla(&self, theme: &Theme) -> Hsla {
92 let system_color = SystemColor::new();
93
94 match self {
95 Self::Default => theme
96 .syntax
97 .get("primary")
98 .cloned()
99 .unwrap_or_else(|| rgb::<Hsla>(0xff00ff)),
100 Self::Comment => theme
101 .syntax
102 .get("comment")
103 .cloned()
104 .unwrap_or_else(|| rgb::<Hsla>(0xff00ff)),
105 Self::String => theme
106 .syntax
107 .get("string")
108 .cloned()
109 .unwrap_or_else(|| rgb::<Hsla>(0xff00ff)),
110 Self::Function => theme
111 .syntax
112 .get("function")
113 .cloned()
114 .unwrap_or_else(|| rgb::<Hsla>(0xff00ff)),
115 Self::Keyword => theme
116 .syntax
117 .get("keyword")
118 .cloned()
119 .unwrap_or_else(|| rgb::<Hsla>(0xff00ff)),
120 }
121 }
122}
123
124#[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, EnumIter)]
125pub enum FileSystemStatus {
126 #[default]
127 None,
128 Conflict,
129 Deleted,
130}
131
132impl FileSystemStatus {
133 pub fn to_string(&self) -> String {
134 match self {
135 Self::None => "None".to_string(),
136 Self::Conflict => "Conflict".to_string(),
137 Self::Deleted => "Deleted".to_string(),
138 }
139 }
140}
141
142#[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, EnumIter)]
143pub enum GitStatus {
144 #[default]
145 None,
146 Created,
147 Modified,
148 Deleted,
149 Conflict,
150 Renamed,
151}
152
153impl GitStatus {
154 pub fn to_string(&self) -> String {
155 match self {
156 Self::None => "None".to_string(),
157 Self::Created => "Created".to_string(),
158 Self::Modified => "Modified".to_string(),
159 Self::Deleted => "Deleted".to_string(),
160 Self::Conflict => "Conflict".to_string(),
161 Self::Renamed => "Renamed".to_string(),
162 }
163 }
164
165 pub fn hsla(&self, cx: &WindowContext) -> Hsla {
166 let theme = theme(cx);
167 let system_color = SystemColor::new();
168
169 match self {
170 Self::None => system_color.transparent,
171 Self::Created => theme.lowest.positive.default.foreground,
172 Self::Modified => theme.lowest.warning.default.foreground,
173 Self::Deleted => theme.lowest.negative.default.foreground,
174 Self::Conflict => theme.lowest.warning.default.foreground,
175 Self::Renamed => theme.lowest.accent.default.foreground,
176 }
177 }
178}
179
180#[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, EnumIter)]
181pub enum DiagnosticStatus {
182 #[default]
183 None,
184 Error,
185 Warning,
186 Info,
187}
188
189#[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, EnumIter)]
190pub enum IconSide {
191 #[default]
192 Left,
193 Right,
194}
195
196#[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, EnumIter)]
197pub enum OrderMethod {
198 #[default]
199 Ascending,
200 Descending,
201 MostRecent,
202}
203
204#[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, EnumIter)]
205pub enum Shape {
206 #[default]
207 Circle,
208 RoundedRectangle,
209}
210
211#[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, EnumIter)]
212pub enum DisclosureControlVisibility {
213 #[default]
214 OnHover,
215 Always,
216}
217
218#[derive(Default, PartialEq, Copy, Clone, EnumIter, strum::Display)]
219pub enum InteractionState {
220 #[default]
221 Enabled,
222 Hovered,
223 Active,
224 Focused,
225 Disabled,
226}
227
228impl InteractionState {
229 pub fn if_enabled(&self, enabled: bool) -> Self {
230 if enabled {
231 *self
232 } else {
233 InteractionState::Disabled
234 }
235 }
236}
237
238#[derive(Default, PartialEq)]
239pub enum SelectedState {
240 #[default]
241 Unselected,
242 PartiallySelected,
243 Selected,
244}
245
246#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
247pub enum Toggleable {
248 Toggleable(ToggleState),
249 #[default]
250 NotToggleable,
251}
252
253impl Toggleable {
254 pub fn is_toggled(&self) -> bool {
255 match self {
256 Self::Toggleable(ToggleState::Toggled) => true,
257 _ => false,
258 }
259 }
260}
261
262impl From<ToggleState> for Toggleable {
263 fn from(state: ToggleState) -> Self {
264 Self::Toggleable(state)
265 }
266}
267
268#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
269pub enum ToggleState {
270 /// The "on" state of a toggleable element.
271 ///
272 /// Example:
273 /// - A collasable list that is currently expanded
274 /// - A toggle button that is currently on.
275 Toggled,
276 /// The "off" state of a toggleable element.
277 ///
278 /// Example:
279 /// - A collasable list that is currently collapsed
280 /// - A toggle button that is currently off.
281 #[default]
282 NotToggled,
283}
284
285impl From<Toggleable> for ToggleState {
286 fn from(toggleable: Toggleable) -> Self {
287 match toggleable {
288 Toggleable::Toggleable(state) => state,
289 Toggleable::NotToggleable => ToggleState::NotToggled,
290 }
291 }
292}
293
294impl From<bool> for ToggleState {
295 fn from(toggled: bool) -> Self {
296 if toggled {
297 ToggleState::Toggled
298 } else {
299 ToggleState::NotToggled
300 }
301 }
302}