Checkpoint

This commit is contained in:
Nathan Sobo 2023-08-19 21:24:28 -06:00
parent 2c6f692c56
commit afff46b335
4 changed files with 123 additions and 54 deletions

View file

@ -1,3 +1,4 @@
use std::cell::Cell;
use std::{marker::PhantomData, rc::Rc};
use crate::element::{AnyElement, PaintContext};
@ -15,20 +16,22 @@ use util::ResultExt;
type LayoutId = gpui::LayoutId;
#[derive(Deref, DerefMut)]
pub struct Layout<V, E: Element<V>> {
pub struct Layout<V, D> {
id: LayoutId,
engine_layout: Option<EngineLayout>,
#[deref]
#[deref_mut]
element_data: E::Layout,
element_data: D,
view_type: PhantomData<V>,
}
impl<V: 'static, E: Element<V>> Layout<V, E> {
pub fn new(id: LayoutId, engine_layout: Option<EngineLayout>, element_data: E::Layout) -> Self {
impl<V: 'static, D> Layout<V, D> {
pub fn new(id: LayoutId, engine_layout: Option<EngineLayout>, element_data: D) -> Self {
Self {
id,
engine_layout,
element_data,
view_type: PhantomData,
}
}
@ -36,6 +39,10 @@ impl<V: 'static, E: Element<V>> Layout<V, E> {
self.engine_layout(cx).bounds
}
pub fn order(&mut self, cx: &mut PaintContext<V>) -> u32 {
self.engine_layout(cx).order
}
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())
@ -45,12 +52,20 @@ impl<V: 'static, E: Element<V>> Layout<V, E> {
pub trait Element<V> {
type Layout;
fn layout(&mut self, view: &mut V, cx: &mut LayoutContext<V>) -> Result<Layout<V, Self>>
fn layout(
&mut self,
view: &mut V,
cx: &mut LayoutContext<V>,
) -> Result<Layout<V, Self::Layout>>
where
Self: Sized;
fn paint(&mut self, view: &mut V, cx: &mut PaintContext<V>)
where
fn paint(
&mut self,
view: &mut V,
layout: &mut Layout<V, Self::Layout>,
cx: &mut PaintContext<V>,
) where
Self: Sized;
/// ## Helpers
@ -106,7 +121,7 @@ pub fn div<V>() -> Div<V> {
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>>
fn layout(&mut self, view: &mut V, cx: &mut LayoutContext<V>) -> Result<Layout<V, ()>>
where
Self: Sized,
{
@ -119,7 +134,7 @@ impl<V: 'static> Element<V> for Div<V> {
cx.add_layout_node(self.style(), (), children)
}
fn paint(&mut self, view: &mut V, cx: &mut PaintContext<V>)
fn paint(&mut self, view: &mut V, layout: &mut Layout<V, ()>, cx: &mut PaintContext<V>)
where
Self: Sized,
{
@ -128,12 +143,65 @@ impl<V: 'static> Element<V> for Div<V> {
}
pub struct Hoverable<V, E: Element<V> + Styleable> {
default_style: Style,
hovered: Cell<bool>,
child_style: StyleRefinement,
hovered_style: StyleRefinement,
child: E,
view_type: PhantomData<V>,
}
pub fn hoverable<V, E: Element<V> + Styleable>(mut child: E) -> Hoverable<V, E> {
Hoverable {
hovered: Cell::new(false),
child_style: child.declared_style().clone(),
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: 'static, 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::Layout>>
where
Self: Sized,
{
if self.hovered.get() {
// If hovered, refine the child's style with this element's style.
self.child.declared_style().refine(&self.hovered_style);
} else {
// Otherwise, set the child's style back to its original style.
*self.child.declared_style() = self.child_style.clone();
}
self.child.layout(view, cx)
}
fn paint(
&mut self,
view: &mut V,
layout: &mut Layout<V, Self::Layout>,
cx: &mut PaintContext<V>,
) where
Self: Sized,
{
let bounds = layout.bounds(cx);
let order = layout.order(cx);
self.hovered.set(bounds.contains_point(cx.mouse_position()));
let hovered = self.hovered.clone();
cx.on_event(order, move |view, event: &MouseMovedEvent, cx| {});
}
}
pub trait Interactive<V> {
fn declared_interactions(&mut self) -> &mut Interactions<V>;
@ -154,41 +222,6 @@ 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();