Compiling checkpoint

This commit is contained in:
Nathan Sobo
2023-08-15 19:29:57 -06:00
parent e7489bd4c9
commit 65a5c54a2c
7 changed files with 224 additions and 82 deletions
-1
View File
@@ -4,7 +4,6 @@ use util::ResultExt;
use crate::element::AnyElement;
#[derive(Clone)]
pub struct Adapter<V>(pub(crate) AnyElement<V>);
impl<V: 'static> gpui::Element<V> for Adapter<V> {
+60 -12
View File
@@ -1,41 +1,57 @@
use crate::{element::Element, frame, themes::rose_pine};
use crate::{
element::{AnyElement, Element, ElementMetadata},
frame,
themes::rose_pine,
};
use gpui::ViewContext;
use std::{any::Any, borrow::Cow, marker::PhantomData, rc::Rc};
use std::{borrow::Cow, marker::PhantomData, rc::Rc};
struct ButtonHandlers<V, D> {
click: Option<Rc<dyn Fn(&mut V, &D)>>,
}
impl<V, D> Default for ButtonHandlers<V, D> {
fn default() -> Self {
Self { click: None }
}
}
pub struct Button<V: 'static, D: 'static> {
metadata: ElementMetadata<V>,
button_handlers: ButtonHandlers<V, D>,
label: Cow<'static, str>,
data: Rc<D>,
click_handler: Option<Rc<dyn Fn(&mut V, &dyn Any)>>,
view_type: PhantomData<V>,
}
impl<V: 'static> Button<V, ()> {
fn new(label: impl Into<Cow<'static, str>>) -> Self {
Self {
metadata: Default::default(),
button_handlers: ButtonHandlers::default(),
label: label.into(),
data: Rc::new(()),
click_handler: None,
view_type: PhantomData,
}
}
pub fn data<D: 'static>(self, data: D) -> Button<V, D> {
Button {
metadata: Default::default(),
button_handlers: ButtonHandlers::default(),
label: self.label,
data: Rc::new(data),
click_handler: None,
view_type: PhantomData,
}
}
}
impl<V: 'static, D: 'static> Button<V, D> {
fn click(mut self, handler: impl Fn(&mut V, &D) + 'static) -> Self {
self.click_handler = Some(Rc::new(move |view, data| {
let data = data.downcast_ref::<D>().unwrap();
handler(view, data);
}));
self
fn click(self, handler: impl Fn(&mut V, &D) + 'static) -> Self {
let data = self.data.clone();
Element::click(self, move |view, _| {
handler(view, data.as_ref());
})
}
}
@@ -48,7 +64,7 @@ impl<V: 'static, D: 'static> Button<V, D> {
// TODO: Drive from the context
let button = frame().fill(rose_pine::dawn().error(0.5)).h_5().w_9();
if let Some(handler) = self.click_handler.clone() {
if let Some(handler) = self.button_handlers.click.clone() {
let data = self.data.clone();
button.click(move |view, event| handler(view, data.as_ref()))
} else {
@@ -56,3 +72,35 @@ impl<V: 'static, D: 'static> Button<V, D> {
}
}
}
impl<V: 'static, D> Element<V> for Button<V, D> {
type Layout = AnyElement<V>;
fn style_mut(&mut self) -> &mut crate::style::ElementStyle {
&mut self.metadata.style
}
fn handlers_mut(&mut self) -> &mut crate::element::ElementHandlers<V> {
&mut self.metadata.handlers
}
fn layout(
&mut self,
view: &mut V,
cx: &mut crate::element::LayoutContext<V>,
) -> anyhow::Result<(taffy::tree::NodeId, Self::Layout)> {
let mut element = self.render(view, cx).into_any();
let node_id = element.layout(view, cx)?;
Ok((node_id, element))
}
fn paint<'a>(
&mut self,
layout: crate::element::Layout<'a, Self::Layout>,
view: &mut V,
cx: &mut crate::element::PaintContext<V>,
) -> anyhow::Result<()> {
layout.from_element.paint(view, cx)?;
Ok(())
}
}
+97 -43
View File
@@ -1,13 +1,14 @@
use std::{any::Any, sync::Arc};
use std::{any::Any, rc::Rc};
use crate::{
adapter::Adapter,
style::{DefinedLength, Display, Fill, Length, Overflow, Position, Style},
style::{DefinedLength, Display, ElementStyle, Fill, Length, Overflow, Position},
};
use anyhow::Result;
use derive_more::{Deref, DerefMut};
use gpui::{
EngineLayout, LayoutContext as LegacyLayoutContext, PaintContext as LegacyPaintContext,
scene::MouseClick, EngineLayout, LayoutContext as LegacyLayoutContext,
PaintContext as LegacyPaintContext,
};
use playground_macros::tailwind_lengths;
pub use taffy::tree::NodeId;
@@ -25,14 +26,48 @@ pub struct PaintContext<'a, 'b, 'c, 'd, V> {
pub(crate) scene: &'d mut gpui::SceneBuilder,
}
pub trait Element<V: 'static>: 'static + Clone {
pub struct Layout<'a, E: ?Sized> {
pub from_engine: EngineLayout,
pub from_element: &'a mut E,
}
pub struct ElementHandlers<V> {
click: Option<Rc<dyn Fn(&mut V, MouseClick)>>,
}
pub struct ElementMetadata<V> {
pub style: ElementStyle,
pub handlers: ElementHandlers<V>,
}
impl<V> Default for ElementMetadata<V> {
fn default() -> Self {
Self {
style: ElementStyle::default(),
handlers: ElementHandlers::default(),
}
}
}
impl<V> Default for ElementHandlers<V> {
fn default() -> Self {
ElementHandlers { click: None }
}
}
pub trait Element<V: 'static>: 'static {
type Layout: 'static;
fn style_mut(&mut self) -> &mut Style;
fn style_mut(&mut self) -> &mut ElementStyle;
fn handlers_mut(&mut self) -> &mut ElementHandlers<V>;
fn layout(&mut self, view: &mut V, cx: &mut LayoutContext<V>)
-> Result<(NodeId, Self::Layout)>;
fn paint(&mut self, layout: EngineLayout, view: &mut V, cx: &mut PaintContext<V>)
-> Result<()>;
fn paint<'a>(
&mut self,
layout: Layout<Self::Layout>,
view: &mut V,
cx: &mut PaintContext<V>,
) -> Result<()>;
/// Convert to a dynamically-typed element suitable for layout and paint.
fn into_any(self) -> AnyElement<V>
@@ -53,6 +88,16 @@ pub trait Element<V: 'static>: 'static + Clone {
Adapter(self.into_any())
}
fn click(mut self, handler: impl Fn(&mut V, MouseClick) + 'static) -> Self
where
Self: Sized,
{
self.handlers_mut().click = Some(Rc::new(move |view, event| {
handler(view, event);
}));
self
}
// Display ////////////////////
fn block(mut self) -> Self
@@ -265,46 +310,59 @@ pub trait Element<V: 'static>: 'static + Clone {
}
pub trait ElementObject<V> {
fn style_mut(&mut self) -> &mut Style;
fn style_mut(&mut self) -> &mut ElementStyle;
fn handlers_mut(&mut self) -> &mut ElementHandlers<V>;
fn layout(&mut self, view: &mut V, cx: &mut LayoutContext<V>)
-> Result<(NodeId, Arc<dyn Any>)>;
fn paint(&mut self, layout: EngineLayout, view: &mut V, cx: &mut PaintContext<V>)
-> Result<()>;
fn clone_object(&self) -> Box<dyn ElementObject<V>>;
-> Result<(NodeId, Box<dyn Any>)>;
fn paint(
&mut self,
layout: Layout<dyn Any>,
view: &mut V,
cx: &mut PaintContext<V>,
) -> Result<()>;
}
impl<V: 'static, E: Element<V>> ElementObject<V> for E {
fn style_mut(&mut self) -> &mut Style {
self.style_mut()
fn style_mut(&mut self) -> &mut ElementStyle {
Element::style_mut(self)
}
fn handlers_mut(&mut self) -> &mut ElementHandlers<V> {
Element::handlers_mut(self)
}
fn layout(
&mut self,
view: &mut V,
cx: &mut LayoutContext<V>,
) -> Result<(NodeId, Arc<dyn Any>)> {
) -> Result<(NodeId, Box<dyn Any>)> {
let (node_id, layout) = self.layout(view, cx)?;
let layout = Arc::new(layout) as Arc<dyn Any>;
let layout = Box::new(layout) as Box<dyn Any>;
Ok((node_id, layout))
}
fn paint(
&mut self,
layout: EngineLayout,
layout: Layout<dyn Any>,
view: &mut V,
cx: &mut PaintContext<V>,
) -> Result<()> {
let layout = Layout {
from_engine: layout.from_engine,
from_element: layout.from_element.downcast_mut::<E::Layout>().unwrap(),
};
self.paint(layout, view, cx)
}
fn clone_object(&self) -> Box<dyn ElementObject<V>> {
Box::new(Clone::clone(self))
}
// fn clone_object(&self) -> Box<dyn ElementObject<V>> {
// Box::new(Clone::clone(self))
// }
}
pub struct AnyElement<V> {
element: Box<dyn ElementObject<V>>,
layout: Option<(NodeId, Arc<dyn Any>)>,
layout: Option<(NodeId, Box<dyn Any>)>,
}
impl<V> AnyElement<V> {
@@ -315,32 +373,33 @@ impl<V> AnyElement<V> {
}
pub fn paint(&mut self, view: &mut V, cx: &mut PaintContext<V>) -> Result<()> {
let (layout_node_id, layout) = self.layout.clone().expect("paint called before layout");
let layout = cx
.layout_engine()
.unwrap()
.computed_layout(layout_node_id)
.expect("you can currently only use playground elements within an adapter");
self.element.paint(layout, view, cx)
}
}
let (layout_node_id, element_layout) =
self.layout.as_mut().expect("paint called before layout");
impl<V> Clone for AnyElement<V> {
fn clone(&self) -> Self {
Self {
element: self.element.clone_object(),
layout: self.layout.clone(),
}
let layout = Layout {
from_engine: cx
.layout_engine()
.unwrap()
.computed_layout(*layout_node_id)
.expect("you can currently only use playground elements within an adapter"),
from_element: element_layout.as_mut(),
};
self.element.paint(layout, view, cx)
}
}
impl<V: 'static> Element<V> for AnyElement<V> {
type Layout = ();
fn style_mut(&mut self) -> &mut Style {
fn style_mut(&mut self) -> &mut ElementStyle {
self.element.style_mut()
}
fn handlers_mut(&mut self) -> &mut ElementHandlers<V> {
self.element.handlers_mut()
}
fn layout(
&mut self,
view: &mut V,
@@ -349,12 +408,7 @@ impl<V: 'static> Element<V> for AnyElement<V> {
Ok((self.layout(view, cx)?, ()))
}
fn paint(
&mut self,
layout: EngineLayout,
view: &mut V,
cx: &mut PaintContext<V>,
) -> Result<()> {
fn paint(&mut self, layout: Layout<()>, view: &mut V, cx: &mut PaintContext<V>) -> Result<()> {
self.paint(view, cx)
}
}
+14 -22
View File
@@ -1,18 +1,20 @@
use crate::{
element::{AnyElement, Element, LayoutContext, NodeId, PaintContext},
style::Style,
element::{AnyElement, Element, ElementHandlers, Layout, LayoutContext, NodeId, PaintContext},
style::ElementStyle,
};
use anyhow::{anyhow, Result};
use gpui::{EngineLayout, LayoutNodeId};
use gpui::LayoutNodeId;
pub struct Frame<V> {
style: Style,
style: ElementStyle,
handlers: ElementHandlers<V>,
children: Vec<AnyElement<V>>,
}
pub fn frame<V>() -> Frame<V> {
Frame {
style: Style::default(),
style: ElementStyle::default(),
handlers: ElementHandlers::default(),
children: Vec::new(),
}
}
@@ -20,10 +22,14 @@ pub fn frame<V>() -> Frame<V> {
impl<V: 'static> Element<V> for Frame<V> {
type Layout = ();
fn style_mut(&mut self) -> &mut Style {
fn style_mut(&mut self) -> &mut ElementStyle {
&mut self.style
}
fn handlers_mut(&mut self) -> &mut ElementHandlers<V> {
&mut self.handlers
}
fn layout(
&mut self,
view: &mut V,
@@ -44,14 +50,9 @@ impl<V: 'static> Element<V> for Frame<V> {
Ok((node_id, ()))
}
fn paint(
&mut self,
layout: EngineLayout,
view: &mut V,
cx: &mut PaintContext<V>,
) -> Result<()> {
fn paint(&mut self, layout: Layout<()>, view: &mut V, cx: &mut PaintContext<V>) -> Result<()> {
cx.scene.push_quad(gpui::scene::Quad {
bounds: layout.bounds,
bounds: layout.from_engine.bounds,
background: self.style.fill.color().map(Into::into),
border: Default::default(),
corner_radii: Default::default(),
@@ -63,12 +64,3 @@ impl<V: 'static> Element<V> for Frame<V> {
Ok(())
}
}
impl<V> Clone for Frame<V> {
fn clone(&self) -> Self {
Self {
style: self.style.clone(),
children: self.children.clone(),
}
}
}
+1
View File
@@ -14,6 +14,7 @@ use view::view;
mod adapter;
mod color;
mod components;
mod element;
mod frame;
mod style;
+4 -4
View File
@@ -5,7 +5,7 @@ pub use taffy::style::{
};
#[derive(Clone)]
pub struct Style {
pub struct ElementStyle {
/// What layout strategy should be used?
pub display: Display,
@@ -67,8 +67,8 @@ pub struct Style {
pub fill: Fill,
}
impl Style {
pub const DEFAULT: Style = Style {
impl ElementStyle {
pub const DEFAULT: ElementStyle = ElementStyle {
display: Display::DEFAULT,
overflow: Point {
x: Overflow::Visible,
@@ -137,7 +137,7 @@ impl Style {
}
}
impl Default for Style {
impl Default for ElementStyle {
fn default() -> Self {
Self::DEFAULT.clone()
}
@@ -0,0 +1,48 @@
// type Result = ();
// type LayoutContext<> = ();
// trait Element<V: 'static>: 'static + Clone {
// type Layout: 'static;
// fn style_mut(&mut self) -> &mut Style;
// fn layout(&mut self, view: &mut V, cx: &mut LayoutContext<V>)
// -> Result<(NodeId, Self::Layout)>;
// fn paint<'a>(
// &mut self,
// layout: Layout<'a, Self::Layout>,
// view: &mut V,
// cx: &mut PaintContext<V>,
// ) -> Result<()>;
// }
// struct Button {
// style: Style,
// }
// type Style = ();
// impl Button {
// fn render<V>() -> impl Element<V> {
// todo!()
// }
// }
// impl<V: 'static> Element<V> for Foo {
// type Layout = ();
// fn style_mut(&mut self) -> &mut Style {
// unimplemented!()
// }
// fn layout(
// &mut self,
// view: &mut V,
// cx: &mut LayoutContext<V>,
// ) -> Result<(NodeId, Self::Layout)> {
// unimplemented!()
// }
// fn paint(&mut self, layout: Layout<()>, view: &mut V, cx: &mut PaintContext<V>) -> Result<()> {
// unimplemented!()
// }
// }