From 7841a56a11bde8ef72bdcacbfae1b80ade1b3a20 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Mon, 30 Oct 2023 16:21:59 -0400 Subject: [PATCH] Start work on defining color scales --- crates/theme2/src/default.rs | 101 +++++++++++++++++++++ crates/theme2/src/scale.rs | 166 +++++++++++++++++++++++++++++++++++ crates/theme2/src/theme2.rs | 8 ++ 3 files changed, 275 insertions(+) create mode 100644 crates/theme2/src/default.rs create mode 100644 crates/theme2/src/scale.rs diff --git a/crates/theme2/src/default.rs b/crates/theme2/src/default.rs new file mode 100644 index 0000000000..d1550f9e78 --- /dev/null +++ b/crates/theme2/src/default.rs @@ -0,0 +1,101 @@ +use std::collections::HashMap; + +use gpui2::Rgba; + +use crate::scale::{ColorScaleName, ColorScaleSet, ColorScales}; + +struct DefaultColorScaleSet { + scale: ColorScaleName, + light: [&'static str; 12], + light_alpha: [&'static str; 12], + dark: [&'static str; 12], + dark_alpha: [&'static str; 12], +} + +impl From for ColorScaleSet { + fn from(default: DefaultColorScaleSet) -> Self { + Self::new( + default.scale, + default + .light + .map(|color| Rgba::try_from(color).unwrap().into()), + default + .light_alpha + .map(|color| Rgba::try_from(color).unwrap().into()), + default + .dark + .map(|color| Rgba::try_from(color).unwrap().into()), + default + .dark_alpha + .map(|color| Rgba::try_from(color).unwrap().into()), + ) + } +} + +pub fn default_color_scales() -> ColorScales { + use ColorScaleName::*; + + HashMap::from_iter([(Red, red().into())]) +} + +fn red() -> DefaultColorScaleSet { + DefaultColorScaleSet { + scale: ColorScaleName::Red, + light: [ + "#fffcfc00", + "#fff7f700", + "#feebec00", + "#ffdbdc00", + "#ffcdce00", + "#fdbdbe00", + "#f4a9aa00", + "#eb8e9000", + "#e5484d00", + "#dc3e4200", + "#ce2c3100", + "#64172300", + ], + light_alpha: [ + "#ff000003", + "#ff000008", + "#f3000d14", + "#ff000824", + "#ff000632", + "#f8000442", + "#df000356", + "#d2000571", + "#db0007b7", + "#d10005c1", + "#c40006d3", + "#55000de8", + ], + dark: [ + "#19111100", + "#20131400", + "#3b121900", + "#500f1c00", + "#61162300", + "#72232d00", + "#8c333a00", + "#b5454800", + "#e5484d00", + "#ec5d5e00", + "#ff959200", + "#ffd1d900", + ], + dark_alpha: [ + "#f4121209", + "#f22f3e11", + "#ff173f2d", + "#fe0a3b44", + "#ff204756", + "#ff3e5668", + "#ff536184", + "#ff5d61b0", + "#fe4e54e4", + "#ff6465eb", + "#ff959200", + "#ffd1d900", + ], + } +} diff --git a/crates/theme2/src/scale.rs b/crates/theme2/src/scale.rs new file mode 100644 index 0000000000..a7bd6a5e22 --- /dev/null +++ b/crates/theme2/src/scale.rs @@ -0,0 +1,166 @@ +use std::collections::HashMap; + +use gpui2::{AppContext, Hsla}; + +use crate::{theme, Appearance}; + +#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub enum ColorScaleName { + Gray, + Mauve, + Slate, + Sage, + Olive, + Sand, + Gold, + Bronze, + Brown, + Yellow, + Amber, + Orange, + Tomato, + Red, + Ruby, + Crimson, + Pink, + Plum, + Purple, + Violet, + Iris, + Indigo, + Blue, + Cyan, + Teal, + Jade, + Green, + Grass, + Lime, + Mint, + Sky, + Black, + White, +} + +impl std::fmt::Display for ColorScaleName { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "{}", + match self { + Self::Gray => "Gray", + Self::Mauve => "Mauve", + Self::Slate => "Slate", + Self::Sage => "Sage", + Self::Olive => "Olive", + Self::Sand => "Sand", + Self::Gold => "Gold", + Self::Bronze => "Bronze", + Self::Brown => "Brown", + Self::Yellow => "Yellow", + Self::Amber => "Amber", + Self::Orange => "Orange", + Self::Tomato => "Tomato", + Self::Red => "Red", + Self::Ruby => "Ruby", + Self::Crimson => "Crimson", + Self::Pink => "Pink", + Self::Plum => "Plum", + Self::Purple => "Purple", + Self::Violet => "Violet", + Self::Iris => "Iris", + Self::Indigo => "Indigo", + Self::Blue => "Blue", + Self::Cyan => "Cyan", + Self::Teal => "Teal", + Self::Jade => "Jade", + Self::Green => "Green", + Self::Grass => "Grass", + Self::Lime => "Lime", + Self::Mint => "Mint", + Self::Sky => "Sky", + Self::Black => "Black", + Self::White => "White", + } + ) + } +} + +pub type ColorScale = [Hsla; 12]; + +pub type ColorScales = HashMap; + +pub struct ColorScaleSet { + name: ColorScaleName, + light: ColorScale, + dark: ColorScale, + light_alpha: ColorScale, + dark_alpha: ColorScale, +} + +impl ColorScaleSet { + pub fn new( + name: ColorScaleName, + light: ColorScale, + light_alpha: ColorScale, + dark: ColorScale, + dark_alpha: ColorScale, + ) -> Self { + Self { + name, + light, + light_alpha, + dark, + dark_alpha, + } + } + + pub fn name(&self) -> String { + self.name.to_string() + } + + pub fn light(&self, step: usize) -> Hsla { + self.light[step - 1] + } + + pub fn light_alpha(&self, step: usize) -> Hsla { + self.light_alpha[step - 1] + } + + pub fn dark(&self, step: usize) -> Hsla { + self.dark[step - 1] + } + + pub fn dark_alpha(&self, step: usize) -> Hsla { + self.dark[step - 1] + } + + fn current_appearance(cx: &AppContext) -> Appearance { + let theme = theme(cx); + if theme.metadata.is_light { + Appearance::Light + } else { + Appearance::Dark + } + } + + /// Returns the one-based step in the scale. + /// + /// We usually reference steps as 1-12 instead of 0-11, so we + /// automatically subtract 1 from the index. + pub fn step(self, cx: &AppContext, index: usize) -> Hsla { + let appearance = Self::current_appearance(cx); + + match appearance { + Appearance::Light => self.light(index), + Appearance::Dark => self.dark(index), + } + } + + pub fn step_alpha(self, cx: &AppContext, index: usize) -> Hsla { + let appearance = Self::current_appearance(cx); + match appearance { + Appearance::Light => self.light_alpha(index), + Appearance::Dark => self.dark_alpha(index), + } + } +} diff --git a/crates/theme2/src/theme2.rs b/crates/theme2/src/theme2.rs index 6d4d5269e3..66d70296d2 100644 --- a/crates/theme2/src/theme2.rs +++ b/crates/theme2/src/theme2.rs @@ -1,4 +1,6 @@ +mod default; mod registry; +mod scale; mod settings; mod themes; @@ -9,6 +11,12 @@ use gpui2::{AppContext, HighlightStyle, Hsla, SharedString}; use settings2::Settings; use std::sync::Arc; +#[derive(Debug, Clone, PartialEq)] +pub enum Appearance { + Light, + Dark, +} + pub fn init(cx: &mut AppContext) { cx.set_global(ThemeRegistry::default()); ThemeSettings::register(cx);