From 4266ead9589b644133560b2003cc6a2ebdbb304a Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Thu, 26 Oct 2023 10:46:02 +0200 Subject: [PATCH] WIP: Trait bounds --- crates/gpui2/src/element.rs | 4 +- crates/ui2/src/components/panes.rs | 77 ++++++++++++++---------------- 2 files changed, 38 insertions(+), 43 deletions(-) diff --git a/crates/gpui2/src/element.rs b/crates/gpui2/src/element.rs index c6707049a6..3b53884e35 100644 --- a/crates/gpui2/src/element.rs +++ b/crates/gpui2/src/element.rs @@ -8,6 +8,8 @@ pub trait Element: IntoAnyElement { fn id(&self) -> Option; + /// Called to initialize this element for the current frame. If this + /// element had state in a previous frame, it will be passed in for the 3rd argument. fn initialize( &mut self, view_state: &mut V, @@ -41,7 +43,7 @@ pub trait Element: IntoAnyElement { #[derive(Deref, DerefMut, Default, Clone, Debug, Eq, PartialEq, Hash)] pub struct GlobalElementId(SmallVec<[ElementId; 32]>); -pub trait ParentElement: Element { +pub trait ParentElement { fn children_mut(&mut self) -> &mut SmallVec<[AnyElement; 2]>; fn child(mut self, child: impl IntoAnyElement) -> Self diff --git a/crates/ui2/src/components/panes.rs b/crates/ui2/src/components/panes.rs index 0c2714916b..789898cb9d 100644 --- a/crates/ui2/src/components/panes.rs +++ b/crates/ui2/src/components/panes.rs @@ -23,56 +23,54 @@ pub struct Pane { impl IntoAnyElement for Pane { fn into_any(self) -> AnyElement { - ElementRenderer { - id: Some(self.id), - render: Some(move |view_state, cx| self.render(view_state, cx)), + let render = move |view_state, cx| self.render(view_state, cx); + + AnyElement::new(ElementRenderer { + render: Some(render), view_type: PhantomData, element_type: PhantomData, - } + }) } } struct ElementRenderer where - E: IntoAnyElement, - F: FnOnce(&mut V, &mut ViewContext) -> E, + V: 'static + Send + Sync, + E: 'static + IntoAnyElement + Send + Sync, + F: FnOnce(&mut V, &mut ViewContext) -> E + 'static + Send + Sync, { - id: Option, render: Option, view_type: PhantomData, element_type: PhantomData, } -impl Element for ElementRenderer +impl Element for ElementRenderer where - V: 'static, - E: IntoAnyElement, - F: FnOnce(&mut V, &mut ViewContext) -> E, + V: 'static + Send + Sync, + E: 'static + IntoAnyElement + Send + Sync, + F: FnOnce(&mut V, &mut ViewContext) -> E + 'static + Send + Sync, { - type ViewState = V; type ElementState = AnyElement; fn id(&self) -> Option { - self.id + None } fn initialize( &mut self, - view_state: &mut Self::ViewState, - rendered_element: Option, - cx: &mut ViewContext, + view_state: &mut V, + _element_state: Option, + cx: &mut ViewContext, ) -> Self::ElementState { - rendered_element.unwrap_or_else(|| { - let render = self.render.take().unwrap(); - (render)(view_state, cx) - }) + let render = self.render.take().unwrap(); + (render)(view_state, cx).into_any() } fn layout( &mut self, - view_state: &mut Self::ViewState, + view_state: &mut V, rendered_element: &mut Self::ElementState, - cx: &mut ViewContext, + cx: &mut ViewContext, ) -> gpui2::LayoutId { rendered_element.layout(view_state, cx) } @@ -80,9 +78,9 @@ where fn paint( &mut self, bounds: gpui2::Bounds, - view_state: &mut Self::ViewState, + view_state: &mut V, rendered_element: &mut Self::ElementState, - cx: &mut ViewContext, + cx: &mut ViewContext, ) { rendered_element.paint(view_state, cx) } @@ -90,16 +88,16 @@ where impl IntoAnyElement for ElementRenderer where - V: 'static, - E: IntoAnyElement, - F: FnOnce(&mut V, &mut ViewContext) -> E, + V: 'static + Send + Sync, + E: 'static + IntoAnyElement + Send + Sync, + F: FnOnce(&mut V, &mut ViewContext) -> E + 'static + Send + Sync, { fn into_any(self) -> AnyElement { - self + AnyElement::new(self) } } -impl Pane { +impl Pane { pub fn new(id: impl Into, size: Size) -> Self { // Fill is only here for debugging purposes, remove before release @@ -118,7 +116,7 @@ impl Pane { self } - fn render(&mut self, view: &mut S, cx: &mut ViewContext) -> impl Element { + fn render(self, view: &mut V, cx: &mut ViewContext) -> Div> IntoAnyElement { div() .id(self.id.clone()) .flex() @@ -127,12 +125,7 @@ impl Pane { .w(self.size.width) .h(self.size.height) .relative() - .child( - div() - .z_index(0) - .size_full() - .children(self.children.drain(..)), - ) + .child(div().z_index(0).size_full().children(self.children)) .child( // TODO kb! Figure out why we can't we see the red background when we drag a file over this div. div() @@ -162,8 +155,8 @@ pub struct PaneGroup { split_direction: SplitDirection, } -impl PaneGroup { - pub fn new_groups(groups: Vec>, split_direction: SplitDirection) -> Self { +impl PaneGroup { + pub fn new_groups(groups: Vec>, split_direction: SplitDirection) -> Self { Self { state_type: PhantomData, groups, @@ -172,7 +165,7 @@ impl PaneGroup { } } - pub fn new_panes(panes: Vec>, split_direction: SplitDirection) -> Self { + pub fn new_panes(panes: Vec>, split_direction: SplitDirection) -> Self { Self { state_type: PhantomData, groups: Vec::new(), @@ -181,7 +174,7 @@ impl PaneGroup { } } - fn render(&mut self, view: &mut S, cx: &mut ViewContext) -> impl Element { + fn render(&mut self, view: &mut V, cx: &mut ViewContext) -> impl Element { let theme = theme(cx); if !self.panes.is_empty() { @@ -191,7 +184,7 @@ impl PaneGroup { .gap_px() .w_full() .h_full() - .children(self.panes.iter_mut().map(|pane| pane.render(view, cx))); + .children(self.panes.drain(..).map(|pane| pane.render(view, cx))); if self.split_direction == SplitDirection::Horizontal { return el; @@ -208,7 +201,7 @@ impl PaneGroup { .w_full() .h_full() .bg(theme.editor) - .children(self.groups.iter_mut().map(|group| group.render(view, cx))); + .children(self.groups.iter_mut().map(| group| group.render(view, cx))); if self.split_direction == SplitDirection::Horizontal { return el;