players.rs

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