zed/crates/gpui3/src/view.rs

148 lines
3.9 KiB
Rust
Raw Normal View History

2023-09-26 17:29:44 +00:00
use parking_lot::Mutex;
2023-09-22 14:33:51 +00:00
use crate::{
2023-09-29 23:20:18 +00:00
AnyElement, Element, Handle, IntoAnyElement, Layout, LayoutId, MainThread, Result, ViewContext,
2023-09-22 14:33:51 +00:00
WindowContext,
};
2023-09-26 17:29:44 +00:00
use std::{any::Any, marker::PhantomData, sync::Arc};
2023-09-22 14:33:51 +00:00
2023-09-29 23:20:18 +00:00
pub struct View<S: Send + Sync, P, Thread = ()> {
2023-09-22 14:33:51 +00:00
state: Handle<S>,
2023-09-29 23:20:18 +00:00
render:
Arc<dyn Fn(&mut S, &mut ViewContext<S, Thread>) -> AnyElement<S> + Send + Sync + 'static>,
2023-09-22 14:33:51 +00:00
parent_state_type: PhantomData<P>,
}
2023-09-26 17:29:44 +00:00
impl<S: 'static + Send + Sync, P: 'static + Send> View<S, P> {
pub fn into_any(self) -> AnyView<P> {
AnyView {
view: Arc::new(Mutex::new(self)),
parent_state_type: PhantomData,
}
}
}
2023-09-28 07:16:42 +00:00
impl<S: Send + Sync, P> Clone for View<S, P> {
2023-09-22 14:33:51 +00:00
fn clone(&self) -> Self {
Self {
state: self.state.clone(),
render: self.render.clone(),
parent_state_type: PhantomData,
}
}
}
pub type RootView<S> = View<S, ()>;
2023-09-28 07:16:42 +00:00
pub fn view<S, P, E>(
2023-09-22 14:33:51 +00:00
state: Handle<S>,
render: impl Fn(&mut S, &mut ViewContext<S>) -> E + Send + Sync + 'static,
2023-09-28 07:16:42 +00:00
) -> View<S, P>
where
S: 'static + Send + Sync,
P: 'static,
E: Element<State = S>,
{
2023-09-22 14:33:51 +00:00
View {
state,
render: Arc::new(move |state, cx| render(state, cx).into_any()),
2023-09-22 14:33:51 +00:00
parent_state_type: PhantomData,
}
}
2023-09-25 17:47:37 +00:00
impl<S: Send + Sync + 'static, P: Send + 'static> Element for View<S, P> {
2023-09-22 14:33:51 +00:00
type State = P;
type FrameState = AnyElement<S>;
fn layout(
&mut self,
_: &mut Self::State,
cx: &mut ViewContext<Self::State>,
) -> Result<(LayoutId, Self::FrameState)> {
2023-09-30 02:53:24 +00:00
dbg!("Layout view");
2023-09-22 14:33:51 +00:00
self.state.update(cx, |state, cx| {
let mut element = (self.render)(state, cx);
let layout_id = element.layout(state, cx)?;
Ok((layout_id, element))
})
}
fn paint(
&mut self,
2023-09-28 05:10:22 +00:00
_: Layout,
2023-09-22 14:33:51 +00:00
_: &mut Self::State,
element: &mut Self::FrameState,
cx: &mut ViewContext<Self::State>,
) -> Result<()> {
2023-09-30 02:53:24 +00:00
dbg!("Paint view");
2023-09-22 14:33:51 +00:00
self.state
.update(cx, |state, cx| element.paint(state, None, cx))
}
}
2023-09-26 17:29:44 +00:00
trait ViewObject: Send + 'static {
2023-09-22 14:33:51 +00:00
fn layout(&mut self, cx: &mut WindowContext) -> Result<(LayoutId, Box<dyn Any>)>;
fn paint(
&mut self,
layout: Layout,
element: &mut dyn Any,
cx: &mut WindowContext,
) -> Result<()>;
}
2023-09-26 17:29:44 +00:00
impl<S: Send + Sync + 'static, P: Send + 'static> ViewObject for View<S, P> {
2023-09-22 14:33:51 +00:00
fn layout(&mut self, cx: &mut WindowContext) -> Result<(LayoutId, Box<dyn Any>)> {
self.state.update(cx, |state, cx| {
let mut element = (self.render)(state, cx);
let layout_id = element.layout(state, cx)?;
let element = Box::new(element) as Box<dyn Any>;
Ok((layout_id, element))
})
}
2023-09-28 05:10:22 +00:00
fn paint(&mut self, _: Layout, element: &mut dyn Any, cx: &mut WindowContext) -> Result<()> {
2023-09-22 14:33:51 +00:00
self.state.update(cx, |state, cx| {
2023-09-30 15:43:52 +00:00
let element = element.downcast_mut::<AnyElement<S>>().unwrap();
2023-09-30 02:53:24 +00:00
element.paint(state, None, cx)
2023-09-22 14:33:51 +00:00
})
}
}
pub struct AnyView<S> {
2023-09-26 17:29:44 +00:00
view: Arc<Mutex<dyn ViewObject>>,
2023-09-22 14:33:51 +00:00
parent_state_type: PhantomData<S>,
}
impl<S: 'static> Element for AnyView<S> {
2023-09-26 17:29:44 +00:00
type State = ();
2023-09-22 14:33:51 +00:00
type FrameState = Box<dyn Any>;
fn layout(
&mut self,
_: &mut Self::State,
cx: &mut ViewContext<Self::State>,
) -> Result<(LayoutId, Self::FrameState)> {
2023-09-26 17:29:44 +00:00
self.view.lock().layout(cx)
2023-09-22 14:33:51 +00:00
}
fn paint(
&mut self,
layout: Layout,
_: &mut Self::State,
element: &mut Self::FrameState,
cx: &mut ViewContext<Self::State>,
) -> Result<()> {
2023-09-30 02:53:24 +00:00
dbg!("Element.paint for AnyView");
2023-09-30 15:43:52 +00:00
self.view.lock().paint(layout, element.as_mut(), cx)
2023-09-22 14:33:51 +00:00
}
}
impl<S> Clone for AnyView<S> {
fn clone(&self) -> Self {
Self {
view: self.view.clone(),
parent_state_type: PhantomData,
}
}
}