diff --git a/crates/gpui/playground/src/components.rs b/crates/gpui/playground/src/components.rs index 48ecb8d1d7..eecbc3104b 100644 --- a/crates/gpui/playground/src/components.rs +++ b/crates/gpui/playground/src/components.rs @@ -1,6 +1,6 @@ use crate::{ - div, element::{Element, ElementMetadata}, + frame, text::ArcCow, themes::rose_pine, }; @@ -82,9 +82,8 @@ pub fn button() -> Button { impl Button { fn render(&mut self, view: &mut V, cx: &mut ViewContext) -> impl Element { // TODO: Drive theme from the context - let button = div() + let button = frame() .fill(rose_pine::dawn().error(0.5)) - // .hover_fill(rose_pine::dawn().error(0.6)) .h_4() .children(self.label.clone()); diff --git a/crates/gpui/playground/src/element.rs b/crates/gpui/playground/src/element.rs index 7d5d972cfc..af99bea925 100644 --- a/crates/gpui/playground/src/element.rs +++ b/crates/gpui/playground/src/element.rs @@ -1,7 +1,7 @@ use crate::{ adapter::Adapter, color::Hsla, - style::{Display, ElementStyle, ElementStyleOverrides, Fill, Overflow, Position}, + style::{Display, ElementStyle, Fill, Overflow, Position}, }; use anyhow::Result; pub use gpui::LayoutContext; @@ -27,7 +27,6 @@ pub struct Layout<'a, E: ?Sized> { pub struct ElementMetadata { pub style: ElementStyle, - pub hover_style: ElementStyleOverrides, pub handlers: Vec>, } @@ -51,7 +50,6 @@ impl Default for ElementMetadata { fn default() -> Self { Self { style: ElementStyle::default(), - hover_style: ElementStyleOverrides::default(), handlers: Vec::new(), } } @@ -60,7 +58,8 @@ impl Default for ElementMetadata { pub trait Element: 'static { type Layout: 'static; - fn metadata(&mut self) -> &mut ElementMetadata; + fn style_mut(&mut self) -> &mut ElementStyle; + fn handlers_mut(&mut self) -> &mut Vec>; fn layout(&mut self, view: &mut V, cx: &mut LayoutContext) -> Result<(NodeId, Self::Layout)>; @@ -127,7 +126,7 @@ pub trait Element: 'static { where Self: Sized, { - self.metadata().handlers.push(EventHandler { + self.handlers_mut().push(EventHandler { handler: Rc::new(move |view, event, event_cx| { let event = event.downcast_ref::().unwrap(); if event.button == button && event.is_down { @@ -148,7 +147,7 @@ pub trait Element: 'static { where Self: Sized, { - self.metadata().handlers.push(EventHandler { + self.handlers_mut().push(EventHandler { handler: Rc::new(move |view, event, event_cx| { let event = event.downcast_ref::().unwrap(); if event.button == button && event.is_down { @@ -169,7 +168,7 @@ pub trait Element: 'static { where Self: Sized, { - self.metadata().handlers.push(EventHandler { + self.handlers_mut().push(EventHandler { handler: Rc::new(move |view, event, event_cx| { let event = event.downcast_ref::().unwrap(); if event.button == button && !event.is_down { @@ -190,7 +189,7 @@ pub trait Element: 'static { where Self: Sized, { - self.metadata().handlers.push(EventHandler { + self.handlers_mut().push(EventHandler { handler: Rc::new(move |view, event, event_cx| { let event = event.downcast_ref::().unwrap(); if event.button == button && !event.is_down { @@ -209,7 +208,7 @@ pub trait Element: 'static { where Self: Sized, { - self.metadata().style.display = Display::Block; + self.style_mut().display = Display::Block; self } @@ -217,7 +216,7 @@ pub trait Element: 'static { where Self: Sized, { - self.metadata().style.display = Display::Flex; + self.style_mut().display = Display::Flex; self } @@ -225,7 +224,7 @@ pub trait Element: 'static { where Self: Sized, { - self.metadata().style.display = Display::Grid; + self.style_mut().display = Display::Grid; self } @@ -235,8 +234,8 @@ pub trait Element: 'static { where Self: Sized, { - self.metadata().style.overflow.x = Overflow::Visible; - self.metadata().style.overflow.y = Overflow::Visible; + self.style_mut().overflow.x = Overflow::Visible; + self.style_mut().overflow.y = Overflow::Visible; self } @@ -244,8 +243,8 @@ pub trait Element: 'static { where Self: Sized, { - self.metadata().style.overflow.x = Overflow::Hidden; - self.metadata().style.overflow.y = Overflow::Hidden; + self.style_mut().overflow.x = Overflow::Hidden; + self.style_mut().overflow.y = Overflow::Hidden; self } @@ -253,8 +252,8 @@ pub trait Element: 'static { where Self: Sized, { - self.metadata().style.overflow.x = Overflow::Scroll; - self.metadata().style.overflow.y = Overflow::Scroll; + self.style_mut().overflow.x = Overflow::Scroll; + self.style_mut().overflow.y = Overflow::Scroll; self } @@ -262,7 +261,7 @@ pub trait Element: 'static { where Self: Sized, { - self.metadata().style.overflow.x = Overflow::Visible; + self.style_mut().overflow.x = Overflow::Visible; self } @@ -270,7 +269,7 @@ pub trait Element: 'static { where Self: Sized, { - self.metadata().style.overflow.x = Overflow::Hidden; + self.style_mut().overflow.x = Overflow::Hidden; self } @@ -278,7 +277,7 @@ pub trait Element: 'static { where Self: Sized, { - self.metadata().style.overflow.x = Overflow::Scroll; + self.style_mut().overflow.x = Overflow::Scroll; self } @@ -286,7 +285,7 @@ pub trait Element: 'static { where Self: Sized, { - self.metadata().style.overflow.y = Overflow::Visible; + self.style_mut().overflow.y = Overflow::Visible; self } @@ -294,7 +293,7 @@ pub trait Element: 'static { where Self: Sized, { - self.metadata().style.overflow.y = Overflow::Hidden; + self.style_mut().overflow.y = Overflow::Hidden; self } @@ -302,7 +301,7 @@ pub trait Element: 'static { where Self: Sized, { - self.metadata().style.overflow.y = Overflow::Scroll; + self.style_mut().overflow.y = Overflow::Scroll; self } @@ -312,7 +311,7 @@ pub trait Element: 'static { where Self: Sized, { - self.metadata().style.position = Position::Relative; + self.style_mut().position = Position::Relative; self } @@ -320,7 +319,7 @@ pub trait Element: 'static { where Self: Sized, { - self.metadata().style.position = Position::Absolute; + self.style_mut().position = Position::Absolute; self } @@ -330,10 +329,10 @@ pub trait Element: 'static { where Self: Sized, { - self.metadata().style.inset.top = length; - self.metadata().style.inset.right = length; - self.metadata().style.inset.bottom = length; - self.metadata().style.inset.left = length; + self.style_mut().inset.top = length; + self.style_mut().inset.right = length; + self.style_mut().inset.bottom = length; + self.style_mut().inset.left = length; self } @@ -341,7 +340,7 @@ pub trait Element: 'static { where Self: Sized, { - self.metadata().style.size.width = width.into(); + self.style_mut().size.width = width.into(); self } @@ -349,7 +348,7 @@ pub trait Element: 'static { where Self: Sized, { - self.metadata().style.size.width = Length::Auto; + self.style_mut().size.width = Length::Auto; self } @@ -358,7 +357,7 @@ pub trait Element: 'static { where Self: Sized, { - self.metadata().style.size.width = length; + self.style_mut().size.width = length; self } @@ -367,7 +366,7 @@ pub trait Element: 'static { where Self: Sized, { - self.metadata().style.min_size.width = length; + self.style_mut().min_size.width = length; self } @@ -375,7 +374,7 @@ pub trait Element: 'static { where Self: Sized, { - self.metadata().style.size.height = height.into(); + self.style_mut().size.height = height.into(); self } @@ -383,7 +382,7 @@ pub trait Element: 'static { where Self: Sized, { - self.metadata().style.size.height = Length::Auto; + self.style_mut().size.height = Length::Auto; self } @@ -392,7 +391,7 @@ pub trait Element: 'static { where Self: Sized, { - self.metadata().style.size.height = height; + self.style_mut().size.height = height; self } @@ -401,7 +400,7 @@ pub trait Element: 'static { where Self: Sized, { - self.metadata().style.min_size.height = length; + self.style_mut().min_size.height = length; self } @@ -409,7 +408,7 @@ pub trait Element: 'static { where Self: Sized, { - self.metadata().style.fill = fill.into(); + self.style_mut().fill = fill.into(); self } @@ -417,14 +416,15 @@ pub trait Element: 'static { where Self: Sized, { - self.metadata().style.text_color = Some(color.into()); + self.style_mut().text_color = Some(color.into()); self } } // Object-safe counterpart of Element used by AnyElement to store elements as trait objects. trait ElementObject { - fn metadata(&mut self) -> &mut ElementMetadata; + fn style_mut(&mut self) -> &mut ElementStyle; + fn handlers_mut(&mut self) -> &mut Vec>; fn layout(&mut self, view: &mut V, cx: &mut LayoutContext) -> Result<(NodeId, Box)>; fn paint( @@ -436,8 +436,12 @@ trait ElementObject { } impl> ElementObject for E { - fn metadata(&mut self) -> &mut ElementMetadata { - Element::metadata(self) + fn style_mut(&mut self) -> &mut ElementStyle { + Element::style_mut(self) + } + + fn handlers_mut(&mut self) -> &mut Vec> { + Element::handlers_mut(self) } fn layout( @@ -486,7 +490,7 @@ impl AnyElement { } pub fn push_text_style(&mut self, cx: &mut impl RenderContext) -> bool { - let text_style = self.element.metadata().style.text_style(); + let text_style = self.element.style_mut().text_style(); if let Some(text_style) = text_style { let mut current_text_style = cx.text_style(); text_style.apply(&mut current_text_style); @@ -512,7 +516,7 @@ impl AnyElement { from_element: element_layout.as_mut(), }; - for event_handler in self.element.metadata().handlers.iter().cloned() { + for event_handler in self.element.handlers_mut().iter().cloned() { let EngineLayout { order, bounds } = layout.from_engine; let view_id = cx.view_id(); @@ -547,8 +551,12 @@ impl AnyElement { impl Element for AnyElement { type Layout = (); - fn metadata(&mut self) -> &mut ElementMetadata { - self.element.metadata() + fn style_mut(&mut self) -> &mut ElementStyle { + self.element.style_mut() + } + + fn handlers_mut(&mut self) -> &mut Vec> { + self.element.handlers_mut() } fn layout( diff --git a/crates/gpui/playground/src/div.rs b/crates/gpui/playground/src/frame.rs similarity index 67% rename from crates/gpui/playground/src/div.rs rename to crates/gpui/playground/src/frame.rs index 9ec77c69f6..8749d86199 100644 --- a/crates/gpui/playground/src/div.rs +++ b/crates/gpui/playground/src/frame.rs @@ -1,5 +1,8 @@ -use crate::element::{ - AnyElement, Element, ElementMetadata, IntoElement, Layout, LayoutContext, NodeId, PaintContext, +use crate::{ + element::{ + AnyElement, Element, EventHandler, IntoElement, Layout, LayoutContext, NodeId, PaintContext, + }, + style::ElementStyle, }; use anyhow::{anyhow, Result}; use gpui::LayoutNodeId; @@ -7,23 +10,29 @@ use playground_macros::IntoElement; #[derive(IntoElement)] #[element_crate = "crate"] -pub struct Div { - metadata: ElementMetadata, +pub struct Frame { + style: ElementStyle, + handlers: Vec>, children: Vec>, } -pub fn div() -> Div { - Div { - metadata: ElementMetadata::default(), +pub fn frame() -> Frame { + Frame { + style: ElementStyle::default(), + handlers: Vec::new(), children: Vec::new(), } } -impl Element for Div { +impl Element for Frame { type Layout = (); - fn metadata(&mut self) -> &mut ElementMetadata { - &mut self.metadata + fn style_mut(&mut self) -> &mut ElementStyle { + &mut self.style + } + + fn handlers_mut(&mut self) -> &mut Vec> { + &mut self.handlers } fn layout( @@ -41,10 +50,7 @@ impl Element for Div { let node_id = cx .layout_engine() .ok_or_else(|| anyhow!("no layout engine"))? - .add_node( - self.metadata.style.to_taffy(rem_size), - child_layout_node_ids, - )?; + .add_node(self.style.to_taffy(rem_size), child_layout_node_ids)?; Ok((node_id, ())) } @@ -52,7 +58,7 @@ impl Element for Div { fn paint(&mut self, layout: Layout<()>, view: &mut V, cx: &mut PaintContext) -> Result<()> { cx.scene.push_quad(gpui::scene::Quad { bounds: layout.from_engine.bounds, - background: self.metadata.style.fill.color().map(Into::into), + background: self.style.fill.color().map(Into::into), border: Default::default(), corner_radii: Default::default(), }); @@ -64,7 +70,7 @@ impl Element for Div { } } -impl Div { +impl Frame { pub fn child(mut self, child: impl IntoElement) -> Self { self.children.push(child.into_any_element()); self diff --git a/crates/gpui/playground/src/playground.rs b/crates/gpui/playground/src/playground.rs index 9e05d86d58..6549171792 100644 --- a/crates/gpui/playground/src/playground.rs +++ b/crates/gpui/playground/src/playground.rs @@ -1,11 +1,11 @@ #![allow(dead_code, unused_variables)] use color::black; use components::button; -use div::div; use element::Element; +use frame::frame; use gpui::{ geometry::{rect::RectF, vector::vec2f}, - platform::WindowOptions, + platform::{MouseButton, WindowOptions}, }; use log::LevelFilter; use simplelog::SimpleLogger; @@ -16,8 +16,8 @@ use view::view; mod adapter; mod color; mod components; -mod div; mod element; +mod frame; mod paint_context; mod style; mod text; @@ -44,7 +44,7 @@ fn main() { } fn playground(theme: &ThemeColors) -> impl Element { - div() + frame() .text_color(black()) .h_full() .w_half() diff --git a/crates/gpui/playground/src/style.rs b/crates/gpui/playground/src/style.rs index 2caf58065b..915b4a958d 100644 --- a/crates/gpui/playground/src/style.rs +++ b/crates/gpui/playground/src/style.rs @@ -1,20 +1,11 @@ use crate::color::Hsla; use gpui::geometry::{DefinedLength, Edges, Length, Point, Size}; -use playground_macros::Overrides; pub use taffy::style::{ AlignContent, AlignItems, AlignSelf, Display, FlexDirection, FlexWrap, JustifyContent, Overflow, Position, }; -pub trait Overrides { - type Base; - - fn is_some(&self) -> bool; - fn apply(&self, base: &mut Self::Base); -} - -#[derive(Clone, Overrides)] -#[overrides_crate = "crate"] +#[derive(Clone)] pub struct ElementStyle { /// What layout strategy should be used? pub display: Display, diff --git a/crates/gpui/playground/src/text.rs b/crates/gpui/playground/src/text.rs index b29d5e8925..0c67eb1c2a 100644 --- a/crates/gpui/playground/src/text.rs +++ b/crates/gpui/playground/src/text.rs @@ -1,4 +1,4 @@ -use crate::element::{Element, ElementMetadata, IntoElement}; +use crate::element::{Element, ElementMetadata, EventHandler, IntoElement}; use gpui::{geometry::Size, text_layout::LineLayout, RenderContext}; use parking_lot::Mutex; use std::sync::Arc; @@ -22,8 +22,8 @@ pub struct Text { impl Element for Text { type Layout = Arc>>; - fn metadata(&mut self) -> &mut crate::element::ElementMetadata { - &mut self.metadata + fn style_mut(&mut self) -> &mut crate::style::ElementStyle { + &mut self.metadata.style } fn layout( @@ -91,6 +91,10 @@ impl Element for Text { ); Ok(()) } + + fn handlers_mut(&mut self) -> &mut Vec> { + &mut self.metadata.handlers + } } pub struct TextLayout { diff --git a/crates/gpui/playground_macros/src/derive_element.rs b/crates/gpui/playground_macros/src/derive_element.rs index 11909871b3..6d5922c621 100644 --- a/crates/gpui/playground_macros/src/derive_element.rs +++ b/crates/gpui/playground_macros/src/derive_element.rs @@ -79,8 +79,12 @@ pub fn derive_element(input: TokenStream) -> TokenStream { { type Layout = #crate_name::element::AnyElement; - fn metadata(&mut self) -> &mut #crate_name::element::ElementMetadata { - &mut self.metadata + fn style_mut(&mut self) -> &mut #crate_name::style::ElementStyle { + &mut self.metadata.style + } + + fn handlers_mut(&mut self) -> &mut Vec<#crate_name::element::EventHandler> { + &mut self.metadata.handlers } fn layout( diff --git a/crates/gpui/playground_macros/src/derive_overrides.rs b/crates/gpui/playground_macros/src/derive_overrides.rs deleted file mode 100644 index 2169bcba95..0000000000 --- a/crates/gpui/playground_macros/src/derive_overrides.rs +++ /dev/null @@ -1,119 +0,0 @@ -extern crate proc_macro; -use proc_macro::TokenStream; -use quote::{format_ident, quote}; -use syn::{parse_macro_input, Data, DeriveInput, Fields, Lit, Meta}; - -/// When deriving Overrides on a struct Foo, builds a new struct FooOverrides -/// that implements the Overrides trait so it can be applied to Foo. -pub fn derive_overrides(input: TokenStream) -> TokenStream { - let input = parse_macro_input!(input as DeriveInput); - - let crate_name: String = input - .attrs - .iter() - .find_map(|attr| { - if attr.path.is_ident("overrides_crate") { - match attr.parse_meta() { - Ok(Meta::NameValue(nv)) => { - if let Lit::Str(s) = nv.lit { - Some(s.value()) - } else { - None - } - } - _ => None, - } - } else { - None - } - }) - .unwrap_or_else(|| String::from("playground")); - let crate_name = format_ident!("{}", crate_name); - - let ident = input.ident; - let new_ident = syn::Ident::new(&format!("{}Overrides", ident), ident.span()); - let data = match input.data { - Data::Struct(s) => s, - _ => panic!("Override can only be derived for structs"), - }; - - let fields = match data.fields { - Fields::Named(fields) => fields.named, - _ => panic!("Override can only be derived for structs with named fields"), - }; - - let new_fields = fields - .iter() - .map(|f| { - let name = &f.ident; - let ty = &f.ty; - - if let syn::Type::Path(typepath) = ty { - if typepath.path.segments.last().unwrap().ident == "Option" { - return quote! { #name: #ty }; - } - } - quote! { #name: Option<#ty> } - }) - .collect::>(); - - let names = fields.iter().map(|f| &f.ident); - let is_some_implementation = names.clone().map(|name| { - quote! { - self.#name.is_some() - } - }); - - let apply_implementation = fields.iter().map(|f| { - let name = &f.ident; - let ty = &f.ty; - - if let syn::Type::Path(typepath) = ty { - if typepath.path.segments.last().unwrap().ident == "Option" { - return quote! { - base.#name = self.#name.clone(); - }; - } - } - - quote! { - if let Some(value) = &self.#name { - base.#name = value.clone(); - } - } - }); - - let default_implementation = names.map(|name| { - quote! { - #name: None, - } - }); - - let expanded = quote! { - pub struct #new_ident { - #(#new_fields,)* - } - - impl #crate_name::style::Overrides for #new_ident { - type Base = #ident; - - fn is_some(&self) -> bool { - #(#is_some_implementation)||* - } - - fn apply(&self, base: &mut Self::Base) { - #(#apply_implementation)* - } - } - - impl Default for #new_ident { - fn default() -> Self { - Self { - #(#default_implementation)* - } - } - } - }; - - TokenStream::from(expanded) -} diff --git a/crates/gpui/playground_macros/src/playground_macros.rs b/crates/gpui/playground_macros/src/playground_macros.rs index fc8c976913..4b0de71015 100644 --- a/crates/gpui/playground_macros/src/playground_macros.rs +++ b/crates/gpui/playground_macros/src/playground_macros.rs @@ -2,7 +2,6 @@ use proc_macro::TokenStream; mod derive_element; mod derive_into_element; -mod derive_overrides; mod tailwind_lengths; #[proc_macro_derive(Element, attributes(element_crate))] @@ -15,11 +14,6 @@ pub fn derive_into_element(input: TokenStream) -> TokenStream { derive_into_element::derive_into_element(input) } -#[proc_macro_derive(Overrides, attributes(overrides_crate))] -pub fn derive_overrides(input: TokenStream) -> TokenStream { - derive_overrides::derive_overrides(input) -} - #[proc_macro_attribute] pub fn tailwind_lengths(attr: TokenStream, item: TokenStream) -> TokenStream { tailwind_lengths::tailwind_lengths(attr, item)