user_theme.rs

 1use crate::{
 2    Appearance, PlayerColors, StatusColors, StatusColorsRefinement, ThemeColors,
 3    ThemeColorsRefinement,
 4};
 5use gpui::{FontStyle, FontWeight, Hsla};
 6use refineable::Refineable;
 7use serde::Deserialize;
 8
 9#[derive(Deserialize)]
10pub struct UserThemeFamily {
11    pub name: String,
12    pub author: String,
13    pub themes: Vec<UserTheme>,
14}
15
16#[derive(Deserialize)]
17pub struct UserTheme {
18    pub name: String,
19    pub appearance: Appearance,
20    pub styles: UserThemeStylesRefinement,
21}
22
23#[derive(Refineable, Clone)]
24#[refineable(Deserialize)]
25pub struct UserThemeStyles {
26    #[refineable]
27    pub colors: ThemeColors,
28    #[refineable]
29    pub status: StatusColors,
30    pub player: PlayerColors,
31    pub syntax: UserSyntaxTheme,
32}
33
34#[derive(Clone, Default, Deserialize)]
35pub struct UserSyntaxTheme {
36    pub highlights: Vec<(String, UserHighlightStyle)>,
37}
38
39#[derive(Clone, Default, Deserialize)]
40pub struct UserHighlightStyle {
41    pub color: Option<Hsla>,
42    pub font_style: Option<UserFontStyle>,
43    pub font_weight: Option<UserFontWeight>,
44}
45
46#[derive(Clone, Copy, Default, Deserialize)]
47pub struct UserFontWeight(pub f32);
48
49impl UserFontWeight {
50    /// Thin weight (100), the thinnest value.
51    pub const THIN: Self = Self(FontWeight::THIN.0);
52    /// Extra light weight (200).
53    pub const EXTRA_LIGHT: Self = Self(FontWeight::EXTRA_LIGHT.0);
54    /// Light weight (300).
55    pub const LIGHT: Self = Self(FontWeight::LIGHT.0);
56    /// Normal (400).
57    pub const NORMAL: Self = Self(FontWeight::NORMAL.0);
58    /// Medium weight (500, higher than normal).
59    pub const MEDIUM: Self = Self(FontWeight::MEDIUM.0);
60    /// Semibold weight (600).
61    pub const SEMIBOLD: Self = Self(FontWeight::SEMIBOLD.0);
62    /// Bold weight (700).
63    pub const BOLD: Self = Self(FontWeight::BOLD.0);
64    /// Extra-bold weight (800).
65    pub const EXTRA_BOLD: Self = Self(FontWeight::EXTRA_BOLD.0);
66    /// Black weight (900), the thickest value.
67    pub const BLACK: Self = Self(FontWeight::BLACK.0);
68}
69
70impl From<UserFontWeight> for FontWeight {
71    fn from(value: UserFontWeight) -> Self {
72        Self(value.0)
73    }
74}
75
76#[derive(Debug, Clone, Copy, Deserialize)]
77pub enum UserFontStyle {
78    Normal,
79    Italic,
80    Oblique,
81}
82
83impl From<UserFontStyle> for FontStyle {
84    fn from(value: UserFontStyle) -> Self {
85        match value {
86            UserFontStyle::Normal => FontStyle::Normal,
87            UserFontStyle::Italic => FontStyle::Italic,
88            UserFontStyle::Oblique => FontStyle::Oblique,
89        }
90    }
91}
92
93impl UserHighlightStyle {
94    pub fn is_empty(&self) -> bool {
95        self.color.is_none() && self.font_style.is_none() && self.font_weight.is_none()
96    }
97}