1use gpui::Hsla;
2
3use crate::{amber, blue, jade, lime, orange, pink, purple, red};
4
5#[derive(Debug, Clone, Copy, Default)]
6pub struct PlayerColor {
7 pub cursor: Hsla,
8 pub background: Hsla,
9 pub selection: Hsla,
10}
11
12/// A collection of colors that are used to color players in the editor.
13///
14/// The first color is always the local player's color, usually a blue.
15///
16/// The rest of the default colors crisscross back and forth on the
17/// color wheel so that the colors are as distinct as possible.
18#[derive(Clone)]
19pub struct PlayerColors(pub Vec<PlayerColor>);
20
21impl Default for PlayerColors {
22 /// Don't use this!
23 /// We have to have a default to be `[refineable::Refinable]`.
24 /// todo!("Find a way to not need this for Refinable")
25 fn default() -> Self {
26 Self::dark()
27 }
28}
29
30impl PlayerColors {
31 pub fn dark() -> Self {
32 Self(vec![
33 PlayerColor {
34 cursor: blue().dark().step_9(),
35 background: blue().dark().step_5(),
36 selection: blue().dark().step_3(),
37 },
38 PlayerColor {
39 cursor: orange().dark().step_9(),
40 background: orange().dark().step_5(),
41 selection: orange().dark().step_3(),
42 },
43 PlayerColor {
44 cursor: pink().dark().step_9(),
45 background: pink().dark().step_5(),
46 selection: pink().dark().step_3(),
47 },
48 PlayerColor {
49 cursor: lime().dark().step_9(),
50 background: lime().dark().step_5(),
51 selection: lime().dark().step_3(),
52 },
53 PlayerColor {
54 cursor: purple().dark().step_9(),
55 background: purple().dark().step_5(),
56 selection: purple().dark().step_3(),
57 },
58 PlayerColor {
59 cursor: amber().dark().step_9(),
60 background: amber().dark().step_5(),
61 selection: amber().dark().step_3(),
62 },
63 PlayerColor {
64 cursor: jade().dark().step_9(),
65 background: jade().dark().step_5(),
66 selection: jade().dark().step_3(),
67 },
68 PlayerColor {
69 cursor: red().dark().step_9(),
70 background: red().dark().step_5(),
71 selection: red().dark().step_3(),
72 },
73 ])
74 }
75
76 pub fn light() -> Self {
77 Self(vec![
78 PlayerColor {
79 cursor: blue().light().step_9(),
80 background: blue().light().step_4(),
81 selection: blue().light().step_3(),
82 },
83 PlayerColor {
84 cursor: orange().light().step_9(),
85 background: orange().light().step_4(),
86 selection: orange().light().step_3(),
87 },
88 PlayerColor {
89 cursor: pink().light().step_9(),
90 background: pink().light().step_4(),
91 selection: pink().light().step_3(),
92 },
93 PlayerColor {
94 cursor: lime().light().step_9(),
95 background: lime().light().step_4(),
96 selection: lime().light().step_3(),
97 },
98 PlayerColor {
99 cursor: purple().light().step_9(),
100 background: purple().light().step_4(),
101 selection: purple().light().step_3(),
102 },
103 PlayerColor {
104 cursor: amber().light().step_9(),
105 background: amber().light().step_4(),
106 selection: amber().light().step_3(),
107 },
108 PlayerColor {
109 cursor: jade().light().step_9(),
110 background: jade().light().step_4(),
111 selection: jade().light().step_3(),
112 },
113 PlayerColor {
114 cursor: red().light().step_9(),
115 background: red().light().step_4(),
116 selection: red().light().step_3(),
117 },
118 ])
119 }
120}
121
122impl PlayerColors {
123 pub fn local(&self) -> PlayerColor {
124 // todo!("use a valid color");
125 *self.0.first().unwrap()
126 }
127
128 pub fn absent(&self) -> PlayerColor {
129 // todo!("use a valid color");
130 *self.0.last().unwrap()
131 }
132
133 pub fn color_for_participant(&self, participant_index: u32) -> PlayerColor {
134 let len = self.0.len() - 1;
135 self.0[(participant_index as usize % len) + 1]
136 }
137}