185 lines · 6.1 KB · Rust
RawDownload
#![allow(missing_docs)] use gpui::Hsla;use serde_derive::Deserialize; use crate::{    amber, blue, jade, lime, orange, pink, purple, red, try_parse_color, PlayerColorContent,}; #[derive(Debug, Clone, Copy, Deserialize, Default, PartialEq)]pub struct PlayerColor {    pub cursor: Hsla,    pub background: Hsla,    pub selection: Hsla,} /// A collection of colors that are used to color players in the editor.////// The first color is always the local player's color, usually a blue.////// The rest of the default colors crisscross back and forth on the/// color wheel so that the colors are as distinct as possible.#[derive(Clone, Deserialize, PartialEq)]pub struct PlayerColors(pub Vec<PlayerColor>); impl Default for PlayerColors {    /// Don't use this!    /// We have to have a default to be `[refineable::Refinable]`.    /// TODO "Find a way to not need this for Refinable"    fn default() -> Self {        Self::dark()    }} impl PlayerColors {    pub fn dark() -> Self {        Self(vec![            PlayerColor {                cursor: blue().dark().step_9(),                background: blue().dark().step_5(),                selection: blue().dark().step_3(),            },            PlayerColor {                cursor: orange().dark().step_9(),                background: orange().dark().step_5(),                selection: orange().dark().step_3(),            },            PlayerColor {                cursor: pink().dark().step_9(),                background: pink().dark().step_5(),                selection: pink().dark().step_3(),            },            PlayerColor {                cursor: lime().dark().step_9(),                background: lime().dark().step_5(),                selection: lime().dark().step_3(),            },            PlayerColor {                cursor: purple().dark().step_9(),                background: purple().dark().step_5(),                selection: purple().dark().step_3(),            },            PlayerColor {                cursor: amber().dark().step_9(),                background: amber().dark().step_5(),                selection: amber().dark().step_3(),            },            PlayerColor {                cursor: jade().dark().step_9(),                background: jade().dark().step_5(),                selection: jade().dark().step_3(),            },            PlayerColor {                cursor: red().dark().step_9(),                background: red().dark().step_5(),                selection: red().dark().step_3(),            },        ])    }     pub fn light() -> Self {        Self(vec![            PlayerColor {                cursor: blue().light().step_9(),                background: blue().light().step_4(),                selection: blue().light().step_3(),            },            PlayerColor {                cursor: orange().light().step_9(),                background: orange().light().step_4(),                selection: orange().light().step_3(),            },            PlayerColor {                cursor: pink().light().step_9(),                background: pink().light().step_4(),                selection: pink().light().step_3(),            },            PlayerColor {                cursor: lime().light().step_9(),                background: lime().light().step_4(),                selection: lime().light().step_3(),            },            PlayerColor {                cursor: purple().light().step_9(),                background: purple().light().step_4(),                selection: purple().light().step_3(),            },            PlayerColor {                cursor: amber().light().step_9(),                background: amber().light().step_4(),                selection: amber().light().step_3(),            },            PlayerColor {                cursor: jade().light().step_9(),                background: jade().light().step_4(),                selection: jade().light().step_3(),            },            PlayerColor {                cursor: red().light().step_9(),                background: red().light().step_4(),                selection: red().light().step_3(),            },        ])    }} impl PlayerColors {    pub fn local(&self) -> PlayerColor {        *self.0.first().unwrap()    }     pub fn absent(&self) -> PlayerColor {        *self.0.last().unwrap()    }     pub fn read_only(&self) -> PlayerColor {        let local = self.local();        PlayerColor {            cursor: local.cursor.grayscale(),            background: local.background.grayscale(),            selection: local.selection.grayscale(),        }    }     pub fn color_for_participant(&self, participant_index: u32) -> PlayerColor {        let len = self.0.len() - 1;        self.0[(participant_index as usize % len) + 1]    }     /// Merges the given player colors into this [`PlayerColors`] instance.    pub fn merge(&mut self, user_player_colors: &[PlayerColorContent]) {        if user_player_colors.is_empty() {            return;        }         for (idx, player) in user_player_colors.iter().enumerate() {            let cursor = player                .cursor                .as_ref()                .and_then(|color| try_parse_color(color).ok());            let background = player                .background                .as_ref()                .and_then(|color| try_parse_color(color).ok());            let selection = player                .selection                .as_ref()                .and_then(|color| try_parse_color(color).ok());             if let Some(player_color) = self.0.get_mut(idx) {                *player_color = PlayerColor {                    cursor: cursor.unwrap_or(player_color.cursor),                    background: background.unwrap_or(player_color.background),                    selection: selection.unwrap_or(player_color.selection),                };            } else {                self.0.push(PlayerColor {                    cursor: cursor.unwrap_or_default(),                    background: background.unwrap_or_default(),                    selection: selection.unwrap_or_default(),                });            }        }    }}