Compiling
This commit is contained in:
parent
9b74dc196e
commit
3709eff34b
8 changed files with 95 additions and 37 deletions
|
@ -12,6 +12,7 @@ use gpui::{
|
||||||
EngineLayout, EventContext, RenderContext, ViewContext,
|
EngineLayout, EventContext, RenderContext, ViewContext,
|
||||||
};
|
};
|
||||||
use playground_macros::tailwind_lengths;
|
use playground_macros::tailwind_lengths;
|
||||||
|
use refineable::Refineable;
|
||||||
use std::{
|
use std::{
|
||||||
any::{Any, TypeId},
|
any::{Any, TypeId},
|
||||||
cell::Cell,
|
cell::Cell,
|
||||||
|
@ -61,7 +62,7 @@ pub trait Element<V: 'static>: 'static {
|
||||||
|
|
||||||
fn declared_style(&mut self) -> &mut StyleRefinement;
|
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()
|
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.
|
// Object-safe counterpart of Element used by AnyElement to store elements as trait objects.
|
||||||
trait ElementObject<V> {
|
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 handlers_mut(&mut self) -> &mut Vec<EventHandler<V>>;
|
||||||
fn layout(&mut self, view: &mut V, cx: &mut LayoutContext<V>)
|
fn layout(&mut self, view: &mut V, cx: &mut LayoutContext<V>)
|
||||||
-> Result<(NodeId, Box<dyn Any>)>;
|
-> Result<(NodeId, Box<dyn Any>)>;
|
||||||
|
@ -457,10 +459,14 @@ trait ElementObject<V> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<V: 'static, E: Element<V>> ElementObject<V> for E {
|
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)
|
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>> {
|
fn handlers_mut(&mut self) -> &mut Vec<EventHandler<V>> {
|
||||||
Element::handlers_mut(self)
|
Element::handlers_mut(self)
|
||||||
}
|
}
|
||||||
|
@ -510,10 +516,13 @@ impl<V: 'static> AnyElement<V> {
|
||||||
Ok(node_id)
|
Ok(node_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn push_text_style(&mut self, cx: &mut impl RenderContext) -> bool {
|
pub fn push_text_style<'a: 'b, 'b>(&mut self, cx: &mut impl RenderContext<'a, 'b, V>) -> bool {
|
||||||
let text_style = self.element.style().text_style();
|
let text_style = self
|
||||||
|
.element
|
||||||
|
.computed_style(cx.as_view_context())
|
||||||
|
.text_style();
|
||||||
if let Some(text_style) = 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
|
true
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
|
@ -535,7 +544,7 @@ impl<V: 'static> AnyElement<V> {
|
||||||
from_element: element_layout.as_mut(),
|
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());
|
let fill_color = style.fill.as_ref().and_then(|fill| fill.color());
|
||||||
if let Some(fill_color) = fill_color {
|
if let Some(fill_color) = fill_color {
|
||||||
|
@ -583,7 +592,11 @@ impl<V: 'static> Element<V> for AnyElement<V> {
|
||||||
type Layout = ();
|
type Layout = ();
|
||||||
|
|
||||||
fn declared_style(&mut self) -> &mut StyleRefinement {
|
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>> {
|
fn handlers_mut(&mut self) -> &mut Vec<EventHandler<V>> {
|
||||||
|
|
|
@ -48,7 +48,7 @@ impl<V: 'static> Element<V> for Frame<V> {
|
||||||
.collect::<Result<Vec<LayoutNodeId>>>()?;
|
.collect::<Result<Vec<LayoutNodeId>>>()?;
|
||||||
|
|
||||||
let rem_size = cx.rem_pixels();
|
let rem_size = cx.rem_pixels();
|
||||||
let style = Style::default().refine(&self.style);
|
let style = Style::default().refined(&self.style);
|
||||||
let node_id = cx
|
let node_id = cx
|
||||||
.layout_engine()
|
.layout_engine()
|
||||||
.ok_or_else(|| anyhow!("no layout engine"))?
|
.ok_or_else(|| anyhow!("no layout engine"))?
|
||||||
|
|
|
@ -3,17 +3,15 @@ use std::{cell::Cell, marker::PhantomData, rc::Rc};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
geometry::{rect::RectF, vector::Vector2F},
|
geometry::{rect::RectF, vector::Vector2F},
|
||||||
scene::MouseMove,
|
scene::MouseMove,
|
||||||
EngineLayout,
|
EngineLayout, ViewContext,
|
||||||
};
|
};
|
||||||
|
use refineable::Refineable;
|
||||||
|
|
||||||
use crate::{
|
use crate::{element::Element, style::StyleRefinement};
|
||||||
element::Element,
|
|
||||||
style::{Style, StyleRefinement},
|
|
||||||
};
|
|
||||||
|
|
||||||
pub struct Hoverable<V, E> {
|
pub struct Hoverable<V, E> {
|
||||||
hover_style: StyleRefinement,
|
hover_style: StyleRefinement,
|
||||||
computed_style: Option<Style>,
|
computed_style: Option<StyleRefinement>,
|
||||||
view_type: PhantomData<V>,
|
view_type: PhantomData<V>,
|
||||||
child: E,
|
child: E,
|
||||||
}
|
}
|
||||||
|
@ -36,8 +34,13 @@ impl<V: 'static, E: Element<V>> Element<V> for Hoverable<V, E> {
|
||||||
&mut self.hover_style
|
&mut self.hover_style
|
||||||
}
|
}
|
||||||
|
|
||||||
fn computed_style(&mut self) -> &StyleRefinement {
|
fn computed_style(&mut self, cx: &mut ViewContext<V>) -> &StyleRefinement {
|
||||||
todo!()
|
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>> {
|
fn handlers_mut(&mut self) -> &mut Vec<crate::element::EventHandler<V>> {
|
||||||
|
|
|
@ -13,7 +13,7 @@ pub struct PaintContext<'a, 'b, 'c, 'd, V> {
|
||||||
pub(crate) scene: &'d mut gpui::SceneBuilder,
|
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 {
|
fn text_style(&self) -> gpui::fonts::TextStyle {
|
||||||
self.legacy_cx.text_style()
|
self.legacy_cx.text_style()
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,10 @@ impl<V> RenderContext for PaintContext<'_, '_, '_, '_, V> {
|
||||||
fn pop_text_style(&mut self) {
|
fn pop_text_style(&mut self) {
|
||||||
self.legacy_cx.pop_text_style()
|
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> {
|
impl<'a, 'b, 'c, 'd, V: 'static> PaintContext<'a, 'b, 'c, 'd, V> {
|
||||||
|
|
|
@ -43,7 +43,7 @@ impl<V: 'static> Element<V> for Text<V> {
|
||||||
let text = self.text.clone();
|
let text = self.text.clone();
|
||||||
let layout = Arc::new(Mutex::new(None));
|
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 node_id = layout_engine.add_measured_node(style.to_taffy(rem_size), {
|
||||||
let layout = layout.clone();
|
let layout = layout.clone();
|
||||||
move |params| {
|
move |params| {
|
||||||
|
|
|
@ -3383,10 +3383,11 @@ impl<V> BorrowWindowContext for ViewContext<'_, '_, V> {
|
||||||
///
|
///
|
||||||
/// It's that PaintContext should be implemented in terms of layout context and
|
/// It's that PaintContext should be implemented in terms of layout context and
|
||||||
/// deref to it, in which case we wouldn't need this.
|
/// 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 text_style(&self) -> TextStyle;
|
||||||
fn push_text_style(&mut self, style: TextStyle);
|
fn push_text_style(&mut self, style: TextStyle);
|
||||||
fn pop_text_style(&mut self);
|
fn pop_text_style(&mut self);
|
||||||
|
fn as_view_context(&mut self) -> &mut ViewContext<'a, 'b, V>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct LayoutContext<'a, 'b, 'c, 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 {
|
fn text_style(&self) -> TextStyle {
|
||||||
self.text_style_stack
|
self.text_style_stack
|
||||||
.last()
|
.last()
|
||||||
|
@ -3487,6 +3488,10 @@ impl<'a, 'b, 'c, V> RenderContext for LayoutContext<'a, 'b, 'c, V> {
|
||||||
fn pop_text_style(&mut self) {
|
fn pop_text_style(&mut self) {
|
||||||
self.text_style_stack.pop();
|
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> {
|
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> {
|
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>,
|
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 {
|
fn text_style(&self) -> TextStyle {
|
||||||
self.text_style_stack
|
self.text_style_stack
|
||||||
.last()
|
.last()
|
||||||
|
@ -3572,6 +3577,10 @@ impl<'a, 'b, 'c, V> RenderContext for PaintContext<'a, 'b, 'c, V> {
|
||||||
fn pop_text_style(&mut self) {
|
fn pop_text_style(&mut self) {
|
||||||
self.text_style_stack.pop();
|
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> {
|
impl<'a, 'b, 'c, V> Deref for PaintContext<'a, 'b, 'c, V> {
|
||||||
|
|
|
@ -44,14 +44,14 @@ pub fn derive_refineable(input: TokenStream) -> TokenStream {
|
||||||
paren_token: None,
|
paren_token: None,
|
||||||
modifier: syn::TraitBoundModifier::None,
|
modifier: syn::TraitBoundModifier::None,
|
||||||
lifetimes: None,
|
lifetimes: None,
|
||||||
path: parse_quote!(std::clone::Clone),
|
path: parse_quote!(Clone),
|
||||||
}));
|
}));
|
||||||
punctuated.push_punct(syn::token::Add::default());
|
punctuated.push_punct(syn::token::Add::default());
|
||||||
punctuated.push_value(TypeParamBound::Trait(TraitBound {
|
punctuated.push_value(TypeParamBound::Trait(TraitBound {
|
||||||
paren_token: None,
|
paren_token: None,
|
||||||
modifier: syn::TraitBoundModifier::None,
|
modifier: syn::TraitBoundModifier::None,
|
||||||
lifetimes: None,
|
lifetimes: None,
|
||||||
path: parse_quote!(std::default::Default),
|
path: parse_quote!(Default),
|
||||||
}));
|
}));
|
||||||
punctuated
|
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()
|
.iter()
|
||||||
.map(|field| {
|
.map(|field| {
|
||||||
let name = &field.ident;
|
let name = &field.ident;
|
||||||
|
@ -82,18 +82,38 @@ pub fn derive_refineable(input: TokenStream) -> TokenStream {
|
||||||
|
|
||||||
if is_refineable {
|
if is_refineable {
|
||||||
quote! {
|
quote! {
|
||||||
clone.#name = self.#name.refine(&refinement.#name);
|
self.#name.refine(&refinement.#name);
|
||||||
}
|
}
|
||||||
} else if is_optional {
|
} else if is_optional {
|
||||||
quote! {
|
quote! {
|
||||||
if let Some(ref value) = &refinement.#name {
|
if let Some(ref value) = &refinement.#name {
|
||||||
clone.#name = Some(value.clone());
|
self.#name = Some(value.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
quote! {
|
quote! {
|
||||||
if let Some(ref value) = &refinement.#name {
|
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;
|
type Refinement = #refinement_ident #ty_generics;
|
||||||
|
|
||||||
fn refine(&self, refinement: &Self::Refinement) -> Self {
|
fn refine(&mut self, refinement: &Self::Refinement) {
|
||||||
let mut clone = self.clone();
|
#( #field_assignments )*
|
||||||
#( #field_initializations )*
|
}
|
||||||
clone
|
}
|
||||||
|
|
||||||
|
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 )*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,11 +3,12 @@ pub use derive_refineable::Refineable;
|
||||||
pub trait Refineable {
|
pub trait Refineable {
|
||||||
type Refinement;
|
type Refinement;
|
||||||
|
|
||||||
fn refine(&self, refinement: &Self::Refinement) -> Self;
|
fn refine(&mut self, refinement: &Self::Refinement);
|
||||||
fn from_refinement(refinement: &Self::Refinement) -> Self
|
fn refined(mut self, refinement: &Self::Refinement) -> Self
|
||||||
where
|
where
|
||||||
Self: Sized + Default,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
Self::default().refine(refinement)
|
self.refine(refinement);
|
||||||
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue