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