mirror of
https://github.com/zed-industries/zed.git
synced 2025-01-24 19:10:24 +00:00
Get playground rendering with backward compatible theming
This commit is contained in:
parent
d763946b18
commit
1d491fcd78
7 changed files with 115 additions and 40 deletions
3
Cargo.lock
generated
3
Cargo.lock
generated
|
@ -5176,9 +5176,12 @@ dependencies = [
|
|||
"parking_lot 0.11.2",
|
||||
"playground_macros",
|
||||
"refineable",
|
||||
"rust-embed",
|
||||
"serde",
|
||||
"settings",
|
||||
"simplelog",
|
||||
"smallvec",
|
||||
"theme",
|
||||
"util",
|
||||
]
|
||||
|
||||
|
|
|
@ -16,9 +16,12 @@ log.workspace = true
|
|||
playground_macros = { path = "../playground_macros" }
|
||||
parking_lot.workspace = true
|
||||
refineable.workspace = true
|
||||
rust-embed.workspace = true
|
||||
serde.workspace = true
|
||||
settings = { path = "../../settings" }
|
||||
simplelog = "0.9"
|
||||
smallvec.workspace = true
|
||||
theme = { path = "../../theme" }
|
||||
util = { path = "../../util" }
|
||||
|
||||
[dev-dependencies]
|
||||
|
|
|
@ -3,9 +3,12 @@ use crate::element::Element;
|
|||
use gpui::{
|
||||
geometry::{rect::RectF, vector::vec2f},
|
||||
platform::WindowOptions,
|
||||
serde_json, ViewContext,
|
||||
};
|
||||
use log::LevelFilter;
|
||||
use settings::{default_settings, SettingsStore};
|
||||
use simplelog::SimpleLogger;
|
||||
use theme::ThemeSettings;
|
||||
use themes::Theme;
|
||||
use view::view;
|
||||
use workspace::workspace;
|
||||
|
@ -30,6 +33,13 @@ fn main() {
|
|||
SimpleLogger::init(LevelFilter::Info, Default::default()).expect("could not initialize logger");
|
||||
|
||||
gpui::App::new(()).unwrap().run(|cx| {
|
||||
let mut store = SettingsStore::default();
|
||||
store
|
||||
.set_default_settings(default_settings().as_ref(), cx)
|
||||
.unwrap();
|
||||
cx.set_global(store);
|
||||
theme::init(Assets, cx);
|
||||
|
||||
cx.add_window(
|
||||
WindowOptions {
|
||||
bounds: gpui::platform::WindowBounds::Fixed(RectF::new(
|
||||
|
@ -39,12 +49,51 @@ fn main() {
|
|||
center: true,
|
||||
..Default::default()
|
||||
},
|
||||
|_| view(|cx| playground(Theme::default())),
|
||||
|_| view(|cx| playground(cx)),
|
||||
);
|
||||
cx.platform().activate(true);
|
||||
});
|
||||
}
|
||||
|
||||
fn playground<V: 'static>(theme: Theme) -> impl Element<V> {
|
||||
workspace().themed(theme)
|
||||
fn playground<V: 'static>(cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
workspace().themed(current_theme(cx))
|
||||
}
|
||||
|
||||
// Nathan: During the transition, we will include the base theme on the legacy Theme struct.
|
||||
fn current_theme<V: 'static>(cx: &mut ViewContext<V>) -> Theme {
|
||||
settings::get::<ThemeSettings>(cx)
|
||||
.theme
|
||||
.deserialized_base_theme
|
||||
.lock()
|
||||
.get_or_insert_with(|| {
|
||||
let theme: Theme =
|
||||
serde_json::from_value(settings::get::<ThemeSettings>(cx).theme.base_theme.clone())
|
||||
.unwrap();
|
||||
Box::new(theme)
|
||||
})
|
||||
.downcast_ref::<Theme>()
|
||||
.unwrap()
|
||||
.clone()
|
||||
}
|
||||
|
||||
use anyhow::{anyhow, Result};
|
||||
use gpui::AssetSource;
|
||||
use rust_embed::RustEmbed;
|
||||
|
||||
#[derive(RustEmbed)]
|
||||
#[folder = "../../../assets"]
|
||||
#[include = "themes/**/*"]
|
||||
#[exclude = "*.DS_Store"]
|
||||
pub struct Assets;
|
||||
|
||||
impl AssetSource for Assets {
|
||||
fn load(&self, path: &str) -> Result<std::borrow::Cow<[u8]>> {
|
||||
Self::get(path)
|
||||
.map(|f| f.data)
|
||||
.ok_or_else(|| anyhow!("could not find asset at path \"{}\"", path))
|
||||
}
|
||||
|
||||
fn list(&self, path: &str) -> Vec<std::borrow::Cow<'static, str>> {
|
||||
Self::iter().filter(|p| p.starts_with(path)).collect()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,59 +9,59 @@ use std::{collections::HashMap, fmt, marker::PhantomData};
|
|||
|
||||
#[derive(Deserialize, Clone, Default, Debug)]
|
||||
pub struct Theme {
|
||||
name: String,
|
||||
is_light: bool,
|
||||
lowest: Layer,
|
||||
middle: Layer,
|
||||
highest: Layer,
|
||||
popover_shadow: Shadow,
|
||||
modal_shadow: Shadow,
|
||||
pub name: String,
|
||||
pub is_light: bool,
|
||||
pub lowest: Layer,
|
||||
pub middle: Layer,
|
||||
pub highest: Layer,
|
||||
pub popover_shadow: Shadow,
|
||||
pub modal_shadow: Shadow,
|
||||
#[serde(deserialize_with = "deserialize_player_colors")]
|
||||
players: Vec<PlayerColors>,
|
||||
pub players: Vec<PlayerColors>,
|
||||
#[serde(deserialize_with = "deserialize_syntax_colors")]
|
||||
syntax: HashMap<String, Hsla>,
|
||||
pub syntax: HashMap<String, Hsla>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Clone, Default, Debug)]
|
||||
pub struct Layer {
|
||||
base: StyleSet,
|
||||
variant: StyleSet,
|
||||
on: StyleSet,
|
||||
accent: StyleSet,
|
||||
positive: StyleSet,
|
||||
warning: StyleSet,
|
||||
negative: StyleSet,
|
||||
pub base: StyleSet,
|
||||
pub variant: StyleSet,
|
||||
pub on: StyleSet,
|
||||
pub accent: StyleSet,
|
||||
pub positive: StyleSet,
|
||||
pub warning: StyleSet,
|
||||
pub negative: StyleSet,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Clone, Default, Debug)]
|
||||
pub struct StyleSet {
|
||||
#[serde(rename = "default")]
|
||||
default: ContainerColors,
|
||||
hovered: ContainerColors,
|
||||
pressed: ContainerColors,
|
||||
active: ContainerColors,
|
||||
disabled: ContainerColors,
|
||||
inverted: ContainerColors,
|
||||
pub default: ContainerColors,
|
||||
pub hovered: ContainerColors,
|
||||
pub pressed: ContainerColors,
|
||||
pub active: ContainerColors,
|
||||
pub disabled: ContainerColors,
|
||||
pub inverted: ContainerColors,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Clone, Default, Debug)]
|
||||
pub struct ContainerColors {
|
||||
background: Hsla,
|
||||
foreground: Hsla,
|
||||
border: Hsla,
|
||||
pub background: Hsla,
|
||||
pub foreground: Hsla,
|
||||
pub border: Hsla,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Clone, Default, Debug)]
|
||||
pub struct PlayerColors {
|
||||
selection: Hsla,
|
||||
cursor: Hsla,
|
||||
pub selection: Hsla,
|
||||
pub cursor: Hsla,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Clone, Default, Debug)]
|
||||
pub struct Shadow {
|
||||
blur: u8,
|
||||
color: Hsla,
|
||||
offset: Vec<u8>,
|
||||
pub blur: u8,
|
||||
pub color: Hsla,
|
||||
pub offset: Vec<u8>,
|
||||
}
|
||||
|
||||
pub fn theme<'a>(cx: &'a WindowContext) -> &'a Theme {
|
||||
|
@ -107,6 +107,11 @@ fn deserialize_syntax_colors<'de, D>(deserializer: D) -> Result<HashMap<String,
|
|||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
#[derive(Deserialize)]
|
||||
struct ColorWrapper {
|
||||
color: Hsla,
|
||||
}
|
||||
|
||||
struct SyntaxVisitor;
|
||||
|
||||
impl<'de> Visitor<'de> for SyntaxVisitor {
|
||||
|
@ -122,8 +127,8 @@ where
|
|||
{
|
||||
let mut result = HashMap::new();
|
||||
while let Some(key) = map.next_key()? {
|
||||
let hsla: Hsla = map.next_value()?; // Deserialize values as Hsla
|
||||
result.insert(key, hsla);
|
||||
let wrapper: ColorWrapper = map.next_value()?; // Deserialize values as Hsla
|
||||
result.insert(key, wrapper.color);
|
||||
}
|
||||
Ok(result)
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ use crate::{
|
|||
div::div,
|
||||
element::{Element, IntoElement, ParentElement},
|
||||
style::StyleHelpers,
|
||||
themes::theme,
|
||||
};
|
||||
use gpui::{geometry::pixels, ViewContext};
|
||||
use playground_macros::Element;
|
||||
|
@ -16,20 +17,22 @@ pub fn workspace<V: 'static>() -> impl Element<V> {
|
|||
|
||||
impl WorkspaceElement {
|
||||
fn render<V: 'static>(&mut self, _: &mut V, cx: &mut ViewContext<V>) -> impl IntoElement<V> {
|
||||
// let theme = &cx.theme::<Theme>().colors;
|
||||
let theme = theme(cx);
|
||||
div()
|
||||
.full()
|
||||
.flex()
|
||||
.flex_col()
|
||||
// .fill(theme.base(0.5))
|
||||
.fill(theme.middle.base.default.background)
|
||||
.child(self.title_bar(cx))
|
||||
.child(self.stage(cx))
|
||||
.child(self.status_bar(cx))
|
||||
}
|
||||
|
||||
fn title_bar<V: 'static>(&mut self, cx: &mut ViewContext<V>) -> impl IntoElement<V> {
|
||||
// let colors = &theme(cx).colors;
|
||||
div().h(pixels(cx.titlebar_height())) //.fill(colors.base(0.))
|
||||
let theme = theme(cx);
|
||||
div()
|
||||
.h(pixels(cx.titlebar_height()))
|
||||
.fill(theme.lowest.base.default.background)
|
||||
}
|
||||
|
||||
fn status_bar<V: 'static>(&mut self, cx: &mut ViewContext<V>) -> impl IntoElement<V> {
|
||||
|
|
|
@ -10,11 +10,12 @@ use gpui::{
|
|||
fonts::{HighlightStyle, TextStyle},
|
||||
platform, AppContext, AssetSource, Border, MouseState,
|
||||
};
|
||||
use parking_lot::Mutex;
|
||||
use schemars::JsonSchema;
|
||||
use serde::{de::DeserializeOwned, Deserialize};
|
||||
use serde_json::Value;
|
||||
use settings::SettingsStore;
|
||||
use std::{collections::HashMap, ops::Deref, sync::Arc};
|
||||
use std::{any::Any, collections::HashMap, ops::Deref, sync::Arc};
|
||||
use ui::{CheckboxStyle, CopilotCTAButton, IconStyle, ModalStyle};
|
||||
|
||||
pub use theme_registry::*;
|
||||
|
@ -67,6 +68,14 @@ pub struct Theme {
|
|||
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)]
|
||||
|
|
|
@ -32,6 +32,9 @@ function write_themes(themes: Theme[], output_directory: string) {
|
|||
setTheme(theme)
|
||||
|
||||
const style_tree = app()
|
||||
// Nathan: New elements will read directly from the theme colors.
|
||||
// Adding this during the transition. Afterwards, we can port all themes to Rust.
|
||||
style_tree.base_theme = theme
|
||||
const style_tree_json = JSON.stringify(style_tree, null, 2)
|
||||
const temp_path = path.join(temp_directory, `${theme.name}.json`)
|
||||
const out_path = path.join(
|
||||
|
|
Loading…
Reference in a new issue