From 1ef486b227a92f8f50d4cdcacaa490868f71db7c Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Sun, 13 Aug 2023 01:40:05 -0600 Subject: [PATCH] WIP --- Cargo.lock | 11 + Cargo.toml | 1 + crates/gpui/playground/Cargo.toml | 1 + crates/gpui/playground/src/color.rs | 2 +- crates/gpui/playground/src/frame.rs | 2585 ++++++++++------------ crates/gpui/playground/src/playground.rs | 54 +- crates/gpui/playground/src/tokens.rs | 156 -- 7 files changed, 1249 insertions(+), 1561 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a81b8e3e82..cb3cce0b67 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5303,6 +5303,7 @@ dependencies = [ "gpui", "log", "optional_struct", + "playground_macros", "serde", "simplelog", "smallvec", @@ -5310,6 +5311,16 @@ dependencies = [ "util", ] +[[package]] +name = "playground_macros" +version = "0.1.0" +dependencies = [ + "once_cell", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "plist" version = "1.5.0" diff --git a/Cargo.toml b/Cargo.toml index 0faff00dbb..a82d5daa2d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,6 +29,7 @@ members = [ "crates/go_to_line", "crates/gpui", "crates/gpui/playground", + "crates/gpui/playground_macros", "crates/gpui_macros", "crates/install_cli", "crates/journal", diff --git a/crates/gpui/playground/Cargo.toml b/crates/gpui/playground/Cargo.toml index 11f56d230c..ed994e08d0 100644 --- a/crates/gpui/playground/Cargo.toml +++ b/crates/gpui/playground/Cargo.toml @@ -13,6 +13,7 @@ derive_more.workspace = true gpui = { path = ".." } log.workspace = true optional_struct = "0.3.1" +playground_macros = { path = "../playground_macros" } serde.workspace = true simplelog = "0.9" smallvec.workspace = true diff --git a/crates/gpui/playground/src/color.rs b/crates/gpui/playground/src/color.rs index afbe8e06db..b0aa10dc3f 100644 --- a/crates/gpui/playground/src/color.rs +++ b/crates/gpui/playground/src/color.rs @@ -99,7 +99,7 @@ impl Into for Rgba { } } -#[derive(Copy, Clone, Debug, PartialEq)] +#[derive(Default, Copy, Clone, Debug, PartialEq)] pub struct Hsla { pub h: f32, pub s: f32, diff --git a/crates/gpui/playground/src/frame.rs b/crates/gpui/playground/src/frame.rs index 327b798669..285ff2fe24 100644 --- a/crates/gpui/playground/src/frame.rs +++ b/crates/gpui/playground/src/frame.rs @@ -1,461 +1,25 @@ -#![allow(unused_variables, dead_code)] +use playground_macros::tailwind_lengths; +use taffy::style::{Position, *}; -use derive_more::{Add, Deref, DerefMut}; -use gpui::{ - color::Color, - elements::layout_highlighted_chunks, - fonts::{HighlightStyle, Underline}, - geometry::{ - rect::RectF, - vector::{vec2f, Vector2F}, - }, - json::{json, ToJson}, - serde_json::Value, - text_layout::{Line, ShapedBoundary}, - AnyElement, AppContext, Element, Entity, LayoutContext, PaintContext, SceneBuilder, - SizeConstraint, View, ViewContext, WindowContext, -}; -use length::{Length, Rems}; -use log::warn; -use optional_struct::*; -use smallvec::SmallVec; -use std::{any::Any, borrow::Cow, f32, ops::Range, sync::Arc}; -use util::ResultExt; - -use crate::color::{Hsla, Rgba}; - -use self::length::rems; - -pub struct Frame { - style: FrameStyle, - metadata: FrameMetadata, - children: Vec>, - id: Option>, - before_paint: Option)>>, +#[derive(Clone, Debug)] +struct Style { + display: Display, + position: Position, + overflow: Point, + inset: Edges, } -pub fn column() -> Frame { - Frame::default() +#[derive(Clone, Copy, Debug)] +pub enum Length { + Rems(f32), + Pixels(f32), + Percent(f32), + Auto, } -pub fn row() -> Frame { - todo!() -} - -pub fn stack() -> Frame { - todo!() -} - -impl Default for Frame { +impl Default for Length { fn default() -> Self { - Self { - style: Default::default(), - metadata: Default::default(), - children: Default::default(), - id: None, - before_paint: None, - } - } -} - -impl Element for Frame { - type LayoutState = FrameLayout; - type PaintState = (); - - fn layout( - &mut self, - constraint: SizeConstraint, - view: &mut V, - cx: &mut LayoutContext, - ) -> (Vector2F, Self::LayoutState) { - let mut pushed_text_style = false; - if self.style.text.is_some() { - let mut style = TextStyle::from_legacy(&cx.text_style(), cx); - self.style.text.clone().apply_to(&mut style); - if let Some(legacy_style) = style.to_legacy(cx).log_err() { - cx.push_text_style(legacy_style); - pushed_text_style = true; - } - } - - let mut child_node_ids = SmallVec::<[_; 2]>::new(); - for child in &mut self.children { - child.layout(constraint, view, cx); - child_node_ids.extend( - child - .metadata::() - .and_then(|meta| meta.layout_node_id), - ); - } - - self.metadata.layout_node_id = cx - .layout_engine() - .new_with_children(self.style.layout.clone(), child_node_ids.as_slice()) - .log_err(); - - if pushed_text_style { - cx.pop_text_style(); - } - - (todo!(), todo!()) - } - - fn paint( - &mut self, - scene: &mut SceneBuilder, - bounds: RectF, - visible_bounds: RectF, - layout: &mut FrameLayout, - view: &mut V, - cx: &mut PaintContext, - ) -> Self::PaintState { - if let Some(before_paint) = &mut self.before_paint { - before_paint(bounds, layout, cx); - } - - // // Paint drop shadow - // for shadow in &self.style.shadows { - // scene.push_shadow(scene::Shadow { - // bounds: margined_bounds + shadow.offset, - // corner_radius: self.style.corner_radius, - // sigma: shadow.blur, - // color: shadow.color, - // }); - // } - - // // Paint cursor style - // if let Some(hit_bounds) = content_bounds.intersection(visible_bounds) { - // if let Some(style) = self.style.cursor { - // scene.push_cursor_region(CursorRegion { - // bounds: hit_bounds, - // style, - // }); - // } - // } - - // // Render the background and/or the border. - // let Fill::Color(fill_color) = self.style.fill; - // let is_fill_visible = fill_color.a > 0.; - // if is_fill_visible || self.style.borders.is_visible() { - // scene.push_quad(Quad { - // bounds: margined_bounds, - // background: is_fill_visible.then_some(fill_color.into()), - // border: scene::Border { - // width: self.style.borders.width, - // color: self.style.borders.color, - // overlay: false, - // top: self.style.borders.top, - // right: self.style.borders.right, - // bottom: self.style.borders.bottom, - // left: self.style.borders.left, - // }, - // corner_radius: self.style.corner_radius, - // }); - // } - - // if !self.children.is_empty() { - // // Account for padding first. - // let borders = &self.style.borders; - // let padded_bounds = RectF::from_points( - // margined_bounds.origin() - // + vec2f( - // borders.left_width() + layout.padding.left, - // borders.top_width() + layout.padding.top, - // ), - // margined_bounds.lower_right() - // - vec2f( - // layout.padding.right + borders.right_width(), - // layout.padding.bottom + borders.bottom_width(), - // ), - // ); - - // if let Some(axis) = self.style.axis.to_2d() { - // // let parent_size = padded_bounds.size(); - // let mut child_origin = padded_bounds.origin(); - - // for child in &mut self.children { - // child.paint(scene, child_origin, visible_bounds, view, cx); - - // // Advance along the primary axis by the size of this child - // child_origin.set(axis, child_origin.get(axis) + child.size().get(axis)); - // } - // } else { - // unimplemented!(); - // } - // } - } - - fn rect_for_text_range( - &self, - range_utf16: Range, - _: RectF, - _: RectF, - _: &Self::LayoutState, - _: &Self::PaintState, - view: &V, - cx: &ViewContext, - ) -> Option { - self.children - .iter() - .find_map(|child| child.rect_for_text_range(range_utf16.clone(), view, cx)) - } - - fn debug( - &self, - bounds: RectF, - _: &Self::LayoutState, - _: &Self::PaintState, - view: &V, - cx: &ViewContext, - ) -> Value { - json!({ - "type": "Frame", - "bounds": bounds.to_json(), - // TODO! - // "children": self.content.iter().map(|child| child.debug(view, cx)).collect::>() - }) - } - - fn metadata(&self) -> Option<&dyn Any> { - Some(&self.metadata) - } -} - -impl Frame { - pub fn id(mut self, id: impl Into>) -> Self { - self.id = Some(id.into()); - self - } - - pub fn child(mut self, child: impl Element) -> Self { - self.children.push(child.into_any()); - self - } - - pub fn children(mut self, children: I) -> Self - where - I: IntoIterator, - E: Element, - { - self.children - .extend(children.into_iter().map(|child| child.into_any())); - self - } - - pub fn fill(mut self, fill: impl Into) -> Self { - self.style.fill = fill.into(); - self - } - - pub fn text_size(mut self, text_size: Rems) -> Self { - self.style.text.size = Some(text_size); - self - } - - pub fn text_color(mut self, color: Hsla) -> Self { - self.style.text.color = Some(color); - self - } - - fn before_paint(mut self, handler: H) -> Self - where - H: 'static + FnMut(RectF, &mut FrameLayout, &mut PaintContext), - { - self.before_paint = Some(Box::new(handler)); - self - } -} - -pub struct TopBottom { - top: Length, - bottom: Length, -} - -impl> From<(T, T)> for TopBottom { - fn from((top, bottom): (T, T)) -> Self { - Self { - top: top.into(), - bottom: bottom.into(), - } - } -} - -impl> From for TopBottom { - fn from(both: T) -> Self { - Self { - top: both.into(), - bottom: both.into(), - } - } -} - -pub struct LeftRight { - left: Length, - right: Length, -} - -impl From<(Length, Length)> for LeftRight { - fn from((left, right): (Length, Length)) -> Self { - Self { left, right } - } -} - -impl From for LeftRight { - fn from(both: Length) -> Self { - Self { - left: both, - right: both, - } - } -} - -struct Interactive