scale.rs

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