prelude.rs

  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: rems(0.3).into(),
 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    pub border_transparent: Hsla,
 62    /// The background color of an elevated surface, like a modal, tooltip or toast.
 63    pub elevated_surface: Hsla,
 64    pub surface: Hsla,
 65    /// Default background for elements like filled buttons,
 66    /// text fields, checkboxes, radio buttons, etc.
 67    /// - TODO: Map to step 3.
 68    pub filled_element: Hsla,
 69    /// The background color of a hovered element, like a button being hovered
 70    /// with a mouse, or hovered on a touch screen.
 71    /// - TODO: Map to step 4.
 72    pub filled_element_hover: Hsla,
 73    /// The background color of an active element, like a button being pressed,
 74    /// or tapped on a touch screen.
 75    /// - TODO: Map to step 5.
 76    pub filled_element_active: Hsla,
 77    /// The background color of a selected element, like a selected tab,
 78    /// a button toggled on, or a checkbox that is checked.
 79    pub filled_element_selected: Hsla,
 80    pub filled_element_disabled: Hsla,
 81    pub ghost_element: Hsla,
 82    /// - TODO: Map to step 3.
 83    pub ghost_element_hover: Hsla,
 84    /// - TODO: Map to step 4.
 85    pub ghost_element_active: Hsla,
 86    pub ghost_element_selected: Hsla,
 87    pub ghost_element_disabled: Hsla,
 88}
 89
 90impl ThemeColor {
 91    pub fn new(cx: &WindowContext) -> Self {
 92        let theme = theme(cx);
 93        let system_color = SystemColor::new();
 94
 95        Self {
 96            border: theme.lowest.base.default.border,
 97            border_variant: theme.lowest.variant.default.border,
 98            border_focused: theme.lowest.accent.default.border,
 99            border_transparent: system_color.transparent,
100            elevated_surface: theme.middle.base.default.background,
101            surface: theme.middle.base.default.background,
102            filled_element: theme.lowest.base.default.background,
103            filled_element_hover: theme.lowest.base.hovered.background,
104            filled_element_active: theme.lowest.base.active.background,
105            filled_element_selected: theme.lowest.accent.default.background,
106            filled_element_disabled: system_color.transparent,
107            ghost_element: system_color.transparent,
108            ghost_element_hover: theme.lowest.base.default.background,
109            ghost_element_active: theme.lowest.base.hovered.background,
110            ghost_element_selected: theme.lowest.accent.default.background,
111            ghost_element_disabled: system_color.transparent,
112        }
113    }
114}
115
116#[derive(Default, PartialEq, EnumIter, Clone, Copy)]
117pub enum HighlightColor {
118    #[default]
119    Default,
120    Comment,
121    String,
122    Function,
123    Keyword,
124}
125
126impl HighlightColor {
127    pub fn hsla(&self, theme: &Theme) -> Hsla {
128        let system_color = SystemColor::new();
129
130        match self {
131            Self::Default => theme
132                .syntax
133                .get("primary")
134                .cloned()
135                .unwrap_or_else(|| rgb::<Hsla>(0xff00ff)),
136            Self::Comment => theme
137                .syntax
138                .get("comment")
139                .cloned()
140                .unwrap_or_else(|| rgb::<Hsla>(0xff00ff)),
141            Self::String => theme
142                .syntax
143                .get("string")
144                .cloned()
145                .unwrap_or_else(|| rgb::<Hsla>(0xff00ff)),
146            Self::Function => theme
147                .syntax
148                .get("function")
149                .cloned()
150                .unwrap_or_else(|| rgb::<Hsla>(0xff00ff)),
151            Self::Keyword => theme
152                .syntax
153                .get("keyword")
154                .cloned()
155                .unwrap_or_else(|| rgb::<Hsla>(0xff00ff)),
156        }
157    }
158}
159
160#[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, EnumIter)]
161pub enum FileSystemStatus {
162    #[default]
163    None,
164    Conflict,
165    Deleted,
166}
167
168impl FileSystemStatus {
169    pub fn to_string(&self) -> String {
170        match self {
171            Self::None => "None".to_string(),
172            Self::Conflict => "Conflict".to_string(),
173            Self::Deleted => "Deleted".to_string(),
174        }
175    }
176}
177
178#[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, EnumIter)]
179pub enum GitStatus {
180    #[default]
181    None,
182    Created,
183    Modified,
184    Deleted,
185    Conflict,
186    Renamed,
187}
188
189impl GitStatus {
190    pub fn to_string(&self) -> String {
191        match self {
192            Self::None => "None".to_string(),
193            Self::Created => "Created".to_string(),
194            Self::Modified => "Modified".to_string(),
195            Self::Deleted => "Deleted".to_string(),
196            Self::Conflict => "Conflict".to_string(),
197            Self::Renamed => "Renamed".to_string(),
198        }
199    }
200
201    pub fn hsla(&self, cx: &WindowContext) -> Hsla {
202        let theme = theme(cx);
203        let system_color = SystemColor::new();
204
205        match self {
206            Self::None => system_color.transparent,
207            Self::Created => theme.lowest.positive.default.foreground,
208            Self::Modified => theme.lowest.warning.default.foreground,
209            Self::Deleted => theme.lowest.negative.default.foreground,
210            Self::Conflict => theme.lowest.warning.default.foreground,
211            Self::Renamed => theme.lowest.accent.default.foreground,
212        }
213    }
214}
215
216#[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, EnumIter)]
217pub enum DiagnosticStatus {
218    #[default]
219    None,
220    Error,
221    Warning,
222    Info,
223}
224
225#[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, EnumIter)]
226pub enum IconSide {
227    #[default]
228    Left,
229    Right,
230}
231
232#[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, EnumIter)]
233pub enum OrderMethod {
234    #[default]
235    Ascending,
236    Descending,
237    MostRecent,
238}
239
240#[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, EnumIter)]
241pub enum Shape {
242    #[default]
243    Circle,
244    RoundedRectangle,
245}
246
247#[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, EnumIter)]
248pub enum DisclosureControlVisibility {
249    #[default]
250    OnHover,
251    Always,
252}
253
254#[derive(Default, PartialEq, Copy, Clone, EnumIter, strum::Display)]
255pub enum InteractionState {
256    #[default]
257    Enabled,
258    Hovered,
259    Active,
260    Focused,
261    Disabled,
262}
263
264impl InteractionState {
265    pub fn if_enabled(&self, enabled: bool) -> Self {
266        if enabled {
267            *self
268        } else {
269            InteractionState::Disabled
270        }
271    }
272}
273
274#[derive(Default, PartialEq)]
275pub enum SelectedState {
276    #[default]
277    Unselected,
278    PartiallySelected,
279    Selected,
280}
281
282#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
283pub enum Toggleable {
284    Toggleable(ToggleState),
285    #[default]
286    NotToggleable,
287}
288
289impl Toggleable {
290    pub fn is_toggled(&self) -> bool {
291        match self {
292            Self::Toggleable(ToggleState::Toggled) => true,
293            _ => false,
294        }
295    }
296}
297
298impl From<ToggleState> for Toggleable {
299    fn from(state: ToggleState) -> Self {
300        Self::Toggleable(state)
301    }
302}
303
304#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
305pub enum ToggleState {
306    /// The "on" state of a toggleable element.
307    ///
308    /// Example:
309    ///     - A collasable list that is currently expanded
310    ///     - A toggle button that is currently on.
311    Toggled,
312    /// The "off" state of a toggleable element.
313    ///
314    /// Example:
315    ///     - A collasable list that is currently collapsed
316    ///     - A toggle button that is currently off.
317    #[default]
318    NotToggled,
319}
320
321impl From<Toggleable> for ToggleState {
322    fn from(toggleable: Toggleable) -> Self {
323        match toggleable {
324            Toggleable::Toggleable(state) => state,
325            Toggleable::NotToggleable => ToggleState::NotToggled,
326        }
327    }
328}
329
330impl From<bool> for ToggleState {
331    fn from(toggled: bool) -> Self {
332        if toggled {
333            ToggleState::Toggled
334        } else {
335            ToggleState::NotToggled
336        }
337    }
338}