diff --git a/crates/theme2/src/theme2.rs b/crates/theme2/src/theme2.rs index 7b60802e75..9b9d2678c5 100644 --- a/crates/theme2/src/theme2.rs +++ b/crates/theme2/src/theme2.rs @@ -6,6 +6,8 @@ mod registry; mod scale; mod settings; mod styles; +mod theme3; +mod theme3_ayu; #[cfg(not(feature = "importing-themes"))] mod themes; mod user_theme; diff --git a/crates/theme2/src/theme3.rs b/crates/theme2/src/theme3.rs new file mode 100644 index 0000000000..9e93cfb816 --- /dev/null +++ b/crates/theme2/src/theme3.rs @@ -0,0 +1,216 @@ +use gpui::{hsla, rgba, HighlightStyle, Hsla, SharedString}; + +/// Turn a hex string into an Hsla color +/// Accepts 3, 4, 6, or 8 digit hex strings +/// +/// # Examples +/// ``` +/// use gpui::Hsla; +/// use theme3::hex; +/// +/// assert_eq!(hex("000"), Hsla::new(0.0, 0.0, 0.0, 1.0)); +/// assert_eq!(hex("0000"), Hsla::new(0.0, 0.0, 0.0, 0.0)); +/// assert_eq!(hex("000000"), Hsla::new(0.0, 0.0, 0.0, 1.0)); +/// assert_eq!(hex("00000000"), Hsla::new(0.0, 0.0, 0.0, 0.0)); +/// ``` +pub fn hex(s: &str) -> Hsla { + let mut hex = s.to_string(); + + if hex.starts_with('#') { + hex = hex[1..].to_string(); + } + + if hex.len() == 3 { + let mut new_hex = String::with_capacity(6); + for c in hex.chars() { + new_hex.push(c); + new_hex.push(c); + } + hex = hex; + } + + if hex.len() == 4 { + let mut new_hex = String::with_capacity(8); + for c in hex.chars() { + new_hex.push(c); + new_hex.push(c); + } + hex = hex; + } + + if hex.len() == 6 { + hex = format!("{}{}", s, "ff"); + } + + if s.len() == 8 { + hex = s.to_string(); + } + + let hex = u32::from_str_radix(&hex, 16).unwrap(); + + rgba(hex).into() +} + +#[derive(Debug, PartialEq, Clone, Copy)] +pub enum Appearance { + Light, + Dark, +} + +impl From for Appearance { + fn from(s: String) -> Self { + match s.to_lowercase().as_str() { + "light" => Self::Light, + "dark" => Self::Dark, + _ => Self::Light, + } + } +} + +impl Appearance { + pub fn is_light(&self) -> bool { + match self { + Self::Light => true, + Self::Dark => false, + } + } +} + +pub struct ThemeFamily { + pub id: String, + pub name: SharedString, + pub author: SharedString, + pub themes: Vec, +} + +impl ThemeFamily {} + +pub struct Theme { + pub id: String, + pub name: SharedString, + pub appearance: Appearance, + pub styles: ThemeStyles, +} + +#[derive(Debug, Clone, Copy, Default)] +pub struct PlayerColor { + pub cursor: Hsla, + pub background: Hsla, + pub selection: Hsla, +} + +impl From for PlayerColor { + fn from(color: Hsla) -> Self { + Self { + cursor: color, + background: ColorTools::alpha_color(color, 0.2), + selection: ColorTools::alpha_color(color, 0.12), + } + } +} + +pub struct ColorTools {} + +impl ColorTools { + pub fn alpha_color(color: Hsla, alpha: f32) -> Hsla { + hsla(color.h, color.s, color.l, alpha) + } +} + +#[derive(Clone, Debug)] +pub struct ThemeStyles { + pub background: Hsla, + pub background_selected: Hsla, + pub background_variant: Hsla, + pub border: Hsla, + pub border_selected: Hsla, + pub border_variant: Hsla, + pub button_background: Hsla, + pub drag_target_background: Hsla, + pub editor_active_line_background: Hsla, + pub editor_active_line_number: Hsla, + pub editor_active_wrap_guide: Hsla, + pub editor_background: Hsla, + pub editor_document_highlight_read_background: Hsla, + pub editor_document_highlight_write_background: Hsla, + pub editor_foreground: Hsla, + pub editor_gutter_background: Hsla, + pub editor_highlighted_line_background: Hsla, + pub editor_invisible: Hsla, + pub editor_line_number: Hsla, + pub editor_occurrence: Hsla, + pub editor_predictive: Hsla, + pub editor_subheader_background: Hsla, + pub editor_unreachable: Hsla, + pub editor_wrap_guide: Hsla, + pub foreground: Hsla, + pub foreground_accent: Hsla, + pub foreground_placeholder: Hsla, + pub foreground_selected: Hsla, + pub foreground_variant: Hsla, + pub highlights: Vec<(String, HighlightStyle)>, + pub input_background: Hsla, + pub input_border: Hsla, + pub modal_background: Hsla, + pub pane_background: Hsla, + pub pane_focused_border: Hsla, + pub panel_background: Hsla, + pub panel_button: Hsla, + pub panel_focused_border: Hsla, + pub player_host: PlayerColor, + pub players: Vec, + pub popover_background: Hsla, + pub popover_border: Hsla, + pub scrollbar_thumb: Hsla, + pub scrollbar_thumb_border: Hsla, + pub scrollbar_track_background: Hsla, + pub scrollbar_track_border: Hsla, + pub search_match: Hsla, + pub shadow: PlayerColor, + pub state_focused: Hsla, + pub state_selected: Hsla, + pub status_bar_background: Hsla, + pub status_conflict: Hsla, + pub status_created: Hsla, + pub status_deleted: Hsla, + pub status_error: Hsla, + pub status_hidden: Hsla, + pub status_hint: Hsla, + pub status_ignored: Hsla, + pub status_info: Hsla, + pub status_modified: Hsla, + pub status_renamed: Hsla, + pub status_success: Hsla, + pub status_warning: Hsla, + pub tab_active_background: Hsla, + pub tab_bar_background: Hsla, + pub tab_inactive_background: Hsla, + pub terminal: TerminalColors, + pub title_bar_background: Hsla, + pub title_bar_button: Hsla, + pub toolbar_background: Hsla, + pub toolbar_button: Hsla, +} + +#[derive(Clone, Debug)] +pub struct TerminalColors { + pub background: Hsla, + pub foreground: Hsla, + pub cursor: Hsla, + pub ansi_bright_black: Hsla, + pub ansi_bright_red: Hsla, + pub ansi_bright_green: Hsla, + pub ansi_bright_yellow: Hsla, + pub ansi_bright_blue: Hsla, + pub ansi_bright_magenta: Hsla, + pub ansi_bright_cyan: Hsla, + pub ansi_bright_white: Hsla, + pub ansi_black: Hsla, + pub ansi_red: Hsla, + pub ansi_green: Hsla, + pub ansi_yellow: Hsla, + pub ansi_blue: Hsla, + pub ansi_magenta: Hsla, + pub ansi_cyan: Hsla, + pub ansi_white: Hsla, +} diff --git a/crates/theme2/src/theme3_ayu.rs b/crates/theme2/src/theme3_ayu.rs new file mode 100644 index 0000000000..d661c4bd45 --- /dev/null +++ b/crates/theme2/src/theme3_ayu.rs @@ -0,0 +1,95 @@ +use crate::theme3::{hex, TerminalColors, Theme, ThemeFamily, ThemeStyles}; + +pub fn ayu_family() -> ThemeFamily { + ThemeFamily { + id: "ayu_family".to_string(), + name: "Ayu".into(), + author: "dempfi".into(), + themes: vec![ + // ayu_light(), + ayu_mirage(), + // ayu_dark(), + ], + } +} + +fn ayu_mirage() -> Theme { + Theme { + id: "ayu_mirage".to_string(), + name: "Ayu Mirage".into(), + appearance: "Dark".to_string().into(), + styles: ThemeStyles { + background: todo!(), + background_selected: todo!(), + background_variant: todo!(), + border: todo!(), + border_selected: todo!(), + border_variant: todo!(), + button_background: todo!(), + drag_target_background: todo!(), + editor_active_line_background: todo!(), + editor_active_line_number: todo!(), + editor_active_wrap_guide: todo!(), + editor_background: todo!(), + editor_document_highlight_read_background: todo!(), + editor_document_highlight_write_background: todo!(), + editor_foreground: todo!(), + editor_gutter_background: todo!(), + editor_highlighted_line_background: todo!(), + editor_invisible: todo!(), + editor_line_number: todo!(), + editor_occurrence: todo!(), + editor_predictive: todo!(), + editor_subheader_background: todo!(), + editor_unreachable: todo!(), + editor_wrap_guide: todo!(), + foreground: todo!(), + foreground_accent: todo!(), + foreground_placeholder: todo!(), + foreground_selected: todo!(), + foreground_variant: todo!(), + highlights: todo!(), + input_background: todo!(), + input_border: todo!(), + modal_background: todo!(), + pane_background: todo!(), + pane_focused_border: todo!(), + panel_background: todo!(), + panel_button: todo!(), + panel_focused_border: todo!(), + player_host: todo!(), + players: todo!(), + popover_background: todo!(), + popover_border: todo!(), + scrollbar_thumb: todo!(), + scrollbar_thumb_border: todo!(), + scrollbar_track_background: todo!(), + scrollbar_track_border: todo!(), + search_match: todo!(), + shadow: todo!(), + state_focused: todo!(), + state_selected: todo!(), + status_bar_background: todo!(), + status_conflict: todo!(), + status_created: todo!(), + status_deleted: todo!(), + status_error: todo!(), + status_hidden: todo!(), + status_hint: todo!(), + status_ignored: todo!(), + status_info: todo!(), + status_modified: todo!(), + status_renamed: todo!(), + status_success: todo!(), + status_warning: todo!(), + tab_active_background: todo!(), + tab_bar_background: todo!(), + tab_inactive_background: todo!(), + terminal: todo!(), + title_bar_background: todo!(), + title_bar_button: todo!(), + toolbar_background: todo!(), + toolbar_button: todo!(), + }, + } +}