Detailed changes
@@ -15,7 +15,7 @@ dependencies = [
"project",
"settings",
"smallvec",
- "theme2",
+ "theme",
"ui",
"util",
"workspace",
@@ -331,7 +331,7 @@ dependencies = [
"serde_json",
"settings",
"smol",
- "theme2",
+ "theme",
"tiktoken-rs",
"ui",
"util",
@@ -688,7 +688,7 @@ dependencies = [
"settings",
"smol",
"tempdir",
- "theme2",
+ "theme",
"util",
"workspace",
]
@@ -1017,7 +1017,7 @@ dependencies = [
"project",
"search",
"settings",
- "theme2",
+ "theme",
"ui",
"workspace",
]
@@ -1501,7 +1501,7 @@ dependencies = [
"smallvec",
"sqlx",
"text",
- "theme2",
+ "theme",
"time",
"tokio",
"tokio-tungstenite",
@@ -1552,7 +1552,7 @@ dependencies = [
"serde_derive",
"settings",
"smallvec",
- "theme2",
+ "theme",
"theme_selector",
"time",
"tree-sitter-markdown",
@@ -1611,7 +1611,7 @@ dependencies = [
"serde",
"serde_json",
"settings",
- "theme2",
+ "theme",
"ui",
"util",
"workspace",
@@ -1713,7 +1713,7 @@ dependencies = [
"serde_derive",
"settings",
"smol",
- "theme2",
+ "theme",
"ui",
"util",
]
@@ -1731,7 +1731,7 @@ dependencies = [
"language",
"settings",
"smol",
- "theme2",
+ "theme",
"util",
"workspace",
"zed_actions",
@@ -2241,7 +2241,7 @@ dependencies = [
"serde_json",
"settings",
"smallvec",
- "theme2",
+ "theme",
"ui",
"unindent",
"util",
@@ -2423,7 +2423,7 @@ dependencies = [
"sqlez",
"sum_tree",
"text",
- "theme2",
+ "theme",
"tree-sitter",
"tree-sitter-html",
"tree-sitter-rust",
@@ -2636,7 +2636,7 @@ dependencies = [
"smallvec",
"smol",
"sysinfo",
- "theme2",
+ "theme",
"tree-sitter-markdown",
"ui",
"urlencoding",
@@ -2663,7 +2663,7 @@ dependencies = [
"serde_json",
"settings",
"text",
- "theme2",
+ "theme",
"ui",
"util",
"workspace",
@@ -3155,7 +3155,7 @@ dependencies = [
"serde",
"settings",
"text",
- "theme2",
+ "theme",
"ui",
"util",
"workspace",
@@ -3961,7 +3961,7 @@ dependencies = [
"smol",
"sum_tree",
"text",
- "theme2",
+ "theme",
"tree-sitter",
"tree-sitter-elixir",
"tree-sitter-embedded-template",
@@ -3990,7 +3990,7 @@ dependencies = [
"picker",
"project",
"settings",
- "theme2",
+ "theme",
"ui",
"util",
"workspace",
@@ -4012,7 +4012,7 @@ dependencies = [
"project",
"serde",
"settings",
- "theme2",
+ "theme",
"tree-sitter",
"ui",
"unindent",
@@ -4625,7 +4625,7 @@ dependencies = [
"snippet",
"sum_tree",
"text",
- "theme2",
+ "theme",
"tree-sitter",
"tree-sitter-html",
"tree-sitter-rust",
@@ -5203,7 +5203,7 @@ dependencies = [
"settings",
"smol",
"text",
- "theme2",
+ "theme",
"ui",
"util",
"workspace",
@@ -5424,7 +5424,7 @@ dependencies = [
"parking_lot 0.11.2",
"serde_json",
"settings",
- "theme2",
+ "theme",
"ui",
"util",
"workspace",
@@ -5776,7 +5776,7 @@ dependencies = [
"serde_json",
"settings",
"smallvec",
- "theme2",
+ "theme",
"ui",
"unicase",
"util",
@@ -5801,7 +5801,7 @@ dependencies = [
"settings",
"smol",
"text",
- "theme2",
+ "theme",
"util",
"workspace",
]
@@ -6150,7 +6150,7 @@ dependencies = [
"settings",
"smol",
"text",
- "theme2",
+ "theme",
"ui",
"util",
"workspace",
@@ -6346,7 +6346,7 @@ dependencies = [
"smallvec",
"smol",
"sum_tree",
- "theme2",
+ "theme",
"util",
]
@@ -6933,7 +6933,7 @@ dependencies = [
"settings",
"smallvec",
"smol",
- "theme2",
+ "theme",
"ui",
"unindent",
"util",
@@ -7777,7 +7777,7 @@ dependencies = [
"smallvec",
"story",
"strum",
- "theme2",
+ "theme",
"ui",
"util",
]
@@ -8081,7 +8081,7 @@ dependencies = [
"shellexpand",
"smallvec",
"smol",
- "theme2",
+ "theme",
"thiserror",
"util",
]
@@ -8113,7 +8113,7 @@ dependencies = [
"smallvec",
"smol",
"terminal",
- "theme2",
+ "theme",
"thiserror",
"ui",
"util",
@@ -8152,24 +8152,6 @@ checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d"
[[package]]
name = "theme"
version = "0.1.0"
-dependencies = [
- "anyhow",
- "fs",
- "gpui",
- "indexmap 1.9.3",
- "parking_lot 0.11.2",
- "schemars",
- "serde",
- "serde_derive",
- "serde_json",
- "settings",
- "toml 0.5.11",
- "util",
-]
-
-[[package]]
-name = "theme2"
-version = "0.1.0"
dependencies = [
"anyhow",
"fs",
@@ -8207,7 +8189,7 @@ dependencies = [
"serde",
"simplelog",
"strum",
- "theme2",
+ "theme",
"uuid 1.4.1",
]
@@ -8227,7 +8209,7 @@ dependencies = [
"postage",
"settings",
"smol",
- "theme2",
+ "theme",
"ui",
"util",
"workspace",
@@ -9046,7 +9028,7 @@ dependencies = [
"smallvec",
"story",
"strum",
- "theme2",
+ "theme",
]
[[package]]
@@ -9329,7 +9311,7 @@ dependencies = [
"serde_derive",
"serde_json",
"settings",
- "theme2",
+ "theme",
"tokio",
"ui",
"util",
@@ -9742,7 +9724,7 @@ dependencies = [
"schemars",
"serde",
"settings",
- "theme2",
+ "theme",
"theme_selector",
"ui",
"util",
@@ -10021,7 +10003,7 @@ dependencies = [
"settings",
"smallvec",
"terminal",
- "theme2",
+ "theme",
"ui",
"util",
"uuid 1.4.1",
@@ -10190,7 +10172,7 @@ dependencies = [
"tempdir",
"terminal_view",
"text",
- "theme2",
+ "theme",
"theme_selector",
"thiserror",
"tiny_http",
@@ -76,7 +76,6 @@ members = [
"crates/terminal_view",
"crates/text",
"crates/theme",
- "crates/theme2",
"crates/theme_importer",
"crates/theme_selector",
"crates/ui",
@@ -17,7 +17,7 @@ project = { path = "../project" }
settings = { path = "../settings" }
ui = { path = "../ui" }
util = { path = "../util" }
-theme = { path = "../theme2", package = "theme2" }
+theme = { path = "../theme" }
workspace = { path = "../workspace", package = "workspace" }
anyhow.workspace = true
@@ -22,7 +22,7 @@ project = { path = "../project" }
search = { path = "../search" }
semantic_index = { path = "../semantic_index" }
settings = { path = "../settings" }
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
ui = { path = "../ui" }
util = { path = "../util" }
workspace = { path = "../workspace" }
@@ -15,7 +15,7 @@ gpui = { package = "gpui2", path = "../gpui2" }
menu = { path = "../menu" }
project = { path = "../project" }
settings = { path = "../settings" }
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
workspace = { path = "../workspace" }
util = { path = "../util" }
anyhow.workspace = true
@@ -17,7 +17,7 @@ language = { path = "../language" }
project = { path = "../project" }
search = { path = "../search" }
settings = { path = "../settings" }
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
workspace = { path = "../workspace" }
outline = { path = "../outline" }
itertools = "0.10"
@@ -78,7 +78,7 @@ notifications = { path = "../notifications", features = ["test-support"] }
project = { path = "../project", features = ["test-support"] }
rpc = { path = "../rpc", features = ["test-support"] }
settings = { path = "../settings", features = ["test-support"] }
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
workspace = { path = "../workspace", features = ["test-support"] }
collab_ui = { path = "../collab_ui", features = ["test-support"] }
@@ -0,0 +1,99 @@
+[package]
+authors = ["Nathan Sobo <nathan@zed.dev>"]
+default-run = "collab"
+edition = "2021"
+name = "collab"
+version = "0.28.0"
+publish = false
+
+[[bin]]
+name = "collab"
+
+[[bin]]
+name = "seed"
+required-features = ["seed-support"]
+
+[dependencies]
+clock = { path = "../clock" }
+collections = { path = "../collections" }
+live_kit_server = { path = "../live_kit_server" }
+text = { path = "../text" }
+rpc = { path = "../rpc" }
+util = { path = "../util" }
+
+anyhow.workspace = true
+async-tungstenite = "0.16"
+axum = { version = "0.5", features = ["json", "headers", "ws"] }
+axum-extra = { version = "0.3", features = ["erased-json"] }
+base64 = "0.13"
+clap = { version = "3.1", features = ["derive"], optional = true }
+dashmap = "5.4"
+envy = "0.4.2"
+futures.workspace = true
+hyper = "0.14"
+lazy_static.workspace = true
+lipsum = { version = "0.8", optional = true }
+log.workspace = true
+nanoid = "0.4"
+parking_lot.workspace = true
+prometheus = "0.13"
+prost.workspace = true
+rand.workspace = true
+reqwest = { version = "0.11", features = ["json"], optional = true }
+scrypt = "0.7"
+smallvec.workspace = true
+sea-orm = { version = "0.12.x", features = ["sqlx-postgres", "postgres-array", "runtime-tokio-rustls", "with-uuid"] }
+serde.workspace = true
+serde_derive.workspace = true
+serde_json.workspace = true
+sha-1 = "0.9"
+sqlx = { version = "0.7", features = ["runtime-tokio-rustls", "postgres", "json", "time", "uuid", "any"] }
+time.workspace = true
+tokio = { version = "1", features = ["full"] }
+tokio-tungstenite = "0.17"
+tonic = "0.6"
+tower = "0.4"
+toml.workspace = true
+tracing = "0.1.34"
+tracing-log = "0.1.3"
+tracing-subscriber = { version = "0.3.11", features = ["env-filter", "json"] }
+uuid.workspace = true
+
+[dev-dependencies]
+audio = { path = "../audio" }
+collections = { path = "../collections", features = ["test-support"] }
+gpui = { package = "gpui2", path = "../gpui2", features = ["test-support"] }
+call = { path = "../call", features = ["test-support"] }
+client = { path = "../client", features = ["test-support"] }
+channel = { path = "../channel" }
+editor = { path = "../editor", features = ["test-support"] }
+language = { path = "../language", features = ["test-support"] }
+fs = { path = "../fs", features = ["test-support"] }
+git = { path = "../git", features = ["test-support"] }
+live_kit_client = { package = "live_kit_client2", path = "../live_kit_client2", features = ["test-support"] }
+lsp = { path = "../lsp", features = ["test-support"] }
+node_runtime = { path = "../node_runtime" }
+notifications = { path = "../notifications", features = ["test-support"] }
+
+project = { path = "../project", features = ["test-support"] }
+rpc = { path = "../rpc", features = ["test-support"] }
+settings = { path = "../settings", features = ["test-support"] }
+theme = { path = "../theme" }
+workspace = { path = "../workspace", features = ["test-support"] }
+
+collab_ui = { path = "../collab_ui", features = ["test-support"] }
+
+async-trait.workspace = true
+pretty_assertions.workspace = true
+ctor.workspace = true
+env_logger.workspace = true
+indoc.workspace = true
+util = { path = "../util" }
+lazy_static.workspace = true
+sea-orm = { version = "0.12.x", features = ["sqlx-sqlite"] }
+serde_json.workspace = true
+sqlx = { version = "0.7", features = ["sqlite"] }
+unindent.workspace = true
+
+[features]
+seed-support = ["clap", "lipsum", "reqwest"]
@@ -45,7 +45,7 @@ recent_projects = { path = "../recent_projects" }
rpc = { path = "../rpc" }
settings = { path = "../settings" }
feature_flags = { path = "../feature_flags"}
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
theme_selector = { path = "../theme_selector" }
vcs_menu = { path = "../vcs_menu" }
ui = { path = "../ui" }
@@ -18,7 +18,7 @@ project = { path = "../project" }
settings = { path = "../settings" }
ui = { path = "../ui" }
util = { path = "../util" }
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
workspace = { path = "../workspace" }
zed_actions = { path = "../zed_actions" }
anyhow.workspace = true
@@ -24,7 +24,7 @@ collections = { path = "../collections" }
gpui = { package = "gpui2", path = "../gpui2" }
language = { path = "../language" }
settings = { path = "../settings" }
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
lsp = { path = "../lsp" }
node_runtime = { path = "../node_runtime"}
util = { path = "../util" }
@@ -16,7 +16,7 @@ zed_actions = { path = "../zed_actions"}
gpui = { package = "gpui2", path = "../gpui2" }
language = { path = "../language" }
settings = { path = "../settings" }
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
util = { path = "../util" }
workspace = {path = "../workspace" }
anyhow.workspace = true
@@ -17,7 +17,7 @@ language = { path = "../language" }
lsp = { path = "../lsp" }
project = { path = "../project" }
settings = { path = "../settings" }
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
util = { path = "../util" }
workspace = {path = "../workspace" }
@@ -37,7 +37,7 @@ language = { path = "../language", features = ["test-support"] }
lsp = { path = "../lsp", features = ["test-support"] }
gpui = { package = "gpui2", path = "../gpui2", features = ["test-support"] }
workspace = {path = "../workspace", features = ["test-support"] }
-theme = { package = "theme2", path = "../theme2", features = ["test-support"] }
+theme = { path = "../theme", features = ["test-support"] }
serde_json.workspace = true
unindent.workspace = true
@@ -42,7 +42,7 @@ settings = { path = "../settings" }
snippet = { path = "../snippet" }
sum_tree = { path = "../sum_tree" }
text = { path = "../text" }
-theme = { package="theme2", path = "../theme2" }
+theme = { path = "../theme" }
ui = { path = "../ui" }
util = { path = "../util" }
sqlez = { path = "../sqlez" }
@@ -20,7 +20,7 @@ menu = { path = "../menu" }
project = { path = "../project" }
search = { path = "../search" }
settings = { path = "../settings" }
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
ui = { path = "../ui" }
util = { path = "../util" }
workspace = { path = "../workspace"}
@@ -19,7 +19,7 @@ project = { path = "../project" }
settings = { path = "../settings" }
text = { path = "../text" }
util = { path = "../util" }
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
ui = { path = "../ui" }
workspace = { path = "../workspace" }
postage.workspace = true
@@ -30,7 +30,7 @@ editor = { path = "../editor", features = ["test-support"] }
gpui = { package = "gpui2", path = "../gpui2", features = ["test-support"] }
language = { path = "../language", features = ["test-support"] }
workspace = { path = "../workspace", features = ["test-support"] }
-theme = { package = "theme2", path = "../theme2", features = ["test-support"] }
+theme = { path = "../theme", features = ["test-support"] }
serde_json.workspace = true
ctor.workspace = true
@@ -17,7 +17,7 @@ settings = { path = "../settings" }
text = { path = "../text" }
workspace = { path = "../workspace" }
postage.workspace = true
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
ui = { path = "../ui" }
util = { path = "../util" }
@@ -32,7 +32,7 @@ rpc = { path = "../rpc" }
settings = { path = "../settings" }
sum_tree = { path = "../sum_tree" }
text = { path = "../text" }
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
util = { path = "../util" }
anyhow.workspace = true
@@ -15,7 +15,7 @@ language = { path = "../language" }
gpui = { package = "gpui2", path = "../gpui2" }
picker = { path = "../picker" }
project = { path = "../project" }
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
ui = { path = "../ui" }
settings = { path = "../settings" }
util = { path = "../util" }
@@ -12,7 +12,7 @@ doctest = false
collections = { path = "../collections" }
editor = { path = "../editor" }
settings = { path = "../settings" }
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
language = { path = "../language" }
project = { path = "../project" }
workspace = { path = "../workspace" }
@@ -32,7 +32,7 @@ settings = { path = "../settings" }
snippet = { path = "../snippet" }
sum_tree = { path = "../sum_tree" }
text = { path = "../text" }
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
util = { path = "../util" }
aho-corasick = "1.1"
@@ -17,7 +17,7 @@ language = { path = "../language" }
picker = { path = "../picker" }
settings = { path = "../settings" }
text = { path = "../text" }
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
workspace = { path = "../workspace" }
util = { path = "../util" }
@@ -15,7 +15,7 @@ gpui = { package = "gpui2", path = "../gpui2" }
menu = { path = "../menu" }
settings = { path = "../settings" }
util = { path = "../util" }
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
workspace = { path = "../workspace"}
parking_lot.workspace = true
@@ -17,7 +17,7 @@ menu = { path = "../menu" }
project = { path = "../project" }
search = { path = "../search" }
settings = { path = "../settings" }
-theme = { path = "../theme2", package = "theme2" }
+theme = { path = "../theme" }
ui = { path = "../ui" }
util = { path = "../util" }
workspace = { path = "../workspace", package = "workspace" }
@@ -17,7 +17,7 @@ project = { path = "../project" }
text = { path = "../text" }
settings = { path = "../settings" }
workspace = { path = "../workspace" }
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
util = { path = "../util" }
anyhow.workspace = true
@@ -33,5 +33,5 @@ gpui = { package = "gpui2", path = "../gpui2", features = ["test-support"] }
language = { path = "../language", features = ["test-support"] }
lsp = { path = "../lsp", features = ["test-support"] }
project = { path = "../project", features = ["test-support"] }
-theme = { package = "theme2", path = "../theme2", features = ["test-support"] }
+theme = { path = "../theme", features = ["test-support"] }
workspace = { path = "../workspace", features = ["test-support"] }
@@ -17,7 +17,7 @@ picker = { path = "../picker" }
settings = { path = "../settings" }
text = { path = "../text" }
util = { path = "../util"}
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
ui = { path = "../ui" }
workspace = { path = "../workspace" }
@@ -18,7 +18,7 @@ test-support = [
collections = { path = "../collections" }
gpui = { package = "gpui2", path = "../gpui2" }
sum_tree = { path = "../sum_tree" }
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
language = { path = "../language" }
util = { path = "../util" }
anyhow.workspace = true
@@ -17,7 +17,7 @@ language = { path = "../language" }
menu = { path = "../menu" }
project = { path = "../project" }
settings = { path = "../settings" }
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
util = { path = "../util" }
ui = {path = "../ui"}
workspace = { path = "../workspace" }
@@ -29,7 +29,7 @@ simplelog = "0.9"
smallvec.workspace = true
story = { path = "../story" }
strum = { version = "0.25.0", features = ["derive"] }
-theme2 = { path = "../theme2" }
+theme = { path = "../theme" }
menu = { path = "../menu" }
ui = { path = "../ui", features = ["stories"] }
util = { path = "../util" }
@@ -14,7 +14,7 @@ use log::LevelFilter;
use settings::{default_settings, Settings, SettingsStore};
use simplelog::SimpleLogger;
use strum::IntoEnumIterator;
-use theme2::{ThemeRegistry, ThemeSettings};
+use theme::{ThemeRegistry, ThemeSettings};
use ui::prelude::*;
use crate::assets::Assets;
@@ -69,7 +69,7 @@ fn main() {
.unwrap();
cx.set_global(store);
- theme2::init(theme2::LoadThemes::All, cx);
+ theme::init(theme::LoadThemes::All, cx);
let selector = story_selector;
@@ -13,7 +13,7 @@ doctest = false
gpui = { package = "gpui2", path = "../gpui2" }
settings = { path = "../settings" }
db = { path = "../db" }
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
util = { path = "../util" }
alacritty_terminal = { git = "https://github.com/zed-industries/alacritty", rev = "33306142195b354ef3485ca2b1d8a85dfc6605ca" }
@@ -15,7 +15,7 @@ gpui = { package = "gpui2", path = "../gpui2" }
project = { path = "../project" }
# search = { path = "../search" }
settings = { path = "../settings" }
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
util = { path = "../util" }
workspace = { path = "../workspace" }
db = { path = "../db" }
@@ -5,6 +5,9 @@ edition = "2021"
publish = false
[features]
+default = []
+importing-themes = []
+stories = ["dep:itertools", "dep:story"]
test-support = [
"gpui/test-support",
"fs/test-support",
@@ -16,21 +19,24 @@ path = "src/theme.rs"
doctest = false
[dependencies]
-gpui = { path = "../gpui" }
-fs = { path = "../fs" }
-settings = { path = "../settings" }
-util = { path = "../util" }
-
anyhow.workspace = true
+fs = { path = "../fs" }
+gpui = { package = "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
+settings = { path = "../settings" }
+story = { path = "../story", optional = true }
toml.workspace = true
+uuid.workspace = true
+util = { path = "../util" }
+itertools = { version = "0.11.0", optional = true }
[dev-dependencies]
-gpui = { path = "../gpui", features = ["test-support"] }
+gpui = { package = "gpui2", path = "../gpui2", features = ["test-support"] }
fs = { path = "../fs", features = ["test-support"] }
settings = { path = "../settings", features = ["test-support"] }
@@ -1,480 +0,0 @@
-use gpui::{elements::SafeStylable, Action};
-
-use crate::{Interactive, Toggleable};
-
-use self::{action_button::ButtonStyle, disclosure::Disclosable, svg::SvgStyle, toggle::Toggle};
-
-pub type IconButtonStyle = Interactive<ButtonStyle<SvgStyle>>;
-pub type ToggleIconButtonStyle = Toggleable<IconButtonStyle>;
-
-pub trait ComponentExt<C: SafeStylable> {
- fn toggleable(self, active: bool) -> Toggle<C, ()>;
- fn disclosable(self, disclosed: Option<bool>, action: Box<dyn Action>) -> Disclosable<C, ()>;
-}
-
-impl<C: SafeStylable> ComponentExt<C> for C {
- fn toggleable(self, active: bool) -> Toggle<C, ()> {
- Toggle::new(self, active)
- }
-
- /// Some(True) => disclosed => content is visible
- /// Some(false) => closed => content is hidden
- /// None => No disclosure button, but reserve disclosure spacing
- fn disclosable(self, disclosed: Option<bool>, action: Box<dyn Action>) -> Disclosable<C, ()> {
- Disclosable::new(disclosed, self, action)
- }
-}
-
-pub mod disclosure {
- use gpui::{
- elements::{Component, ContainerStyle, Empty, Flex, ParentElement, SafeStylable},
- Action, Element,
- };
- use schemars::JsonSchema;
- use serde_derive::Deserialize;
-
- use super::{action_button::Button, svg::Svg, IconButtonStyle};
-
- #[derive(Clone, Default, Deserialize, JsonSchema)]
- pub struct DisclosureStyle<S> {
- pub button: IconButtonStyle,
- #[serde(flatten)]
- pub container: ContainerStyle,
- pub spacing: f32,
- #[serde(flatten)]
- content: S,
- }
-
- impl<S> DisclosureStyle<S> {
- pub fn button_space(&self) -> f32 {
- self.spacing + self.button.button_width.unwrap()
- }
- }
-
- pub struct Disclosable<C, S> {
- disclosed: Option<bool>,
- action: Box<dyn Action>,
- id: usize,
- content: C,
- style: S,
- }
-
- impl Disclosable<(), ()> {
- pub fn new<C>(
- disclosed: Option<bool>,
- content: C,
- action: Box<dyn Action>,
- ) -> Disclosable<C, ()> {
- Disclosable {
- disclosed,
- content,
- action,
- id: 0,
- style: (),
- }
- }
- }
-
- impl<C> Disclosable<C, ()> {
- pub fn with_id(mut self, id: usize) -> Disclosable<C, ()> {
- self.id = id;
- self
- }
- }
-
- impl<C: SafeStylable> SafeStylable for Disclosable<C, ()> {
- type Style = DisclosureStyle<C::Style>;
-
- type Output = Disclosable<C, Self::Style>;
-
- fn with_style(self, style: Self::Style) -> Self::Output {
- Disclosable {
- disclosed: self.disclosed,
- action: self.action,
- content: self.content,
- id: self.id,
- style,
- }
- }
- }
-
- impl<C: SafeStylable> Component for Disclosable<C, DisclosureStyle<C::Style>> {
- fn render<V: 'static>(self, cx: &mut gpui::ViewContext<V>) -> gpui::AnyElement<V> {
- Flex::row()
- .with_spacing(self.style.spacing)
- .with_child(if let Some(disclosed) = self.disclosed {
- Button::dynamic_action(self.action)
- .with_id(self.id)
- .with_contents(Svg::new(if disclosed {
- "icons/file_icons/chevron_down.svg"
- } else {
- "icons/file_icons/chevron_right.svg"
- }))
- .with_style(self.style.button)
- .element()
- .into_any()
- } else {
- Empty::new()
- .into_any()
- .constrained()
- // TODO: Why is this optional at all?
- .with_width(self.style.button.button_width.unwrap())
- .into_any()
- })
- .with_child(
- self.content
- .with_style(self.style.content)
- .render(cx)
- .flex(1., true),
- )
- .align_children_center()
- .contained()
- .with_style(self.style.container)
- .into_any()
- }
- }
-}
-
-pub mod toggle {
- use gpui::elements::{Component, SafeStylable};
-
- use crate::Toggleable;
-
- pub struct Toggle<C, S> {
- style: S,
- active: bool,
- component: C,
- }
-
- impl<C: SafeStylable> Toggle<C, ()> {
- pub fn new(component: C, active: bool) -> Self {
- Toggle {
- active,
- component,
- style: (),
- }
- }
- }
-
- impl<C: SafeStylable> SafeStylable for Toggle<C, ()> {
- type Style = Toggleable<C::Style>;
-
- type Output = Toggle<C, Self::Style>;
-
- fn with_style(self, style: Self::Style) -> Self::Output {
- Toggle {
- active: self.active,
- component: self.component,
- style,
- }
- }
- }
-
- impl<C: SafeStylable> Component for Toggle<C, Toggleable<C::Style>> {
- fn render<V: 'static>(self, cx: &mut gpui::ViewContext<V>) -> gpui::AnyElement<V> {
- self.component
- .with_style(self.style.in_state(self.active).clone())
- .render(cx)
- }
- }
-}
-
-pub mod action_button {
- use std::borrow::Cow;
-
- use gpui::{
- elements::{Component, ContainerStyle, MouseEventHandler, SafeStylable, TooltipStyle},
- platform::{CursorStyle, MouseButton},
- Action, Element, TypeTag,
- };
- use schemars::JsonSchema;
- use serde_derive::Deserialize;
-
- use crate::Interactive;
-
- #[derive(Clone, Deserialize, Default, JsonSchema)]
- pub struct ButtonStyle<C> {
- #[serde(flatten)]
- pub container: ContainerStyle,
- // TODO: These are incorrect for the intended usage of the buttons.
- // The size should be constant, but putting them here duplicates them
- // across the states the buttons can be in
- pub button_width: Option<f32>,
- pub button_height: Option<f32>,
- #[serde(flatten)]
- contents: C,
- }
-
- pub struct Button<C, S> {
- action: Box<dyn Action>,
- tooltip: Option<(Cow<'static, str>, TooltipStyle)>,
- tag: TypeTag,
- id: usize,
- contents: C,
- style: Interactive<S>,
- }
-
- impl Button<(), ()> {
- pub fn dynamic_action(action: Box<dyn Action>) -> Button<(), ()> {
- Self {
- contents: (),
- tag: action.type_tag(),
- action,
- style: Interactive::new_blank(),
- tooltip: None,
- id: 0,
- }
- }
-
- pub fn action<A: Action + Clone>(action: A) -> Self {
- Self::dynamic_action(Box::new(action))
- }
-
- pub fn with_tooltip(
- mut self,
- tooltip: impl Into<Cow<'static, str>>,
- tooltip_style: TooltipStyle,
- ) -> Self {
- self.tooltip = Some((tooltip.into(), tooltip_style));
- self
- }
-
- pub fn with_id(mut self, id: usize) -> Self {
- self.id = id;
- self
- }
-
- pub fn with_contents<C: SafeStylable>(self, contents: C) -> Button<C, ()> {
- Button {
- action: self.action,
- tag: self.tag,
- style: self.style,
- tooltip: self.tooltip,
- id: self.id,
- contents,
- }
- }
- }
-
- impl<C: SafeStylable> SafeStylable for Button<C, ()> {
- type Style = Interactive<ButtonStyle<C::Style>>;
- type Output = Button<C, ButtonStyle<C::Style>>;
-
- fn with_style(self, style: Self::Style) -> Self::Output {
- Button {
- action: self.action,
- tag: self.tag,
- contents: self.contents,
- tooltip: self.tooltip,
- id: self.id,
- style,
- }
- }
- }
-
- impl<C: SafeStylable> Component for Button<C, ButtonStyle<C::Style>> {
- fn render<V: 'static>(self, cx: &mut gpui::ViewContext<V>) -> gpui::AnyElement<V> {
- let mut button = MouseEventHandler::new_dynamic(self.tag, self.id, cx, |state, cx| {
- let style = self.style.style_for(state);
- let mut contents = self
- .contents
- .with_style(style.contents.to_owned())
- .render(cx)
- .contained()
- .with_style(style.container)
- .constrained();
-
- if let Some(height) = style.button_height {
- contents = contents.with_height(height);
- }
-
- if let Some(width) = style.button_width {
- contents = contents.with_width(width);
- }
-
- contents.into_any()
- })
- .on_click(MouseButton::Left, {
- let action = self.action.boxed_clone();
- move |_, _, cx| {
- let window = cx.window();
- let view = cx.view_id();
- let action = action.boxed_clone();
- cx.spawn(|_, mut cx| async move {
- window.dispatch_action(view, action.as_ref(), &mut cx)
- })
- .detach();
- }
- })
- .with_cursor_style(CursorStyle::PointingHand)
- .into_any();
-
- if let Some((tooltip, style)) = self.tooltip {
- button = button
- .with_dynamic_tooltip(self.tag, 0, tooltip, Some(self.action), style, cx)
- .into_any()
- }
-
- button
- }
- }
-}
-
-pub mod svg {
- use std::borrow::Cow;
-
- use gpui::{
- elements::{Component, Empty, SafeStylable},
- Element,
- };
- use schemars::JsonSchema;
- use serde::Deserialize;
-
- #[derive(Clone, Default, JsonSchema)]
- pub struct SvgStyle {
- icon_width: f32,
- icon_height: f32,
- color: gpui::color::Color,
- }
-
- impl<'de> Deserialize<'de> for SvgStyle {
- fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
- where
- D: serde::Deserializer<'de>,
- {
- #[derive(Deserialize)]
- #[serde(untagged)]
- pub enum IconSize {
- IconSize { icon_size: f32 },
- Dimensions { width: f32, height: f32 },
- IconDimensions { icon_width: f32, icon_height: f32 },
- }
-
- #[derive(Deserialize)]
- struct SvgStyleHelper {
- #[serde(flatten)]
- size: IconSize,
- color: gpui::color::Color,
- }
-
- let json = SvgStyleHelper::deserialize(deserializer)?;
- let color = json.color;
-
- let result = match json.size {
- IconSize::IconSize { icon_size } => SvgStyle {
- icon_width: icon_size,
- icon_height: icon_size,
- color,
- },
- IconSize::Dimensions { width, height } => SvgStyle {
- icon_width: width,
- icon_height: height,
- color,
- },
- IconSize::IconDimensions {
- icon_width,
- icon_height,
- } => SvgStyle {
- icon_width,
- icon_height,
- color,
- },
- };
-
- Ok(result)
- }
- }
-
- pub struct Svg<S> {
- path: Option<Cow<'static, str>>,
- style: S,
- }
-
- impl Svg<()> {
- pub fn new(path: impl Into<Cow<'static, str>>) -> Self {
- Self {
- path: Some(path.into()),
- style: (),
- }
- }
-
- pub fn optional(path: Option<impl Into<Cow<'static, str>>>) -> Self {
- Self {
- path: path.map(Into::into),
- style: (),
- }
- }
- }
-
- impl SafeStylable for Svg<()> {
- type Style = SvgStyle;
-
- type Output = Svg<SvgStyle>;
-
- fn with_style(self, style: Self::Style) -> Self::Output {
- Svg {
- path: self.path,
- style,
- }
- }
- }
-
- impl Component for Svg<SvgStyle> {
- fn render<V: 'static>(self, _: &mut gpui::ViewContext<V>) -> gpui::AnyElement<V> {
- if let Some(path) = self.path {
- gpui::elements::Svg::new(path)
- .with_color(self.style.color)
- .constrained()
- } else {
- Empty::new().constrained()
- }
- .constrained()
- .with_width(self.style.icon_width)
- .with_height(self.style.icon_height)
- .into_any()
- }
- }
-}
-
-pub mod label {
- use std::borrow::Cow;
-
- use gpui::{
- elements::{Component, LabelStyle, SafeStylable},
- fonts::TextStyle,
- Element,
- };
-
- pub struct Label<S> {
- text: Cow<'static, str>,
- style: S,
- }
-
- impl Label<()> {
- pub fn new(text: impl Into<Cow<'static, str>>) -> Self {
- Self {
- text: text.into(),
- style: (),
- }
- }
- }
-
- impl SafeStylable for Label<()> {
- type Style = TextStyle;
-
- type Output = Label<LabelStyle>;
-
- fn with_style(self, style: Self::Style) -> Self::Output {
- Label {
- text: self.text,
- style: style.into(),
- }
- }
- }
-
- impl Component for Label<LabelStyle> {
- fn render<V: 'static>(self, _: &mut gpui::ViewContext<V>) -> gpui::AnyElement<V> {
- gpui::elements::Label::new(self.text, self.style).into_any()
- }
- }
-}
@@ -1,1329 +1,148 @@
-pub mod components;
-mod theme_registry;
-mod theme_settings;
-pub mod ui;
-
-use components::{
- action_button::ButtonStyle, disclosure::DisclosureStyle, IconButtonStyle, ToggleIconButtonStyle,
-};
-use gpui::{
- color::Color,
- elements::{Border, ContainerStyle, ImageStyle, LabelStyle, SvgStyle, TooltipStyle},
- fonts::{HighlightStyle, TextStyle},
- platform, AppContext, AssetSource, MouseState,
-};
-use parking_lot::Mutex;
-use schemars::JsonSchema;
-use serde::{de::DeserializeOwned, Deserialize};
-use serde_json::Value;
-use settings::SettingsStore;
-use std::{any::Any, collections::HashMap, ops::Deref, sync::Arc};
-use ui::{CheckboxStyle, CopilotCTAButton, IconStyle, ModalStyle};
-
-pub use theme_registry::*;
-pub use theme_settings::*;
-
-pub fn current(cx: &AppContext) -> Arc<Theme> {
- settings::get::<ThemeSettings>(cx).theme.clone()
-}
-
-pub fn init(source: impl AssetSource, cx: &mut AppContext) {
- cx.set_global(ThemeRegistry::new(source, cx.font_cache().clone()));
- settings::register::<ThemeSettings>(cx);
-
- let mut prev_buffer_font_size = settings::get::<ThemeSettings>(cx).buffer_font_size;
- cx.observe_global::<SettingsStore, _>(move |cx| {
- let buffer_font_size = settings::get::<ThemeSettings>(cx).buffer_font_size;
- if buffer_font_size != prev_buffer_font_size {
- prev_buffer_font_size = buffer_font_size;
- reset_font_size(cx);
- }
- })
- .detach();
-}
-
-#[derive(Deserialize, Default, JsonSchema)]
-pub struct Theme {
- #[serde(default)]
- pub meta: ThemeMeta,
- pub workspace: Workspace,
- pub context_menu: ContextMenu,
- pub toolbar_dropdown_menu: DropdownMenu,
- pub copilot: Copilot,
- pub collab_panel: CollabPanel,
- pub project_panel: ProjectPanel,
- pub chat_panel: ChatPanel,
- pub notification_panel: NotificationPanel,
- pub command_palette: CommandPalette,
- pub picker: Picker,
- pub editor: Editor,
- pub search: Search,
- pub project_diagnostics: ProjectDiagnostics,
- pub shared_screen: ContainerStyle,
- pub contact_notification: ContactNotification,
- pub update_notification: UpdateNotification,
- pub simple_message_notification: MessageNotification,
- pub project_shared_notification: ProjectSharedNotification,
- pub incoming_call_notification: IncomingCallNotification,
- pub tooltip: TooltipStyle,
- pub terminal: TerminalStyle,
- pub assistant: AssistantStyle,
- pub feedback: FeedbackStyle,
- pub welcome: WelcomeStyle,
- pub titlebar: Titlebar,
- pub component_test: ComponentTest,
- // Nathan: New elements are styled in Rust, directly from the base theme.
- // We store it on the legacy theme so we can mix both kinds of elements during the transition.
- #[schemars(skip)]
- pub base_theme: serde_json::Value,
- // A place to cache deserialized base theme.
- #[serde(skip_deserializing)]
- #[schemars(skip)]
- pub deserialized_base_theme: Mutex<Option<Box<dyn Any + Send + Sync>>>,
-}
-
-#[derive(Deserialize, Default, Clone, JsonSchema)]
-pub struct ThemeMeta {
- #[serde(skip_deserializing)]
- pub id: usize,
- pub name: String,
- pub is_light: bool,
-}
-
-#[derive(Deserialize, Default, JsonSchema)]
-pub struct Workspace {
- pub background: Color,
- pub blank_pane: BlankPaneStyle,
- pub tab_bar: TabBar,
- pub pane_divider: Border,
- pub leader_border_opacity: f32,
- pub leader_border_width: f32,
- pub dock: Dock,
- pub status_bar: StatusBar,
- pub toolbar: Toolbar,
- pub disconnected_overlay: ContainedText,
- pub modal: ContainerStyle,
- pub zoomed_panel_foreground: ContainerStyle,
- pub zoomed_pane_foreground: ContainerStyle,
- pub zoomed_background: ContainerStyle,
- pub notification: ContainerStyle,
- pub notifications: Notifications,
- pub joining_project_avatar: ImageStyle,
- pub joining_project_message: ContainedText,
- pub external_location_message: ContainedText,
- pub drop_target_overlay_color: Color,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct BlankPaneStyle {
- pub logo: SvgStyle,
- pub logo_shadow: SvgStyle,
- pub logo_container: ContainerStyle,
- pub keyboard_hints: ContainerStyle,
- pub keyboard_hint: Interactive<ContainedText>,
- pub keyboard_hint_width: f32,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct Titlebar {
- #[serde(flatten)]
- pub container: ContainerStyle,
- pub height: f32,
- pub menu: TitlebarMenu,
- pub project_menu_button: Toggleable<Interactive<ContainedText>>,
- pub git_menu_button: Toggleable<Interactive<ContainedText>>,
- pub project_host: Interactive<ContainedText>,
- pub item_spacing: f32,
- pub face_pile_spacing: f32,
- pub avatar_ribbon: AvatarRibbon,
- pub follower_avatar_overlap: f32,
- pub leader_selection: ContainerStyle,
- pub offline_icon: OfflineIcon,
- pub leader_avatar: AvatarStyle,
- pub follower_avatar: AvatarStyle,
- pub inactive_avatar_grayscale: bool,
- pub sign_in_button: Toggleable<Interactive<ContainedText>>,
- pub outdated_warning: ContainedText,
- pub share_button: Toggleable<Interactive<ContainedText>>,
- pub muted: Color,
- pub speaking: Color,
- pub screen_share_button: Toggleable<Interactive<IconButton>>,
- pub toggle_contacts_button: Toggleable<Interactive<IconButton>>,
- pub toggle_microphone_button: Toggleable<Interactive<IconButton>>,
- pub toggle_speakers_button: Toggleable<Interactive<IconButton>>,
- pub leave_call_button: Interactive<IconButton>,
- pub toggle_contacts_badge: ContainerStyle,
- pub user_menu: UserMenu,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct TitlebarMenu {
- pub width: f32,
- pub height: f32,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct UserMenu {
- pub user_menu_button_online: UserMenuButton,
- pub user_menu_button_offline: UserMenuButton,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct UserMenuButton {
- pub user_menu: Toggleable<Interactive<Icon>>,
- pub avatar: AvatarStyle,
- pub icon: Icon,
-}
-
-#[derive(Copy, Clone, Deserialize, Default, JsonSchema)]
-pub struct AvatarStyle {
- #[serde(flatten)]
- pub image: ImageStyle,
- pub outer_width: f32,
- pub outer_corner_radius: f32,
-}
-
-#[derive(Deserialize, Default, Clone, JsonSchema)]
-pub struct Copilot {
- pub out_link_icon: Interactive<IconStyle>,
- pub modal: ModalStyle,
- pub auth: CopilotAuth,
-}
-
-#[derive(Deserialize, Default, Clone, JsonSchema)]
-pub struct CopilotAuth {
- pub content_width: f32,
- pub prompting: CopilotAuthPrompting,
- pub not_authorized: CopilotAuthNotAuthorized,
- pub authorized: CopilotAuthAuthorized,
- pub cta_button: CopilotCTAButton,
- pub header: IconStyle,
-}
-
-#[derive(Deserialize, Default, Clone, JsonSchema)]
-pub struct CopilotAuthPrompting {
- pub subheading: ContainedText,
- pub hint: ContainedText,
- pub device_code: DeviceCode,
-}
-
-#[derive(Deserialize, Default, Clone, JsonSchema)]
-pub struct DeviceCode {
- pub text: TextStyle,
- pub cta: CopilotCTAButton,
- pub left: f32,
- pub left_container: ContainerStyle,
- pub right: f32,
- pub right_container: Interactive<ContainerStyle>,
-}
-
-#[derive(Deserialize, Default, Clone, JsonSchema)]
-pub struct CopilotAuthNotAuthorized {
- pub subheading: ContainedText,
- pub warning: ContainedText,
-}
-
-#[derive(Deserialize, Default, Clone, JsonSchema)]
-pub struct CopilotAuthAuthorized {
- pub subheading: ContainedText,
- pub hint: ContainedText,
-}
-
-#[derive(Deserialize, Default, JsonSchema)]
-pub struct CollabPanel {
- #[serde(flatten)]
- pub container: ContainerStyle,
- pub disclosure: DisclosureStyle<()>,
- pub list_empty_state: Toggleable<Interactive<ContainedText>>,
- pub list_empty_icon: Icon,
- pub list_empty_label_container: ContainerStyle,
- pub log_in_button: Interactive<ContainedText>,
- pub channel_editor: ContainerStyle,
- pub channel_hash: Icon,
- pub channel_note_active_color: Color,
- pub tabbed_modal: TabbedModal,
- pub contact_finder: ContactFinder,
- pub channel_modal: ChannelModal,
- pub user_query_editor: FieldEditor,
- pub user_query_editor_height: f32,
- pub leave_call_button: Toggleable<Interactive<IconButton>>,
- pub add_contact_button: Toggleable<Interactive<IconButton>>,
- pub add_channel_button: Toggleable<Interactive<IconButton>>,
- pub header_row: ContainedText,
- pub dragged_over_header: ContainerStyle,
- pub subheader_row: Toggleable<Interactive<ContainedText>>,
- pub leave_call: Interactive<ContainedText>,
- pub contact_row: Toggleable<Interactive<ContainerStyle>>,
- pub channel_row: Toggleable<Interactive<ContainerStyle>>,
- pub channel_name: Toggleable<ContainedText>,
- pub row_height: f32,
- pub project_row: Toggleable<Interactive<ProjectRow>>,
- pub tree_branch: Toggleable<Interactive<TreeBranch>>,
- pub contact_avatar: ImageStyle,
- pub channel_avatar: ImageStyle,
- pub extra_participant_label: ContainedText,
- pub contact_status_free: ContainerStyle,
- pub contact_status_busy: ContainerStyle,
- pub contact_username: ContainedText,
- pub contact_button: Interactive<IconButton>,
- pub contact_button_spacing: f32,
- pub channel_indent: f32,
- pub disabled_button: IconButton,
- pub section_icon_size: f32,
- pub calling_indicator: ContainedText,
- pub face_overlap: f32,
-}
-
-#[derive(Deserialize, Default, JsonSchema)]
-pub struct ComponentTest {
- pub button: Interactive<ButtonStyle<TextStyle>>,
- pub toggle: Toggleable<Interactive<ButtonStyle<TextStyle>>>,
- pub disclosure: DisclosureStyle<TextStyle>,
-}
-
-#[derive(Deserialize, Default, JsonSchema)]
-pub struct TabbedModal {
- pub tab_button: Toggleable<Interactive<ContainedText>>,
- pub modal: ContainerStyle,
- pub header: ContainerStyle,
- pub body: ContainerStyle,
- pub title: ContainedText,
- pub visibility_toggle: Interactive<ContainedText>,
- pub channel_link: Interactive<ContainedText>,
- pub picker: Picker,
- pub max_height: f32,
- pub max_width: f32,
- pub row_height: f32,
-}
-
-#[derive(Deserialize, Default, JsonSchema)]
-pub struct ChannelModal {
- pub contact_avatar: ImageStyle,
- pub contact_username: ContainerStyle,
- pub remove_member_button: ContainedText,
- pub cancel_invite_button: ContainedText,
- pub member_icon: IconButton,
- pub invitee_icon: IconButton,
- pub member_tag: ContainedText,
-}
-
-#[derive(Deserialize, Default, JsonSchema)]
-pub struct ProjectRow {
- #[serde(flatten)]
- pub container: ContainerStyle,
- pub icon: Icon,
- pub name: ContainedText,
-}
-
-#[derive(Deserialize, Default, Clone, Copy, JsonSchema)]
-pub struct TreeBranch {
- pub width: f32,
- pub color: Color,
-}
-
-#[derive(Deserialize, Default, JsonSchema)]
-pub struct ContactFinder {
- pub contact_avatar: ImageStyle,
- pub contact_username: ContainerStyle,
- pub contact_button: IconButton,
- pub disabled_contact_button: IconButton,
-}
-
-#[derive(Deserialize, Default, JsonSchema)]
-pub struct DropdownMenu {
- #[serde(flatten)]
- pub container: ContainerStyle,
- pub header: Interactive<DropdownMenuItem>,
- pub section_header: ContainedText,
- pub item: Toggleable<Interactive<DropdownMenuItem>>,
- pub row_height: f32,
-}
-
-#[derive(Deserialize, Default, JsonSchema)]
-pub struct DropdownMenuItem {
- #[serde(flatten)]
- pub container: ContainerStyle,
- #[serde(flatten)]
- pub text: TextStyle,
- pub secondary_text: Option<TextStyle>,
- #[serde(default)]
- pub secondary_text_spacing: f32,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct TabBar {
- #[serde(flatten)]
- pub container: ContainerStyle,
- pub pane_button: Toggleable<Interactive<IconButton>>,
- pub pane_button_container: ContainerStyle,
- pub active_pane: TabStyles,
- pub inactive_pane: TabStyles,
- pub dragged_tab: Tab,
- pub height: f32,
- pub nav_button: Interactive<IconButton>,
-}
-
-impl TabBar {
- pub fn tab_style(&self, pane_active: bool, tab_active: bool) -> &Tab {
- let tabs = if pane_active {
- &self.active_pane
- } else {
- &self.inactive_pane
- };
-
- if tab_active {
- &tabs.active_tab
- } else {
- &tabs.inactive_tab
+mod default_colors;
+mod default_theme;
+mod one_themes;
+pub mod prelude;
+mod registry;
+mod scale;
+mod settings;
+mod styles;
+#[cfg(not(feature = "importing-themes"))]
+mod themes;
+mod user_theme;
+
+use std::sync::Arc;
+
+use ::settings::Settings;
+pub use default_colors::*;
+pub use default_theme::*;
+pub use registry::*;
+pub use scale::*;
+pub use settings::*;
+pub use styles::*;
+#[cfg(not(feature = "importing-themes"))]
+pub use themes::*;
+pub use user_theme::*;
+
+use gpui::{AppContext, Hsla, SharedString};
+use serde::Deserialize;
+
+#[derive(Debug, PartialEq, Clone, Copy, Deserialize)]
+pub enum Appearance {
+ Light,
+ Dark,
+}
+
+impl Appearance {
+ pub fn is_light(&self) -> bool {
+ match self {
+ Self::Light => true,
+ Self::Dark => false,
}
}
}
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct TabStyles {
- pub active_tab: Tab,
- pub inactive_tab: Tab,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct AvatarRibbon {
- #[serde(flatten)]
- pub container: ContainerStyle,
- pub width: f32,
- pub height: f32,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct OfflineIcon {
- #[serde(flatten)]
- pub container: ContainerStyle,
- pub width: f32,
- pub color: Color,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct Tab {
- pub height: f32,
- #[serde(flatten)]
- pub container: ContainerStyle,
- #[serde(flatten)]
- pub label: LabelStyle,
- pub description: ContainedText,
- pub spacing: f32,
- pub close_icon_width: f32,
- pub type_icon_width: f32,
- pub icon_close: Color,
- pub icon_close_active: Color,
- pub icon_dirty: Color,
- pub icon_conflict: Color,
- pub git: GitProjectStatus,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct Toolbar {
- #[serde(flatten)]
- pub container: ContainerStyle,
- pub height: f32,
- pub item_spacing: f32,
- pub toggleable_tool: Toggleable<Interactive<IconButton>>,
- pub toggleable_text_tool: Toggleable<Interactive<ContainedText>>,
- pub breadcrumb_height: f32,
- pub breadcrumbs: Interactive<ContainedText>,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct Notifications {
- #[serde(flatten)]
- pub container: ContainerStyle,
- pub width: f32,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct Search {
- #[serde(flatten)]
- pub container: ContainerStyle,
- pub editor: FindEditor,
- pub invalid_editor: ContainerStyle,
- pub option_button_group: ContainerStyle,
- pub include_exclude_editor: FindEditor,
- pub invalid_include_exclude_editor: ContainerStyle,
- pub include_exclude_inputs: ContainedText,
- pub option_button_component: ToggleIconButtonStyle,
- pub match_background: Color,
- pub match_index: ContainedText,
- pub major_results_status: TextStyle,
- pub minor_results_status: TextStyle,
- pub editor_icon: IconStyle,
- pub mode_button: Toggleable<Interactive<ContainedText>>,
- pub nav_button: Toggleable<Interactive<ContainedLabel>>,
- pub search_bar_row_height: f32,
- pub search_row_spacing: f32,
- pub option_button_height: f32,
- pub modes_container: ContainerStyle,
- pub replace_icon: IconStyle,
- // Used for filters and replace
- pub option_button: Toggleable<Interactive<IconButton>>,
- pub action_button: IconButtonStyle,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct FindEditor {
- #[serde(flatten)]
- pub input: FieldEditor,
- pub min_width: f32,
- pub max_width: f32,
-}
-
-#[derive(Deserialize, Default, JsonSchema)]
-pub struct StatusBar {
- #[serde(flatten)]
- pub container: ContainerStyle,
- pub height: f32,
- pub item_spacing: f32,
- pub cursor_position: TextStyle,
- pub vim_mode_indicator: ContainedText,
- pub active_language: Interactive<ContainedText>,
- pub auto_update_progress_message: TextStyle,
- pub auto_update_done_message: TextStyle,
- pub lsp_status: Interactive<StatusBarLspStatus>,
- pub panel_buttons: StatusBarPanelButtons,
- pub diagnostic_summary: Interactive<StatusBarDiagnosticSummary>,
- pub diagnostic_message: Interactive<ContainedText>,
-}
-
-#[derive(Deserialize, Default, JsonSchema)]
-pub struct StatusBarPanelButtons {
- pub group_left: ContainerStyle,
- pub group_bottom: ContainerStyle,
- pub group_right: ContainerStyle,
- pub button: Toggleable<Interactive<PanelButton>>,
-}
-
-#[derive(Deserialize, Default, JsonSchema)]
-pub struct StatusBarDiagnosticSummary {
- pub container_ok: ContainerStyle,
- pub container_warning: ContainerStyle,
- pub container_error: ContainerStyle,
- pub text: TextStyle,
- pub icon_color_ok: Color,
- pub icon_color_warning: Color,
- pub icon_color_error: Color,
- pub height: f32,
- pub icon_width: f32,
- pub icon_spacing: f32,
- pub summary_spacing: f32,
-}
-
-#[derive(Deserialize, Default, JsonSchema)]
-pub struct StatusBarLspStatus {
- #[serde(flatten)]
- pub container: ContainerStyle,
- pub height: f32,
- pub icon_spacing: f32,
- pub icon_color: Color,
- pub icon_width: f32,
- pub message: TextStyle,
-}
-
-#[derive(Deserialize, Default, JsonSchema)]
-pub struct Dock {
- pub left: ContainerStyle,
- pub bottom: ContainerStyle,
- pub right: ContainerStyle,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct PanelButton {
- #[serde(flatten)]
- pub container: ContainerStyle,
- pub icon_color: Color,
- pub icon_size: f32,
- pub label: ContainedText,
-}
-
-#[derive(Deserialize, Default, JsonSchema)]
-pub struct ProjectPanel {
- #[serde(flatten)]
- pub container: ContainerStyle,
- pub entry: Toggleable<Interactive<ProjectPanelEntry>>,
- pub dragged_entry: ProjectPanelEntry,
- pub ignored_entry: Toggleable<Interactive<ProjectPanelEntry>>,
- pub cut_entry: Toggleable<Interactive<ProjectPanelEntry>>,
- pub filename_editor: FieldEditor,
- pub indent_width: f32,
- pub open_project_button: Interactive<ContainedText>,
-}
-
-#[derive(Clone, Debug, Deserialize, Default, JsonSchema)]
-pub struct ProjectPanelEntry {
- pub height: f32,
- #[serde(flatten)]
- pub container: ContainerStyle,
- pub text: TextStyle,
- pub icon_size: f32,
- pub icon_color: Color,
- pub chevron_color: Color,
- pub chevron_size: f32,
- pub icon_spacing: f32,
- pub status: EntryStatus,
-}
-
-#[derive(Clone, Debug, Deserialize, Default, JsonSchema)]
-pub struct EntryStatus {
- pub git: GitProjectStatus,
-}
-
-#[derive(Clone, Debug, Deserialize, Default, JsonSchema)]
-pub struct GitProjectStatus {
- pub modified: Color,
- pub inserted: Color,
- pub conflict: Color,
-}
-
-#[derive(Clone, Debug, Deserialize, Default, JsonSchema)]
-pub struct ContextMenu {
- #[serde(flatten)]
- pub container: ContainerStyle,
- pub item: Toggleable<Interactive<ContextMenuItem>>,
- pub keystroke_margin: f32,
- pub separator: ContainerStyle,
-}
-
-#[derive(Clone, Debug, Deserialize, Default, JsonSchema)]
-pub struct ContextMenuItem {
- #[serde(flatten)]
- pub container: ContainerStyle,
- pub label: TextStyle,
- pub keystroke: ContainedText,
- pub icon_width: f32,
- pub icon_spacing: f32,
-}
-
-#[derive(Debug, Deserialize, Default, JsonSchema)]
-pub struct CommandPalette {
- pub key: Toggleable<ContainedLabel>,
- pub keystroke_spacing: f32,
-}
-
-#[derive(Deserialize, Default, JsonSchema)]
-pub struct InviteLink {
- #[serde(flatten)]
- pub container: ContainerStyle,
- #[serde(flatten)]
- pub label: LabelStyle,
- pub icon: Icon,
-}
-
-#[derive(Deserialize, Clone, Copy, Default, JsonSchema)]
-pub struct Icon {
- #[serde(flatten)]
- pub container: ContainerStyle,
- pub color: Color,
- pub width: f32,
-}
-
-#[derive(Deserialize, Clone, Copy, Default, JsonSchema)]
-pub struct IconButton {
- #[serde(flatten)]
- pub container: ContainerStyle,
- pub color: Color,
- pub icon_width: f32,
- pub button_width: f32,
-}
+#[derive(Debug, PartialEq, Eq, Clone, Copy)]
+pub enum LoadThemes {
+ /// Only load the base theme.
+ ///
+ /// No user themes will be loaded.
+ JustBase,
-#[derive(Deserialize, Default, JsonSchema)]
-pub struct ChatPanel {
- #[serde(flatten)]
- pub container: ContainerStyle,
- pub list: ContainerStyle,
- pub channel_select: ChannelSelect,
- pub input_editor: FieldEditor,
- pub avatar: AvatarStyle,
- pub avatar_container: ContainerStyle,
- pub rich_text: RichTextStyle,
- pub message_sender: ContainedText,
- pub message_timestamp: ContainedText,
- pub message: Interactive<ContainerStyle>,
- pub continuation_message: Interactive<ContainerStyle>,
- pub pending_message: Interactive<ContainerStyle>,
- pub last_message_bottom_spacing: f32,
- pub sign_in_prompt: Interactive<TextStyle>,
- pub icon_button: Interactive<IconButton>,
+ /// Load all of the built-in themes.
+ All,
}
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct RichTextStyle {
- pub text: TextStyle,
- pub mention_highlight: HighlightStyle,
- pub mention_background: Option<Color>,
- pub self_mention_highlight: HighlightStyle,
- pub self_mention_background: Option<Color>,
- pub code_background: Option<Color>,
-}
+pub fn init(themes_to_load: LoadThemes, cx: &mut AppContext) {
+ cx.set_global(ThemeRegistry::default());
-#[derive(Deserialize, Default, JsonSchema)]
-pub struct NotificationPanel {
- #[serde(flatten)]
- pub container: ContainerStyle,
- pub title: ContainedText,
- pub title_icon: SvgStyle,
- pub title_height: f32,
- pub list: ContainerStyle,
- pub avatar: AvatarStyle,
- pub avatar_container: ContainerStyle,
- pub sign_in_prompt: Interactive<TextStyle>,
- pub icon_button: Interactive<IconButton>,
- pub unread_text: ContainedText,
- pub read_text: ContainedText,
- pub timestamp: ContainedText,
- pub button: Interactive<ContainedText>,
-}
-
-#[derive(Deserialize, Default, JsonSchema)]
-pub struct ChannelSelect {
- #[serde(flatten)]
- pub container: ContainerStyle,
- pub header: ChannelName,
- pub item: ChannelName,
- pub active_item: ChannelName,
- pub hovered_item: ChannelName,
- pub menu: ContainerStyle,
-}
-
-#[derive(Deserialize, Default, JsonSchema)]
-pub struct ChannelName {
- #[serde(flatten)]
- pub container: ContainerStyle,
- pub hash: ContainedText,
- pub name: TextStyle,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct Picker {
- #[serde(flatten)]
- pub container: ContainerStyle,
- pub empty_container: ContainerStyle,
- pub input_editor: FieldEditor,
- pub empty_input_editor: FieldEditor,
- pub no_matches: ContainedLabel,
- pub item: Toggleable<Interactive<ContainedLabel>>,
- pub header: ContainedLabel,
- pub footer: Interactive<ContainedLabel>,
-}
-
-#[derive(Clone, Debug, Deserialize, Default, JsonSchema)]
-pub struct ContainedText {
- #[serde(flatten)]
- pub container: ContainerStyle,
- #[serde(flatten)]
- pub text: TextStyle,
-}
-
-#[derive(Clone, Debug, Deserialize, Default, JsonSchema)]
-pub struct ContainedLabel {
- #[serde(flatten)]
- pub container: ContainerStyle,
- #[serde(flatten)]
- pub label: LabelStyle,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct ProjectDiagnostics {
- #[serde(flatten)]
- pub container: ContainerStyle,
- pub empty_message: TextStyle,
- pub tab_icon_width: f32,
- pub tab_icon_spacing: f32,
- pub tab_summary_spacing: f32,
-}
-
-#[derive(Deserialize, Default, JsonSchema)]
-pub struct ContactNotification {
- pub header_avatar: ImageStyle,
- pub header_message: ContainedText,
- pub header_height: f32,
- pub body_message: ContainedText,
- pub button: Interactive<ContainedText>,
- pub dismiss_button: Interactive<IconButton>,
-}
-
-#[derive(Deserialize, Default, JsonSchema)]
-pub struct UpdateNotification {
- pub message: ContainedText,
- pub action_message: Interactive<ContainedText>,
- pub dismiss_button: Interactive<IconButton>,
-}
-
-#[derive(Deserialize, Default, JsonSchema)]
-pub struct MessageNotification {
- pub message: ContainedText,
- pub action_message: Interactive<ContainedText>,
- pub dismiss_button: Interactive<IconButton>,
-}
-
-#[derive(Deserialize, Default, JsonSchema)]
-pub struct ProjectSharedNotification {
- pub window_height: f32,
- pub window_width: f32,
- #[serde(default)]
- pub background: Color,
- pub owner_container: ContainerStyle,
- pub owner_avatar: ImageStyle,
- pub owner_metadata: ContainerStyle,
- pub owner_username: ContainedText,
- pub message: ContainedText,
- pub worktree_roots: ContainedText,
- pub button_width: f32,
- pub open_button: ContainedText,
- pub dismiss_button: ContainedText,
-}
-
-#[derive(Deserialize, Default, JsonSchema)]
-pub struct IncomingCallNotification {
- pub window_height: f32,
- pub window_width: f32,
- #[serde(default)]
- pub background: Color,
- pub caller_container: ContainerStyle,
- pub caller_avatar: ImageStyle,
- pub caller_metadata: ContainerStyle,
- pub caller_username: ContainedText,
- pub caller_message: ContainedText,
- pub worktree_roots: ContainedText,
- pub button_width: f32,
- pub accept_button: ContainedText,
- pub decline_button: ContainedText,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct Editor {
- pub text_color: Color,
- #[serde(default)]
- pub background: Color,
- pub selection: SelectionStyle,
- pub gutter_background: Color,
- pub gutter_padding_factor: f32,
- pub active_line_background: Color,
- pub highlighted_line_background: Color,
- pub rename_fade: f32,
- pub document_highlight_read_background: Color,
- pub document_highlight_write_background: Color,
- pub diff: DiffStyle,
- pub wrap_guide: Color,
- pub active_wrap_guide: Color,
- pub line_number: Color,
- pub line_number_active: Color,
- pub guest_selections: Vec<SelectionStyle>,
- pub absent_selection: SelectionStyle,
- pub syntax: Arc<SyntaxTheme>,
- pub hint: HighlightStyle,
- pub suggestion: HighlightStyle,
- pub diagnostic_path_header: DiagnosticPathHeader,
- pub diagnostic_header: DiagnosticHeader,
- pub error_diagnostic: DiagnosticStyle,
- pub invalid_error_diagnostic: DiagnosticStyle,
- pub warning_diagnostic: DiagnosticStyle,
- pub invalid_warning_diagnostic: DiagnosticStyle,
- pub information_diagnostic: DiagnosticStyle,
- pub invalid_information_diagnostic: DiagnosticStyle,
- pub hint_diagnostic: DiagnosticStyle,
- pub invalid_hint_diagnostic: DiagnosticStyle,
- pub autocomplete: AutocompleteStyle,
- pub code_actions: CodeActions,
- pub folds: Folds,
- pub unnecessary_code_fade: f32,
- pub hover_popover: HoverPopover,
- pub link_definition: HighlightStyle,
- pub composition_mark: HighlightStyle,
- pub jump_icon: Interactive<IconButton>,
- pub scrollbar: Scrollbar,
- pub whitespace: Color,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct Scrollbar {
- pub track: ContainerStyle,
- pub thumb: ContainerStyle,
- pub width: f32,
- pub min_height_factor: f32,
- pub git: BufferGitDiffColors,
- pub selections: Color,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct BufferGitDiffColors {
- pub inserted: Color,
- pub modified: Color,
- pub deleted: Color,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct DiagnosticPathHeader {
- #[serde(flatten)]
- pub container: ContainerStyle,
- pub filename: ContainedText,
- pub path: ContainedText,
- pub text_scale_factor: f32,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct DiagnosticHeader {
- #[serde(flatten)]
- pub container: ContainerStyle,
- pub source: ContainedLabel,
- pub message: ContainedLabel,
- pub code: ContainedText,
- pub text_scale_factor: f32,
- pub icon_width_factor: f32,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct DiagnosticStyle {
- pub message: LabelStyle,
- #[serde(default)]
- pub header: ContainerStyle,
- pub text_scale_factor: f32,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct AutocompleteStyle {
- #[serde(flatten)]
- pub container: ContainerStyle,
- pub item: ContainerStyle,
- pub selected_item: ContainerStyle,
- pub hovered_item: ContainerStyle,
- pub match_highlight: HighlightStyle,
- pub completion_min_width: f32,
- pub completion_max_width: f32,
- pub inline_docs_container: ContainerStyle,
- pub inline_docs_color: Color,
- pub inline_docs_size_percent: f32,
- pub alongside_docs_max_width: f32,
- pub alongside_docs_container: ContainerStyle,
-}
-
-#[derive(Clone, Copy, Default, Deserialize, JsonSchema)]
-pub struct SelectionStyle {
- pub cursor: Color,
- pub selection: Color,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct FieldEditor {
- #[serde(flatten)]
- pub container: ContainerStyle,
- pub text: TextStyle,
- #[serde(default)]
- pub placeholder_text: Option<TextStyle>,
- pub selection: SelectionStyle,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct InteractiveColor {
- pub color: Color,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct CodeActions {
- #[serde(default)]
- pub indicator: Toggleable<Interactive<InteractiveColor>>,
- pub vertical_scale: f32,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct Folds {
- pub indicator: Toggleable<Interactive<InteractiveColor>>,
- pub ellipses: FoldEllipses,
- pub fold_background: Color,
- pub icon_margin_scale: f32,
- pub folded_icon: String,
- pub foldable_icon: String,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct FoldEllipses {
- pub text_color: Color,
- pub background: Interactive<InteractiveColor>,
- pub corner_radius_factor: f32,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct DiffStyle {
- pub inserted: Color,
- pub modified: Color,
- pub deleted: Color,
- pub removed_width_em: f32,
- pub width_em: f32,
- pub corner_radius: f32,
-}
-
-#[derive(Debug, Default, Clone, Copy, JsonSchema)]
-pub struct Interactive<T> {
- pub default: T,
- pub hovered: Option<T>,
- pub clicked: Option<T>,
- pub disabled: Option<T>,
-}
-
-impl<T> Deref for Interactive<T> {
- type Target = T;
-
- fn deref(&self) -> &Self::Target {
- &self.default
+ match themes_to_load {
+ LoadThemes::JustBase => (),
+ LoadThemes::All => cx.global_mut::<ThemeRegistry>().load_user_themes(),
}
-}
-impl Interactive<()> {
- pub fn new_blank() -> Self {
- Self {
- default: (),
- hovered: None,
- clicked: None,
- disabled: None,
- }
- }
+ ThemeSettings::register(cx);
}
-#[derive(Clone, Copy, Debug, Default, Deserialize, JsonSchema)]
-pub struct Toggleable<T> {
- active: T,
- inactive: T,
+pub trait ActiveTheme {
+ fn theme(&self) -> &Arc<Theme>;
}
-impl<T> Deref for Toggleable<T> {
- type Target = T;
-
- fn deref(&self) -> &Self::Target {
- &self.inactive
+impl ActiveTheme for AppContext {
+ fn theme(&self) -> &Arc<Theme> {
+ &ThemeSettings::get_global(self).active_theme
}
}
-impl Toggleable<()> {
- pub fn new_blank() -> Self {
- Self {
- active: (),
- inactive: (),
- }
- }
+// todo!()
+// impl<'a> ActiveTheme for WindowContext<'a> {
+// fn theme(&self) -> &Arc<Theme> {
+// &ThemeSettings::get_global(self.app()).active_theme
+// }
+// }
+
+pub struct ThemeFamily {
+ pub id: String,
+ pub name: SharedString,
+ pub author: SharedString,
+ pub themes: Vec<Theme>,
+ pub scales: ColorScales,
}
-impl<T> Toggleable<T> {
- pub fn new(active: T, inactive: T) -> Self {
- Self { active, inactive }
- }
- pub fn in_state(&self, active: bool) -> &T {
- if active {
- &self.active
- } else {
- &self.inactive
- }
- }
- pub fn active_state(&self) -> &T {
- self.in_state(true)
- }
+impl ThemeFamily {}
- pub fn inactive_state(&self) -> &T {
- self.in_state(false)
- }
+pub struct Theme {
+ pub id: String,
+ pub name: SharedString,
+ pub appearance: Appearance,
+ pub styles: ThemeStyles,
}
-impl<T> Interactive<T> {
- pub fn style_for(&self, state: &mut MouseState) -> &T {
- if state.clicked() == Some(platform::MouseButton::Left) && self.clicked.is_some() {
- self.clicked.as_ref().unwrap()
- } else if state.hovered() {
- self.hovered.as_ref().unwrap_or(&self.default)
- } else {
- &self.default
- }
- }
- pub fn disabled_style(&self) -> &T {
- self.disabled.as_ref().unwrap_or(&self.default)
+impl Theme {
+ /// Returns the [`SystemColors`] for the theme.
+ #[inline(always)]
+ pub fn system(&self) -> &SystemColors {
+ &self.styles.system
}
-}
-impl<T> Toggleable<Interactive<T>> {
- pub fn style_for(&self, active: bool, state: &mut MouseState) -> &T {
- self.in_state(active).style_for(state)
+ /// Returns the [`PlayerColors`] for the theme.
+ #[inline(always)]
+ pub fn players(&self) -> &PlayerColors {
+ &self.styles.player
}
- pub fn default_style(&self) -> &T {
- &self.inactive.default
+ /// Returns the [`ThemeColors`] for the theme.
+ #[inline(always)]
+ pub fn colors(&self) -> &ThemeColors {
+ &self.styles.colors
}
-}
-
-impl<'de, T: DeserializeOwned> Deserialize<'de> for Interactive<T> {
- fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
- where
- D: serde::Deserializer<'de>,
- {
- #[derive(Deserialize)]
- struct Helper {
- default: Value,
- hovered: Option<Value>,
- clicked: Option<Value>,
- disabled: Option<Value>,
- }
-
- let json = Helper::deserialize(deserializer)?;
-
- let deserialize_state = |state_json: Option<Value>| -> Result<Option<T>, D::Error> {
- if let Some(mut state_json) = state_json {
- if let Value::Object(state_json) = &mut state_json {
- if let Value::Object(default) = &json.default {
- for (key, value) in default {
- if !state_json.contains_key(key) {
- state_json.insert(key.clone(), value.clone());
- }
- }
- }
- }
- Ok(Some(
- serde_json::from_value::<T>(state_json).map_err(serde::de::Error::custom)?,
- ))
- } else {
- Ok(None)
- }
- };
-
- let hovered = deserialize_state(json.hovered)?;
- let clicked = deserialize_state(json.clicked)?;
- let disabled = deserialize_state(json.disabled)?;
- let default = serde_json::from_value(json.default).map_err(serde::de::Error::custom)?;
- Ok(Interactive {
- default,
- hovered,
- clicked,
- disabled,
- })
+ /// Returns the [`SyntaxTheme`] for the theme.
+ #[inline(always)]
+ pub fn syntax(&self) -> &Arc<SyntaxTheme> {
+ &self.styles.syntax
}
-}
-impl Editor {
- pub fn selection_style_for_room_participant(&self, participant_index: u32) -> SelectionStyle {
- if self.guest_selections.is_empty() {
- return SelectionStyle::default();
- }
- let style_ix = participant_index as usize % self.guest_selections.len();
- self.guest_selections[style_ix]
+ /// Returns the [`StatusColors`] for the theme.
+ #[inline(always)]
+ pub fn status(&self) -> &StatusColors {
+ &self.styles.status
}
-}
-#[derive(Default, JsonSchema)]
-pub struct SyntaxTheme {
- pub highlights: Vec<(String, HighlightStyle)>,
-}
-
-impl SyntaxTheme {
- pub fn new(highlights: Vec<(String, HighlightStyle)>) -> Self {
- Self { highlights }
+ /// 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)
}
-}
-
-impl<'de> Deserialize<'de> for SyntaxTheme {
- fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
- where
- D: serde::Deserializer<'de>,
- {
- let syntax_data: HashMap<String, HighlightStyle> = Deserialize::deserialize(deserializer)?;
- let mut result = Self::new(Vec::new());
- for (key, style) in syntax_data {
- match result
- .highlights
- .binary_search_by(|(needle, _)| needle.cmp(&key))
- {
- Ok(i) | Err(i) => {
- result.highlights.insert(i, (key, style));
- }
- }
- }
-
- Ok(result)
+ /// Returns the [`Appearance`] for the theme.
+ #[inline(always)]
+ pub fn appearance(&self) -> Appearance {
+ self.appearance
}
}
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct HoverPopover {
- pub container: ContainerStyle,
- pub info_container: ContainerStyle,
- pub warning_container: ContainerStyle,
- pub error_container: ContainerStyle,
- pub block_style: ContainerStyle,
- pub prose: TextStyle,
- pub diagnostic_source_highlight: HighlightStyle,
- pub highlight: Color,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct TerminalStyle {
- pub black: Color,
- pub red: Color,
- pub green: Color,
- pub yellow: Color,
- pub blue: Color,
- pub magenta: Color,
- pub cyan: Color,
- pub white: Color,
- pub bright_black: Color,
- pub bright_red: Color,
- pub bright_green: Color,
- pub bright_yellow: Color,
- pub bright_blue: Color,
- pub bright_magenta: Color,
- pub bright_cyan: Color,
- pub bright_white: Color,
- pub foreground: Color,
- pub background: Color,
- pub modal_background: Color,
- pub cursor: Color,
- pub dim_black: Color,
- pub dim_red: Color,
- pub dim_green: Color,
- pub dim_yellow: Color,
- pub dim_blue: Color,
- pub dim_magenta: Color,
- pub dim_cyan: Color,
- pub dim_white: Color,
- pub bright_foreground: Color,
- pub dim_foreground: Color,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct AssistantStyle {
- pub container: ContainerStyle,
- pub hamburger_button: Interactive<IconStyle>,
- pub split_button: Interactive<IconStyle>,
- pub assist_button: Interactive<IconStyle>,
- pub quote_button: Interactive<IconStyle>,
- pub zoom_in_button: Interactive<IconStyle>,
- pub zoom_out_button: Interactive<IconStyle>,
- pub plus_button: Interactive<IconStyle>,
- pub title: ContainedText,
- pub message_header: ContainerStyle,
- pub sent_at: ContainedText,
- pub user_sender: Interactive<ContainedText>,
- pub assistant_sender: Interactive<ContainedText>,
- pub system_sender: Interactive<ContainedText>,
- pub model: Interactive<ContainedText>,
- pub remaining_tokens: ContainedText,
- pub low_remaining_tokens: ContainedText,
- pub no_remaining_tokens: ContainedText,
- pub error_icon: Icon,
- pub api_key_editor: FieldEditor,
- pub api_key_prompt: ContainedText,
- pub saved_conversation: SavedConversation,
- pub inline: InlineAssistantStyle,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct InlineAssistantStyle {
- #[serde(flatten)]
- pub container: ContainerStyle,
- pub editor: FieldEditor,
- pub disabled_editor: FieldEditor,
- pub pending_edit_background: Color,
- pub include_conversation: ToggleIconButtonStyle,
- pub retrieve_context: ToggleIconButtonStyle,
- pub context_status: ContextStatusStyle,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct ContextStatusStyle {
- pub error_icon: Icon,
- pub in_progress_icon: Icon,
- pub complete_icon: Icon,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct Contained<T> {
- container: ContainerStyle,
- contained: T,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct SavedConversation {
- pub container: Interactive<ContainerStyle>,
- pub saved_at: ContainedText,
- pub title: ContainedText,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct FeedbackStyle {
- pub submit_button: Interactive<ContainedText>,
- pub button_margin: f32,
- pub info_text_default: ContainedText,
- pub link_text_default: ContainedText,
- pub link_text_hover: ContainedText,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct WelcomeStyle {
- pub page_width: f32,
- pub logo: SvgStyle,
- pub logo_subheading: ContainedText,
- pub usage_note: ContainedText,
- pub checkbox: CheckboxStyle,
- pub checkbox_container: ContainerStyle,
- pub button: Interactive<ContainedText>,
- pub button_group: ContainerStyle,
- pub heading_group: ContainerStyle,
- pub checkbox_group: ContainerStyle,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct ColorScheme {
- pub name: String,
- pub is_light: bool,
- pub lowest: Layer,
- pub middle: Layer,
- pub highest: Layer,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct Player {
- pub cursor: Color,
- pub selection: Color,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct RampSet {
- pub neutral: Vec<Color>,
- pub red: Vec<Color>,
- pub orange: Vec<Color>,
- pub yellow: Vec<Color>,
- pub green: Vec<Color>,
- pub cyan: Vec<Color>,
- pub blue: Vec<Color>,
- pub violet: Vec<Color>,
- pub magenta: Vec<Color>,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct Layer {
- pub base: StyleSet,
- pub variant: StyleSet,
- pub on: StyleSet,
- pub accent: StyleSet,
- pub positive: StyleSet,
- pub warning: StyleSet,
- pub negative: StyleSet,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct StyleSet {
- pub default: Style,
- pub active: Style,
- pub disabled: Style,
- pub hovered: Style,
- pub pressed: Style,
- pub inverted: Style,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct Style {
- pub background: Color,
- pub border: Color,
- pub foreground: Color,
+pub fn color_alpha(color: Hsla, alpha: f32) -> Hsla {
+ let mut color = color;
+ color.a = alpha;
+ color
}
@@ -1,106 +0,0 @@
-use crate::{Theme, ThemeMeta};
-use anyhow::{Context, Result};
-use gpui::{fonts, AssetSource, FontCache};
-use parking_lot::Mutex;
-use serde::Deserialize;
-use serde_json::Value;
-use std::{
- borrow::Cow,
- collections::HashMap,
- sync::{
- atomic::{AtomicUsize, Ordering::SeqCst},
- Arc,
- },
-};
-
-pub struct ThemeRegistry {
- assets: Box<dyn AssetSource>,
- themes: Mutex<HashMap<String, Arc<Theme>>>,
- theme_data: Mutex<HashMap<String, Arc<Value>>>,
- font_cache: Arc<FontCache>,
- next_theme_id: AtomicUsize,
-}
-
-impl ThemeRegistry {
- pub fn new(source: impl AssetSource, font_cache: Arc<FontCache>) -> Arc<Self> {
- let this = Arc::new(Self {
- assets: Box::new(source),
- themes: Default::default(),
- theme_data: Default::default(),
- next_theme_id: Default::default(),
- font_cache,
- });
-
- this.themes.lock().insert(
- settings::EMPTY_THEME_NAME.to_string(),
- gpui::fonts::with_font_cache(this.font_cache.clone(), || {
- let mut theme = Theme::default();
- theme.meta.id = this.next_theme_id.fetch_add(1, SeqCst);
- theme.meta.name = settings::EMPTY_THEME_NAME.into();
- Arc::new(theme)
- }),
- );
-
- this
- }
-
- pub fn list_names(&self, staff: bool) -> impl Iterator<Item = Cow<str>> + '_ {
- let mut dirs = self.assets.list("themes/");
-
- if !staff {
- dirs = dirs
- .into_iter()
- .filter(|path| !path.starts_with("themes/staff"))
- .collect()
- }
-
- fn get_name(path: &str) -> Option<&str> {
- path.strip_prefix("themes/")?.strip_suffix(".json")
- }
-
- dirs.into_iter().filter_map(|path| match path {
- Cow::Borrowed(path) => Some(Cow::Borrowed(get_name(path)?)),
- Cow::Owned(path) => Some(Cow::Owned(get_name(&path)?.to_string())),
- })
- }
-
- pub fn list(&self, staff: bool) -> impl Iterator<Item = ThemeMeta> + '_ {
- self.list_names(staff).filter_map(|theme_name| {
- self.get(theme_name.as_ref())
- .ok()
- .map(|theme| theme.meta.clone())
- })
- }
-
- pub fn clear(&self) {
- self.theme_data.lock().clear();
- self.themes.lock().clear();
- }
-
- pub fn get(&self, name: &str) -> Result<Arc<Theme>> {
- if let Some(theme) = self.themes.lock().get(name) {
- return Ok(theme.clone());
- }
-
- let asset_path = format!("themes/{}.json", name);
- let theme_json = self
- .assets
- .load(&asset_path)
- .with_context(|| format!("failed to load theme file {}", asset_path))?;
-
- // Allocate into the heap directly, the Theme struct is too large to fit in the stack.
- let mut theme = fonts::with_font_cache(self.font_cache.clone(), || {
- let mut theme = Box::new(Theme::default());
- let mut deserializer = serde_json::Deserializer::from_slice(&theme_json);
- let result = Theme::deserialize_in_place(&mut deserializer, &mut theme);
- result.map(|_| theme)
- })?;
-
- // Reset name to be the file path, so that we can use it to access the stored themes
- theme.meta.name = name.into();
- theme.meta.id = self.next_theme_id.fetch_add(1, SeqCst);
- let theme: Arc<Theme> = theme.into();
- self.themes.lock().insert(name.to_string(), theme.clone());
- Ok(theme)
- }
-}
@@ -1,214 +0,0 @@
-use crate::{Theme, ThemeRegistry};
-use anyhow::Result;
-use gpui::{font_cache::FamilyId, fonts, AppContext};
-use schemars::{
- gen::SchemaGenerator,
- schema::{InstanceType, Schema, SchemaObject},
- JsonSchema,
-};
-use serde::{Deserialize, Serialize};
-use serde_json::Value;
-use settings::SettingsJsonSchemaParams;
-use std::sync::Arc;
-use util::ResultExt as _;
-
-const MIN_FONT_SIZE: f32 = 6.0;
-const MIN_LINE_HEIGHT: f32 = 1.0;
-
-#[derive(Clone, JsonSchema)]
-pub struct ThemeSettings {
- pub buffer_font_family_name: String,
- pub buffer_font_features: fonts::Features,
- pub buffer_font_family: FamilyId,
- pub(crate) buffer_font_size: f32,
- pub(crate) buffer_line_height: BufferLineHeight,
- #[serde(skip)]
- pub theme: Arc<Theme>,
-}
-
-pub struct AdjustedBufferFontSize(pub f32);
-
-#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema)]
-pub struct ThemeSettingsContent {
- #[serde(default)]
- pub buffer_font_family: Option<String>,
- #[serde(default)]
- pub buffer_font_size: Option<f32>,
- #[serde(default)]
- pub buffer_line_height: Option<BufferLineHeight>,
- #[serde(default)]
- pub buffer_font_features: Option<fonts::Features>,
- #[serde(default)]
- pub theme: Option<String>,
-}
-
-#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, JsonSchema, Default)]
-#[serde(rename_all = "snake_case")]
-pub enum BufferLineHeight {
- #[default]
- Comfortable,
- Standard,
- Custom(f32),
-}
-
-impl BufferLineHeight {
- pub fn value(&self) -> f32 {
- match self {
- BufferLineHeight::Comfortable => 1.618,
- BufferLineHeight::Standard => 1.3,
- BufferLineHeight::Custom(line_height) => *line_height,
- }
- }
-}
-
-impl ThemeSettings {
- pub fn buffer_font_size(&self, cx: &AppContext) -> f32 {
- if cx.has_global::<AdjustedBufferFontSize>() {
- cx.global::<AdjustedBufferFontSize>().0
- } else {
- self.buffer_font_size
- }
- .max(MIN_FONT_SIZE)
- }
-
- pub fn line_height(&self) -> f32 {
- f32::max(self.buffer_line_height.value(), MIN_LINE_HEIGHT)
- }
-}
-
-pub fn adjusted_font_size(size: f32, cx: &AppContext) -> f32 {
- if cx.has_global::<AdjustedBufferFontSize>() {
- let buffer_font_size = settings::get::<ThemeSettings>(cx).buffer_font_size;
- let delta = cx.global::<AdjustedBufferFontSize>().0 - buffer_font_size;
- size + delta
- } else {
- size
- }
- .max(MIN_FONT_SIZE)
-}
-
-pub fn adjust_font_size(cx: &mut AppContext, f: fn(&mut f32)) {
- if !cx.has_global::<AdjustedBufferFontSize>() {
- let buffer_font_size = settings::get::<ThemeSettings>(cx).buffer_font_size;
- cx.set_global(AdjustedBufferFontSize(buffer_font_size));
- }
-
- cx.update_global::<AdjustedBufferFontSize, _, _>(|delta, cx| {
- f(&mut delta.0);
- delta.0 = delta
- .0
- .max(MIN_FONT_SIZE - settings::get::<ThemeSettings>(cx).buffer_font_size);
- });
- cx.refresh_windows();
-}
-
-pub fn reset_font_size(cx: &mut AppContext) {
- if cx.has_global::<AdjustedBufferFontSize>() {
- cx.remove_global::<AdjustedBufferFontSize>();
- cx.refresh_windows();
- }
-}
-
-impl settings::Setting for ThemeSettings {
- const KEY: Option<&'static str> = None;
-
- type FileContent = ThemeSettingsContent;
-
- fn load(
- defaults: &Self::FileContent,
- user_values: &[&Self::FileContent],
- cx: &AppContext,
- ) -> Result<Self> {
- let buffer_font_features = defaults.buffer_font_features.clone().unwrap();
- let themes = cx.global::<Arc<ThemeRegistry>>();
-
- let mut this = Self {
- buffer_font_family: cx
- .font_cache()
- .load_family(
- &[defaults.buffer_font_family.as_ref().unwrap()],
- &buffer_font_features,
- )
- .unwrap(),
- buffer_font_family_name: defaults.buffer_font_family.clone().unwrap(),
- buffer_font_features,
- buffer_font_size: defaults.buffer_font_size.unwrap(),
- buffer_line_height: defaults.buffer_line_height.unwrap(),
- theme: themes.get(defaults.theme.as_ref().unwrap()).unwrap(),
- };
-
- for value in user_values.into_iter().copied().cloned() {
- let font_cache = cx.font_cache();
- let mut family_changed = false;
- if let Some(value) = value.buffer_font_family {
- this.buffer_font_family_name = value;
- family_changed = true;
- }
- if let Some(value) = value.buffer_font_features {
- this.buffer_font_features = value;
- family_changed = true;
- }
- if family_changed {
- if let Some(id) = font_cache
- .load_family(&[&this.buffer_font_family_name], &this.buffer_font_features)
- .log_err()
- {
- this.buffer_font_family = id;
- }
- }
-
- if let Some(value) = &value.theme {
- if let Some(theme) = themes.get(value).log_err() {
- this.theme = theme;
- }
- }
-
- merge(&mut this.buffer_font_size, value.buffer_font_size);
- merge(&mut this.buffer_line_height, value.buffer_line_height);
- }
-
- Ok(this)
- }
-
- fn json_schema(
- generator: &mut SchemaGenerator,
- params: &SettingsJsonSchemaParams,
- cx: &AppContext,
- ) -> schemars::schema::RootSchema {
- let mut root_schema = generator.root_schema_for::<ThemeSettingsContent>();
- let theme_names = cx
- .global::<Arc<ThemeRegistry>>()
- .list_names(params.staff_mode)
- .map(|theme_name| Value::String(theme_name.to_string()))
- .collect();
-
- let theme_name_schema = SchemaObject {
- instance_type: Some(InstanceType::String.into()),
- enum_values: Some(theme_names),
- ..Default::default()
- };
-
- root_schema
- .definitions
- .extend([("ThemeName".into(), theme_name_schema.into())]);
-
- root_schema
- .schema
- .object
- .as_mut()
- .unwrap()
- .properties
- .extend([(
- "theme".to_owned(),
- Schema::new_ref("#/definitions/ThemeName".into()),
- )]);
-
- root_schema
- }
-}
-
-fn merge<T: Copy>(target: &mut T, value: Option<T>) {
- if let Some(value) = value {
- *target = value;
- }
-}
@@ -1,244 +0,0 @@
-use std::borrow::Cow;
-
-use gpui::{
- elements::{
- ConstrainedBox, Container, ContainerStyle, Dimensions, Empty, Flex, KeystrokeLabel, Label,
- MouseEventHandler, ParentElement, Stack, Svg, SvgStyle,
- },
- fonts::TextStyle,
- geometry::vector::Vector2F,
- platform,
- platform::MouseButton,
- scene::MouseClick,
- Action, Element, EventContext, MouseState, ViewContext,
-};
-use schemars::JsonSchema;
-use serde::Deserialize;
-
-use crate::{ContainedText, Interactive};
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct CheckboxStyle {
- pub icon: SvgStyle,
- pub label: ContainedText,
- pub default: ContainerStyle,
- pub checked: ContainerStyle,
- pub hovered: ContainerStyle,
- pub hovered_and_checked: ContainerStyle,
-}
-
-pub fn checkbox<Tag, V, F>(
- label: &'static str,
- style: &CheckboxStyle,
- checked: bool,
- id: usize,
- cx: &mut ViewContext<V>,
- change: F,
-) -> MouseEventHandler<V>
-where
- Tag: 'static,
- V: 'static,
- F: 'static + Fn(&mut V, bool, &mut EventContext<V>),
-{
- let label = Label::new(label, style.label.text.clone())
- .contained()
- .with_style(style.label.container);
- checkbox_with_label::<Tag, _, _, _>(label, style, checked, id, cx, change)
-}
-
-pub fn checkbox_with_label<Tag, D, V, F>(
- label: D,
- style: &CheckboxStyle,
- checked: bool,
- id: usize,
- cx: &mut ViewContext<V>,
- change: F,
-) -> MouseEventHandler<V>
-where
- Tag: 'static,
- D: Element<V>,
- V: 'static,
- F: 'static + Fn(&mut V, bool, &mut EventContext<V>),
-{
- MouseEventHandler::new::<Tag, _>(id, cx, |state, _| {
- let indicator = if checked {
- svg(&style.icon)
- } else {
- Empty::new()
- .constrained()
- .with_width(style.icon.dimensions.width)
- .with_height(style.icon.dimensions.height)
- };
-
- Flex::row()
- .with_child(indicator.contained().with_style(if checked {
- if state.hovered() {
- style.hovered_and_checked
- } else {
- style.checked
- }
- } else {
- if state.hovered() {
- style.hovered
- } else {
- style.default
- }
- }))
- .with_child(label)
- .align_children_center()
- })
- .on_click(platform::MouseButton::Left, move |_, view, cx| {
- change(view, !checked, cx)
- })
- .with_cursor_style(platform::CursorStyle::PointingHand)
-}
-
-pub fn svg<V: 'static>(style: &SvgStyle) -> ConstrainedBox<V> {
- Svg::new(style.asset.clone())
- .with_color(style.color)
- .constrained()
- .with_width(style.dimensions.width)
- .with_height(style.dimensions.height)
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct IconStyle {
- pub icon: SvgStyle,
- pub container: ContainerStyle,
-}
-
-impl IconStyle {
- pub fn width(&self) -> f32 {
- self.icon.dimensions.width
- + self.container.padding.left
- + self.container.padding.right
- + self.container.margin.left
- + self.container.margin.right
- }
-}
-
-pub fn icon<V: 'static>(style: &IconStyle) -> Container<V> {
- svg(&style.icon).contained().with_style(style.container)
-}
-
-pub fn keystroke_label<V: 'static>(
- label_text: &'static str,
- label_style: &ContainedText,
- keystroke_style: &ContainedText,
- action: Box<dyn Action>,
- cx: &mut ViewContext<V>,
-) -> Container<V> {
- // FIXME: Put the theme in it's own global so we can
- // query the keystroke style on our own
- Flex::row()
- .with_child(Label::new(label_text, label_style.text.clone()).contained())
- .with_child(
- KeystrokeLabel::new(
- cx.view_id(),
- action,
- keystroke_style.container,
- keystroke_style.text.clone(),
- )
- .flex_float(),
- )
- .contained()
- .with_style(label_style.container)
-}
-
-pub type CopilotCTAButton = Interactive<ContainedText>;
-
-pub fn cta_button<Tag, L, V, F>(
- label: L,
- max_width: f32,
- style: &CopilotCTAButton,
- cx: &mut ViewContext<V>,
- f: F,
-) -> MouseEventHandler<V>
-where
- Tag: 'static,
- L: Into<Cow<'static, str>>,
- V: 'static,
- F: Fn(MouseClick, &mut V, &mut EventContext<V>) + 'static,
-{
- MouseEventHandler::new::<Tag, _>(0, cx, |state, _| {
- let style = style.style_for(state);
- Label::new(label, style.text.to_owned())
- .aligned()
- .contained()
- .with_style(style.container)
- .constrained()
- .with_max_width(max_width)
- })
- .on_click(MouseButton::Left, f)
- .with_cursor_style(platform::CursorStyle::PointingHand)
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct ModalStyle {
- close_icon: Interactive<IconStyle>,
- container: ContainerStyle,
- titlebar: ContainerStyle,
- title_text: Interactive<TextStyle>,
- dimensions: Dimensions,
-}
-
-impl ModalStyle {
- pub fn dimensions(&self) -> Vector2F {
- self.dimensions.to_vec()
- }
-}
-
-pub fn modal<Tag, V, I, D, F>(
- title: I,
- style: &ModalStyle,
- cx: &mut ViewContext<V>,
- build_modal: F,
-) -> impl Element<V>
-where
- Tag: 'static,
- I: Into<Cow<'static, str>>,
- D: Element<V>,
- V: 'static,
- F: FnOnce(&mut gpui::ViewContext<V>) -> D,
-{
- const TITLEBAR_HEIGHT: f32 = 28.;
-
- Flex::column()
- .with_child(
- Stack::new()
- .with_child(Label::new(
- title,
- style
- .title_text
- .style_for(&mut MouseState::default())
- .clone(),
- ))
- .with_child(
- // FIXME: Get a better tag type
- MouseEventHandler::new::<Tag, _>(999999, cx, |state, _cx| {
- let style = style.close_icon.style_for(state);
- icon(style)
- })
- .on_click(platform::MouseButton::Left, move |_, _, cx| {
- cx.remove_window();
- })
- .with_cursor_style(platform::CursorStyle::PointingHand)
- .aligned()
- .right(),
- )
- .contained()
- .with_style(style.titlebar)
- .constrained()
- .with_height(TITLEBAR_HEIGHT),
- )
- .with_child(
- build_modal(cx)
- .contained()
- .with_style(style.container)
- .constrained()
- .with_width(style.dimensions().x())
- .with_height(style.dimensions().y() - TITLEBAR_HEIGHT),
- )
- .constrained()
- .with_height(style.dimensions().y())
-}
@@ -1,42 +0,0 @@
-[package]
-name = "theme2"
-version = "0.1.0"
-edition = "2021"
-publish = false
-
-[features]
-default = []
-importing-themes = []
-stories = ["dep:itertools", "dep:story"]
-test-support = [
- "gpui/test-support",
- "fs/test-support",
- "settings/test-support"
-]
-
-[lib]
-path = "src/theme2.rs"
-doctest = false
-
-[dependencies]
-anyhow.workspace = true
-fs = { path = "../fs" }
-gpui = { package = "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
-settings = { path = "../settings" }
-story = { path = "../story", optional = true }
-toml.workspace = true
-uuid.workspace = true
-util = { path = "../util" }
-itertools = { version = "0.11.0", optional = true }
-
-[dev-dependencies]
-gpui = { package = "gpui2", path = "../gpui2", features = ["test-support"] }
-fs = { path = "../fs", features = ["test-support"] }
-settings = { path = "../settings", features = ["test-support"] }
@@ -1,148 +0,0 @@
-mod default_colors;
-mod default_theme;
-mod one_themes;
-pub mod prelude;
-mod registry;
-mod scale;
-mod settings;
-mod styles;
-#[cfg(not(feature = "importing-themes"))]
-mod themes;
-mod user_theme;
-
-use std::sync::Arc;
-
-use ::settings::Settings;
-pub use default_colors::*;
-pub use default_theme::*;
-pub use registry::*;
-pub use scale::*;
-pub use settings::*;
-pub use styles::*;
-#[cfg(not(feature = "importing-themes"))]
-pub use themes::*;
-pub use user_theme::*;
-
-use gpui::{AppContext, Hsla, SharedString};
-use serde::Deserialize;
-
-#[derive(Debug, PartialEq, Clone, Copy, Deserialize)]
-pub enum Appearance {
- Light,
- Dark,
-}
-
-impl Appearance {
- pub fn is_light(&self) -> bool {
- match self {
- Self::Light => true,
- Self::Dark => false,
- }
- }
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy)]
-pub enum LoadThemes {
- /// Only load the base theme.
- ///
- /// No user themes will be loaded.
- JustBase,
-
- /// Load all of the built-in themes.
- All,
-}
-
-pub fn init(themes_to_load: LoadThemes, cx: &mut AppContext) {
- cx.set_global(ThemeRegistry::default());
-
- match themes_to_load {
- LoadThemes::JustBase => (),
- LoadThemes::All => cx.global_mut::<ThemeRegistry>().load_user_themes(),
- }
-
- ThemeSettings::register(cx);
-}
-
-pub trait ActiveTheme {
- fn theme(&self) -> &Arc<Theme>;
-}
-
-impl ActiveTheme for AppContext {
- fn theme(&self) -> &Arc<Theme> {
- &ThemeSettings::get_global(self).active_theme
- }
-}
-
-// todo!()
-// impl<'a> ActiveTheme for WindowContext<'a> {
-// fn theme(&self) -> &Arc<Theme> {
-// &ThemeSettings::get_global(self.app()).active_theme
-// }
-// }
-
-pub struct ThemeFamily {
- pub id: String,
- pub name: SharedString,
- pub author: SharedString,
- pub themes: Vec<Theme>,
- pub scales: ColorScales,
-}
-
-impl ThemeFamily {}
-
-pub struct Theme {
- pub id: String,
- pub name: SharedString,
- pub appearance: Appearance,
- pub styles: ThemeStyles,
-}
-
-impl Theme {
- /// Returns the [`SystemColors`] for the theme.
- #[inline(always)]
- pub fn system(&self) -> &SystemColors {
- &self.styles.system
- }
-
- /// Returns the [`PlayerColors`] for the theme.
- #[inline(always)]
- pub fn players(&self) -> &PlayerColors {
- &self.styles.player
- }
-
- /// Returns the [`ThemeColors`] for the theme.
- #[inline(always)]
- pub fn colors(&self) -> &ThemeColors {
- &self.styles.colors
- }
-
- /// Returns the [`SyntaxTheme`] for the theme.
- #[inline(always)]
- pub fn syntax(&self) -> &Arc<SyntaxTheme> {
- &self.styles.syntax
- }
-
- /// Returns the [`StatusColors`] for the theme.
- #[inline(always)]
- pub fn status(&self) -> &StatusColors {
- &self.styles.status
- }
-
- /// 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)
- }
-
- /// Returns the [`Appearance`] for the theme.
- #[inline(always)]
- pub fn appearance(&self) -> Appearance {
- self.appearance
- }
-}
-
-pub fn color_alpha(color: Hsla, alpha: f32) -> Hsla {
- let mut color = color;
- color.a = alpha;
- color
-}
@@ -19,5 +19,5 @@ rust-embed.workspace = true
serde.workspace = true
simplelog = "0.9"
strum = { version = "0.25.0", features = ["derive"] }
-theme = { package = "theme2", path = "../theme2", features = ["importing-themes"] }
+theme = { path = "../theme", features = ["importing-themes"] }
uuid.workspace = true
@@ -78,7 +78,7 @@ struct Args {
fn main() -> Result<()> {
const SOURCE_PATH: &str = "assets/themes/src/vscode";
- const OUT_PATH: &str = "crates/theme2/src/themes";
+ const OUT_PATH: &str = "crates/theme/src/themes";
let args = Args::parse();
@@ -376,6 +376,6 @@ fn main() -> Result<()> {
fn format_themes_crate() -> std::io::Result<std::process::Output> {
Command::new("cargo")
- .args(["fmt", "--package", "theme2"])
+ .args(["fmt", "--package", "theme"])
.output()
}
@@ -17,7 +17,7 @@ fuzzy = { path = "../fuzzy" }
gpui = { package = "gpui2", path = "../gpui2" }
picker = { path = "../picker" }
settings = { path = "../settings" }
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
ui = { path = "../ui" }
util = { path = "../util" }
workspace = { path = "../workspace" }
@@ -19,7 +19,7 @@ settings = { path = "../settings" }
smallvec.workspace = true
story = { path = "../story", optional = true }
strum = { version = "0.25.0", features = ["derive"] }
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
rand = "0.8"
[features]
@@ -80,7 +80,7 @@ This may change in the future, but this is a little trick that let's you use fam
## Building out the container
-Let's grab our [theme2::colors::ThemeColors] from the theme and start building out a basic container.
+Let's grab our [theme::colors::ThemeColors] from the theme and start building out a basic container.
We can access the current theme's colors like this:
@@ -32,7 +32,7 @@ language = { path = "../language" }
search = { path = "../search" }
settings = { path = "../settings" }
workspace = { path = "../workspace" }
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
ui = { path = "../ui"}
diagnostics = { path = "../diagnostics" }
zed_actions = { path = "../zed_actions" }
@@ -49,5 +49,5 @@ project = { path = "../project", features = ["test-support"] }
util = { path = "../util", features = ["test-support"] }
settings = { path = "../settings" }
workspace = { path = "../workspace", features = ["test-support"] }
-theme = { package = "theme2", path = "../theme2", features = ["test-support"] }
+theme = { path = "../theme", features = ["test-support"] }
lsp = { path = "../lsp", features = ["test-support"] }
@@ -21,7 +21,7 @@ db = { path = "../db" }
install_cli = { path = "../install_cli" }
project = { path = "../project" }
settings = { path = "../settings" }
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
theme_selector = { path = "../theme_selector" }
util = { path = "../util" }
picker = { path = "../picker" }
@@ -33,7 +33,7 @@ node_runtime = { path = "../node_runtime" }
project = { path = "../project" }
settings = { path = "../settings" }
terminal = { path = "../terminal" }
-theme = { path = "../theme2", package = "theme2" }
+theme = { path = "../theme" }
util = { path = "../util" }
ui = { path = "../ui" }
@@ -254,7 +254,7 @@ pub mod simple_message_notification {
// }
// fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> gpui::AnyElement<Self> {
- // let theme = theme2::current(cx).clone();
+ // let theme = theme::current(cx).clone();
// let theme = &theme.simple_message_notification;
// enum MessageNotificationTag {}
@@ -272,7 +272,7 @@ pub struct DraggedTab {
// #[allow(clippy::too_many_arguments)]
// fn nav_button<A: Action, F: 'static + Fn(&mut Pane, &mut ViewContext<Pane>)>(
// svg_path: &'static str,
-// style: theme2::Interactive<theme2::IconButton>,
+// style: theme::Interactive<theme2::IconButton>,
// nav_button_height: f32,
// tooltip_style: TooltipStyle,
// enabled: bool,
@@ -66,7 +66,7 @@ sum_tree = { path = "../sum_tree" }
shellexpand = "2.1.0"
text = { path = "../text" }
terminal_view = { path = "../terminal_view" }
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
theme_selector = { path = "../theme_selector" }
util = { path = "../util" }
semantic_index = { path = "../semantic_index" }