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>);
|
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> {
|
impl<V> AnyElement<V> {
|
||||||
pub fn new<E>(element: E) -> Self
|
pub fn new<E>(element: E) -> Self
|
||||||
where
|
where
|
||||||
|
@ -213,3 +216,67 @@ impl<V> IntoAnyElement<V> for AnyElement<V> {
|
||||||
self
|
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,
|
Vertical,
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[derive(Element)]
|
|
||||||
pub struct Pane<V: 'static> {
|
pub struct Pane<V: 'static> {
|
||||||
id: ElementId,
|
id: ElementId,
|
||||||
state_type: PhantomData<V>,
|
|
||||||
size: Size<Length>,
|
size: Size<Length>,
|
||||||
fill: Hsla,
|
fill: Hsla,
|
||||||
children: SmallVec<[AnyElement<V>; 2]>,
|
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> {
|
fn into_any(self) -> AnyElement<V> {
|
||||||
let render =
|
(move |view_state: &mut V, cx: &mut ViewContext<'_, '_, V>| self.render(view_state, cx))
|
||||||
move |view_state: &mut V, cx: &mut ViewContext<'_, '_, V>| self.render(view_state, cx);
|
.into_any()
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,10 +32,8 @@ impl<V: 'static> Pane<V> {
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
id: id.into(),
|
id: id.into(),
|
||||||
state_type: PhantomData,
|
|
||||||
size,
|
size,
|
||||||
fill: hsla(0.3, 0.3, 0.3, 1.),
|
fill: hsla(0.3, 0.3, 0.3, 1.),
|
||||||
// fill: system_color.transparent,
|
|
||||||
children: SmallVec::new(),
|
children: SmallVec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue