From 18431051d9d750d9e66284a71f7a55a1e31c1374 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Wed, 1 Nov 2023 03:23:00 +0100 Subject: [PATCH] Rework `theme2` with new theme structure (#3194) This PR reworks the theme definition in the `theme2` crate to be based off of the new theme work that @iamnbutler has been working on. We're still developing the new theme system, but it is complete enough that we can now load the default theme and use it to theme the storybook (albeit with some further refining of the color palette required). --------- Co-authored-by: Nate Butler Co-authored-by: Marshall Bowers --- Cargo.lock | 1 + crates/storybook2/src/stories/colors.rs | 7 +- crates/storybook2/src/stories/focus.rs | 16 +- crates/storybook2/src/stories/scroll.rs | 10 +- crates/storybook2/src/storybook2.rs | 3 +- crates/theme2/Cargo.toml | 12 +- crates/theme2/src/colors.rs | 143 +++ .../src/{default.rs => default_colors.rs} | 838 ++++++++++++++++-- crates/theme2/src/default_theme.rs | 58 ++ crates/theme2/src/scale.rs | 193 ++-- crates/theme2/src/settings.rs | 10 +- crates/theme2/src/syntax.rs | 227 +++++ crates/theme2/src/theme2.rs | 63 +- crates/theme2/src/utils.rs | 43 + crates/ui2/src/components/breadcrumb.rs | 24 +- crates/ui2/src/components/buffer.rs | 19 +- crates/ui2/src/components/buffer_search.rs | 4 +- crates/ui2/src/components/collab_panel.rs | 30 +- crates/ui2/src/components/context_menu.rs | 6 +- crates/ui2/src/components/icon_button.rs | 14 +- crates/ui2/src/components/keybinding.rs | 6 +- crates/ui2/src/components/list.rs | 34 +- crates/ui2/src/components/modal.rs | 10 +- crates/ui2/src/components/multi_buffer.rs | 16 +- .../ui2/src/components/notification_toast.rs | 7 +- .../ui2/src/components/notifications_panel.rs | 4 +- crates/ui2/src/components/palette.rs | 16 +- crates/ui2/src/components/panel.rs | 6 +- crates/ui2/src/components/panes.rs | 4 +- crates/ui2/src/components/player_stack.rs | 4 +- crates/ui2/src/components/project_panel.rs | 4 +- crates/ui2/src/components/status_bar.rs | 4 +- crates/ui2/src/components/tab.rs | 13 +- crates/ui2/src/components/tab_bar.rs | 4 +- crates/ui2/src/components/terminal.rs | 6 +- crates/ui2/src/components/title_bar.rs | 3 +- crates/ui2/src/components/toast.rs | 4 +- crates/ui2/src/components/toolbar.rs | 14 +- crates/ui2/src/components/traffic_lights.rs | 10 +- crates/ui2/src/components/workspace.rs | 8 +- crates/ui2/src/elements/avatar.rs | 5 +- crates/ui2/src/elements/button.rs | 18 +- crates/ui2/src/elements/details.rs | 7 +- crates/ui2/src/elements/icon.rs | 13 +- crates/ui2/src/elements/input.rs | 16 +- crates/ui2/src/elements/label.rs | 16 +- crates/ui2/src/elements/player.rs | 8 +- crates/ui2/src/elements/tool_divider.rs | 4 +- crates/ui2/src/prelude.rs | 16 +- crates/ui2/src/static_data.rs | 96 +- crates/ui2/src/story.rs | 12 +- 51 files changed, 1615 insertions(+), 494 deletions(-) create mode 100644 crates/theme2/src/colors.rs rename crates/theme2/src/{default.rs => default_colors.rs} (65%) create mode 100644 crates/theme2/src/default_theme.rs create mode 100644 crates/theme2/src/syntax.rs create mode 100644 crates/theme2/src/utils.rs diff --git a/Cargo.lock b/Cargo.lock index 3aca27106c..272320895d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8759,6 +8759,7 @@ dependencies = [ "gpui2", "indexmap 1.9.3", "parking_lot 0.11.2", + "refineable", "schemars", "serde", "serde_derive", diff --git a/crates/storybook2/src/stories/colors.rs b/crates/storybook2/src/stories/colors.rs index afc29660ff..0dd56071c8 100644 --- a/crates/storybook2/src/stories/colors.rs +++ b/crates/storybook2/src/stories/colors.rs @@ -1,5 +1,6 @@ use crate::story::Story; use gpui2::{px, Div, Render}; +use theme2::default_color_scales; use ui::prelude::*; pub struct ColorsStory; @@ -8,7 +9,7 @@ impl Render for ColorsStory { type Element = Div; fn render(&mut self, cx: &mut ViewContext) -> Self::Element { - let color_scales = theme2::default_color_scales(); + let color_scales = default_color_scales(); Story::container(cx) .child(Story::title(cx, "Colors")) @@ -20,14 +21,14 @@ impl Render for ColorsStory { .gap_1() .overflow_y_scroll() .text_color(gpui2::white()) - .children(color_scales.into_iter().map(|(name, scale)| { + .children(color_scales.into_iter().map(|scale| { div() .flex() .child( div() .w(px(75.)) .line_height(px(24.)) - .child(name.to_string()), + .child(scale.name().to_string()), ) .child(div().flex().gap_1().children( (1..=12).map(|step| div().flex().size_6().bg(scale.step(cx, step))), diff --git a/crates/storybook2/src/stories/focus.rs b/crates/storybook2/src/stories/focus.rs index f3f6a8d5fb..aa71040b47 100644 --- a/crates/storybook2/src/stories/focus.rs +++ b/crates/storybook2/src/stories/focus.rs @@ -3,7 +3,7 @@ use gpui2::{ StatelessInteractive, Styled, View, VisualContext, WindowContext, }; use serde::Deserialize; -use theme2::theme; +use theme2::ActiveTheme; #[derive(Clone, Default, PartialEq, Deserialize)] struct ActionA; @@ -34,13 +34,13 @@ impl Render for FocusStory { type Element = Div, FocusEnabled>; fn render(&mut self, cx: &mut gpui2::ViewContext) -> Self::Element { - let theme = theme(cx); - let color_1 = theme.git_created; - let color_2 = theme.git_modified; - let color_3 = theme.git_deleted; - let color_4 = theme.git_conflict; - let color_5 = theme.git_ignored; - let color_6 = theme.git_renamed; + let theme = cx.theme(); + let color_1 = theme.styles.git.created; + let color_2 = theme.styles.git.modified; + let color_3 = theme.styles.git.deleted; + let color_4 = theme.styles.git.conflict; + let color_5 = theme.styles.git.ignored; + let color_6 = theme.styles.git.renamed; let child_1 = cx.focus_handle(); let child_2 = cx.focus_handle(); diff --git a/crates/storybook2/src/stories/scroll.rs b/crates/storybook2/src/stories/scroll.rs index b504a512a6..9236629c34 100644 --- a/crates/storybook2/src/stories/scroll.rs +++ b/crates/storybook2/src/stories/scroll.rs @@ -2,7 +2,7 @@ use gpui2::{ div, px, Component, Div, ParentElement, Render, SharedString, StatefulInteraction, Styled, View, VisualContext, WindowContext, }; -use theme2::theme; +use theme2::ActiveTheme; pub struct ScrollStory; @@ -16,13 +16,13 @@ impl Render for ScrollStory { type Element = Div>; fn render(&mut self, cx: &mut gpui2::ViewContext) -> Self::Element { - let theme = theme(cx); - let color_1 = theme.git_created; - let color_2 = theme.git_modified; + let theme = cx.theme(); + let color_1 = theme.styles.git.created; + let color_2 = theme.styles.git.modified; div() .id("parent") - .bg(theme.background) + .bg(theme.colors().background) .size_full() .overflow_scroll() .children((0..10).map(|row| { diff --git a/crates/storybook2/src/storybook2.rs b/crates/storybook2/src/storybook2.rs index c2903c88e1..6028695d7f 100644 --- a/crates/storybook2/src/storybook2.rs +++ b/crates/storybook2/src/storybook2.rs @@ -68,10 +68,9 @@ fn main() { let theme_registry = cx.global::(); let mut theme_settings = ThemeSettings::get_global(cx).clone(); - theme_settings.active_theme = theme_registry.get(&theme_name).unwrap(); + theme_settings.old_active_theme = theme_registry.get(&theme_name).unwrap(); ThemeSettings::override_global(theme_settings, cx); - cx.set_global(theme.clone()); ui::settings::init(cx); let window = cx.open_window( diff --git a/crates/theme2/Cargo.toml b/crates/theme2/Cargo.toml index 2f89425d21..6b273e5042 100644 --- a/crates/theme2/Cargo.toml +++ b/crates/theme2/Cargo.toml @@ -16,19 +16,19 @@ path = "src/theme2.rs" doctest = false [dependencies] -gpui2 = { path = "../gpui2" } -fs = { path = "../fs" } -schemars.workspace = true -settings2 = { path = "../settings2" } -util = { path = "../util" } - anyhow.workspace = true +fs = { path = "../fs" } +gpui2 = { path = "../gpui2" } indexmap = "1.6.2" parking_lot.workspace = true +refineable.workspace = true +schemars.workspace = true serde.workspace = true serde_derive.workspace = true serde_json.workspace = true +settings2 = { path = "../settings2" } toml.workspace = true +util = { path = "../util" } [dev-dependencies] gpui2 = { path = "../gpui2", features = ["test-support"] } diff --git a/crates/theme2/src/colors.rs b/crates/theme2/src/colors.rs new file mode 100644 index 0000000000..d23fde1ee0 --- /dev/null +++ b/crates/theme2/src/colors.rs @@ -0,0 +1,143 @@ +use gpui2::Hsla; +use refineable::Refineable; + +use crate::{generate_struct_with_overrides, SyntaxStyles}; + +pub struct SystemColors { + pub transparent: Hsla, + pub mac_os_traffic_light_red: Hsla, + pub mac_os_traffic_light_yellow: Hsla, + pub mac_os_traffic_light_green: Hsla, +} + +#[derive(Debug, Clone, Copy)] +pub struct PlayerColor { + pub cursor: Hsla, + pub background: Hsla, + pub selection: Hsla, +} + +pub struct PlayerColors(pub Vec); + +#[derive(Refineable, Clone, Debug)] +#[refineable(debug)] +pub struct StatusColors { + pub conflict: Hsla, + pub created: Hsla, + pub deleted: Hsla, + pub error: Hsla, + pub hidden: Hsla, + pub ignored: Hsla, + pub info: Hsla, + pub modified: Hsla, + pub renamed: Hsla, + pub success: Hsla, + pub warning: Hsla, +} + +#[derive(Refineable, Clone, Debug)] +#[refineable(debug)] +pub struct GitStatusColors { + pub conflict: Hsla, + pub created: Hsla, + pub deleted: Hsla, + pub ignored: Hsla, + pub modified: Hsla, + pub renamed: Hsla, +} + +#[derive(Refineable, Clone, Debug)] +#[refineable(debug)] +pub struct ThemeColors { + pub border: Hsla, + pub border_variant: Hsla, + pub border_focused: Hsla, + pub border_transparent: Hsla, + pub elevated_surface: Hsla, + pub surface: Hsla, + pub background: Hsla, + pub element: Hsla, + pub element_hover: Hsla, + pub element_active: Hsla, + pub element_selected: Hsla, + pub element_disabled: Hsla, + pub element_placeholder: Hsla, + pub ghost_element: Hsla, + pub ghost_element_hover: Hsla, + pub ghost_element_active: Hsla, + pub ghost_element_selected: Hsla, + pub ghost_element_disabled: Hsla, + pub text: Hsla, + pub text_muted: Hsla, + pub text_placeholder: Hsla, + pub text_disabled: Hsla, + pub text_accent: Hsla, + pub icon: Hsla, + pub icon_muted: Hsla, + pub icon_disabled: Hsla, + pub icon_placeholder: Hsla, + pub icon_accent: Hsla, + pub status_bar: Hsla, + pub title_bar: Hsla, + pub toolbar: Hsla, + pub tab_bar: Hsla, + pub editor: Hsla, + pub editor_subheader: Hsla, + pub editor_active_line: Hsla, +} + +generate_struct_with_overrides! { + ThemeStyle, + ThemeStyleOverrides, + system: SystemColors, + colors: ThemeColors, + status: StatusColors, + git: GitStatusColors, + player: PlayerColors, + syntax: SyntaxStyles +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn override_a_single_theme_color() { + let mut colors = ThemeColors::default_light(); + + let magenta: Hsla = gpui2::rgb(0xff00ff); + + assert_ne!(colors.text, magenta); + + let overrides = ThemeColorsRefinement { + text: Some(magenta), + ..Default::default() + }; + + colors.refine(&overrides); + + assert_eq!(colors.text, magenta); + } + + #[test] + fn override_multiple_theme_colors() { + let mut colors = ThemeColors::default_light(); + + let magenta: Hsla = gpui2::rgb(0xff00ff); + let green: Hsla = gpui2::rgb(0x00ff00); + + assert_ne!(colors.text, magenta); + assert_ne!(colors.background, green); + + let overrides = ThemeColorsRefinement { + text: Some(magenta), + background: Some(green), + ..Default::default() + }; + + colors.refine(&overrides); + + assert_eq!(colors.text, magenta); + assert_eq!(colors.background, green); + } +} diff --git a/crates/theme2/src/default.rs b/crates/theme2/src/default_colors.rs similarity index 65% rename from crates/theme2/src/default.rs rename to crates/theme2/src/default_colors.rs index 41d408f980..e8146cdeaa 100644 --- a/crates/theme2/src/default.rs +++ b/crates/theme2/src/default_colors.rs @@ -1,10 +1,704 @@ -use gpui2::Rgba; +use gpui2::{hsla, FontWeight, Rgba}; use indexmap::IndexMap; -use crate::scale::{ColorScaleName, ColorScaleSet, ColorScales}; +use crate::{ + colors::{GitStatusColors, PlayerColor, PlayerColors, StatusColors, SystemColors, ThemeColors}, + scale::{ColorScaleSet, ColorScales}, + syntax::{SyntaxStyleName, SyntaxStyles}, + SyntaxStyle, +}; + +impl Default for SystemColors { + fn default() -> Self { + Self { + transparent: hsla(0.0, 0.0, 0.0, 0.0), + mac_os_traffic_light_red: hsla(0.0139, 0.79, 0.65, 1.0), + mac_os_traffic_light_yellow: hsla(0.114, 0.88, 0.63, 1.0), + mac_os_traffic_light_green: hsla(0.313, 0.49, 0.55, 1.0), + } + } +} + +impl Default for StatusColors { + fn default() -> Self { + Self { + conflict: gpui2::black(), + created: gpui2::black(), + deleted: gpui2::black(), + error: gpui2::black(), + hidden: gpui2::black(), + ignored: gpui2::black(), + info: gpui2::black(), + modified: gpui2::black(), + renamed: gpui2::black(), + success: gpui2::black(), + warning: gpui2::black(), + } + } +} + +impl Default for GitStatusColors { + fn default() -> Self { + Self { + conflict: gpui2::rgba(0xdec184ff).into(), + created: gpui2::rgba(0xa1c181ff).into(), + deleted: gpui2::rgba(0xd07277ff).into(), + ignored: gpui2::rgba(0x555a63ff).into(), + modified: gpui2::rgba(0x74ade8ff).into(), + renamed: gpui2::rgba(0xdec184ff).into(), + } + } +} + +impl Default for PlayerColors { + fn default() -> Self { + Self(vec![ + PlayerColor { + cursor: hsla(0.0, 0.0, 0.0, 0.0), + background: hsla(0.0, 0.0, 0.0, 0.0), + selection: hsla(0.0, 0.0, 0.0, 0.0), + }, + PlayerColor { + cursor: hsla(0.0, 0.0, 0.0, 0.0), + background: hsla(0.0, 0.0, 0.0, 0.0), + selection: hsla(0.0, 0.0, 0.0, 0.0), + }, + PlayerColor { + cursor: hsla(0.0, 0.0, 0.0, 0.0), + background: hsla(0.0, 0.0, 0.0, 0.0), + selection: hsla(0.0, 0.0, 0.0, 0.0), + }, + PlayerColor { + cursor: hsla(0.0, 0.0, 0.0, 0.0), + background: hsla(0.0, 0.0, 0.0, 0.0), + selection: hsla(0.0, 0.0, 0.0, 0.0), + }, + ]) + } +} + +impl SyntaxStyles { + pub fn default_light() -> Self { + use SyntaxStyleName::*; + + let neutral: ColorScaleSet = slate().into(); + + Self(IndexMap::from_iter([ + ( + Comment, + SyntaxStyle::builder().color(neutral.light(11)).build(), + ), + ( + CommentDoc, + SyntaxStyle::builder().color(neutral.light(11)).build(), + ), + ( + Primary, + SyntaxStyle::builder().color(neutral.light(12)).build(), + ), + ( + Predictive, + SyntaxStyle::builder().color(neutral.light(10)).build(), + ), + ( + Hint, + SyntaxStyle::builder() + .color(ColorScaleSet::from(cyan()).light(10)) + .build(), + ), + ( + Emphasis, + SyntaxStyle::builder().weight(FontWeight(600.0)).build(), + ), + ( + EmphasisStrong, + SyntaxStyle::builder().weight(FontWeight(800.0)).build(), + ), + ( + Title, + SyntaxStyle::builder() + .color(ColorScaleSet::from(red()).light(12)) + .build(), + ), + ( + LinkUri, + SyntaxStyle::builder() + .color(ColorScaleSet::from(blue()).light(12)) + .build(), + ), + ( + LinkText, + SyntaxStyle::builder() + .color(ColorScaleSet::from(orange()).light(12)) + .build(), + ), + ( + TextLiteral, + SyntaxStyle::builder() + .color(ColorScaleSet::from(purple()).light(12)) + .build(), + ), + ( + Punctuation, + SyntaxStyle::builder().color(neutral.light(10)).build(), + ), + ( + PunctuationBracket, + SyntaxStyle::builder().color(neutral.light(10)).build(), + ), + ( + PunctuationDelimiter, + SyntaxStyle::builder().color(neutral.light(10)).build(), + ), + ( + PunctuationSpecial, + SyntaxStyle::builder() + .color(ColorScaleSet::from(red()).light(12)) + .build(), + ), + ( + PunctuationListMarker, + SyntaxStyle::builder() + .color(ColorScaleSet::from(blue()).light(12)) + .build(), + ), + ( + String, + SyntaxStyle::builder() + .color(ColorScaleSet::from(green()).light(12)) + .build(), + ), + ( + StringSpecial, + SyntaxStyle::builder() + .color(ColorScaleSet::from(red()).light(12)) + .build(), + ), + ( + StringSpecialSymbol, + SyntaxStyle::builder() + .color(ColorScaleSet::from(red()).light(12)) + .build(), + ), + ( + StringEscape, + SyntaxStyle::builder() + .color(ColorScaleSet::from(blue()).light(12)) + .build(), + ), + ( + StringRegex, + SyntaxStyle::builder() + .color(ColorScaleSet::from(orange()).light(12)) + .build(), + ), + ( + Constructor, + SyntaxStyle::builder() + .color(ColorScaleSet::from(purple()).light(12)) + .build(), + ), + // TODO: Continue assigning syntax colors from here + ( + Variant, + SyntaxStyle::builder() + .color(ColorScaleSet::from(red()).light(12)) + .build(), + ), + ( + Type, + SyntaxStyle::builder() + .color(ColorScaleSet::from(red()).light(12)) + .build(), + ), + ( + TypeBuiltin, + SyntaxStyle::builder() + .color(ColorScaleSet::from(red()).light(12)) + .build(), + ), + ( + Variable, + SyntaxStyle::builder() + .color(ColorScaleSet::from(red()).light(12)) + .build(), + ), + ( + VariableSpecial, + SyntaxStyle::builder() + .color(ColorScaleSet::from(red()).light(12)) + .build(), + ), + ( + Label, + SyntaxStyle::builder() + .color(ColorScaleSet::from(red()).light(12)) + .build(), + ), + ( + Tag, + SyntaxStyle::builder() + .color(ColorScaleSet::from(red()).light(12)) + .build(), + ), + ( + Attribute, + SyntaxStyle::builder() + .color(ColorScaleSet::from(red()).light(12)) + .build(), + ), + ( + Property, + SyntaxStyle::builder() + .color(ColorScaleSet::from(red()).light(12)) + .build(), + ), + ( + Constant, + SyntaxStyle::builder() + .color(ColorScaleSet::from(red()).light(12)) + .build(), + ), + ( + Keyword, + SyntaxStyle::builder() + .color(ColorScaleSet::from(red()).light(12)) + .build(), + ), + ( + Enum, + SyntaxStyle::builder() + .color(ColorScaleSet::from(red()).light(12)) + .build(), + ), + ( + Operator, + SyntaxStyle::builder() + .color(ColorScaleSet::from(red()).light(12)) + .build(), + ), + ( + Number, + SyntaxStyle::builder() + .color(ColorScaleSet::from(red()).light(12)) + .build(), + ), + ( + Boolean, + SyntaxStyle::builder() + .color(ColorScaleSet::from(red()).light(12)) + .build(), + ), + ( + ConstantBuiltin, + SyntaxStyle::builder() + .color(ColorScaleSet::from(red()).light(12)) + .build(), + ), + ( + Function, + SyntaxStyle::builder() + .color(ColorScaleSet::from(red()).light(12)) + .build(), + ), + ( + FunctionBuiltin, + SyntaxStyle::builder() + .color(ColorScaleSet::from(red()).light(12)) + .build(), + ), + ( + FunctionDefinition, + SyntaxStyle::builder() + .color(ColorScaleSet::from(red()).light(12)) + .build(), + ), + ( + FunctionSpecialDefinition, + SyntaxStyle::builder() + .color(ColorScaleSet::from(red()).light(12)) + .build(), + ), + ( + FunctionMethod, + SyntaxStyle::builder() + .color(ColorScaleSet::from(red()).light(12)) + .build(), + ), + ( + FunctionMethodBuiltin, + SyntaxStyle::builder() + .color(ColorScaleSet::from(red()).light(12)) + .build(), + ), + ( + Preproc, + SyntaxStyle::builder() + .color(ColorScaleSet::from(red()).light(12)) + .build(), + ), + ( + Embedded, + SyntaxStyle::builder() + .color(ColorScaleSet::from(red()).light(12)) + .build(), + ), + ])) + } + + pub fn default_dark() -> Self { + use SyntaxStyleName::*; + + let neutral: ColorScaleSet = slate().into(); + + Self(IndexMap::from_iter([ + ( + Comment, + SyntaxStyle::builder().color(neutral.dark(11)).build(), + ), + ( + CommentDoc, + SyntaxStyle::builder().color(neutral.dark(11)).build(), + ), + ( + Primary, + SyntaxStyle::builder().color(neutral.dark(12)).build(), + ), + ( + Predictive, + SyntaxStyle::builder().color(neutral.dark(10)).build(), + ), + ( + Hint, + SyntaxStyle::builder() + .color(ColorScaleSet::from(cyan()).dark(10)) + .build(), + ), + ( + Emphasis, + SyntaxStyle::builder().weight(FontWeight(600.0)).build(), + ), + ( + EmphasisStrong, + SyntaxStyle::builder().weight(FontWeight(800.0)).build(), + ), + ( + Title, + SyntaxStyle::builder() + .color(ColorScaleSet::from(red()).dark(12)) + .build(), + ), + ( + LinkUri, + SyntaxStyle::builder() + .color(ColorScaleSet::from(blue()).dark(12)) + .build(), + ), + ( + LinkText, + SyntaxStyle::builder() + .color(ColorScaleSet::from(orange()).dark(12)) + .build(), + ), + ( + TextLiteral, + SyntaxStyle::builder() + .color(ColorScaleSet::from(purple()).dark(12)) + .build(), + ), + ( + Punctuation, + SyntaxStyle::builder().color(neutral.dark(10)).build(), + ), + ( + PunctuationBracket, + SyntaxStyle::builder().color(neutral.dark(10)).build(), + ), + ( + PunctuationDelimiter, + SyntaxStyle::builder().color(neutral.dark(10)).build(), + ), + ( + PunctuationSpecial, + SyntaxStyle::builder() + .color(ColorScaleSet::from(red()).dark(12)) + .build(), + ), + ( + PunctuationListMarker, + SyntaxStyle::builder() + .color(ColorScaleSet::from(blue()).dark(12)) + .build(), + ), + ( + String, + SyntaxStyle::builder() + .color(ColorScaleSet::from(green()).dark(12)) + .build(), + ), + ( + StringSpecial, + SyntaxStyle::builder() + .color(ColorScaleSet::from(red()).dark(12)) + .build(), + ), + ( + StringSpecialSymbol, + SyntaxStyle::builder() + .color(ColorScaleSet::from(red()).dark(12)) + .build(), + ), + ( + StringEscape, + SyntaxStyle::builder() + .color(ColorScaleSet::from(blue()).dark(12)) + .build(), + ), + ( + StringRegex, + SyntaxStyle::builder() + .color(ColorScaleSet::from(orange()).dark(12)) + .build(), + ), + ( + Constructor, + SyntaxStyle::builder() + .color(ColorScaleSet::from(purple()).dark(12)) + .build(), + ), + // TODO: Continue assigning syntax colors from here + ( + Variant, + SyntaxStyle::builder() + .color(ColorScaleSet::from(red()).dark(12)) + .build(), + ), + ( + Type, + SyntaxStyle::builder() + .color(ColorScaleSet::from(red()).dark(12)) + .build(), + ), + ( + TypeBuiltin, + SyntaxStyle::builder() + .color(ColorScaleSet::from(red()).dark(12)) + .build(), + ), + ( + Variable, + SyntaxStyle::builder() + .color(ColorScaleSet::from(red()).dark(12)) + .build(), + ), + ( + VariableSpecial, + SyntaxStyle::builder() + .color(ColorScaleSet::from(red()).dark(12)) + .build(), + ), + ( + Label, + SyntaxStyle::builder() + .color(ColorScaleSet::from(red()).dark(12)) + .build(), + ), + ( + Tag, + SyntaxStyle::builder() + .color(ColorScaleSet::from(red()).dark(12)) + .build(), + ), + ( + Attribute, + SyntaxStyle::builder() + .color(ColorScaleSet::from(red()).dark(12)) + .build(), + ), + ( + Property, + SyntaxStyle::builder() + .color(ColorScaleSet::from(red()).dark(12)) + .build(), + ), + ( + Constant, + SyntaxStyle::builder() + .color(ColorScaleSet::from(red()).dark(12)) + .build(), + ), + ( + Keyword, + SyntaxStyle::builder() + .color(ColorScaleSet::from(red()).dark(12)) + .build(), + ), + ( + Enum, + SyntaxStyle::builder() + .color(ColorScaleSet::from(red()).dark(12)) + .build(), + ), + ( + Operator, + SyntaxStyle::builder() + .color(ColorScaleSet::from(red()).dark(12)) + .build(), + ), + ( + Number, + SyntaxStyle::builder() + .color(ColorScaleSet::from(red()).dark(12)) + .build(), + ), + ( + Boolean, + SyntaxStyle::builder() + .color(ColorScaleSet::from(red()).dark(12)) + .build(), + ), + ( + ConstantBuiltin, + SyntaxStyle::builder() + .color(ColorScaleSet::from(red()).dark(12)) + .build(), + ), + ( + Function, + SyntaxStyle::builder() + .color(ColorScaleSet::from(red()).dark(12)) + .build(), + ), + ( + FunctionBuiltin, + SyntaxStyle::builder() + .color(ColorScaleSet::from(red()).dark(12)) + .build(), + ), + ( + FunctionDefinition, + SyntaxStyle::builder() + .color(ColorScaleSet::from(red()).dark(12)) + .build(), + ), + ( + FunctionSpecialDefinition, + SyntaxStyle::builder() + .color(ColorScaleSet::from(red()).dark(12)) + .build(), + ), + ( + FunctionMethod, + SyntaxStyle::builder() + .color(ColorScaleSet::from(red()).dark(12)) + .build(), + ), + ( + FunctionMethodBuiltin, + SyntaxStyle::builder() + .color(ColorScaleSet::from(red()).dark(12)) + .build(), + ), + ( + Preproc, + SyntaxStyle::builder() + .color(ColorScaleSet::from(red()).dark(12)) + .build(), + ), + ( + Embedded, + SyntaxStyle::builder() + .color(ColorScaleSet::from(red()).dark(12)) + .build(), + ), + ])) + } +} + +impl ThemeColors { + pub fn default_light() -> Self { + Self { + border: gpui2::white(), + border_variant: gpui2::white(), + border_focused: gpui2::white(), + border_transparent: gpui2::white(), + elevated_surface: gpui2::white(), + surface: gpui2::white(), + background: gpui2::white(), + element: gpui2::white(), + element_hover: gpui2::white(), + element_active: gpui2::white(), + element_selected: gpui2::white(), + element_disabled: gpui2::white(), + element_placeholder: gpui2::white(), + ghost_element: gpui2::white(), + ghost_element_hover: gpui2::white(), + ghost_element_active: gpui2::white(), + ghost_element_selected: gpui2::white(), + ghost_element_disabled: gpui2::white(), + text: gpui2::white(), + text_muted: gpui2::white(), + text_placeholder: gpui2::white(), + text_disabled: gpui2::white(), + text_accent: gpui2::white(), + icon: gpui2::white(), + icon_muted: gpui2::white(), + icon_disabled: gpui2::white(), + icon_placeholder: gpui2::white(), + icon_accent: gpui2::white(), + status_bar: gpui2::white(), + title_bar: gpui2::white(), + toolbar: gpui2::white(), + tab_bar: gpui2::white(), + editor: gpui2::white(), + editor_subheader: gpui2::white(), + editor_active_line: gpui2::white(), + } + } + + pub fn default_dark() -> Self { + Self { + border: gpui2::rgba(0x464b57ff).into(), + border_variant: gpui2::rgba(0x464b57ff).into(), + border_focused: gpui2::rgba(0x293b5bff).into(), + border_transparent: gpui2::rgba(0x00000000).into(), + elevated_surface: gpui2::rgba(0x3b414dff).into(), + surface: gpui2::rgba(0x2f343eff).into(), + background: gpui2::rgba(0x3b414dff).into(), + element: gpui2::rgba(0x3b414dff).into(), + element_hover: gpui2::rgba(0xffffff1e).into(), + element_active: gpui2::rgba(0xffffff28).into(), + element_selected: gpui2::rgba(0x18243dff).into(), + element_disabled: gpui2::rgba(0x00000000).into(), + element_placeholder: gpui2::black(), + ghost_element: gpui2::rgba(0x00000000).into(), + ghost_element_hover: gpui2::rgba(0xffffff14).into(), + ghost_element_active: gpui2::rgba(0xffffff1e).into(), + ghost_element_selected: gpui2::rgba(0x18243dff).into(), + ghost_element_disabled: gpui2::rgba(0x00000000).into(), + text: gpui2::rgba(0xc8ccd4ff).into(), + text_muted: gpui2::rgba(0x838994ff).into(), + text_placeholder: gpui2::rgba(0xd07277ff).into(), + text_disabled: gpui2::rgba(0x555a63ff).into(), + text_accent: gpui2::rgba(0x74ade8ff).into(), + icon: gpui2::black(), + icon_muted: gpui2::rgba(0x838994ff).into(), + icon_disabled: gpui2::black(), + icon_placeholder: gpui2::black(), + icon_accent: gpui2::black(), + status_bar: gpui2::rgba(0x3b414dff).into(), + title_bar: gpui2::rgba(0x3b414dff).into(), + toolbar: gpui2::rgba(0x282c33ff).into(), + tab_bar: gpui2::rgba(0x2f343eff).into(), + editor: gpui2::rgba(0x282c33ff).into(), + editor_subheader: gpui2::rgba(0x2f343eff).into(), + editor_active_line: gpui2::rgba(0x2f343eff).into(), + } + } +} struct DefaultColorScaleSet { - scale: ColorScaleName, + scale: &'static str, light: [&'static str; 12], light_alpha: [&'static str; 12], dark: [&'static str; 12], @@ -32,48 +726,46 @@ impl From for ColorScaleSet { } pub fn default_color_scales() -> ColorScales { - use ColorScaleName::*; - - IndexMap::from_iter([ - (Gray, gray().into()), - (Mauve, mauve().into()), - (Slate, slate().into()), - (Sage, sage().into()), - (Olive, olive().into()), - (Sand, sand().into()), - (Gold, gold().into()), - (Bronze, bronze().into()), - (Brown, brown().into()), - (Yellow, yellow().into()), - (Amber, amber().into()), - (Orange, orange().into()), - (Tomato, tomato().into()), - (Red, red().into()), - (Ruby, ruby().into()), - (Crimson, crimson().into()), - (Pink, pink().into()), - (Plum, plum().into()), - (Purple, purple().into()), - (Violet, violet().into()), - (Iris, iris().into()), - (Indigo, indigo().into()), - (Blue, blue().into()), - (Cyan, cyan().into()), - (Teal, teal().into()), - (Jade, jade().into()), - (Green, green().into()), - (Grass, grass().into()), - (Lime, lime().into()), - (Mint, mint().into()), - (Sky, sky().into()), - (Black, black().into()), - (White, white().into()), - ]) + ColorScales { + gray: gray().into(), + mauve: mauve().into(), + slate: slate().into(), + sage: sage().into(), + olive: olive().into(), + sand: sand().into(), + gold: gold().into(), + bronze: bronze().into(), + brown: brown().into(), + yellow: yellow().into(), + amber: amber().into(), + orange: orange().into(), + tomato: tomato().into(), + red: red().into(), + ruby: ruby().into(), + crimson: crimson().into(), + pink: pink().into(), + plum: plum().into(), + purple: purple().into(), + violet: violet().into(), + iris: iris().into(), + indigo: indigo().into(), + blue: blue().into(), + cyan: cyan().into(), + teal: teal().into(), + jade: jade().into(), + green: green().into(), + grass: grass().into(), + lime: lime().into(), + mint: mint().into(), + sky: sky().into(), + black: black().into(), + white: white().into(), + } } fn gray() -> DefaultColorScaleSet { DefaultColorScaleSet { - scale: ColorScaleName::Gray, + scale: "Gray", light: [ "#fcfcfcff", "#f9f9f9ff", @@ -135,7 +827,7 @@ fn gray() -> DefaultColorScaleSet { fn mauve() -> DefaultColorScaleSet { DefaultColorScaleSet { - scale: ColorScaleName::Mauve, + scale: "Mauve", light: [ "#fdfcfdff", "#faf9fbff", @@ -197,7 +889,7 @@ fn mauve() -> DefaultColorScaleSet { fn slate() -> DefaultColorScaleSet { DefaultColorScaleSet { - scale: ColorScaleName::Slate, + scale: "Slate", light: [ "#fcfcfdff", "#f9f9fbff", @@ -259,7 +951,7 @@ fn slate() -> DefaultColorScaleSet { fn sage() -> DefaultColorScaleSet { DefaultColorScaleSet { - scale: ColorScaleName::Sage, + scale: "Sage", light: [ "#fbfdfcff", "#f7f9f8ff", @@ -321,7 +1013,7 @@ fn sage() -> DefaultColorScaleSet { fn olive() -> DefaultColorScaleSet { DefaultColorScaleSet { - scale: ColorScaleName::Olive, + scale: "Olive", light: [ "#fcfdfcff", "#f8faf8ff", @@ -383,7 +1075,7 @@ fn olive() -> DefaultColorScaleSet { fn sand() -> DefaultColorScaleSet { DefaultColorScaleSet { - scale: ColorScaleName::Sand, + scale: "Sand", light: [ "#fdfdfcff", "#f9f9f8ff", @@ -445,7 +1137,7 @@ fn sand() -> DefaultColorScaleSet { fn gold() -> DefaultColorScaleSet { DefaultColorScaleSet { - scale: ColorScaleName::Gold, + scale: "Gold", light: [ "#fdfdfcff", "#faf9f2ff", @@ -507,7 +1199,7 @@ fn gold() -> DefaultColorScaleSet { fn bronze() -> DefaultColorScaleSet { DefaultColorScaleSet { - scale: ColorScaleName::Bronze, + scale: "Bronze", light: [ "#fdfcfcff", "#fdf7f5ff", @@ -569,7 +1261,7 @@ fn bronze() -> DefaultColorScaleSet { fn brown() -> DefaultColorScaleSet { DefaultColorScaleSet { - scale: ColorScaleName::Brown, + scale: "Brown", light: [ "#fefdfcff", "#fcf9f6ff", @@ -631,7 +1323,7 @@ fn brown() -> DefaultColorScaleSet { fn yellow() -> DefaultColorScaleSet { DefaultColorScaleSet { - scale: ColorScaleName::Yellow, + scale: "Yellow", light: [ "#fdfdf9ff", "#fefce9ff", @@ -693,7 +1385,7 @@ fn yellow() -> DefaultColorScaleSet { fn amber() -> DefaultColorScaleSet { DefaultColorScaleSet { - scale: ColorScaleName::Amber, + scale: "Amber", light: [ "#fefdfbff", "#fefbe9ff", @@ -755,7 +1447,7 @@ fn amber() -> DefaultColorScaleSet { fn orange() -> DefaultColorScaleSet { DefaultColorScaleSet { - scale: ColorScaleName::Orange, + scale: "Orange", light: [ "#fefcfbff", "#fff7edff", @@ -817,7 +1509,7 @@ fn orange() -> DefaultColorScaleSet { fn tomato() -> DefaultColorScaleSet { DefaultColorScaleSet { - scale: ColorScaleName::Tomato, + scale: "Tomato", light: [ "#fffcfcff", "#fff8f7ff", @@ -879,7 +1571,7 @@ fn tomato() -> DefaultColorScaleSet { fn red() -> DefaultColorScaleSet { DefaultColorScaleSet { - scale: ColorScaleName::Red, + scale: "Red", light: [ "#fffcfcff", "#fff7f7ff", @@ -941,7 +1633,7 @@ fn red() -> DefaultColorScaleSet { fn ruby() -> DefaultColorScaleSet { DefaultColorScaleSet { - scale: ColorScaleName::Ruby, + scale: "Ruby", light: [ "#fffcfdff", "#fff7f8ff", @@ -1003,7 +1695,7 @@ fn ruby() -> DefaultColorScaleSet { fn crimson() -> DefaultColorScaleSet { DefaultColorScaleSet { - scale: ColorScaleName::Crimson, + scale: "Crimson", light: [ "#fffcfdff", "#fef7f9ff", @@ -1065,7 +1757,7 @@ fn crimson() -> DefaultColorScaleSet { fn pink() -> DefaultColorScaleSet { DefaultColorScaleSet { - scale: ColorScaleName::Pink, + scale: "Pink", light: [ "#fffcfeff", "#fef7fbff", @@ -1127,7 +1819,7 @@ fn pink() -> DefaultColorScaleSet { fn plum() -> DefaultColorScaleSet { DefaultColorScaleSet { - scale: ColorScaleName::Plum, + scale: "Plum", light: [ "#fefcffff", "#fdf7fdff", @@ -1189,7 +1881,7 @@ fn plum() -> DefaultColorScaleSet { fn purple() -> DefaultColorScaleSet { DefaultColorScaleSet { - scale: ColorScaleName::Purple, + scale: "Purple", light: [ "#fefcfeff", "#fbf7feff", @@ -1251,7 +1943,7 @@ fn purple() -> DefaultColorScaleSet { fn violet() -> DefaultColorScaleSet { DefaultColorScaleSet { - scale: ColorScaleName::Violet, + scale: "Violet", light: [ "#fdfcfeff", "#faf8ffff", @@ -1313,7 +2005,7 @@ fn violet() -> DefaultColorScaleSet { fn iris() -> DefaultColorScaleSet { DefaultColorScaleSet { - scale: ColorScaleName::Iris, + scale: "Iris", light: [ "#fdfdffff", "#f8f8ffff", @@ -1375,7 +2067,7 @@ fn iris() -> DefaultColorScaleSet { fn indigo() -> DefaultColorScaleSet { DefaultColorScaleSet { - scale: ColorScaleName::Indigo, + scale: "Indigo", light: [ "#fdfdfeff", "#f7f9ffff", @@ -1437,7 +2129,7 @@ fn indigo() -> DefaultColorScaleSet { fn blue() -> DefaultColorScaleSet { DefaultColorScaleSet { - scale: ColorScaleName::Blue, + scale: "Blue", light: [ "#fbfdffff", "#f4faffff", @@ -1499,7 +2191,7 @@ fn blue() -> DefaultColorScaleSet { fn cyan() -> DefaultColorScaleSet { DefaultColorScaleSet { - scale: ColorScaleName::Cyan, + scale: "Cyan", light: [ "#fafdfeff", "#f2fafbff", @@ -1561,7 +2253,7 @@ fn cyan() -> DefaultColorScaleSet { fn teal() -> DefaultColorScaleSet { DefaultColorScaleSet { - scale: ColorScaleName::Teal, + scale: "Teal", light: [ "#fafefdff", "#f3fbf9ff", @@ -1623,7 +2315,7 @@ fn teal() -> DefaultColorScaleSet { fn jade() -> DefaultColorScaleSet { DefaultColorScaleSet { - scale: ColorScaleName::Jade, + scale: "Jade", light: [ "#fbfefdff", "#f4fbf7ff", @@ -1685,7 +2377,7 @@ fn jade() -> DefaultColorScaleSet { fn green() -> DefaultColorScaleSet { DefaultColorScaleSet { - scale: ColorScaleName::Green, + scale: "Green", light: [ "#fbfefcff", "#f4fbf6ff", @@ -1747,7 +2439,7 @@ fn green() -> DefaultColorScaleSet { fn grass() -> DefaultColorScaleSet { DefaultColorScaleSet { - scale: ColorScaleName::Grass, + scale: "Grass", light: [ "#fbfefbff", "#f5fbf5ff", @@ -1809,7 +2501,7 @@ fn grass() -> DefaultColorScaleSet { fn lime() -> DefaultColorScaleSet { DefaultColorScaleSet { - scale: ColorScaleName::Lime, + scale: "Lime", light: [ "#fcfdfaff", "#f8faf3ff", @@ -1871,7 +2563,7 @@ fn lime() -> DefaultColorScaleSet { fn mint() -> DefaultColorScaleSet { DefaultColorScaleSet { - scale: ColorScaleName::Mint, + scale: "Mint", light: [ "#f9fefdff", "#f2fbf9ff", @@ -1933,7 +2625,7 @@ fn mint() -> DefaultColorScaleSet { fn sky() -> DefaultColorScaleSet { DefaultColorScaleSet { - scale: ColorScaleName::Sky, + scale: "Sky", light: [ "#f9feffff", "#f1fafdff", @@ -1995,7 +2687,7 @@ fn sky() -> DefaultColorScaleSet { fn black() -> DefaultColorScaleSet { DefaultColorScaleSet { - scale: ColorScaleName::Black, + scale: "Black", light: [ "#0000000d", "#0000001a", @@ -2057,7 +2749,7 @@ fn black() -> DefaultColorScaleSet { fn white() -> DefaultColorScaleSet { DefaultColorScaleSet { - scale: ColorScaleName::White, + scale: "White", light: [ "#ffffff0d", "#ffffff1a", diff --git a/crates/theme2/src/default_theme.rs b/crates/theme2/src/default_theme.rs new file mode 100644 index 0000000000..4b47e403d6 --- /dev/null +++ b/crates/theme2/src/default_theme.rs @@ -0,0 +1,58 @@ +use crate::{ + colors::{GitStatusColors, PlayerColors, StatusColors, SystemColors, ThemeColors, ThemeStyle}, + default_color_scales, Appearance, SyntaxStyles, ThemeFamily, ThemeVariant, +}; + +fn zed_pro_daylight() -> ThemeVariant { + ThemeVariant { + id: "zed_pro_daylight".to_string(), + name: "Zed Pro Daylight".to_string(), + appearance: Appearance::Light, + styles: ThemeStyle { + system: SystemColors::default(), + colors: ThemeColors::default_light(), + status: StatusColors::default(), + git: GitStatusColors::default(), + player: PlayerColors::default(), + syntax: SyntaxStyles::default_light(), + }, + } +} + +pub(crate) fn zed_pro_moonlight() -> ThemeVariant { + ThemeVariant { + id: "zed_pro_moonlight".to_string(), + name: "Zed Pro Moonlight".to_string(), + appearance: Appearance::Light, + styles: ThemeStyle { + system: SystemColors::default(), + colors: ThemeColors::default_dark(), + status: StatusColors::default(), + git: GitStatusColors::default(), + player: PlayerColors::default(), + syntax: SyntaxStyles::default_dark(), + }, + } +} + +pub fn zed_pro_family() -> ThemeFamily { + ThemeFamily { + id: "zed_pro".to_string(), + name: "Zed Pro".to_string(), + author: "Zed Team".to_string(), + themes: vec![zed_pro_daylight(), zed_pro_moonlight()], + scales: default_color_scales(), + } +} + +impl Default for ThemeFamily { + fn default() -> Self { + zed_pro_family() + } +} + +impl Default for ThemeVariant { + fn default() -> Self { + zed_pro_daylight() + } +} diff --git a/crates/theme2/src/scale.rs b/crates/theme2/src/scale.rs index 22a607bf07..21c8592d81 100644 --- a/crates/theme2/src/scale.rs +++ b/crates/theme2/src/scale.rs @@ -1,98 +1,95 @@ -use gpui2::{AppContext, Hsla}; -use indexmap::IndexMap; +use gpui2::{AppContext, Hsla, SharedString}; -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", - } - ) - } -} +use crate::{ActiveTheme, Appearance}; pub type ColorScale = [Hsla; 12]; -pub type ColorScales = IndexMap; +pub struct ColorScales { + pub gray: ColorScaleSet, + pub mauve: ColorScaleSet, + pub slate: ColorScaleSet, + pub sage: ColorScaleSet, + pub olive: ColorScaleSet, + pub sand: ColorScaleSet, + pub gold: ColorScaleSet, + pub bronze: ColorScaleSet, + pub brown: ColorScaleSet, + pub yellow: ColorScaleSet, + pub amber: ColorScaleSet, + pub orange: ColorScaleSet, + pub tomato: ColorScaleSet, + pub red: ColorScaleSet, + pub ruby: ColorScaleSet, + pub crimson: ColorScaleSet, + pub pink: ColorScaleSet, + pub plum: ColorScaleSet, + pub purple: ColorScaleSet, + pub violet: ColorScaleSet, + pub iris: ColorScaleSet, + pub indigo: ColorScaleSet, + pub blue: ColorScaleSet, + pub cyan: ColorScaleSet, + pub teal: ColorScaleSet, + pub jade: ColorScaleSet, + pub green: ColorScaleSet, + pub grass: ColorScaleSet, + pub lime: ColorScaleSet, + pub mint: ColorScaleSet, + pub sky: ColorScaleSet, + pub black: ColorScaleSet, + pub white: ColorScaleSet, +} + +impl IntoIterator for ColorScales { + type Item = ColorScaleSet; + + type IntoIter = std::vec::IntoIter; + + fn into_iter(self) -> Self::IntoIter { + vec![ + self.gray, + self.mauve, + self.slate, + self.sage, + self.olive, + self.sand, + self.gold, + self.bronze, + self.brown, + self.yellow, + self.amber, + self.orange, + self.tomato, + self.red, + self.ruby, + self.crimson, + self.pink, + self.plum, + self.purple, + self.violet, + self.iris, + self.indigo, + self.blue, + self.cyan, + self.teal, + self.jade, + self.green, + self.grass, + self.lime, + self.mint, + self.sky, + self.black, + self.white, + ] + .into_iter() + } +} /// A one-based step in a [`ColorScale`]. pub type ColorScaleStep = usize; pub struct ColorScaleSet { - name: ColorScaleName, + name: SharedString, light: ColorScale, dark: ColorScale, light_alpha: ColorScale, @@ -101,14 +98,14 @@ pub struct ColorScaleSet { impl ColorScaleSet { pub fn new( - name: ColorScaleName, + name: impl Into, light: ColorScale, light_alpha: ColorScale, dark: ColorScale, dark_alpha: ColorScale, ) -> Self { Self { - name, + name: name.into(), light, light_alpha, dark, @@ -116,8 +113,8 @@ impl ColorScaleSet { } } - pub fn name(&self) -> String { - self.name.to_string() + pub fn name(&self) -> &SharedString { + &self.name } pub fn light(&self, step: ColorScaleStep) -> Hsla { @@ -136,27 +133,15 @@ impl ColorScaleSet { self.dark_alpha[step - 1] } - fn current_appearance(cx: &AppContext) -> Appearance { - let theme = theme(cx); - if theme.metadata.is_light { - Appearance::Light - } else { - Appearance::Dark - } - } - pub fn step(&self, cx: &AppContext, step: ColorScaleStep) -> Hsla { - let appearance = Self::current_appearance(cx); - - match appearance { + match cx.theme().appearance { Appearance::Light => self.light(step), Appearance::Dark => self.dark(step), } } pub fn step_alpha(&self, cx: &AppContext, step: ColorScaleStep) -> Hsla { - let appearance = Self::current_appearance(cx); - match appearance { + match cx.theme().appearance { Appearance::Light => self.light_alpha(step), Appearance::Dark => self.dark_alpha(step), } diff --git a/crates/theme2/src/settings.rs b/crates/theme2/src/settings.rs index 379b01dd4b..3a61bbbe1e 100644 --- a/crates/theme2/src/settings.rs +++ b/crates/theme2/src/settings.rs @@ -1,4 +1,4 @@ -use crate::{Theme, ThemeRegistry}; +use crate::{zed_pro_moonlight, Theme, ThemeRegistry, ThemeVariant}; use anyhow::Result; use gpui2::{px, AppContext, Font, FontFeatures, FontStyle, FontWeight, Pixels}; use schemars::{ @@ -20,7 +20,8 @@ pub struct ThemeSettings { pub buffer_font: Font, pub buffer_font_size: Pixels, pub buffer_line_height: BufferLineHeight, - pub active_theme: Arc, + pub active_theme: Arc, + pub old_active_theme: Arc, } #[derive(Default)] @@ -123,7 +124,8 @@ impl settings2::Settings for ThemeSettings { }, buffer_font_size: defaults.buffer_font_size.unwrap().into(), buffer_line_height: defaults.buffer_line_height.unwrap(), - active_theme: themes.get(defaults.theme.as_ref().unwrap()).unwrap(), + active_theme: Arc::new(zed_pro_moonlight()), + old_active_theme: themes.get(defaults.theme.as_ref().unwrap()).unwrap(), }; for value in user_values.into_iter().copied().cloned() { @@ -136,7 +138,7 @@ impl settings2::Settings for ThemeSettings { if let Some(value) = &value.theme { if let Some(theme) = themes.get(value).log_err() { - this.active_theme = theme; + this.old_active_theme = theme; } } diff --git a/crates/theme2/src/syntax.rs b/crates/theme2/src/syntax.rs new file mode 100644 index 0000000000..82c4c87796 --- /dev/null +++ b/crates/theme2/src/syntax.rs @@ -0,0 +1,227 @@ +use gpui2::{FontWeight, Hsla, SharedString}; +use indexmap::IndexMap; + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum SyntaxStyleName { + Comment, + CommentDoc, + Primary, + Predictive, + Hint, + Emphasis, + EmphasisStrong, + Title, + LinkUri, + LinkText, + TextLiteral, + Punctuation, + PunctuationBracket, + PunctuationDelimiter, + PunctuationSpecial, + PunctuationListMarker, + String, + StringSpecial, + StringSpecialSymbol, + StringEscape, + StringRegex, + Constructor, + Variant, + Type, + TypeBuiltin, + Variable, + VariableSpecial, + Label, + Tag, + Attribute, + Property, + Constant, + Keyword, + Enum, + Operator, + Number, + Boolean, + ConstantBuiltin, + Function, + FunctionBuiltin, + FunctionDefinition, + FunctionSpecialDefinition, + FunctionMethod, + FunctionMethodBuiltin, + Preproc, + Embedded, + Custom(SharedString), +} + +impl std::str::FromStr for SyntaxStyleName { + type Err = (); + + fn from_str(s: &str) -> Result { + Ok(match s { + "attribute" => Self::Attribute, + "boolean" => Self::Boolean, + "comment" => Self::Comment, + "comment.doc" => Self::CommentDoc, + "constant" => Self::Constant, + "constructor" => Self::Constructor, + "embedded" => Self::Embedded, + "emphasis" => Self::Emphasis, + "emphasis.strong" => Self::EmphasisStrong, + "enum" => Self::Enum, + "function" => Self::Function, + "function.builtin" => Self::FunctionBuiltin, + "function.definition" => Self::FunctionDefinition, + "function.special_definition" => Self::FunctionSpecialDefinition, + "function.method" => Self::FunctionMethod, + "function.method_builtin" => Self::FunctionMethodBuiltin, + "hint" => Self::Hint, + "keyword" => Self::Keyword, + "label" => Self::Label, + "link_text" => Self::LinkText, + "link_uri" => Self::LinkUri, + "number" => Self::Number, + "operator" => Self::Operator, + "predictive" => Self::Predictive, + "preproc" => Self::Preproc, + "primary" => Self::Primary, + "property" => Self::Property, + "punctuation" => Self::Punctuation, + "punctuation.bracket" => Self::PunctuationBracket, + "punctuation.delimiter" => Self::PunctuationDelimiter, + "punctuation.list_marker" => Self::PunctuationListMarker, + "punctuation.special" => Self::PunctuationSpecial, + "string" => Self::String, + "string.escape" => Self::StringEscape, + "string.regex" => Self::StringRegex, + "string.special" => Self::StringSpecial, + "string.special.symbol" => Self::StringSpecialSymbol, + "tag" => Self::Tag, + "text.literal" => Self::TextLiteral, + "title" => Self::Title, + "type" => Self::Type, + "type.builtin" => Self::TypeBuiltin, + "variable" => Self::Variable, + "variable.special" => Self::VariableSpecial, + "constant.builtin" => Self::ConstantBuiltin, + "variant" => Self::Variant, + name => Self::Custom(name.to_string().into()), + }) + } +} + +#[derive(Debug, Clone, Copy)] +pub struct SyntaxStyle { + pub color: Hsla, + pub weight: FontWeight, + pub underline: bool, + pub italic: bool, + // Nate: In the future I'd like to enable using background highlights for syntax highlighting + // pub highlight: Hsla, +} + +impl SyntaxStyle { + pub fn builder() -> SyntaxStyleBuilder { + SyntaxStyleBuilder::new() + } +} + +impl Default for SyntaxStyle { + fn default() -> Self { + Self { + color: gpui2::black(), + weight: FontWeight::default(), + italic: false, + underline: false, + } + } +} + +pub struct SyntaxStyleBuilder { + pub color: Hsla, + pub weight: FontWeight, + pub underline: bool, + pub italic: bool, +} + +impl SyntaxStyleBuilder { + pub fn new() -> Self { + SyntaxStyleBuilder { + color: gpui2::black(), + weight: FontWeight::default(), + underline: false, + italic: false, + } + } + + pub fn color(mut self, color: Hsla) -> Self { + self.color = color; + self + } + + pub fn weight(mut self, weight: FontWeight) -> Self { + self.weight = weight; + self + } + + pub fn underline(mut self, underline: bool) -> Self { + self.underline = underline; + self + } + + pub fn italic(mut self, italic: bool) -> Self { + self.italic = italic; + self + } + + pub fn build(self) -> SyntaxStyle { + SyntaxStyle { + color: self.color, + weight: self.weight, + underline: self.underline, + italic: self.italic, + } + } +} + +pub struct SyntaxStyles(pub IndexMap); + +impl SyntaxStyles { + // TOOD: Get this working with `#[cfg(test)]`. Why isn't it? + pub fn new_test(colors: impl IntoIterator) -> Self { + Self(IndexMap::from_iter(colors.into_iter().map( + |(name, color)| { + ( + name.parse().unwrap(), + SyntaxStyle::builder().color(color).build(), + ) + }, + ))) + } + + pub fn get(&self, name: &str) -> SyntaxStyle { + self.0 + .get(&name.parse::().unwrap()) + .cloned() + .unwrap_or_default() + } + + pub fn color(&self, name: &str) -> Hsla { + self.get(name).color + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn parse_syntax_style_name() { + let name = "comment".parse::().unwrap(); + assert_eq!(name, SyntaxStyleName::Comment); + } + + #[test] + fn create_custom_syntax_style_name() { + let name = "custom".parse::().unwrap(); + assert_eq!(name, SyntaxStyleName::Custom("custom".into())); + } +} diff --git a/crates/theme2/src/theme2.rs b/crates/theme2/src/theme2.rs index b96a23c338..ea1ad5b26c 100644 --- a/crates/theme2/src/theme2.rs +++ b/crates/theme2/src/theme2.rs @@ -1,17 +1,25 @@ -mod default; +mod colors; +mod default_colors; +mod default_theme; mod registry; mod scale; mod settings; +mod syntax; mod themes; +mod utils; -pub use default::*; +pub use colors::*; +pub use default_colors::*; +pub use default_theme::*; pub use registry::*; pub use scale::*; pub use settings::*; +pub use syntax::*; + +use std::sync::Arc; use gpui2::{AppContext, HighlightStyle, Hsla, SharedString}; use settings2::Settings; -use std::sync::Arc; #[derive(Debug, Clone, PartialEq)] pub enum Appearance { @@ -24,12 +32,53 @@ pub fn init(cx: &mut AppContext) { ThemeSettings::register(cx); } -pub fn active_theme<'a>(cx: &'a AppContext) -> &'a Arc { - &ThemeSettings::get_global(cx).active_theme +pub trait ActiveTheme { + fn theme(&self) -> &ThemeVariant; } -pub fn theme(cx: &AppContext) -> Arc { - active_theme(cx).clone() +impl ActiveTheme for AppContext { + fn theme(&self) -> &ThemeVariant { + &ThemeSettings::get_global(self).active_theme + } +} + +pub struct ThemeFamily { + #[allow(dead_code)] + pub(crate) id: String, + pub name: String, + pub author: String, + pub themes: Vec, + pub scales: ColorScales, +} + +impl ThemeFamily {} + +pub struct ThemeVariant { + #[allow(dead_code)] + pub(crate) id: String, + pub name: String, + pub appearance: Appearance, + pub styles: ThemeStyle, +} + +impl ThemeVariant { + /// Returns the [`ThemeColors`] for the theme. + #[inline(always)] + pub fn colors(&self) -> &ThemeColors { + &self.styles.colors + } + + /// Returns the [`SyntaxStyles`] for the theme. + #[inline(always)] + pub fn syntax(&self) -> &SyntaxStyles { + &self.styles.syntax + } + + /// Returns the color for the syntax node with the given name. + #[inline(always)] + pub fn syntax_color(&self, name: &str) -> Hsla { + self.syntax().color(name) + } } pub struct Theme { diff --git a/crates/theme2/src/utils.rs b/crates/theme2/src/utils.rs new file mode 100644 index 0000000000..ccdcde4274 --- /dev/null +++ b/crates/theme2/src/utils.rs @@ -0,0 +1,43 @@ +/// This macro generates a struct and a corresponding struct with optional fields. +/// +/// It takes as input the name of the struct to be generated, the name of the struct with optional fields, +/// and a list of field names along with their types. +/// +/// # Example +/// ``` +/// generate_struct_with_overrides!( +/// MyStruct, +/// MyStructOverride, +/// field1: i32, +/// field2: String +/// ); +/// ``` +/// This will generate the following structs: +/// ``` +/// pub struct MyStruct { +/// pub field1: i32, +/// pub field2: String, +/// } +/// +/// pub struct MyStructOverride { +/// pub field1: Option, +/// pub field2: Option, +/// } +/// ``` +#[macro_export] +macro_rules! generate_struct_with_overrides { + ($struct_name:ident, $struct_override_name:ident, $($field:ident: $type:ty),*) => { + pub struct $struct_name { + $( + pub $field: $type, + )* + } + + #[allow(dead_code)] + pub struct $struct_override_name { + $( + pub $field: Option<$type>, + )* + } + }; +} diff --git a/crates/ui2/src/components/breadcrumb.rs b/crates/ui2/src/components/breadcrumb.rs index 6b2dfe1cce..163dfabfb0 100644 --- a/crates/ui2/src/components/breadcrumb.rs +++ b/crates/ui2/src/components/breadcrumb.rs @@ -19,24 +19,22 @@ impl Breadcrumb { } fn render_separator(&self, cx: &WindowContext) -> Div { - let theme = theme(cx); - - div().child(" › ").text_color(theme.text_muted) + div() + .child(" › ") + .text_color(cx.theme().colors().text_muted) } fn render(self, view_state: &mut V, cx: &mut ViewContext) -> impl Component { - let theme = theme(cx); - let symbols_len = self.symbols.len(); h_stack() .id("breadcrumb") .px_1() .text_sm() - .text_color(theme.text_muted) + .text_color(cx.theme().colors().text_muted) .rounded_md() - .hover(|style| style.bg(theme.ghost_element_hover)) - .active(|style| style.bg(theme.ghost_element_active)) + .hover(|style| style.bg(cx.theme().colors().ghost_element_hover)) + .active(|style| style.bg(cx.theme().colors().ghost_element_active)) .child(self.path.clone().to_str().unwrap().to_string()) .child(if !self.symbols.is_empty() { self.render_separator(cx) @@ -84,8 +82,6 @@ mod stories { type Element = Div; fn render(&mut self, cx: &mut ViewContext) -> Self::Element { - let theme = theme(cx); - Story::container(cx) .child(Story::title_for::<_, Breadcrumb>(cx)) .child(Story::label(cx, "Default")) @@ -95,21 +91,21 @@ mod stories { Symbol(vec![ HighlightedText { text: "impl ".to_string(), - color: theme.syntax.color("keyword"), + color: cx.theme().syntax_color("keyword"), }, HighlightedText { text: "BreadcrumbStory".to_string(), - color: theme.syntax.color("function"), + color: cx.theme().syntax_color("function"), }, ]), Symbol(vec![ HighlightedText { text: "fn ".to_string(), - color: theme.syntax.color("keyword"), + color: cx.theme().syntax_color("keyword"), }, HighlightedText { text: "render".to_string(), - color: theme.syntax.color("function"), + color: cx.theme().syntax_color("function"), }, ]), ], diff --git a/crates/ui2/src/components/buffer.rs b/crates/ui2/src/components/buffer.rs index 33a98b6ea9..2b3db676ce 100644 --- a/crates/ui2/src/components/buffer.rs +++ b/crates/ui2/src/components/buffer.rs @@ -155,18 +155,16 @@ impl Buffer { } fn render_row(row: BufferRow, cx: &WindowContext) -> impl Component { - let theme = theme(cx); - let line_background = if row.current { - theme.editor_active_line + cx.theme().colors().editor_active_line } else { - theme.transparent + cx.theme().styles.system.transparent }; let line_number_color = if row.current { - theme.text + cx.theme().colors().text } else { - theme.syntax.get("comment").color.unwrap_or_default() + cx.theme().syntax_color("comment") }; h_stack() @@ -216,14 +214,13 @@ impl Buffer { } fn render(self, _view: &mut V, cx: &mut ViewContext) -> impl Component { - let theme = theme(cx); let rows = self.render_rows(cx); v_stack() .flex_1() .w_full() .h_full() - .bg(theme.editor) + .bg(cx.theme().colors().editor) .children(rows) } } @@ -246,8 +243,6 @@ mod stories { type Element = Div; fn render(&mut self, cx: &mut ViewContext) -> Self::Element { - let theme = theme(cx); - Story::container(cx) .child(Story::title_for::<_, Buffer>(cx)) .child(Story::label(cx, "Default")) @@ -257,14 +252,14 @@ mod stories { div() .w(rems(64.)) .h_96() - .child(hello_world_rust_buffer_example(&theme)), + .child(hello_world_rust_buffer_example(cx)), ) .child(Story::label(cx, "Hello World (Rust) with Status")) .child( div() .w(rems(64.)) .h_96() - .child(hello_world_rust_buffer_with_status_example(&theme)), + .child(hello_world_rust_buffer_with_status_example(cx)), ) } } diff --git a/crates/ui2/src/components/buffer_search.rs b/crates/ui2/src/components/buffer_search.rs index c5539f0a4a..5d7de1b408 100644 --- a/crates/ui2/src/components/buffer_search.rs +++ b/crates/ui2/src/components/buffer_search.rs @@ -30,9 +30,7 @@ impl Render for BufferSearch { type Element = Div; fn render(&mut self, cx: &mut ViewContext) -> Div { - let theme = theme(cx); - - h_stack().bg(theme.toolbar).p_2().child( + h_stack().bg(cx.theme().colors().toolbar).p_2().child( h_stack().child(Input::new("Search")).child( IconButton::::new("replace", Icon::Replace) .when(self.is_replace_open, |this| this.color(IconColor::Accent)) diff --git a/crates/ui2/src/components/collab_panel.rs b/crates/ui2/src/components/collab_panel.rs index a8552c0f23..a0e3b55f63 100644 --- a/crates/ui2/src/components/collab_panel.rs +++ b/crates/ui2/src/components/collab_panel.rs @@ -15,27 +15,29 @@ impl CollabPanel { } fn render(self, _view: &mut V, cx: &mut ViewContext) -> impl Component { - let theme = theme(cx); - v_stack() .id(self.id.clone()) .h_full() - .bg(theme.surface) + .bg(cx.theme().colors().surface) .child( v_stack() .id("crdb") .w_full() .overflow_y_scroll() .child( - div().pb_1().border_color(theme.border).border_b().child( - List::new(static_collab_panel_current_call()) - .header( - ListHeader::new("CRDB") - .left_icon(Icon::Hash.into()) - .toggle(ToggleState::Toggled), - ) - .toggle(ToggleState::Toggled), - ), + div() + .pb_1() + .border_color(cx.theme().colors().border) + .border_b() + .child( + List::new(static_collab_panel_current_call()) + .header( + ListHeader::new("CRDB") + .left_icon(Icon::Hash.into()) + .toggle(ToggleState::Toggled), + ) + .toggle(ToggleState::Toggled), + ), ) .child( v_stack().id("channels").py_1().child( @@ -71,13 +73,13 @@ impl CollabPanel { .h_7() .px_2() .border_t() - .border_color(theme.border) + .border_color(cx.theme().colors().border) .flex() .items_center() .child( div() .text_sm() - .text_color(theme.text_placeholder) + .text_color(cx.theme().colors().text_placeholder) .child("Find..."), ), ) diff --git a/crates/ui2/src/components/context_menu.rs b/crates/ui2/src/components/context_menu.rs index 812221036a..8345be1b35 100644 --- a/crates/ui2/src/components/context_menu.rs +++ b/crates/ui2/src/components/context_menu.rs @@ -44,13 +44,11 @@ impl ContextMenu { } fn render(self, _view: &mut V, cx: &mut ViewContext) -> impl Component { - let theme = theme(cx); - v_stack() .flex() - .bg(theme.elevated_surface) + .bg(cx.theme().colors().elevated_surface) .border() - .border_color(theme.border) + .border_color(cx.theme().colors().border) .child( List::new( self.items diff --git a/crates/ui2/src/components/icon_button.rs b/crates/ui2/src/components/icon_button.rs index 980a1c98aa..06e242b1ef 100644 --- a/crates/ui2/src/components/icon_button.rs +++ b/crates/ui2/src/components/icon_button.rs @@ -66,8 +66,6 @@ impl IconButton { } fn render(self, _view: &mut V, cx: &mut ViewContext) -> impl Component { - let theme = theme(cx); - let icon_color = match (self.state, self.color) { (InteractionState::Disabled, _) => IconColor::Disabled, _ => self.color, @@ -75,14 +73,14 @@ impl IconButton { let (bg_color, bg_hover_color, bg_active_color) = match self.variant { ButtonVariant::Filled => ( - theme.filled_element, - theme.filled_element_hover, - theme.filled_element_active, + cx.theme().colors().element, + cx.theme().colors().element_hover, + cx.theme().colors().element_active, ), ButtonVariant::Ghost => ( - theme.ghost_element, - theme.ghost_element_hover, - theme.ghost_element_active, + cx.theme().colors().ghost_element, + cx.theme().colors().ghost_element_hover, + cx.theme().colors().ghost_element_active, ), }; diff --git a/crates/ui2/src/components/keybinding.rs b/crates/ui2/src/components/keybinding.rs index 455cfe5b59..88cabbdc88 100644 --- a/crates/ui2/src/components/keybinding.rs +++ b/crates/ui2/src/components/keybinding.rs @@ -60,15 +60,13 @@ impl Key { } fn render(self, _view: &mut V, cx: &mut ViewContext) -> impl Component { - let theme = theme(cx); - div() .px_2() .py_0() .rounded_md() .text_sm() - .text_color(theme.text) - .bg(theme.filled_element) + .text_color(cx.theme().colors().text) + .bg(cx.theme().colors().element) .child(self.key.clone()) } } diff --git a/crates/ui2/src/components/list.rs b/crates/ui2/src/components/list.rs index 9557e68d7f..1668592a38 100644 --- a/crates/ui2/src/components/list.rs +++ b/crates/ui2/src/components/list.rs @@ -89,8 +89,6 @@ impl ListHeader { } fn render(self, _view: &mut V, cx: &mut ViewContext) -> impl Component { - let theme = theme(cx); - let is_toggleable = self.toggleable != Toggleable::NotToggleable; let is_toggled = self.toggleable.is_toggled(); @@ -99,9 +97,10 @@ impl ListHeader { h_stack() .flex_1() .w_full() - .bg(theme.surface) + .bg(cx.theme().colors().surface) .when(self.state == InteractionState::Focused, |this| { - this.border().border_color(theme.border_focused) + this.border() + .border_color(cx.theme().colors().border_focused) }) .relative() .child( @@ -363,7 +362,6 @@ impl ListEntry { fn render(mut self, _view: &mut V, cx: &mut ViewContext) -> impl Component { let settings = user_settings(cx); - let theme = theme(cx); let left_content = match self.left_content.clone() { Some(LeftContent::Icon(i)) => Some( @@ -385,9 +383,10 @@ impl ListEntry { div() .relative() .group("") - .bg(theme.surface) + .bg(cx.theme().colors().surface) .when(self.state == InteractionState::Focused, |this| { - this.border().border_color(theme.border_focused) + this.border() + .border_color(cx.theme().colors().border_focused) }) .child( sized_item @@ -399,11 +398,11 @@ impl ListEntry { .h_full() .flex() .justify_center() - .group_hover("", |style| style.bg(theme.border_focused)) + .group_hover("", |style| style.bg(cx.theme().colors().border_focused)) .child( h_stack() .child(div().w_px().h_full()) - .child(div().w_px().h_full().bg(theme.border)), + .child(div().w_px().h_full().bg(cx.theme().colors().border)), ) })) .flex() @@ -472,19 +471,18 @@ impl ListDetailsEntry { } fn render(self, _view: &mut V, cx: &mut ViewContext) -> impl Component { - let theme = theme(cx); let settings = user_settings(cx); let (item_bg, item_bg_hover, item_bg_active) = match self.seen { true => ( - theme.ghost_element, - theme.ghost_element_hover, - theme.ghost_element_active, + cx.theme().colors().ghost_element, + cx.theme().colors().ghost_element_hover, + cx.theme().colors().ghost_element_active, ), false => ( - theme.filled_element, - theme.filled_element_hover, - theme.filled_element_active, + cx.theme().colors().element, + cx.theme().colors().element_hover, + cx.theme().colors().element_active, ), }; @@ -524,9 +522,7 @@ impl ListSeparator { } fn render(self, _view: &mut V, cx: &mut ViewContext) -> impl Component { - let theme = theme(cx); - - div().h_px().w_full().bg(theme.border) + div().h_px().w_full().bg(cx.theme().colors().border) } } diff --git a/crates/ui2/src/components/modal.rs b/crates/ui2/src/components/modal.rs index 7c3efe79ba..26986474e0 100644 --- a/crates/ui2/src/components/modal.rs +++ b/crates/ui2/src/components/modal.rs @@ -39,22 +39,20 @@ impl Modal { } fn render(self, _view: &mut V, cx: &mut ViewContext) -> impl Component { - let theme = theme(cx); - v_stack() .id(self.id.clone()) .w_96() // .rounded_xl() - .bg(theme.background) + .bg(cx.theme().colors().background) .border() - .border_color(theme.border) + .border_color(cx.theme().colors().border) .shadow_2xl() .child( h_stack() .justify_between() .p_1() .border_b() - .border_color(theme.border) + .border_color(cx.theme().colors().border) .child(div().children(self.title.clone().map(|t| Label::new(t)))) .child(IconButton::new("close", Icon::Close)), ) @@ -65,7 +63,7 @@ impl Modal { this.child( h_stack() .border_t() - .border_color(theme.border) + .border_color(cx.theme().colors().border) .p_1() .justify_end() .children(self.secondary_action) diff --git a/crates/ui2/src/components/multi_buffer.rs b/crates/ui2/src/components/multi_buffer.rs index 696fc77a62..ea130f20bd 100644 --- a/crates/ui2/src/components/multi_buffer.rs +++ b/crates/ui2/src/components/multi_buffer.rs @@ -12,8 +12,6 @@ impl MultiBuffer { } fn render(self, _view: &mut V, cx: &mut ViewContext) -> impl Component { - let theme = theme(cx); - v_stack() .w_full() .h_full() @@ -26,7 +24,7 @@ impl MultiBuffer { .items_center() .justify_between() .p_4() - .bg(theme.editor_subheader) + .bg(cx.theme().colors().editor_subheader) .child(Label::new("main.rs")) .child(IconButton::new("arrow_up_right", Icon::ArrowUpRight)), ) @@ -50,17 +48,15 @@ mod stories { type Element = Div; fn render(&mut self, cx: &mut ViewContext) -> Self::Element { - let theme = theme(cx); - Story::container(cx) .child(Story::title_for::<_, MultiBuffer>(cx)) .child(Story::label(cx, "Default")) .child(MultiBuffer::new(vec![ - hello_world_rust_buffer_example(&theme), - hello_world_rust_buffer_example(&theme), - hello_world_rust_buffer_example(&theme), - hello_world_rust_buffer_example(&theme), - hello_world_rust_buffer_example(&theme), + hello_world_rust_buffer_example(cx), + hello_world_rust_buffer_example(cx), + hello_world_rust_buffer_example(cx), + hello_world_rust_buffer_example(cx), + hello_world_rust_buffer_example(cx), ])) } } diff --git a/crates/ui2/src/components/notification_toast.rs b/crates/ui2/src/components/notification_toast.rs index f7d280ed16..59078c98f4 100644 --- a/crates/ui2/src/components/notification_toast.rs +++ b/crates/ui2/src/components/notification_toast.rs @@ -1,6 +1,7 @@ use gpui2::rems; -use crate::{h_stack, prelude::*, Icon}; +use crate::prelude::*; +use crate::{h_stack, Icon}; #[derive(Component)] pub struct NotificationToast { @@ -22,8 +23,6 @@ impl NotificationToast { } fn render(self, _view: &mut V, cx: &mut ViewContext) -> impl Component { - let theme = theme(cx); - h_stack() .z_index(5) .absolute() @@ -35,7 +34,7 @@ impl NotificationToast { .px_1p5() .rounded_lg() .shadow_md() - .bg(theme.elevated_surface) + .bg(cx.theme().colors().elevated_surface) .child(div().size_full().child(self.label.clone())) } } diff --git a/crates/ui2/src/components/notifications_panel.rs b/crates/ui2/src/components/notifications_panel.rs index 6872f116e9..10b0e07af6 100644 --- a/crates/ui2/src/components/notifications_panel.rs +++ b/crates/ui2/src/components/notifications_panel.rs @@ -12,15 +12,13 @@ impl NotificationsPanel { } fn render(self, _view: &mut V, cx: &mut ViewContext) -> impl Component { - let theme = theme(cx); - div() .id(self.id.clone()) .flex() .flex_col() .w_full() .h_full() - .bg(theme.surface) + .bg(cx.theme().colors().surface) .child( div() .id("header") diff --git a/crates/ui2/src/components/palette.rs b/crates/ui2/src/components/palette.rs index e47f6a4cea..a1f3eb7e1c 100644 --- a/crates/ui2/src/components/palette.rs +++ b/crates/ui2/src/components/palette.rs @@ -43,22 +43,20 @@ impl Palette { } fn render(self, _view: &mut V, cx: &mut ViewContext) -> impl Component { - let theme = theme(cx); - v_stack() .id(self.id.clone()) .w_96() .rounded_lg() - .bg(theme.elevated_surface) + .bg(cx.theme().colors().elevated_surface) .border() - .border_color(theme.border) + .border_color(cx.theme().colors().border) .child( v_stack() .gap_px() .child(v_stack().py_0p5().px_1().child(div().px_2().py_0p5().child( Label::new(self.input_placeholder.clone()).color(LabelColor::Placeholder), ))) - .child(div().h_px().w_full().bg(theme.filled_element)) + .child(div().h_px().w_full().bg(cx.theme().colors().element)) .child( v_stack() .id("items") @@ -88,8 +86,12 @@ impl Palette { .px_2() .py_0p5() .rounded_lg() - .hover(|style| style.bg(theme.ghost_element_hover)) - .active(|style| style.bg(theme.ghost_element_active)) + .hover(|style| { + style.bg(cx.theme().colors().ghost_element_hover) + }) + .active(|style| { + style.bg(cx.theme().colors().ghost_element_active) + }) .child(item) })), ), diff --git a/crates/ui2/src/components/panel.rs b/crates/ui2/src/components/panel.rs index 12d2207ffd..c4a9ac5111 100644 --- a/crates/ui2/src/components/panel.rs +++ b/crates/ui2/src/components/panel.rs @@ -93,8 +93,6 @@ impl Panel { } fn render(self, _view: &mut V, cx: &mut ViewContext) -> impl Component { - let theme = theme(cx); - let current_size = self.width.unwrap_or(self.initial_width); v_stack() @@ -111,8 +109,8 @@ impl Panel { .when(self.current_side == PanelSide::Bottom, |this| { this.border_b().w_full().h(current_size) }) - .bg(theme.surface) - .border_color(theme.border) + .bg(cx.theme().colors().surface) + .border_color(cx.theme().colors().border) .children(self.children) } } diff --git a/crates/ui2/src/components/panes.rs b/crates/ui2/src/components/panes.rs index 854786ebaa..167e837083 100644 --- a/crates/ui2/src/components/panes.rs +++ b/crates/ui2/src/components/panes.rs @@ -90,8 +90,6 @@ impl PaneGroup { } fn render(self, view: &mut V, cx: &mut ViewContext) -> impl Component { - let theme = theme(cx); - if !self.panes.is_empty() { let el = div() .flex() @@ -115,7 +113,7 @@ impl PaneGroup { .gap_px() .w_full() .h_full() - .bg(theme.editor) + .bg(cx.theme().colors().editor) .children(self.groups.into_iter().map(|group| group.render(view, cx))); if self.split_direction == SplitDirection::Horizontal { diff --git a/crates/ui2/src/components/player_stack.rs b/crates/ui2/src/components/player_stack.rs index ced761a086..1a1231e6c4 100644 --- a/crates/ui2/src/components/player_stack.rs +++ b/crates/ui2/src/components/player_stack.rs @@ -14,9 +14,7 @@ impl PlayerStack { } fn render(self, _view: &mut V, cx: &mut ViewContext) -> impl Component { - let theme = theme(cx); let player = self.player_with_call_status.get_player(); - self.player_with_call_status.get_call_status(); let followers = self .player_with_call_status @@ -50,7 +48,7 @@ impl PlayerStack { .pl_1() .rounded_lg() .bg(if followers.is_none() { - theme.transparent + cx.theme().styles.system.transparent } else { player.selection_color(cx) }) diff --git a/crates/ui2/src/components/project_panel.rs b/crates/ui2/src/components/project_panel.rs index 84c68119fe..76fa50d338 100644 --- a/crates/ui2/src/components/project_panel.rs +++ b/crates/ui2/src/components/project_panel.rs @@ -14,15 +14,13 @@ impl ProjectPanel { } fn render(self, _view: &mut V, cx: &mut ViewContext) -> impl Component { - let theme = theme(cx); - div() .id(self.id.clone()) .flex() .flex_col() .w_full() .h_full() - .bg(theme.surface) + .bg(cx.theme().colors().surface) .child( div() .id("project-panel-contents") diff --git a/crates/ui2/src/components/status_bar.rs b/crates/ui2/src/components/status_bar.rs index a23040193f..136472f605 100644 --- a/crates/ui2/src/components/status_bar.rs +++ b/crates/ui2/src/components/status_bar.rs @@ -86,8 +86,6 @@ impl StatusBar { view: &mut Workspace, cx: &mut ViewContext, ) -> impl Component { - let theme = theme(cx); - div() .py_0p5() .px_1() @@ -95,7 +93,7 @@ impl StatusBar { .items_center() .justify_between() .w_full() - .bg(theme.status_bar) + .bg(cx.theme().colors().status_bar) .child(self.left_tools(view, cx)) .child(self.right_tools(view, cx)) } diff --git a/crates/ui2/src/components/tab.rs b/crates/ui2/src/components/tab.rs index d784ec0174..5f20af0955 100644 --- a/crates/ui2/src/components/tab.rs +++ b/crates/ui2/src/components/tab.rs @@ -87,7 +87,6 @@ impl Tab { } fn render(self, _view: &mut V, cx: &mut ViewContext) -> impl Component { - let theme = theme(cx); let has_fs_conflict = self.fs_status == FileSystemStatus::Conflict; let is_deleted = self.fs_status == FileSystemStatus::Deleted; @@ -110,14 +109,14 @@ impl Tab { let (tab_bg, tab_hover_bg, tab_active_bg) = match self.current { true => ( - theme.ghost_element, - theme.ghost_element_hover, - theme.ghost_element_active, + cx.theme().colors().ghost_element, + cx.theme().colors().ghost_element_hover, + cx.theme().colors().ghost_element_active, ), false => ( - theme.filled_element, - theme.filled_element_hover, - theme.filled_element_active, + cx.theme().colors().element, + cx.theme().colors().element_hover, + cx.theme().colors().element_active, ), }; diff --git a/crates/ui2/src/components/tab_bar.rs b/crates/ui2/src/components/tab_bar.rs index da0a41a1bf..550105b98e 100644 --- a/crates/ui2/src/components/tab_bar.rs +++ b/crates/ui2/src/components/tab_bar.rs @@ -24,15 +24,13 @@ impl TabBar { } fn render(self, _view: &mut V, cx: &mut ViewContext) -> impl Component { - let theme = theme(cx); - let (can_navigate_back, can_navigate_forward) = self.can_navigate; div() .id(self.id.clone()) .w_full() .flex() - .bg(theme.tab_bar) + .bg(cx.theme().colors().tab_bar) // Left Side .child( div() diff --git a/crates/ui2/src/components/terminal.rs b/crates/ui2/src/components/terminal.rs index a751d47dfc..051ebf7315 100644 --- a/crates/ui2/src/components/terminal.rs +++ b/crates/ui2/src/components/terminal.rs @@ -12,8 +12,6 @@ impl Terminal { } fn render(self, _view: &mut V, cx: &mut ViewContext) -> impl Component { - let theme = theme(cx); - let can_navigate_back = true; let can_navigate_forward = false; @@ -26,7 +24,7 @@ impl Terminal { div() .w_full() .flex() - .bg(theme.surface) + .bg(cx.theme().colors().surface) .child( div().px_1().flex().flex_none().gap_2().child( div() @@ -73,7 +71,7 @@ impl Terminal { height: rems(36.).into(), }, ) - .child(crate::static_data::terminal_buffer(&theme)), + .child(crate::static_data::terminal_buffer(cx)), ) } } diff --git a/crates/ui2/src/components/title_bar.rs b/crates/ui2/src/components/title_bar.rs index 4b3b125dea..2fa201440a 100644 --- a/crates/ui2/src/components/title_bar.rs +++ b/crates/ui2/src/components/title_bar.rs @@ -89,7 +89,6 @@ impl Render for TitleBar { type Element = Div; fn render(&mut self, cx: &mut ViewContext) -> Div { - let theme = theme(cx); let settings = user_settings(cx); // let has_focus = cx.window_is_active(); @@ -106,7 +105,7 @@ impl Render for TitleBar { .items_center() .justify_between() .w_full() - .bg(theme.background) + .bg(cx.theme().colors().background) .py_1() .child( div() diff --git a/crates/ui2/src/components/toast.rs b/crates/ui2/src/components/toast.rs index 814e91c498..3b81ac42b4 100644 --- a/crates/ui2/src/components/toast.rs +++ b/crates/ui2/src/components/toast.rs @@ -37,8 +37,6 @@ impl Toast { } fn render(self, _view: &mut V, cx: &mut ViewContext) -> impl Component { - let theme = theme(cx); - let mut div = div(); if self.origin == ToastOrigin::Bottom { @@ -56,7 +54,7 @@ impl Toast { .rounded_lg() .shadow_md() .overflow_hidden() - .bg(theme.elevated_surface) + .bg(cx.theme().colors().elevated_surface) .children(self.children) } } diff --git a/crates/ui2/src/components/toolbar.rs b/crates/ui2/src/components/toolbar.rs index 4b35e2d9d2..05a5c991d6 100644 --- a/crates/ui2/src/components/toolbar.rs +++ b/crates/ui2/src/components/toolbar.rs @@ -55,10 +55,8 @@ impl Toolbar { } fn render(self, _view: &mut V, cx: &mut ViewContext) -> impl Component { - let theme = theme(cx); - div() - .bg(theme.toolbar) + .bg(cx.theme().colors().toolbar) .p_2() .flex() .justify_between() @@ -87,8 +85,6 @@ mod stories { type Element = Div; fn render(&mut self, cx: &mut ViewContext) -> Self::Element { - let theme = theme(cx); - Story::container(cx) .child(Story::title_for::<_, Toolbar>(cx)) .child(Story::label(cx, "Default")) @@ -100,21 +96,21 @@ mod stories { Symbol(vec![ HighlightedText { text: "impl ".to_string(), - color: theme.syntax.color("keyword"), + color: cx.theme().syntax_color("keyword"), }, HighlightedText { text: "ToolbarStory".to_string(), - color: theme.syntax.color("function"), + color: cx.theme().syntax_color("function"), }, ]), Symbol(vec![ HighlightedText { text: "fn ".to_string(), - color: theme.syntax.color("keyword"), + color: cx.theme().syntax_color("keyword"), }, HighlightedText { text: "render".to_string(), - color: theme.syntax.color("function"), + color: cx.theme().syntax_color("function"), }, ]), ], diff --git a/crates/ui2/src/components/traffic_lights.rs b/crates/ui2/src/components/traffic_lights.rs index 8ee19d26f5..9080276cdd 100644 --- a/crates/ui2/src/components/traffic_lights.rs +++ b/crates/ui2/src/components/traffic_lights.rs @@ -22,13 +22,13 @@ impl TrafficLight { } fn render(self, _view: &mut V, cx: &mut ViewContext) -> impl Component { - let theme = theme(cx); + let system_colors = &cx.theme().styles.system; let fill = match (self.window_has_focus, self.color) { - (true, TrafficLightColor::Red) => theme.mac_os_traffic_light_red, - (true, TrafficLightColor::Yellow) => theme.mac_os_traffic_light_yellow, - (true, TrafficLightColor::Green) => theme.mac_os_traffic_light_green, - (false, _) => theme.filled_element, + (true, TrafficLightColor::Red) => system_colors.mac_os_traffic_light_red, + (true, TrafficLightColor::Yellow) => system_colors.mac_os_traffic_light_yellow, + (true, TrafficLightColor::Green) => system_colors.mac_os_traffic_light_green, + (false, _) => cx.theme().colors().element, }; div().w_3().h_3().rounded_full().bg(fill) diff --git a/crates/ui2/src/components/workspace.rs b/crates/ui2/src/components/workspace.rs index 78ab6232a8..0e31c6b9ad 100644 --- a/crates/ui2/src/components/workspace.rs +++ b/crates/ui2/src/components/workspace.rs @@ -179,8 +179,6 @@ impl Render for Workspace { type Element = Div; fn render(&mut self, cx: &mut ViewContext) -> Div { - let theme = theme(cx); - // HACK: This should happen inside of `debug_toggle_user_settings`, but // we don't have `cx.global::()` in event handlers at the moment. // Need to talk with Nathan/Antonio about this. @@ -216,8 +214,8 @@ impl Render for Workspace { .gap_0() .justify_start() .items_start() - .text_color(theme.text) - .bg(theme.background) + .text_color(cx.theme().colors().text) + .bg(cx.theme().colors().background) .child(self.title_bar.clone()) .child( div() @@ -228,7 +226,7 @@ impl Render for Workspace { .overflow_hidden() .border_t() .border_b() - .border_color(theme.border) + .border_color(cx.theme().colors().border) .children( Some( Panel::new("project-panel-outer", cx) diff --git a/crates/ui2/src/elements/avatar.rs b/crates/ui2/src/elements/avatar.rs index f008eeb479..ff92021b11 100644 --- a/crates/ui2/src/elements/avatar.rs +++ b/crates/ui2/src/elements/avatar.rs @@ -22,8 +22,6 @@ impl Avatar { } fn render(self, _view: &mut V, cx: &mut ViewContext) -> impl Component { - let theme = theme(cx); - let mut img = img(); if self.shape == Shape::Circle { @@ -34,7 +32,8 @@ impl Avatar { img.uri(self.src.clone()) .size_4() - .bg(theme.image_fallback_background) + // todo!(Pull the avatar fallback background from the theme.) + .bg(gpui2::red()) } } diff --git a/crates/ui2/src/elements/button.rs b/crates/ui2/src/elements/button.rs index d27a0537d8..e63269197c 100644 --- a/crates/ui2/src/elements/button.rs +++ b/crates/ui2/src/elements/button.rs @@ -21,29 +21,23 @@ pub enum ButtonVariant { impl ButtonVariant { pub fn bg_color(&self, cx: &mut WindowContext) -> Hsla { - let theme = theme(cx); - match self { - ButtonVariant::Ghost => theme.ghost_element, - ButtonVariant::Filled => theme.filled_element, + ButtonVariant::Ghost => cx.theme().colors().ghost_element, + ButtonVariant::Filled => cx.theme().colors().element, } } pub fn bg_color_hover(&self, cx: &mut WindowContext) -> Hsla { - let theme = theme(cx); - match self { - ButtonVariant::Ghost => theme.ghost_element_hover, - ButtonVariant::Filled => theme.filled_element_hover, + ButtonVariant::Ghost => cx.theme().colors().ghost_element_hover, + ButtonVariant::Filled => cx.theme().colors().element_hover, } } pub fn bg_color_active(&self, cx: &mut WindowContext) -> Hsla { - let theme = theme(cx); - match self { - ButtonVariant::Ghost => theme.ghost_element_active, - ButtonVariant::Filled => theme.filled_element_active, + ButtonVariant::Ghost => cx.theme().colors().ghost_element_active, + ButtonVariant::Filled => cx.theme().colors().element_active, } } } diff --git a/crates/ui2/src/elements/details.rs b/crates/ui2/src/elements/details.rs index eca7798c82..1d22c81774 100644 --- a/crates/ui2/src/elements/details.rs +++ b/crates/ui2/src/elements/details.rs @@ -1,4 +1,5 @@ -use crate::{prelude::*, v_stack, ButtonGroup}; +use crate::prelude::*; +use crate::{v_stack, ButtonGroup}; #[derive(Component)] pub struct Details { @@ -27,13 +28,11 @@ impl Details { } fn render(self, _view: &mut V, cx: &mut ViewContext) -> impl Component { - let theme = theme(cx); - v_stack() .p_1() .gap_0p5() .text_xs() - .text_color(theme.text) + .text_color(cx.theme().colors().text) .size_full() .child(self.text) .children(self.meta.map(|m| m)) diff --git a/crates/ui2/src/elements/icon.rs b/crates/ui2/src/elements/icon.rs index 4e4ec2bce7..6c1b3a4f08 100644 --- a/crates/ui2/src/elements/icon.rs +++ b/crates/ui2/src/elements/icon.rs @@ -26,13 +26,14 @@ pub enum IconColor { impl IconColor { pub fn color(self, cx: &WindowContext) -> Hsla { - let theme = theme(cx); + let theme_colors = cx.theme().colors(); + match self { - IconColor::Default => gpui2::red(), - IconColor::Muted => gpui2::red(), - IconColor::Disabled => gpui2::red(), - IconColor::Placeholder => gpui2::red(), - IconColor::Accent => gpui2::red(), + IconColor::Default => theme_colors.icon, + IconColor::Muted => theme_colors.icon_muted, + IconColor::Disabled => theme_colors.icon_disabled, + IconColor::Placeholder => theme_colors.icon_placeholder, + IconColor::Accent => theme_colors.icon_accent, IconColor::Error => gpui2::red(), IconColor::Warning => gpui2::red(), IconColor::Success => gpui2::red(), diff --git a/crates/ui2/src/elements/input.rs b/crates/ui2/src/elements/input.rs index e9e92dd0a6..3f82512b84 100644 --- a/crates/ui2/src/elements/input.rs +++ b/crates/ui2/src/elements/input.rs @@ -57,18 +57,16 @@ impl Input { } fn render(self, _view: &mut V, cx: &mut ViewContext) -> impl Component { - let theme = theme(cx); - let (input_bg, input_hover_bg, input_active_bg) = match self.variant { InputVariant::Ghost => ( - theme.ghost_element, - theme.ghost_element_hover, - theme.ghost_element_active, + cx.theme().colors().ghost_element, + cx.theme().colors().ghost_element_hover, + cx.theme().colors().ghost_element_active, ), InputVariant::Filled => ( - theme.filled_element, - theme.filled_element_hover, - theme.filled_element_active, + cx.theme().colors().element, + cx.theme().colors().element_hover, + cx.theme().colors().element_active, ), }; @@ -90,7 +88,7 @@ impl Input { .w_full() .px_2() .border() - .border_color(theme.transparent) + .border_color(cx.theme().styles.system.transparent) .bg(input_bg) .hover(|style| style.bg(input_hover_bg)) .active(|style| style.bg(input_active_bg)) diff --git a/crates/ui2/src/elements/label.rs b/crates/ui2/src/elements/label.rs index 4d336345fb..ee8ac9a636 100644 --- a/crates/ui2/src/elements/label.rs +++ b/crates/ui2/src/elements/label.rs @@ -18,18 +18,16 @@ pub enum LabelColor { impl LabelColor { pub fn hsla(&self, cx: &WindowContext) -> Hsla { - let theme = theme(cx); - match self { - Self::Default => theme.text, - Self::Muted => theme.text_muted, + Self::Default => cx.theme().colors().text, + Self::Muted => cx.theme().colors().text_muted, Self::Created => gpui2::red(), Self::Modified => gpui2::red(), Self::Deleted => gpui2::red(), - Self::Disabled => theme.text_disabled, + Self::Disabled => cx.theme().colors().text_disabled, Self::Hidden => gpui2::red(), - Self::Placeholder => theme.text_placeholder, - Self::Accent => gpui2::red(), + Self::Placeholder => cx.theme().colors().text_placeholder, + Self::Accent => cx.theme().colors().text_accent, } } } @@ -126,9 +124,7 @@ impl HighlightedLabel { } fn render(self, _view: &mut V, cx: &mut ViewContext) -> impl Component { - let theme = theme(cx); - - let highlight_color = theme.text_accent; + let highlight_color = cx.theme().colors().text_accent; let mut highlight_indices = self.highlight_indices.iter().copied().peekable(); diff --git a/crates/ui2/src/elements/player.rs b/crates/ui2/src/elements/player.rs index 5bf890b8bb..8e3ad5c3a8 100644 --- a/crates/ui2/src/elements/player.rs +++ b/crates/ui2/src/elements/player.rs @@ -1,6 +1,6 @@ use gpui2::{Hsla, ViewContext}; -use crate::theme; +use crate::prelude::*; #[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)] pub enum PlayerStatus { @@ -139,13 +139,11 @@ impl Player { } pub fn cursor_color(&self, cx: &mut ViewContext) -> Hsla { - let theme = theme(cx); - theme.players[self.index].cursor + cx.theme().styles.player.0[self.index].cursor } pub fn selection_color(&self, cx: &mut ViewContext) -> Hsla { - let theme = theme(cx); - theme.players[self.index].selection + cx.theme().styles.player.0[self.index].selection } pub fn avatar_src(&self) -> &str { diff --git a/crates/ui2/src/elements/tool_divider.rs b/crates/ui2/src/elements/tool_divider.rs index e1ebb294a0..8a9bbad97f 100644 --- a/crates/ui2/src/elements/tool_divider.rs +++ b/crates/ui2/src/elements/tool_divider.rs @@ -9,8 +9,6 @@ impl ToolDivider { } fn render(self, _view: &mut V, cx: &mut ViewContext) -> impl Component { - let theme = theme(cx); - - div().w_px().h_3().bg(theme.border) + div().w_px().h_3().bg(cx.theme().colors().border) } } diff --git a/crates/ui2/src/prelude.rs b/crates/ui2/src/prelude.rs index 63405fc2cb..b424ce6123 100644 --- a/crates/ui2/src/prelude.rs +++ b/crates/ui2/src/prelude.rs @@ -6,7 +6,7 @@ pub use gpui2::{ pub use crate::elevation::*; use crate::settings::user_settings; pub use crate::ButtonVariant; -pub use theme2::theme; +pub use theme2::ActiveTheme; use gpui2::{rems, Hsla, Rems}; use strum::EnumIter; @@ -54,15 +54,13 @@ pub enum GitStatus { impl GitStatus { pub fn hsla(&self, cx: &WindowContext) -> Hsla { - let theme = theme(cx); - match self { - Self::None => theme.transparent, - Self::Created => theme.git_created, - Self::Modified => theme.git_modified, - Self::Deleted => theme.git_deleted, - Self::Conflict => theme.git_conflict, - Self::Renamed => theme.git_renamed, + Self::None => cx.theme().styles.system.transparent, + Self::Created => cx.theme().styles.git.created, + Self::Modified => cx.theme().styles.git.modified, + Self::Deleted => cx.theme().styles.git.deleted, + Self::Conflict => cx.theme().styles.git.conflict, + Self::Renamed => cx.theme().styles.git.renamed, } } } diff --git a/crates/ui2/src/static_data.rs b/crates/ui2/src/static_data.rs index 68f1e36b2c..7062c81954 100644 --- a/crates/ui2/src/static_data.rs +++ b/crates/ui2/src/static_data.rs @@ -1,12 +1,12 @@ use std::path::PathBuf; use std::str::FromStr; -use gpui2::ViewContext; +use gpui2::{AppContext, ViewContext}; use rand::Rng; -use theme2::Theme; +use theme2::ActiveTheme; use crate::{ - theme, Buffer, BufferRow, BufferRows, Button, EditorPane, FileSystemStatus, GitStatus, + Buffer, BufferRow, BufferRows, Button, EditorPane, FileSystemStatus, GitStatus, HighlightedLine, Icon, Keybinding, Label, LabelColor, ListEntry, ListEntrySize, ListItem, Livestream, MicStatus, ModifierKeys, PaletteItem, Player, PlayerCallStatus, PlayerWithCallStatus, ScreenShareStatus, Symbol, Tab, ToggleState, VideoStatus, @@ -643,8 +643,6 @@ pub fn empty_buffer_example() -> Buffer { } pub fn hello_world_rust_editor_example(cx: &mut ViewContext) -> EditorPane { - let theme = theme(cx); - EditorPane::new( cx, static_tabs_example(), @@ -652,29 +650,29 @@ pub fn hello_world_rust_editor_example(cx: &mut ViewContext) -> Edit vec![Symbol(vec![ HighlightedText { text: "fn ".to_string(), - color: theme.syntax.color("keyword"), + color: cx.theme().syntax_color("keyword"), }, HighlightedText { text: "main".to_string(), - color: theme.syntax.color("function"), + color: cx.theme().syntax_color("function"), }, ])], - hello_world_rust_buffer_example(&theme), + hello_world_rust_buffer_example(cx), ) } -pub fn hello_world_rust_buffer_example(theme: &Theme) -> Buffer { +pub fn hello_world_rust_buffer_example(cx: &AppContext) -> Buffer { Buffer::new("hello-world-rust-buffer") .set_title("hello_world.rs".to_string()) .set_path("src/hello_world.rs".to_string()) .set_language("rust".to_string()) .set_rows(Some(BufferRows { show_line_numbers: true, - rows: hello_world_rust_buffer_rows(theme), + rows: hello_world_rust_buffer_rows(cx), })) } -pub fn hello_world_rust_buffer_rows(theme: &Theme) -> Vec { +pub fn hello_world_rust_buffer_rows(cx: &AppContext) -> Vec { let show_line_number = true; vec![ @@ -686,15 +684,15 @@ pub fn hello_world_rust_buffer_rows(theme: &Theme) -> Vec { highlighted_texts: vec![ HighlightedText { text: "fn ".to_string(), - color: theme.syntax.color("keyword"), + color: cx.theme().syntax_color("keyword"), }, HighlightedText { text: "main".to_string(), - color: theme.syntax.color("function"), + color: cx.theme().syntax_color("function"), }, HighlightedText { text: "() {".to_string(), - color: theme.text, + color: cx.theme().colors().text, }, ], }), @@ -710,7 +708,7 @@ pub fn hello_world_rust_buffer_rows(theme: &Theme) -> Vec { highlighted_texts: vec![HighlightedText { text: " // Statements here are executed when the compiled binary is called." .to_string(), - color: theme.syntax.color("comment"), + color: cx.theme().syntax_color("comment"), }], }), cursors: None, @@ -733,7 +731,7 @@ pub fn hello_world_rust_buffer_rows(theme: &Theme) -> Vec { line: Some(HighlightedLine { highlighted_texts: vec![HighlightedText { text: " // Print text to the console.".to_string(), - color: theme.syntax.color("comment"), + color: cx.theme().syntax_color("comment"), }], }), cursors: None, @@ -748,15 +746,15 @@ pub fn hello_world_rust_buffer_rows(theme: &Theme) -> Vec { highlighted_texts: vec![ HighlightedText { text: " println!(".to_string(), - color: theme.text, + color: cx.theme().colors().text, }, HighlightedText { text: "\"Hello, world!\"".to_string(), - color: theme.syntax.color("string"), + color: cx.theme().syntax_color("string"), }, HighlightedText { text: ");".to_string(), - color: theme.text, + color: cx.theme().colors().text, }, ], }), @@ -771,7 +769,7 @@ pub fn hello_world_rust_buffer_rows(theme: &Theme) -> Vec { line: Some(HighlightedLine { highlighted_texts: vec![HighlightedText { text: "}".to_string(), - color: theme.text, + color: cx.theme().colors().text, }], }), cursors: None, @@ -782,8 +780,6 @@ pub fn hello_world_rust_buffer_rows(theme: &Theme) -> Vec { } pub fn hello_world_rust_editor_with_status_example(cx: &mut ViewContext) -> EditorPane { - let theme = theme(cx); - EditorPane::new( cx, static_tabs_example(), @@ -791,29 +787,29 @@ pub fn hello_world_rust_editor_with_status_example(cx: &mut ViewContext Buffer { +pub fn hello_world_rust_buffer_with_status_example(cx: &AppContext) -> Buffer { Buffer::new("hello-world-rust-buffer-with-status") .set_title("hello_world.rs".to_string()) .set_path("src/hello_world.rs".to_string()) .set_language("rust".to_string()) .set_rows(Some(BufferRows { show_line_numbers: true, - rows: hello_world_rust_with_status_buffer_rows(theme), + rows: hello_world_rust_with_status_buffer_rows(cx), })) } -pub fn hello_world_rust_with_status_buffer_rows(theme: &Theme) -> Vec { +pub fn hello_world_rust_with_status_buffer_rows(cx: &AppContext) -> Vec { let show_line_number = true; vec![ @@ -825,15 +821,15 @@ pub fn hello_world_rust_with_status_buffer_rows(theme: &Theme) -> Vec highlighted_texts: vec![ HighlightedText { text: "fn ".to_string(), - color: theme.syntax.color("keyword"), + color: cx.theme().syntax_color("keyword"), }, HighlightedText { text: "main".to_string(), - color: theme.syntax.color("function"), + color: cx.theme().syntax_color("function"), }, HighlightedText { text: "() {".to_string(), - color: theme.text, + color: cx.theme().colors().text, }, ], }), @@ -849,7 +845,7 @@ pub fn hello_world_rust_with_status_buffer_rows(theme: &Theme) -> Vec highlighted_texts: vec![HighlightedText { text: "// Statements here are executed when the compiled binary is called." .to_string(), - color: theme.syntax.color("comment"), + color: cx.theme().syntax_color("comment"), }], }), cursors: None, @@ -872,7 +868,7 @@ pub fn hello_world_rust_with_status_buffer_rows(theme: &Theme) -> Vec line: Some(HighlightedLine { highlighted_texts: vec![HighlightedText { text: " // Print text to the console.".to_string(), - color: theme.syntax.color("comment"), + color: cx.theme().syntax_color("comment"), }], }), cursors: None, @@ -887,15 +883,15 @@ pub fn hello_world_rust_with_status_buffer_rows(theme: &Theme) -> Vec highlighted_texts: vec![ HighlightedText { text: " println!(".to_string(), - color: theme.text, + color: cx.theme().colors().text, }, HighlightedText { text: "\"Hello, world!\"".to_string(), - color: theme.syntax.color("string"), + color: cx.theme().syntax_color("string"), }, HighlightedText { text: ");".to_string(), - color: theme.text, + color: cx.theme().colors().text, }, ], }), @@ -910,7 +906,7 @@ pub fn hello_world_rust_with_status_buffer_rows(theme: &Theme) -> Vec line: Some(HighlightedLine { highlighted_texts: vec![HighlightedText { text: "}".to_string(), - color: theme.text, + color: cx.theme().colors().text, }], }), cursors: None, @@ -924,7 +920,7 @@ pub fn hello_world_rust_with_status_buffer_rows(theme: &Theme) -> Vec line: Some(HighlightedLine { highlighted_texts: vec![HighlightedText { text: "".to_string(), - color: theme.text, + color: cx.theme().colors().text, }], }), cursors: None, @@ -938,7 +934,7 @@ pub fn hello_world_rust_with_status_buffer_rows(theme: &Theme) -> Vec line: Some(HighlightedLine { highlighted_texts: vec![HighlightedText { text: "// Marshall and Nate were here".to_string(), - color: theme.syntax.color("comment"), + color: cx.theme().syntax_color("comment"), }], }), cursors: None, @@ -948,16 +944,16 @@ pub fn hello_world_rust_with_status_buffer_rows(theme: &Theme) -> Vec ] } -pub fn terminal_buffer(theme: &Theme) -> Buffer { +pub fn terminal_buffer(cx: &AppContext) -> Buffer { Buffer::new("terminal") .set_title("zed — fish".to_string()) .set_rows(Some(BufferRows { show_line_numbers: false, - rows: terminal_buffer_rows(theme), + rows: terminal_buffer_rows(cx), })) } -pub fn terminal_buffer_rows(theme: &Theme) -> Vec { +pub fn terminal_buffer_rows(cx: &AppContext) -> Vec { let show_line_number = false; vec![ @@ -969,31 +965,31 @@ pub fn terminal_buffer_rows(theme: &Theme) -> Vec { highlighted_texts: vec![ HighlightedText { text: "maxdeviant ".to_string(), - color: theme.syntax.color("keyword"), + color: cx.theme().syntax_color("keyword"), }, HighlightedText { text: "in ".to_string(), - color: theme.text, + color: cx.theme().colors().text, }, HighlightedText { text: "profaned-capital ".to_string(), - color: theme.syntax.color("function"), + color: cx.theme().syntax_color("function"), }, HighlightedText { text: "in ".to_string(), - color: theme.text, + color: cx.theme().colors().text, }, HighlightedText { text: "~/p/zed ".to_string(), - color: theme.syntax.color("function"), + color: cx.theme().syntax_color("function"), }, HighlightedText { text: "on ".to_string(), - color: theme.text, + color: cx.theme().colors().text, }, HighlightedText { text: " gpui2-ui ".to_string(), - color: theme.syntax.color("keyword"), + color: cx.theme().syntax_color("keyword"), }, ], }), @@ -1008,7 +1004,7 @@ pub fn terminal_buffer_rows(theme: &Theme) -> Vec { line: Some(HighlightedLine { highlighted_texts: vec![HighlightedText { text: "λ ".to_string(), - color: theme.syntax.color("string"), + color: cx.theme().syntax_color("string"), }], }), cursors: None, diff --git a/crates/ui2/src/story.rs b/crates/ui2/src/story.rs index d2813bd174..dea4e342b4 100644 --- a/crates/ui2/src/story.rs +++ b/crates/ui2/src/story.rs @@ -6,8 +6,6 @@ pub struct Story {} impl Story { pub fn container(cx: &mut ViewContext) -> Div { - let theme = theme(cx); - div() .size_full() .flex() @@ -15,15 +13,13 @@ impl Story { .pt_2() .px_4() .font("Zed Mono") - .bg(theme.background) + .bg(cx.theme().colors().background) } pub fn title(cx: &mut ViewContext, title: &str) -> impl Component { - let theme = theme(cx); - div() .text_xl() - .text_color(theme.text) + .text_color(cx.theme().colors().text) .child(title.to_owned()) } @@ -32,13 +28,11 @@ impl Story { } pub fn label(cx: &mut ViewContext, label: &str) -> impl Component { - let theme = theme(cx); - div() .mt_4() .mb_2() .text_xs() - .text_color(theme.text) + .text_color(cx.theme().colors().text) .child(label.to_owned()) } }