Compiling

This commit is contained in:
Nathan Sobo 2023-08-18 01:59:21 -06:00
parent 9b74dc196e
commit 3709eff34b
8 changed files with 95 additions and 37 deletions

View file

@ -12,6 +12,7 @@ use gpui::{
EngineLayout, EventContext, RenderContext, ViewContext,
};
use playground_macros::tailwind_lengths;
use refineable::Refineable;
use std::{
any::{Any, TypeId},
cell::Cell,
@ -61,7 +62,7 @@ pub trait Element<V: 'static>: 'static {
fn declared_style(&mut self) -> &mut StyleRefinement;
fn computed_style(&mut self) -> &StyleRefinement {
fn computed_style(&mut self, cx: &mut ViewContext<V>) -> &StyleRefinement {
self.declared_style()
}
@ -444,7 +445,8 @@ pub trait Element<V: 'static>: 'static {
// Object-safe counterpart of Element used by AnyElement to store elements as trait objects.
trait ElementObject<V> {
fn style(&mut self) -> &mut StyleRefinement;
fn declared_style(&mut self) -> &mut StyleRefinement;
fn computed_style(&mut self, cx: &mut ViewContext<V>) -> &StyleRefinement;
fn handlers_mut(&mut self) -> &mut Vec<EventHandler<V>>;
fn layout(&mut self, view: &mut V, cx: &mut LayoutContext<V>)
-> Result<(NodeId, Box<dyn Any>)>;
@ -457,10 +459,14 @@ trait ElementObject<V> {
}
impl<V: 'static, E: Element<V>> ElementObject<V> for E {
fn style(&mut self) -> &mut StyleRefinement {
fn declared_style(&mut self) -> &mut StyleRefinement {
Element::declared_style(self)
}
fn computed_style(&mut self, cx: &mut ViewContext<V>) -> &StyleRefinement {
Element::computed_style(self, cx)
}
fn handlers_mut(&mut self) -> &mut Vec<EventHandler<V>> {
Element::handlers_mut(self)
}
@ -510,10 +516,13 @@ impl<V: 'static> AnyElement<V> {
Ok(node_id)
}
pub fn push_text_style(&mut self, cx: &mut impl RenderContext) -> bool {
let text_style = self.element.style().text_style();
pub fn push_text_style<'a: 'b, 'b>(&mut self, cx: &mut impl RenderContext<'a, 'b, V>) -> bool {
let text_style = self
.element
.computed_style(cx.as_view_context())
.text_style();
if let Some(text_style) = text_style {
cx.push_text_style(cx.text_style().refine(text_style));
cx.push_text_style(cx.text_style().refined(&text_style));
true
} else {
false
@ -535,7 +544,7 @@ impl<V: 'static> AnyElement<V> {
from_element: element_layout.as_mut(),
};
let style = self.element.style();
let style = self.element.computed_style(cx.as_view_context());
let fill_color = style.fill.as_ref().and_then(|fill| fill.color());
if let Some(fill_color) = fill_color {
@ -583,7 +592,11 @@ impl<V: 'static> Element<V> for AnyElement<V> {
type Layout = ();
fn declared_style(&mut self) -> &mut StyleRefinement {
self.element.style()
self.element.declared_style()
}
fn computed_style(&mut self, cx: &mut ViewContext<V>) -> &StyleRefinement {
self.element.computed_style(cx)
}
fn handlers_mut(&mut self) -> &mut Vec<EventHandler<V>> {

View file

@ -48,7 +48,7 @@ impl<V: 'static> Element<V> for Frame<V> {
.collect::<Result<Vec<LayoutNodeId>>>()?;
let rem_size = cx.rem_pixels();
let style = Style::default().refine(&self.style);
let style = Style::default().refined(&self.style);
let node_id = cx
.layout_engine()
.ok_or_else(|| anyhow!("no layout engine"))?

View file

@ -3,17 +3,15 @@ use std::{cell::Cell, marker::PhantomData, rc::Rc};
use gpui::{
geometry::{rect::RectF, vector::Vector2F},
scene::MouseMove,
EngineLayout,
EngineLayout, ViewContext,
};
use refineable::Refineable;
use crate::{
element::Element,
style::{Style, StyleRefinement},
};
use crate::{element::Element, style::StyleRefinement};
pub struct Hoverable<V, E> {
hover_style: StyleRefinement,
computed_style: Option<Style>,
computed_style: Option<StyleRefinement>,
view_type: PhantomData<V>,
child: E,
}
@ -36,8 +34,13 @@ impl<V: 'static, E: Element<V>> Element<V> for Hoverable<V, E> {
&mut self.hover_style
}
fn computed_style(&mut self) -> &StyleRefinement {
todo!()
fn computed_style(&mut self, cx: &mut ViewContext<V>) -> &StyleRefinement {
self.computed_style.get_or_insert_with(|| {
let mut style = self.child.computed_style(cx).clone();
// if hovered
style.refine(&self.hover_style);
style
})
}
fn handlers_mut(&mut self) -> &mut Vec<crate::element::EventHandler<V>> {

View file

@ -13,7 +13,7 @@ pub struct PaintContext<'a, 'b, 'c, 'd, V> {
pub(crate) scene: &'d mut gpui::SceneBuilder,
}
impl<V> RenderContext for PaintContext<'_, '_, '_, '_, V> {
impl<'a, 'b, V> RenderContext<'a, 'b, V> for PaintContext<'a, 'b, '_, '_, V> {
fn text_style(&self) -> gpui::fonts::TextStyle {
self.legacy_cx.text_style()
}
@ -25,6 +25,10 @@ impl<V> RenderContext for PaintContext<'_, '_, '_, '_, V> {
fn pop_text_style(&mut self) {
self.legacy_cx.pop_text_style()
}
fn as_view_context(&mut self) -> &mut ViewContext<'a, 'b, V> {
&mut self.view_context
}
}
impl<'a, 'b, 'c, 'd, V: 'static> PaintContext<'a, 'b, 'c, 'd, V> {

View file

@ -43,7 +43,7 @@ impl<V: 'static> Element<V> for Text<V> {
let text = self.text.clone();
let layout = Arc::new(Mutex::new(None));
let style: Style = Style::default().refine(&self.metadata.style);
let style: Style = Style::default().refined(&self.metadata.style);
let node_id = layout_engine.add_measured_node(style.to_taffy(rem_size), {
let layout = layout.clone();
move |params| {

View file

@ -3383,10 +3383,11 @@ impl<V> BorrowWindowContext for ViewContext<'_, '_, V> {
///
/// It's that PaintContext should be implemented in terms of layout context and
/// deref to it, in which case we wouldn't need this.
pub trait RenderContext {
pub trait RenderContext<'a, 'b, V> {
fn text_style(&self) -> TextStyle;
fn push_text_style(&mut self, style: TextStyle);
fn pop_text_style(&mut self);
fn as_view_context(&mut self) -> &mut ViewContext<'a, 'b, V>;
}
pub struct LayoutContext<'a, 'b, 'c, V> {
@ -3472,7 +3473,7 @@ impl<'a, 'b, 'c, V> LayoutContext<'a, 'b, 'c, V> {
}
}
impl<'a, 'b, 'c, V> RenderContext for LayoutContext<'a, 'b, 'c, V> {
impl<'a, 'b, 'c, V> RenderContext<'a, 'b, V> for LayoutContext<'a, 'b, 'c, V> {
fn text_style(&self) -> TextStyle {
self.text_style_stack
.last()
@ -3487,6 +3488,10 @@ impl<'a, 'b, 'c, V> RenderContext for LayoutContext<'a, 'b, 'c, V> {
fn pop_text_style(&mut self) {
self.text_style_stack.pop();
}
fn as_view_context(&mut self) -> &mut ViewContext<'a, 'b, V> {
&mut self.view_context
}
}
impl<'a, 'b, 'c, V> Deref for LayoutContext<'a, 'b, 'c, V> {
@ -3544,7 +3549,7 @@ impl<V> BorrowWindowContext for LayoutContext<'_, '_, '_, V> {
}
pub struct PaintContext<'a, 'b, 'c, V> {
view_context: &'c mut ViewContext<'a, 'b, V>,
pub view_context: &'c mut ViewContext<'a, 'b, V>,
text_style_stack: Vec<TextStyle>,
}
@ -3557,7 +3562,7 @@ impl<'a, 'b, 'c, V> PaintContext<'a, 'b, 'c, V> {
}
}
impl<'a, 'b, 'c, V> RenderContext for PaintContext<'a, 'b, 'c, V> {
impl<'a, 'b, 'c, V> RenderContext<'a, 'b, V> for PaintContext<'a, 'b, 'c, V> {
fn text_style(&self) -> TextStyle {
self.text_style_stack
.last()
@ -3572,6 +3577,10 @@ impl<'a, 'b, 'c, V> RenderContext for PaintContext<'a, 'b, 'c, V> {
fn pop_text_style(&mut self) {
self.text_style_stack.pop();
}
fn as_view_context(&mut self) -> &mut ViewContext<'a, 'b, V> {
&mut self.view_context
}
}
impl<'a, 'b, 'c, V> Deref for PaintContext<'a, 'b, 'c, V> {

View file

@ -44,14 +44,14 @@ pub fn derive_refineable(input: TokenStream) -> TokenStream {
paren_token: None,
modifier: syn::TraitBoundModifier::None,
lifetimes: None,
path: parse_quote!(std::clone::Clone),
path: parse_quote!(Clone),
}));
punctuated.push_punct(syn::token::Add::default());
punctuated.push_value(TypeParamBound::Trait(TraitBound {
paren_token: None,
modifier: syn::TraitBoundModifier::None,
lifetimes: None,
path: parse_quote!(std::default::Default),
path: parse_quote!(Default),
}));
punctuated
},
@ -73,7 +73,7 @@ pub fn derive_refineable(input: TokenStream) -> TokenStream {
},
};
let field_initializations: Vec<TokenStream2> = fields
let field_assignments: Vec<TokenStream2> = fields
.iter()
.map(|field| {
let name = &field.ident;
@ -82,18 +82,38 @@ pub fn derive_refineable(input: TokenStream) -> TokenStream {
if is_refineable {
quote! {
clone.#name = self.#name.refine(&refinement.#name);
self.#name.refine(&refinement.#name);
}
} else if is_optional {
quote! {
if let Some(ref value) = &refinement.#name {
clone.#name = Some(value.clone());
self.#name = Some(value.clone());
}
}
} else {
quote! {
if let Some(ref value) = &refinement.#name {
clone.#name = value.clone();
self.#name = value.clone();
}
}
}
})
.collect();
let refinement_field_assignments: Vec<TokenStream2> = fields
.iter()
.map(|field| {
let name = &field.ident;
let is_refineable = is_refineable_field(field);
if is_refineable {
quote! {
self.#name.refine(&refinement.#name);
}
} else {
quote! {
if let Some(ref value) = &refinement.#name {
self.#name = Some(value.clone());
}
}
}
@ -111,10 +131,18 @@ pub fn derive_refineable(input: TokenStream) -> TokenStream {
{
type Refinement = #refinement_ident #ty_generics;
fn refine(&self, refinement: &Self::Refinement) -> Self {
let mut clone = self.clone();
#( #field_initializations )*
clone
fn refine(&mut self, refinement: &Self::Refinement) {
#( #field_assignments )*
}
}
impl #impl_generics Refineable for #refinement_ident #ty_generics
#where_clause
{
type Refinement = #refinement_ident #ty_generics;
fn refine(&mut self, refinement: &Self::Refinement) {
#( #refinement_field_assignments )*
}
}
};

View file

@ -3,11 +3,12 @@ pub use derive_refineable::Refineable;
pub trait Refineable {
type Refinement;
fn refine(&self, refinement: &Self::Refinement) -> Self;
fn from_refinement(refinement: &Self::Refinement) -> Self
fn refine(&mut self, refinement: &Self::Refinement);
fn refined(mut self, refinement: &Self::Refinement) -> Self
where
Self: Sized + Default,
Self: Sized,
{
Self::default().refine(refinement)
self.refine(refinement);
self
}
}