Compiling checkpoint

This commit is contained in:
Nathan Sobo 2023-08-19 19:51:17 -06:00
parent 76993f6b57
commit 0747131bd4
11 changed files with 262 additions and 48 deletions

View file

@ -1,57 +1,180 @@
use crate::style::StyleRefinement;
use std::{marker::PhantomData, rc::Rc};
use crate::element::{AnyElement, PaintContext};
use crate::layout_context::LayoutContext;
use crate::style::{Style, StyleRefinement};
use anyhow::Result;
use derive_more::{Deref, DerefMut};
use gpui::EngineLayout;
use gpui::{geometry::rect::RectF, platform::MouseMovedEvent, EventContext};
use playground_macros::styleable_trait;
use refineable::Refineable;
use smallvec::SmallVec;
use util::ResultExt;
trait Element<V> {
type Style;
type LayoutId = gpui::LayoutId;
fn hover(self) -> Hover<V, Self>
where
Self: Sized,
Self::Style: Refineable,
<Self::Style as Refineable>::Refinement: Default,
{
Hover {
child: self,
style: <<Self as Element<V>>::Style as Refineable>::Refinement::default(),
#[derive(Deref, DerefMut)]
pub struct Layout<V, E: Element<V>> {
id: LayoutId,
engine_layout: Option<EngineLayout>,
#[deref]
#[deref_mut]
element_data: E::Layout,
}
impl<V: 'static, E: Element<V>> Layout<V, E> {
pub fn new(id: LayoutId, engine_layout: Option<EngineLayout>, element_data: E::Layout) -> Self {
Self {
id,
engine_layout,
element_data,
}
}
pub fn bounds(&mut self, cx: &mut PaintContext<V>) -> RectF {
self.engine_layout(cx).bounds
}
fn engine_layout(&mut self, cx: &mut PaintContext<'_, '_, '_, '_, V>) -> &mut EngineLayout {
self.engine_layout
.get_or_insert_with(|| cx.computed_layout(self.id).log_err().unwrap_or_default())
}
}
pub trait Element<V> {
type Layout;
fn layout(&mut self, view: &mut V, cx: &mut LayoutContext<V>) -> Result<Layout<V, Self>>
where
Self: Sized;
fn paint(&mut self, view: &mut V, cx: &mut PaintContext<V>)
where
Self: Sized;
/// ## Helpers
fn hoverable(self) -> Hoverable<V, Self>
where
Self: Styleable + Sized,
{
hoverable(self)
}
}
use crate as playground;
styleable_trait!();
struct Hover<V, E: Element<V>>
where
E::Style: Refineable,
{
child: E,
style: <E::Style as Refineable>::Refinement,
}
struct Div {
pub struct Div<V> {
style: StyleRefinement,
children: SmallVec<[AnyElement<V>; 2]>,
}
impl Styleable for Div {
impl<V> Styleable for Div<V> {
type Style = Style;
fn declared_style(&mut self) -> &mut StyleRefinement {
&mut self.style
}
}
fn div() -> Div {
pub fn div<V>() -> Div<V> {
Div {
style: Default::default(),
children: Default::default(),
}
}
impl<V> Element<V> for Div {
type Style = StyleRefinement;
impl<V: 'static> Element<V> for Div<V> {
type Layout = ();
fn layout(&mut self, view: &mut V, cx: &mut LayoutContext<V>) -> Result<Layout<V, Self>>
where
Self: Sized,
{
let children = self
.children
.iter_mut()
.map(|child| child.layout(view, cx))
.collect::<Result<Vec<LayoutId>>>()?;
cx.add_layout_node(self.style(), (), children)
}
fn paint(&mut self, view: &mut V, cx: &mut PaintContext<V>)
where
Self: Sized,
{
todo!()
}
}
pub struct Hoverable<V, E: Element<V> + Styleable> {
default_style: Style,
hovered_style: StyleRefinement,
child: E,
view_type: PhantomData<V>,
}
pub trait Interactive<V> {
fn declared_interactions(&mut self) -> &mut Interactions<V>;
fn on_mouse_move<H>(mut self, handler: H) -> Self
where
H: 'static + Fn(&mut V, &MouseMovedEvent, &mut EventContext<V>),
Self: Sized,
{
self.declared_interactions().mouse_moved = Some(Rc::new(move |view, event, cx| {
handler(view, event, cx);
cx.bubble
}));
self
}
}
pub struct Interactions<V> {
mouse_moved: Option<Rc<dyn Fn(&mut V, &MouseMovedEvent, &mut EventContext<V>) -> bool>>,
}
pub fn hoverable<V, E: Element<V> + Styleable>(mut child: E) -> Hoverable<V, E> {
Hoverable {
default_style: child.style(),
hovered_style: Default::default(),
child,
view_type: PhantomData,
}
}
impl<V, E: Element<V> + Styleable> Styleable for Hoverable<V, E> {
type Style = E::Style;
fn declared_style(&mut self) -> &mut playground::style::StyleRefinement {
self.child.declared_style()
}
}
impl<V, E: Element<V> + Styleable> Element<V> for Hoverable<V, E> {
type Layout = E::Layout;
fn layout(&mut self, view: &mut V, cx: &mut LayoutContext<V>) -> Result<Layout<V, Self>>
where
Self: Sized,
{
todo!()
}
fn paint(&mut self, view: &mut V, cx: &mut PaintContext<V>)
where
Self: Sized,
{
todo!()
}
}
#[test]
fn test() {
let elt = div().w_auto();
// let elt = div().w_auto();
}
// trait Element<V: 'static> {

View file

@ -6,7 +6,7 @@ use crate::{
style::{Style, StyleRefinement},
};
use anyhow::{anyhow, Result};
use gpui::LayoutNodeId;
use gpui::LayoutId;
use playground_macros::IntoElement;
use refineable::Refineable;
@ -46,7 +46,7 @@ impl<V: 'static> Element<V> for Frame<V> {
.children
.iter_mut()
.map(|child| child.layout(view, cx))
.collect::<Result<Vec<LayoutNodeId>>>()?;
.collect::<Result<Vec<LayoutId>>>()?;
let rem_size = cx.rem_pixels();
let style = Style::default().refined(&self.style);

View file

@ -0,0 +1,61 @@
use anyhow::{anyhow, Result};
use derive_more::{Deref, DerefMut};
pub use gpui::LayoutContext as LegacyLayoutContext;
use gpui::{RenderContext, ViewContext};
pub use taffy::tree::NodeId;
use crate::{
div::{Element, Layout},
style::Style,
};
#[derive(Deref, DerefMut)]
pub struct LayoutContext<'a, 'b, 'c, 'd, V> {
#[deref]
#[deref_mut]
pub(crate) legacy_cx: &'d mut LegacyLayoutContext<'a, 'b, 'c, V>,
pub(crate) scene: &'d mut gpui::SceneBuilder,
}
impl<'a, 'b, V> RenderContext<'a, 'b, V> for LayoutContext<'a, 'b, '_, '_, V> {
fn text_style(&self) -> gpui::fonts::TextStyle {
self.legacy_cx.text_style()
}
fn push_text_style(&mut self, style: gpui::fonts::TextStyle) {
self.legacy_cx.push_text_style(style)
}
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> LayoutContext<'a, 'b, 'c, 'd, V> {
pub fn new(
legacy_cx: &'d mut LegacyLayoutContext<'a, 'b, 'c, V>,
scene: &'d mut gpui::SceneBuilder,
) -> Self {
Self { legacy_cx, scene }
}
pub fn add_layout_node<E: Element<V>>(
&mut self,
style: Style,
element_data: E::Layout,
children: impl IntoIterator<Item = NodeId>,
) -> Result<Layout<V, E>> {
let rem_size = self.rem_pixels();
let id = self
.legacy_cx
.layout_engine()
.ok_or_else(|| anyhow!("no layout engine"))?
.add_node(style.to_taffy(rem_size), children)?;
Ok(Layout::new(id, None, element_data))
}
}

View file

@ -1,8 +1,10 @@
use std::{any::TypeId, rc::Rc};
use anyhow::{anyhow, Result};
use derive_more::{Deref, DerefMut};
use gpui::{geometry::rect::RectF, EventContext, RenderContext, ViewContext};
use gpui::{
geometry::rect::RectF, EngineLayout, EventContext, LayoutId, RenderContext, ViewContext,
};
pub use gpui::{LayoutContext, PaintContext as LegacyPaintContext};
use std::{any::TypeId, rc::Rc};
pub use taffy::tree::NodeId;
#[derive(Deref, DerefMut)]
@ -66,4 +68,10 @@ impl<'a, 'b, 'c, 'd, V: 'static> PaintContext<'a, 'b, 'c, 'd, V> {
view_id: self.view_id(),
});
}
pub(crate) fn computed_layout(&mut self, layout_id: LayoutId) -> Result<EngineLayout> {
self.layout_engine()
.ok_or_else(|| anyhow!("no layout engine present"))?
.computed_layout(layout_id)
}
}

View file

@ -20,6 +20,7 @@ mod div;
mod element;
mod frame;
mod hoverable;
mod layout_context;
mod paint_context;
mod style;
mod text;