Make FnOnces that render elements IntoAnyElement
This commit is contained in:
parent
db7d12f628
commit
45a8aea0f0
2 changed files with 70 additions and 93 deletions
|
@ -180,6 +180,9 @@ where
|
|||
|
||||
pub struct AnyElement<V>(Box<dyn ElementObject<V> + Send + Sync>);
|
||||
|
||||
unsafe impl<V> Send for AnyElement<V> {}
|
||||
unsafe impl<V> Sync for AnyElement<V> {}
|
||||
|
||||
impl<V> AnyElement<V> {
|
||||
pub fn new<E>(element: E) -> Self
|
||||
where
|
||||
|
@ -213,3 +216,67 @@ impl<V> IntoAnyElement<V> for AnyElement<V> {
|
|||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<V, E, F> Element<V> for Option<F>
|
||||
where
|
||||
V: 'static,
|
||||
E: 'static + IntoAnyElement<V> + Send + Sync,
|
||||
F: FnOnce(&mut V, &mut ViewContext<'_, '_, V>) -> E + Send + Sync + 'static,
|
||||
{
|
||||
type ElementState = AnyElement<V>;
|
||||
|
||||
fn id(&self) -> Option<ElementId> {
|
||||
None
|
||||
}
|
||||
|
||||
fn initialize(
|
||||
&mut self,
|
||||
view_state: &mut V,
|
||||
_rendered_element: Option<Self::ElementState>,
|
||||
cx: &mut ViewContext<V>,
|
||||
) -> Self::ElementState {
|
||||
let render = self.take().unwrap();
|
||||
(render)(view_state, cx).into_any()
|
||||
}
|
||||
|
||||
fn layout(
|
||||
&mut self,
|
||||
view_state: &mut V,
|
||||
rendered_element: &mut Self::ElementState,
|
||||
cx: &mut ViewContext<V>,
|
||||
) -> LayoutId {
|
||||
rendered_element.layout(view_state, cx)
|
||||
}
|
||||
|
||||
fn paint(
|
||||
&mut self,
|
||||
_bounds: Bounds<Pixels>,
|
||||
view_state: &mut V,
|
||||
rendered_element: &mut Self::ElementState,
|
||||
cx: &mut ViewContext<V>,
|
||||
) {
|
||||
rendered_element.paint(view_state, cx)
|
||||
}
|
||||
}
|
||||
|
||||
impl<V, E, F> IntoAnyElement<V> for Option<F>
|
||||
where
|
||||
V: 'static,
|
||||
E: 'static + IntoAnyElement<V> + Send + Sync,
|
||||
F: FnOnce(&mut V, &mut ViewContext<'_, '_, V>) -> E + Send + Sync + 'static,
|
||||
{
|
||||
fn into_any(self) -> AnyElement<V> {
|
||||
AnyElement::new(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<V, E, F> IntoAnyElement<V> for F
|
||||
where
|
||||
V: 'static,
|
||||
E: 'static + IntoAnyElement<V> + Send + Sync,
|
||||
F: FnOnce(&mut V, &mut ViewContext<'_, '_, V>) -> E + Send + Sync + 'static,
|
||||
{
|
||||
fn into_any(self) -> AnyElement<V> {
|
||||
AnyElement::new(Some(self))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,105 +12,17 @@ pub enum SplitDirection {
|
|||
Vertical,
|
||||
}
|
||||
|
||||
// #[derive(Element)]
|
||||
pub struct Pane<V: 'static> {
|
||||
id: ElementId,
|
||||
state_type: PhantomData<V>,
|
||||
size: Size<Length>,
|
||||
fill: Hsla,
|
||||
children: SmallVec<[AnyElement<V>; 2]>,
|
||||
}
|
||||
|
||||
impl<V: 'static + Send + Sync> IntoAnyElement<V> for Pane<V> {
|
||||
impl<V: 'static> IntoAnyElement<V> for Pane<V> {
|
||||
fn into_any(self) -> AnyElement<V> {
|
||||
let render =
|
||||
move |view_state: &mut V, cx: &mut ViewContext<'_, '_, V>| self.render(view_state, cx);
|
||||
|
||||
AnyElement::new(ElementRenderer {
|
||||
render: Some(render),
|
||||
view_type: PhantomData,
|
||||
element_type: PhantomData,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
struct ElementRenderer<V, E, F>
|
||||
where
|
||||
V: 'static,
|
||||
E: 'static + IntoAnyElement<V> + Send + Sync,
|
||||
F: FnOnce(&mut V, &mut ViewContext<'_, '_, V>) -> E + 'static + Send + Sync,
|
||||
{
|
||||
render: Option<F>,
|
||||
view_type: PhantomData<V>,
|
||||
element_type: PhantomData<E>,
|
||||
}
|
||||
|
||||
unsafe impl<V, E, F> Send for ElementRenderer<V, E, F>
|
||||
where
|
||||
V: 'static,
|
||||
E: 'static + IntoAnyElement<V> + Send + Sync,
|
||||
F: FnOnce(&mut V, &mut ViewContext<'_, '_, V>) -> E + 'static + Send + Sync,
|
||||
{
|
||||
}
|
||||
|
||||
unsafe impl<V, E, F> Sync for ElementRenderer<V, E, F>
|
||||
where
|
||||
V: 'static,
|
||||
E: 'static + IntoAnyElement<V> + Send + Sync,
|
||||
F: FnOnce(&mut V, &mut ViewContext<'_, '_, V>) -> E + 'static + Send + Sync,
|
||||
{
|
||||
}
|
||||
|
||||
impl<V, E, F> Element<V> for ElementRenderer<V, E, F>
|
||||
where
|
||||
V: 'static,
|
||||
E: 'static + IntoAnyElement<V> + Send + Sync,
|
||||
F: FnOnce(&mut V, &mut ViewContext<'_, '_, V>) -> E + 'static + Send + Sync,
|
||||
{
|
||||
type ElementState = AnyElement<V>;
|
||||
|
||||
fn id(&self) -> Option<ElementId> {
|
||||
None
|
||||
}
|
||||
|
||||
fn initialize(
|
||||
&mut self,
|
||||
view_state: &mut V,
|
||||
_element_state: Option<Self::ElementState>,
|
||||
cx: &mut ViewContext<V>,
|
||||
) -> Self::ElementState {
|
||||
let render = self.render.take().unwrap();
|
||||
(render)(view_state, cx).into_any()
|
||||
}
|
||||
|
||||
fn layout(
|
||||
&mut self,
|
||||
view_state: &mut V,
|
||||
rendered_element: &mut Self::ElementState,
|
||||
cx: &mut ViewContext<V>,
|
||||
) -> gpui2::LayoutId {
|
||||
rendered_element.layout(view_state, cx)
|
||||
}
|
||||
|
||||
fn paint(
|
||||
&mut self,
|
||||
bounds: gpui2::Bounds<gpui2::Pixels>,
|
||||
view_state: &mut V,
|
||||
rendered_element: &mut Self::ElementState,
|
||||
cx: &mut ViewContext<V>,
|
||||
) {
|
||||
rendered_element.paint(view_state, cx)
|
||||
}
|
||||
}
|
||||
|
||||
impl<V, E, F> IntoAnyElement<V> for ElementRenderer<V, E, F>
|
||||
where
|
||||
V: 'static,
|
||||
E: 'static + IntoAnyElement<V> + Send + Sync,
|
||||
F: FnOnce(&mut V, &mut ViewContext<V>) -> E + 'static + Send + Sync,
|
||||
{
|
||||
fn into_any(self) -> AnyElement<V> {
|
||||
AnyElement::new(self)
|
||||
(move |view_state: &mut V, cx: &mut ViewContext<'_, '_, V>| self.render(view_state, cx))
|
||||
.into_any()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -120,10 +32,8 @@ impl<V: 'static> Pane<V> {
|
|||
|
||||
Self {
|
||||
id: id.into(),
|
||||
state_type: PhantomData,
|
||||
size,
|
||||
fill: hsla(0.3, 0.3, 0.3, 1.),
|
||||
// fill: system_color.transparent,
|
||||
children: SmallVec::new(),
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue