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}