scale.rs

  1use gpui::{AppContext, Hsla, SharedString};
  2
  3use crate::{ActiveTheme, Appearance};
  4
  5/// A one-based step in a [`ColorScale`].
  6#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
  7pub struct ColorScaleStep(usize);
  8
  9impl ColorScaleStep {
 10    /// The first step in a [`ColorScale`].
 11    pub const ONE: Self = Self(1);
 12
 13    /// The second step in a [`ColorScale`].
 14    pub const TWO: Self = Self(2);
 15
 16    /// The third step in a [`ColorScale`].
 17    pub const THREE: Self = Self(3);
 18
 19    /// The fourth step in a [`ColorScale`].
 20    pub const FOUR: Self = Self(4);
 21
 22    /// The fifth step in a [`ColorScale`].
 23    pub const FIVE: Self = Self(5);
 24
 25    /// The sixth step in a [`ColorScale`].
 26    pub const SIX: Self = Self(6);
 27
 28    /// The seventh step in a [`ColorScale`].
 29    pub const SEVEN: Self = Self(7);
 30
 31    /// The eighth step in a [`ColorScale`].
 32    pub const EIGHT: Self = Self(8);
 33
 34    /// The ninth step in a [`ColorScale`].
 35    pub const NINE: Self = Self(9);
 36
 37    /// The tenth step in a [`ColorScale`].
 38    pub const TEN: Self = Self(10);
 39
 40    /// The eleventh step in a [`ColorScale`].
 41    pub const ELEVEN: Self = Self(11);
 42
 43    /// The twelfth step in a [`ColorScale`].
 44    pub const TWELVE: Self = Self(12);
 45
 46    /// All of the steps in a [`ColorScale`].
 47    pub const ALL: [ColorScaleStep; 12] = [
 48        Self::ONE,
 49        Self::TWO,
 50        Self::THREE,
 51        Self::FOUR,
 52        Self::FIVE,
 53        Self::SIX,
 54        Self::SEVEN,
 55        Self::EIGHT,
 56        Self::NINE,
 57        Self::TEN,
 58        Self::ELEVEN,
 59        Self::TWELVE,
 60    ];
 61}
 62
 63pub struct ColorScale(Vec<Hsla>);
 64
 65impl FromIterator<Hsla> for ColorScale {
 66    fn from_iter<T: IntoIterator<Item = Hsla>>(iter: T) -> Self {
 67        Self(Vec::from_iter(iter))
 68    }
 69}
 70
 71impl ColorScale {
 72    /// Returns the specified step in the [`ColorScale`].
 73    #[inline]
 74    pub fn step(&self, step: ColorScaleStep) -> Hsla {
 75        // Steps are one-based, so we need convert to the zero-based vec index.
 76        self.0[step.0 - 1]
 77    }
 78
 79    /// Returns the first step in the [`ColorScale`].
 80    #[inline]
 81    pub fn step_1(&self) -> Hsla {
 82        self.step(ColorScaleStep::ONE)
 83    }
 84
 85    /// Returns the second step in the [`ColorScale`].
 86    #[inline]
 87    pub fn step_2(&self) -> Hsla {
 88        self.step(ColorScaleStep::TWO)
 89    }
 90
 91    /// Returns the third step in the [`ColorScale`].
 92    #[inline]
 93    pub fn step_3(&self) -> Hsla {
 94        self.step(ColorScaleStep::THREE)
 95    }
 96
 97    /// Returns the fourth step in the [`ColorScale`].
 98    #[inline]
 99    pub fn step_4(&self) -> Hsla {
100        self.step(ColorScaleStep::FOUR)
101    }
102
103    /// Returns the fifth step in the [`ColorScale`].
104    #[inline]
105    pub fn step_5(&self) -> Hsla {
106        self.step(ColorScaleStep::FIVE)
107    }
108
109    /// Returns the sixth step in the [`ColorScale`].
110    #[inline]
111    pub fn step_6(&self) -> Hsla {
112        self.step(ColorScaleStep::SIX)
113    }
114
115    /// Returns the seventh step in the [`ColorScale`].
116    #[inline]
117    pub fn step_7(&self) -> Hsla {
118        self.step(ColorScaleStep::SEVEN)
119    }
120
121    /// Returns the eighth step in the [`ColorScale`].
122    #[inline]
123    pub fn step_8(&self) -> Hsla {
124        self.step(ColorScaleStep::EIGHT)
125    }
126
127    /// Returns the ninth step in the [`ColorScale`].
128    #[inline]
129    pub fn step_9(&self) -> Hsla {
130        self.step(ColorScaleStep::NINE)
131    }
132
133    /// Returns the tenth step in the [`ColorScale`].
134    #[inline]
135    pub fn step_10(&self) -> Hsla {
136        self.step(ColorScaleStep::TEN)
137    }
138
139    /// Returns the eleventh step in the [`ColorScale`].
140    #[inline]
141    pub fn step_11(&self) -> Hsla {
142        self.step(ColorScaleStep::ELEVEN)
143    }
144
145    /// Returns the twelfth step in the [`ColorScale`].
146    #[inline]
147    pub fn step_12(&self) -> Hsla {
148        self.step(ColorScaleStep::TWELVE)
149    }
150}
151
152pub struct ColorScales {
153    pub gray: ColorScaleSet,
154    pub mauve: ColorScaleSet,
155    pub slate: ColorScaleSet,
156    pub sage: ColorScaleSet,
157    pub olive: ColorScaleSet,
158    pub sand: ColorScaleSet,
159    pub gold: ColorScaleSet,
160    pub bronze: ColorScaleSet,
161    pub brown: ColorScaleSet,
162    pub yellow: ColorScaleSet,
163    pub amber: ColorScaleSet,
164    pub orange: ColorScaleSet,
165    pub tomato: ColorScaleSet,
166    pub red: ColorScaleSet,
167    pub ruby: ColorScaleSet,
168    pub crimson: ColorScaleSet,
169    pub pink: ColorScaleSet,
170    pub plum: ColorScaleSet,
171    pub purple: ColorScaleSet,
172    pub violet: ColorScaleSet,
173    pub iris: ColorScaleSet,
174    pub indigo: ColorScaleSet,
175    pub blue: ColorScaleSet,
176    pub cyan: ColorScaleSet,
177    pub teal: ColorScaleSet,
178    pub jade: ColorScaleSet,
179    pub green: ColorScaleSet,
180    pub grass: ColorScaleSet,
181    pub lime: ColorScaleSet,
182    pub mint: ColorScaleSet,
183    pub sky: ColorScaleSet,
184    pub black: ColorScaleSet,
185    pub white: ColorScaleSet,
186}
187
188impl IntoIterator for ColorScales {
189    type Item = ColorScaleSet;
190
191    type IntoIter = std::vec::IntoIter<Self::Item>;
192
193    fn into_iter(self) -> Self::IntoIter {
194        vec![
195            self.gray,
196            self.mauve,
197            self.slate,
198            self.sage,
199            self.olive,
200            self.sand,
201            self.gold,
202            self.bronze,
203            self.brown,
204            self.yellow,
205            self.amber,
206            self.orange,
207            self.tomato,
208            self.red,
209            self.ruby,
210            self.crimson,
211            self.pink,
212            self.plum,
213            self.purple,
214            self.violet,
215            self.iris,
216            self.indigo,
217            self.blue,
218            self.cyan,
219            self.teal,
220            self.jade,
221            self.green,
222            self.grass,
223            self.lime,
224            self.mint,
225            self.sky,
226            self.black,
227            self.white,
228        ]
229        .into_iter()
230    }
231}
232
233pub struct ColorScaleSet {
234    name: SharedString,
235    light: ColorScale,
236    dark: ColorScale,
237    light_alpha: ColorScale,
238    dark_alpha: ColorScale,
239}
240
241impl ColorScaleSet {
242    pub fn new(
243        name: impl Into<SharedString>,
244        light: ColorScale,
245        light_alpha: ColorScale,
246        dark: ColorScale,
247        dark_alpha: ColorScale,
248    ) -> Self {
249        Self {
250            name: name.into(),
251            light,
252            light_alpha,
253            dark,
254            dark_alpha,
255        }
256    }
257
258    pub fn name(&self) -> &SharedString {
259        &self.name
260    }
261
262    pub fn light(&self) -> &ColorScale {
263        &self.light
264    }
265
266    pub fn light_alpha(&self) -> &ColorScale {
267        &self.light_alpha
268    }
269
270    pub fn dark(&self) -> &ColorScale {
271        &self.dark
272    }
273
274    pub fn dark_alpha(&self) -> &ColorScale {
275        &self.dark_alpha
276    }
277
278    pub fn step(&self, cx: &AppContext, step: ColorScaleStep) -> Hsla {
279        match cx.theme().appearance {
280            Appearance::Light => self.light().step(step),
281            Appearance::Dark => self.dark().step(step),
282        }
283    }
284
285    pub fn step_alpha(&self, cx: &AppContext, step: ColorScaleStep) -> Hsla {
286        match cx.theme().appearance {
287            Appearance::Light => self.light_alpha.step(step),
288            Appearance::Dark => self.dark_alpha.step(step),
289        }
290    }
291}