#![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(), }); } } }}
#![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(),
});
}
}
}
}