mirror of
https://github.com/zed-industries/zed.git
synced 2024-12-26 10:40:54 +00:00
WIP
This commit is contained in:
parent
90f226193c
commit
fedb787b4f
5 changed files with 239 additions and 29 deletions
|
@ -1,6 +1,13 @@
|
|||
use crate::{AnyElement, Element, IntoAnyElement, Style, StyleCascade, StyleRefinement};
|
||||
use refineable::Refineable;
|
||||
use crate::{
|
||||
group_bounds, AnyElement, DispatchPhase, Element, IntoAnyElement, MouseMoveEvent, SharedString,
|
||||
Style, StyleCascade, StyleRefinement,
|
||||
};
|
||||
use refineable::CascadeSlot;
|
||||
use smallvec::SmallVec;
|
||||
use std::sync::{
|
||||
atomic::{AtomicBool, Ordering::SeqCst},
|
||||
Arc,
|
||||
};
|
||||
|
||||
trait LayoutNode<V: 'static + Send + Sync> {
|
||||
fn state(&mut self) -> &mut LayoutNodeState<V>;
|
||||
|
@ -28,6 +35,7 @@ trait LayoutNode<V: 'static + Send + Sync> {
|
|||
|
||||
struct LayoutNodeState<V: 'static + Send + Sync> {
|
||||
style_cascade: StyleCascade,
|
||||
computed_style: Option<Style>,
|
||||
children: SmallVec<[AnyElement<V>; 2]>,
|
||||
}
|
||||
|
||||
|
@ -61,7 +69,7 @@ impl<V: 'static + Send + Sync> Element for LayoutNodeState<V> {
|
|||
.collect::<Vec<_>>();
|
||||
|
||||
// todo!("pass just the style cascade")
|
||||
let style = Style::from_refinement(&self.style_cascade().merged());
|
||||
let style = self.computed_style().clone();
|
||||
let layout_id = cx.request_layout(style, layout_ids);
|
||||
(layout_id, ())
|
||||
}
|
||||
|
@ -81,6 +89,49 @@ impl<V: 'static + Send + Sync> Element for LayoutNodeState<V> {
|
|||
|
||||
pub trait Styled {
|
||||
fn style_cascade(&mut self) -> &mut StyleCascade;
|
||||
fn computed_style(&mut self) -> &Style;
|
||||
}
|
||||
|
||||
pub struct StyledElement<E> {
|
||||
child: E,
|
||||
}
|
||||
|
||||
impl<E> IntoAnyElement<E::ViewState> for StyledElement<E>
|
||||
where
|
||||
E: Element + Styled,
|
||||
{
|
||||
fn into_any(self) -> AnyElement<E::ViewState> {
|
||||
AnyElement::new(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: Element + Styled> Element for StyledElement<E> {
|
||||
type ViewState = E::ViewState;
|
||||
type ElementState = E::ElementState;
|
||||
|
||||
fn element_id(&self) -> Option<crate::ElementId> {
|
||||
self.child.element_id()
|
||||
}
|
||||
|
||||
fn layout(
|
||||
&mut self,
|
||||
state: &mut Self::ViewState,
|
||||
element_state: Option<Self::ElementState>,
|
||||
cx: &mut crate::ViewContext<Self::ViewState>,
|
||||
) -> (crate::LayoutId, Self::ElementState) {
|
||||
self.child.layout(state, element_state, cx)
|
||||
}
|
||||
|
||||
fn paint(
|
||||
&mut self,
|
||||
bounds: crate::Bounds<crate::Pixels>,
|
||||
state: &mut Self::ViewState,
|
||||
element_state: &mut Self::ElementState,
|
||||
cx: &mut crate::ViewContext<Self::ViewState>,
|
||||
) {
|
||||
self.child.computed_style().paint(bounds, cx);
|
||||
self.child.paint(bounds, state, element_state, cx);
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Hoverable {
|
||||
|
@ -95,18 +146,83 @@ pub trait Hoverable {
|
|||
}
|
||||
}
|
||||
|
||||
struct HoverableState<Child: Styled + Element> {
|
||||
struct HoverableElement<Child> {
|
||||
hover_style: StyleRefinement,
|
||||
group: Option<SharedString>,
|
||||
cascade_slot: CascadeSlot,
|
||||
hovered: Arc<AtomicBool>,
|
||||
child: Child,
|
||||
}
|
||||
|
||||
impl<Child: Styled + Element> HoverableState<Child> {
|
||||
impl<Child: Styled + Element> HoverableElement<Child> {
|
||||
fn hover_style(&mut self) -> &mut StyleRefinement {
|
||||
&mut self.hover_style
|
||||
}
|
||||
}
|
||||
|
||||
struct Div<V: 'static + Send + Sync>(HoverableState<LayoutNodeState<V>>);
|
||||
impl<E> IntoAnyElement<E::ViewState> for HoverableElement<E>
|
||||
where
|
||||
E: Element + Styled,
|
||||
{
|
||||
fn into_any(self) -> AnyElement<E::ViewState> {
|
||||
AnyElement::new(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<E> Element for HoverableElement<E>
|
||||
where
|
||||
E: Element + Styled,
|
||||
{
|
||||
type ViewState = E::ViewState;
|
||||
type ElementState = E::ElementState;
|
||||
|
||||
fn element_id(&self) -> Option<crate::ElementId> {
|
||||
self.child.element_id()
|
||||
}
|
||||
|
||||
fn layout(
|
||||
&mut self,
|
||||
state: &mut Self::ViewState,
|
||||
element_state: Option<Self::ElementState>,
|
||||
cx: &mut crate::ViewContext<Self::ViewState>,
|
||||
) -> (crate::LayoutId, Self::ElementState) {
|
||||
self.child.layout(state, element_state, cx)
|
||||
}
|
||||
|
||||
fn paint(
|
||||
&mut self,
|
||||
bounds: crate::Bounds<crate::Pixels>,
|
||||
state: &mut Self::ViewState,
|
||||
element_state: &mut Self::ElementState,
|
||||
cx: &mut crate::ViewContext<Self::ViewState>,
|
||||
) {
|
||||
let target_bounds = self
|
||||
.group
|
||||
.as_ref()
|
||||
.and_then(|group| group_bounds(group, cx))
|
||||
.unwrap_or(bounds);
|
||||
|
||||
let hovered = target_bounds.contains_point(cx.mouse_position());
|
||||
|
||||
let slot = self.cascade_slot;
|
||||
let style = hovered.then_some(self.hover_style.clone());
|
||||
self.child.style_cascade().set(slot, style);
|
||||
self.hovered.store(hovered, SeqCst);
|
||||
|
||||
let hovered = self.hovered.clone();
|
||||
cx.on_mouse_event(move |_, event: &MouseMoveEvent, phase, cx| {
|
||||
if phase == DispatchPhase::Capture {
|
||||
if target_bounds.contains_point(event.position) != hovered.load(SeqCst) {
|
||||
cx.notify();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
self.child.paint(bounds, state, element_state, cx);
|
||||
}
|
||||
}
|
||||
|
||||
struct Div<V: 'static + Send + Sync>(HoverableElement<LayoutNodeState<V>>);
|
||||
|
||||
impl<V: 'static + Send + Sync> LayoutNode<V> for Div<V> {
|
||||
fn state(&mut self) -> &mut LayoutNodeState<V> {
|
||||
|
@ -118,11 +234,20 @@ impl<V: 'static + Send + Sync> Styled for LayoutNodeState<V> {
|
|||
fn style_cascade(&mut self) -> &mut StyleCascade {
|
||||
&mut self.style_cascade
|
||||
}
|
||||
|
||||
fn computed_style(&mut self) -> &Style {
|
||||
self.computed_style
|
||||
.get_or_insert_with(|| Style::from(self.style_cascade.merged()))
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: 'static + Send + Sync> Styled for Div<V> {
|
||||
fn style_cascade(&mut self) -> &mut StyleCascade {
|
||||
&mut self.0.child.style_cascade
|
||||
self.0.child.style_cascade()
|
||||
}
|
||||
|
||||
fn computed_style(&mut self) -> &Style {
|
||||
self.0.child.computed_style()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -244,12 +244,12 @@ impl Size<Length> {
|
|||
#[derive(Refineable, Clone, Default, Debug, Eq, PartialEq)]
|
||||
#[refineable(debug)]
|
||||
#[repr(C)]
|
||||
pub struct Bounds<T: Clone + Debug> {
|
||||
pub struct Bounds<T: Clone + Debug + Default> {
|
||||
pub origin: Point<T>,
|
||||
pub size: Size<T>,
|
||||
}
|
||||
|
||||
impl<T: Clone + Debug + Sub<Output = T>> Bounds<T> {
|
||||
impl<T: Clone + Debug + Sub<Output = T> + Default> Bounds<T> {
|
||||
pub fn from_corners(upper_left: Point<T>, lower_right: Point<T>) -> Self {
|
||||
let origin = Point {
|
||||
x: upper_left.x.clone(),
|
||||
|
@ -263,7 +263,7 @@ impl<T: Clone + Debug + Sub<Output = T>> Bounds<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T: Clone + Debug + PartialOrd + Add<T, Output = T> + Sub<Output = T>> Bounds<T> {
|
||||
impl<T: Clone + Debug + PartialOrd + Add<T, Output = T> + Sub<Output = T> + Default> Bounds<T> {
|
||||
pub fn intersects(&self, other: &Bounds<T>) -> bool {
|
||||
let my_lower_right = self.lower_right();
|
||||
let their_lower_right = other.lower_right();
|
||||
|
|
|
@ -7,7 +7,10 @@ pub trait Styled {
|
|||
fn declared_style(&mut self) -> &mut <Self::Style as Refineable>::Refinement;
|
||||
|
||||
fn computed_style(&mut self) -> Self::Style {
|
||||
Self::Style::from_refinement(&self.style_cascade().merged())
|
||||
todo!()
|
||||
// let x: StyleRefinement = self.style_cascade().merged();
|
||||
|
||||
// x.into();
|
||||
}
|
||||
|
||||
fn hover(self) -> Hoverable<Self>
|
||||
|
|
|
@ -79,7 +79,11 @@ pub fn derive_refineable(input: TokenStream) -> TokenStream {
|
|||
},
|
||||
};
|
||||
|
||||
let field_assignments: Vec<TokenStream2> = fields
|
||||
// refinable_refine_assignments
|
||||
// refinable_refined_assignments
|
||||
// refinement_refine_assignments
|
||||
|
||||
let refineable_refine_assignments: Vec<TokenStream2> = fields
|
||||
.iter()
|
||||
.map(|field| {
|
||||
let name = &field.ident;
|
||||
|
@ -106,7 +110,34 @@ pub fn derive_refineable(input: TokenStream) -> TokenStream {
|
|||
})
|
||||
.collect();
|
||||
|
||||
let refinement_field_assignments: Vec<TokenStream2> = fields
|
||||
let refineable_refined_assignments: Vec<TokenStream2> = fields
|
||||
.iter()
|
||||
.map(|field| {
|
||||
let name = &field.ident;
|
||||
let is_refineable = is_refineable_field(field);
|
||||
let is_optional = is_optional_field(field);
|
||||
|
||||
if is_refineable {
|
||||
quote! {
|
||||
self.#name = self.#name.refined(refinement.#name);
|
||||
}
|
||||
} else if is_optional {
|
||||
quote! {
|
||||
if let Some(value) = refinement.#name {
|
||||
self.#name = Some(value);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
if let Some(value) = refinement.#name {
|
||||
self.#name = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
let refinement_refine_assigments: Vec<TokenStream2> = fields
|
||||
.iter()
|
||||
.map(|field| {
|
||||
let name = &field.ident;
|
||||
|
@ -126,6 +157,49 @@ pub fn derive_refineable(input: TokenStream) -> TokenStream {
|
|||
})
|
||||
.collect();
|
||||
|
||||
let refinement_refined_assigments: Vec<TokenStream2> = fields
|
||||
.iter()
|
||||
.map(|field| {
|
||||
let name = &field.ident;
|
||||
let is_refineable = is_refineable_field(field);
|
||||
|
||||
if is_refineable {
|
||||
quote! {
|
||||
self.#name = self.#name.refined(refinement.#name);
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
if let Some(value) = refinement.#name {
|
||||
self.#name = Some(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
let from_refinement_assigments: Vec<TokenStream2> = fields
|
||||
.iter()
|
||||
.map(|field| {
|
||||
let name = &field.ident;
|
||||
let is_refineable = is_refineable_field(field);
|
||||
let is_optional = is_optional_field(field);
|
||||
|
||||
if is_refineable {
|
||||
quote! {
|
||||
#name: value.#name.into(),
|
||||
}
|
||||
} else if is_optional {
|
||||
quote! {
|
||||
#name: value.#name.map(|v| v.into()),
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
#name: value.#name.map(|v| v.into()).unwrap_or_default(),
|
||||
}
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
let debug_impl = if impl_debug_on_refinement {
|
||||
let refinement_field_debugs: Vec<TokenStream2> = fields
|
||||
.iter()
|
||||
|
@ -173,7 +247,12 @@ pub fn derive_refineable(input: TokenStream) -> TokenStream {
|
|||
type Refinement = #refinement_ident #ty_generics;
|
||||
|
||||
fn refine(&mut self, refinement: &Self::Refinement) {
|
||||
#( #field_assignments )*
|
||||
#( #refineable_refine_assignments )*
|
||||
}
|
||||
|
||||
fn refined(mut self, refinement: Self::Refinement) -> Self {
|
||||
#( #refineable_refined_assignments )*
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -183,7 +262,22 @@ pub fn derive_refineable(input: TokenStream) -> TokenStream {
|
|||
type Refinement = #refinement_ident #ty_generics;
|
||||
|
||||
fn refine(&mut self, refinement: &Self::Refinement) {
|
||||
#( #refinement_field_assignments )*
|
||||
#( #refinement_refine_assigments )*
|
||||
}
|
||||
|
||||
fn refined(mut self, refinement: Self::Refinement) -> Self {
|
||||
#( #refinement_refined_assigments )*
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl #impl_generics From<#refinement_ident #ty_generics> for #ident #ty_generics
|
||||
#where_clause
|
||||
{
|
||||
fn from(value: #refinement_ident #ty_generics) -> Self {
|
||||
Self {
|
||||
#( #from_refinement_assigments )*
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,24 +4,12 @@ pub trait Refineable: Clone {
|
|||
type Refinement: Refineable<Refinement = Self::Refinement> + Default;
|
||||
|
||||
fn refine(&mut self, refinement: &Self::Refinement);
|
||||
fn refined(mut self, refinement: &Self::Refinement) -> Self
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
self.refine(refinement);
|
||||
self
|
||||
}
|
||||
fn from_refinement(refinement: &Self::Refinement) -> Self
|
||||
where
|
||||
Self: Default + Sized,
|
||||
{
|
||||
Self::default().refined(refinement)
|
||||
}
|
||||
fn refined(self, refinement: Self::Refinement) -> Self;
|
||||
fn from_cascade(cascade: &Cascade<Self>) -> Self
|
||||
where
|
||||
Self: Default + Sized,
|
||||
{
|
||||
Self::default().refined(&cascade.merged())
|
||||
Self::default().refined(cascade.merged())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue