scale.rs

  1use gpui2::{AppContext, Hsla};
  2use indexmap::IndexMap;
  3
  4use crate::{theme, Appearance};
  5
  6#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
  7pub enum ColorScaleName {
  8    Gray,
  9    Mauve,
 10    Slate,
 11    Sage,
 12    Olive,
 13    Sand,
 14    Gold,
 15    Bronze,
 16    Brown,
 17    Yellow,
 18    Amber,
 19    Orange,
 20    Tomato,
 21    Red,
 22    Ruby,
 23    Crimson,
 24    Pink,
 25    Plum,
 26    Purple,
 27    Violet,
 28    Iris,
 29    Indigo,
 30    Blue,
 31    Cyan,
 32    Teal,
 33    Jade,
 34    Green,
 35    Grass,
 36    Lime,
 37    Mint,
 38    Sky,
 39    Black,
 40    White,
 41}
 42
 43impl std::fmt::Display for ColorScaleName {
 44    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 45        write!(
 46            f,
 47            "{}",
 48            match self {
 49                Self::Gray => "Gray",
 50                Self::Mauve => "Mauve",
 51                Self::Slate => "Slate",
 52                Self::Sage => "Sage",
 53                Self::Olive => "Olive",
 54                Self::Sand => "Sand",
 55                Self::Gold => "Gold",
 56                Self::Bronze => "Bronze",
 57                Self::Brown => "Brown",
 58                Self::Yellow => "Yellow",
 59                Self::Amber => "Amber",
 60                Self::Orange => "Orange",
 61                Self::Tomato => "Tomato",
 62                Self::Red => "Red",
 63                Self::Ruby => "Ruby",
 64                Self::Crimson => "Crimson",
 65                Self::Pink => "Pink",
 66                Self::Plum => "Plum",
 67                Self::Purple => "Purple",
 68                Self::Violet => "Violet",
 69                Self::Iris => "Iris",
 70                Self::Indigo => "Indigo",
 71                Self::Blue => "Blue",
 72                Self::Cyan => "Cyan",
 73                Self::Teal => "Teal",
 74                Self::Jade => "Jade",
 75                Self::Green => "Green",
 76                Self::Grass => "Grass",
 77                Self::Lime => "Lime",
 78                Self::Mint => "Mint",
 79                Self::Sky => "Sky",
 80                Self::Black => "Black",
 81                Self::White => "White",
 82            }
 83        )
 84    }
 85}
 86
 87pub type ColorScale = [Hsla; 12];
 88
 89pub type ColorScales = IndexMap<ColorScaleName, ColorScaleSet>;
 90
 91/// A one-based step in a [`ColorScale`].
 92pub type ColorScaleStep = usize;
 93
 94pub struct ColorScaleSet {
 95    name: ColorScaleName,
 96    light: ColorScale,
 97    dark: ColorScale,
 98    light_alpha: ColorScale,
 99    dark_alpha: ColorScale,
100}
101
102impl ColorScaleSet {
103    pub fn new(
104        name: ColorScaleName,
105        light: ColorScale,
106        light_alpha: ColorScale,
107        dark: ColorScale,
108        dark_alpha: ColorScale,
109    ) -> Self {
110        Self {
111            name,
112            light,
113            light_alpha,
114            dark,
115            dark_alpha,
116        }
117    }
118
119    pub fn name(&self) -> String {
120        self.name.to_string()
121    }
122
123    pub fn light(&self, step: ColorScaleStep) -> Hsla {
124        self.light[step - 1]
125    }
126
127    pub fn light_alpha(&self, step: ColorScaleStep) -> Hsla {
128        self.light_alpha[step - 1]
129    }
130
131    pub fn dark(&self, step: ColorScaleStep) -> Hsla {
132        self.dark[step - 1]
133    }
134
135    pub fn dark_alpha(&self, step: ColorScaleStep) -> Hsla {
136        self.dark_alpha[step - 1]
137    }
138
139    fn current_appearance(cx: &AppContext) -> Appearance {
140        let theme = theme(cx);
141        if theme.metadata.is_light {
142            Appearance::Light
143        } else {
144            Appearance::Dark
145        }
146    }
147
148    pub fn step(&self, cx: &AppContext, step: ColorScaleStep) -> Hsla {
149        let appearance = Self::current_appearance(cx);
150
151        match appearance {
152            Appearance::Light => self.light(step),
153            Appearance::Dark => self.dark(step),
154        }
155    }
156
157    pub fn step_alpha(&self, cx: &AppContext, step: ColorScaleStep) -> Hsla {
158        let appearance = Self::current_appearance(cx);
159        match appearance {
160            Appearance::Light => self.light_alpha(step),
161            Appearance::Dark => self.dark_alpha(step),
162        }
163    }
164}