This commit is contained in:
Nathan Sobo 2023-08-15 09:26:16 -06:00
parent f9858445b8
commit 0fe457020b
8 changed files with 199 additions and 107 deletions

View file

@ -0,0 +1,58 @@
use crate::{element::Element, frame, themes::rose_pine};
use gpui::ViewContext;
use std::{any::Any, borrow::Cow, marker::PhantomData, rc::Rc};
pub struct Button<V: 'static, D: 'static> {
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 {
label: label.into(),
data: Rc::new(()),
click_handler: None,
view_type: PhantomData,
}
}
pub fn data<D: 'static>(self, data: D) -> Button<V, D> {
Button {
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
}
}
pub fn button<V>(label: impl Into<Cow<'static, str>>) -> Button<V, ()> {
Button::new(label)
}
impl<V: 'static, D: 'static> Button<V, D> {
fn render(&mut self, view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
// 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() {
let data = self.data.clone();
button.click(move |view, event| handler(view, data.as_ref()))
} else {
button
}
}
}

View file

@ -4,7 +4,9 @@ use crate::{
};
use anyhow::Result;
use derive_more::{Deref, DerefMut};
use gpui::{Layout, LayoutContext as LegacyLayoutContext, PaintContext as LegacyPaintContext};
use gpui::{
EngineLayout, LayoutContext as LegacyLayoutContext, PaintContext as LegacyPaintContext,
};
use playground_macros::tailwind_lengths;
pub use taffy::tree::NodeId;
@ -24,7 +26,8 @@ pub struct PaintContext<'a, 'b, 'c, 'd, V> {
pub trait Element<V: 'static>: 'static + Clone {
fn style_mut(&mut self) -> &mut Style;
fn layout(&mut self, view: &mut V, cx: &mut LayoutContext<V>) -> Result<NodeId>;
fn paint(&mut self, layout: Layout, view: &mut V, cx: &mut PaintContext<V>) -> Result<()>;
fn paint(&mut self, layout: EngineLayout, 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>
@ -259,7 +262,8 @@ pub trait Element<V: 'static>: 'static + Clone {
pub trait ElementObject<V> {
fn style_mut(&mut self) -> &mut Style;
fn layout(&mut self, view: &mut V, cx: &mut LayoutContext<V>) -> Result<NodeId>;
fn paint(&mut self, layout: Layout, view: &mut V, cx: &mut PaintContext<V>) -> Result<()>;
fn paint(&mut self, layout: EngineLayout, view: &mut V, cx: &mut PaintContext<V>)
-> Result<()>;
fn clone_object(&self) -> Box<dyn ElementObject<V>>;
}
@ -272,7 +276,12 @@ impl<V: 'static, E: Element<V>> ElementObject<V> for E {
self.layout(view, cx)
}
fn paint(&mut self, layout: Layout, view: &mut V, cx: &mut PaintContext<V>) -> Result<()> {
fn paint(
&mut self,
layout: EngineLayout,
view: &mut V,
cx: &mut PaintContext<V>,
) -> Result<()> {
self.paint(layout, view, cx)
}
@ -286,6 +295,12 @@ pub struct AnyElement<V> {
layout_node_id: Option<NodeId>,
}
// enum LayoutState {
// None,
// Registered(NodeId, Box<dyn Any>),
// Computed(Layout, Box<dyn Any>),
// }
impl<V> AnyElement<V> {
pub fn layout(&mut self, view: &mut V, cx: &mut LayoutContext<V>) -> Result<NodeId> {
let layout_node_id = self.element.layout(view, cx)?;
@ -322,7 +337,12 @@ impl<V: 'static> Element<V> for AnyElement<V> {
self.layout(view, cx)
}
fn paint(&mut self, layout: Layout, view: &mut V, cx: &mut PaintContext<V>) -> Result<()> {
fn paint(
&mut self,
layout: EngineLayout,
view: &mut V,
cx: &mut PaintContext<V>,
) -> Result<()> {
self.paint(view, cx)
}
}

View file

@ -1,5 +1,5 @@
use anyhow::{anyhow, Result};
use gpui::{Layout, LayoutNodeId};
use gpui::{EngineLayout, LayoutNodeId};
use crate::{
element::{AnyElement, Element, LayoutContext, PaintContext},
@ -36,7 +36,12 @@ impl<V: 'static> Element<V> for Frame<V> {
.add_node(self.style.to_taffy(rem_size), child_layout_node_ids)
}
fn paint(&mut self, layout: Layout, view: &mut V, cx: &mut PaintContext<V>) -> Result<()> {
fn paint(
&mut self,
layout: EngineLayout,
view: &mut V,
cx: &mut PaintContext<V>,
) -> Result<()> {
cx.scene.push_quad(gpui::scene::Quad {
bounds: layout.bounds,
background: self.style.fill.color().map(Into::into),