WIP
This commit is contained in:
parent
6dbe983461
commit
ca35573ad5
16 changed files with 255 additions and 62 deletions
|
@ -9,8 +9,8 @@ use refineable::Refineable;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
current_platform, image_cache::ImageCache, AssetSource, Context, DisplayId, Executor, LayoutId,
|
current_platform, image_cache::ImageCache, AssetSource, Context, DisplayId, Executor, LayoutId,
|
||||||
MainThread, MainThreadOnly, Platform, RootView, SubscriberSet, SvgRenderer, Task, TextStyle,
|
MainThread, MainThreadOnly, Platform, SubscriberSet, SvgRenderer, Task, TextStyle,
|
||||||
TextStyleRefinement, TextSystem, Window, WindowContext, WindowHandle, WindowId,
|
TextStyleRefinement, TextSystem, View, Window, WindowContext, WindowHandle, WindowId,
|
||||||
};
|
};
|
||||||
use anyhow::{anyhow, Result};
|
use anyhow::{anyhow, Result};
|
||||||
use collections::{HashMap, HashSet, VecDeque};
|
use collections::{HashMap, HashSet, VecDeque};
|
||||||
|
@ -404,7 +404,7 @@ impl MainThread<AppContext> {
|
||||||
pub fn open_window<S: 'static + Send + Sync>(
|
pub fn open_window<S: 'static + Send + Sync>(
|
||||||
&mut self,
|
&mut self,
|
||||||
options: crate::WindowOptions,
|
options: crate::WindowOptions,
|
||||||
build_root_view: impl FnOnce(&mut WindowContext) -> RootView<S> + Send + 'static,
|
build_root_view: impl FnOnce(&mut WindowContext) -> View<S> + Send + 'static,
|
||||||
) -> WindowHandle<S> {
|
) -> WindowHandle<S> {
|
||||||
self.update(|cx| {
|
self.update(|cx| {
|
||||||
let id = cx.windows.insert(None);
|
let id = cx.windows.insert(None);
|
||||||
|
|
|
@ -7,7 +7,7 @@ use crate::{
|
||||||
use derive_more::{Deref, DerefMut};
|
use derive_more::{Deref, DerefMut};
|
||||||
pub(crate) use smallvec::SmallVec;
|
pub(crate) use smallvec::SmallVec;
|
||||||
|
|
||||||
pub trait Element: 'static + Send + Sync {
|
pub trait Element: 'static + Send + Sync + IntoAnyElement<Self::ViewState> {
|
||||||
type ViewState: 'static + Send + Sync;
|
type ViewState: 'static + Send + Sync;
|
||||||
type ElementState: 'static + Send + Sync;
|
type ElementState: 'static + Send + Sync;
|
||||||
|
|
||||||
|
@ -227,6 +227,12 @@ where
|
||||||
|
|
||||||
pub struct AnyElement<S>(Box<dyn ElementObject<S>>);
|
pub struct AnyElement<S>(Box<dyn ElementObject<S>>);
|
||||||
|
|
||||||
|
impl<S: 'static + Send + Sync> AnyElement<S> {
|
||||||
|
pub fn new<E: Element<ViewState = S>>(element: E) -> Self {
|
||||||
|
AnyElement(Box::new(RenderedElement::new(element)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<S: 'static + Send + Sync> AnyElement<S> {
|
impl<S: 'static + Send + Sync> AnyElement<S> {
|
||||||
pub fn layout(&mut self, state: &mut S, cx: &mut ViewContext<S>) -> LayoutId {
|
pub fn layout(&mut self, state: &mut S, cx: &mut ViewContext<S>) -> LayoutId {
|
||||||
self.0.layout(state, cx)
|
self.0.layout(state, cx)
|
||||||
|
@ -241,12 +247,6 @@ pub trait IntoAnyElement<S> {
|
||||||
fn into_any(self) -> AnyElement<S>;
|
fn into_any(self) -> AnyElement<S>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: Element> IntoAnyElement<E::ViewState> for E {
|
|
||||||
fn into_any(self) -> AnyElement<E::ViewState> {
|
|
||||||
AnyElement(Box::new(RenderedElement::new(self)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S> IntoAnyElement<S> for AnyElement<S> {
|
impl<S> IntoAnyElement<S> for AnyElement<S> {
|
||||||
fn into_any(self) -> AnyElement<S> {
|
fn into_any(self) -> AnyElement<S> {
|
||||||
self
|
self
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
AnyElement, Bounds, DispatchPhase, Element, IdentifiedElement, Interactive, MouseDownEvent,
|
AnyElement, Bounds, DispatchPhase, Element, IdentifiedElement, Interactive, IntoAnyElement,
|
||||||
MouseEventListeners, MouseUpEvent, ParentElement, Pixels, Styled, ViewContext,
|
MouseDownEvent, MouseEventListeners, MouseUpEvent, ParentElement, Pixels, Styled, ViewContext,
|
||||||
};
|
};
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use refineable::Cascade;
|
use refineable::Cascade;
|
||||||
|
@ -51,6 +51,12 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<E: IdentifiedElement> IntoAnyElement<E::ViewState> for Clickable<E> {
|
||||||
|
fn into_any(self) -> AnyElement<E::ViewState> {
|
||||||
|
AnyElement::new(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<E> Element for Clickable<E>
|
impl<E> Element for Clickable<E>
|
||||||
where
|
where
|
||||||
E: IdentifiedElement,
|
E: IdentifiedElement,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
AnyElement, BorrowWindow, Bounds, Cascade, Element, ElementId, IdentifiedElement, Interactive,
|
AnyElement, BorrowWindow, Bounds, Cascade, Element, ElementId, IdentifiedElement, Interactive,
|
||||||
LayoutId, MouseEventListeners, Overflow, ParentElement, Pixels, Point, Refineable, Style,
|
IntoAnyElement, LayoutId, MouseEventListeners, Overflow, ParentElement, Pixels, Point,
|
||||||
Styled, ViewContext,
|
Refineable, Style, Styled, ViewContext,
|
||||||
};
|
};
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
@ -29,7 +29,21 @@ pub fn div<S>() -> Div<S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: 'static + Send + Sync, Marker: 'static + Send + Sync> Element for Div<S, Marker> {
|
impl<S, Marker> IntoAnyElement<S> for Div<S, Marker>
|
||||||
|
where
|
||||||
|
S: 'static + Send + Sync,
|
||||||
|
Marker: 'static + Send + Sync,
|
||||||
|
{
|
||||||
|
fn into_any(self) -> AnyElement<S> {
|
||||||
|
AnyElement::new(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S, Marker> Element for Div<S, Marker>
|
||||||
|
where
|
||||||
|
S: 'static + Send + Sync,
|
||||||
|
Marker: 'static + Send + Sync,
|
||||||
|
{
|
||||||
type ViewState = S;
|
type ViewState = S;
|
||||||
type ElementState = ();
|
type ElementState = ();
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
AnyElement, AppContext, Bounds, Element, ElementId, IdentifiedElement, Interactive,
|
AnyElement, AppContext, Bounds, Element, ElementId, IdentifiedElement, Interactive,
|
||||||
MouseEventListeners, ParentElement, Pixels, SharedString, Styled, ViewContext,
|
IntoAnyElement, MouseEventListeners, ParentElement, Pixels, SharedString, Styled, ViewContext,
|
||||||
};
|
};
|
||||||
use collections::HashMap;
|
use collections::HashMap;
|
||||||
use refineable::Cascade;
|
use refineable::Cascade;
|
||||||
|
@ -27,6 +27,12 @@ impl<E> Group<E> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<E: Element> IntoAnyElement<E::ViewState> for Group<E> {
|
||||||
|
fn into_any(self) -> AnyElement<E::ViewState> {
|
||||||
|
AnyElement::new(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<E: Element> Element for Group<E> {
|
impl<E: Element> Element for Group<E> {
|
||||||
type ViewState = E::ViewState;
|
type ViewState = E::ViewState;
|
||||||
type ElementState = E::ElementState;
|
type ElementState = E::ElementState;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
group_bounds, AnyElement, Bounds, DispatchPhase, Element, ElementId, IdentifiedElement,
|
group_bounds, AnyElement, Bounds, DispatchPhase, Element, ElementId, IdentifiedElement,
|
||||||
Interactive, MouseEventListeners, MouseMoveEvent, ParentElement, Pixels, SharedString, Styled,
|
Interactive, IntoAnyElement, MouseEventListeners, MouseMoveEvent, ParentElement, Pixels,
|
||||||
ViewContext,
|
SharedString, Styled, ViewContext,
|
||||||
};
|
};
|
||||||
use refineable::{Cascade, CascadeSlot, Refineable};
|
use refineable::{Cascade, CascadeSlot, Refineable};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
@ -51,6 +51,17 @@ impl<S: 'static + Send + Sync, E: Interactive<S> + Styled> Interactive<S> for Ho
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<E> IntoAnyElement<E::ViewState> for Hoverable<E>
|
||||||
|
where
|
||||||
|
E: Element + Styled,
|
||||||
|
<E as Styled>::Style: 'static + Refineable + Send + Sync + Default,
|
||||||
|
<<E as Styled>::Style as Refineable>::Refinement: 'static + Refineable + Send + Sync + Default,
|
||||||
|
{
|
||||||
|
fn into_any(self) -> AnyElement<E::ViewState> {
|
||||||
|
AnyElement::new(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<E> Element for Hoverable<E>
|
impl<E> Element for Hoverable<E>
|
||||||
where
|
where
|
||||||
E: Element + Styled,
|
E: Element + Styled,
|
||||||
|
|
|
@ -2,8 +2,8 @@ use refineable::{Cascade, Refineable};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
AnyElement, BorrowWindow, Bounds, Element, ElementId, IdentifiedElement, LayoutId,
|
AnyElement, BorrowWindow, Bounds, Element, ElementId, IdentifiedElement, IntoAnyElement,
|
||||||
ParentElement, Styled, ViewContext,
|
LayoutId, ParentElement, Styled, ViewContext,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct Identified<E> {
|
pub struct Identified<E> {
|
||||||
|
@ -11,6 +11,12 @@ pub struct Identified<E> {
|
||||||
pub(crate) id: ElementId,
|
pub(crate) id: ElementId,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<E: Element> IntoAnyElement<E::ViewState> for Identified<E> {
|
||||||
|
fn into_any(self) -> AnyElement<E::ViewState> {
|
||||||
|
AnyElement::new(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<E: Element> Element for Identified<E> {
|
impl<E: Element> Element for Identified<E> {
|
||||||
type ViewState = E::ViewState;
|
type ViewState = E::ViewState;
|
||||||
type ElementState = E::ElementState;
|
type ElementState = E::ElementState;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
BorrowWindow, Bounds, Element, LayoutId, Pixels, SharedString, Style, Styled, ViewContext,
|
AnyElement, BorrowWindow, Bounds, Element, IntoAnyElement, LayoutId, Pixels, SharedString,
|
||||||
|
Style, Styled, ViewContext,
|
||||||
};
|
};
|
||||||
use futures::FutureExt;
|
use futures::FutureExt;
|
||||||
use refineable::Cascade;
|
use refineable::Cascade;
|
||||||
|
@ -34,6 +35,15 @@ impl<S> Img<S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<S> IntoAnyElement<S> for Img<S>
|
||||||
|
where
|
||||||
|
S: 'static + Send + Sync,
|
||||||
|
{
|
||||||
|
fn into_any(self) -> AnyElement<S> {
|
||||||
|
AnyElement::new(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<S: Send + Sync + 'static> Element for Img<S> {
|
impl<S: Send + Sync + 'static> Element for Img<S> {
|
||||||
type ViewState = S;
|
type ViewState = S;
|
||||||
type ElementState = ();
|
type ElementState = ();
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
group_bounds, AnyElement, Bounds, DispatchPhase, Element, IdentifiedElement, Interactive,
|
group_bounds, AnyElement, Bounds, DispatchPhase, Element, IdentifiedElement, Interactive,
|
||||||
MouseDownEvent, MouseEventListeners, MouseUpEvent, ParentElement, Pixels, SharedString, Styled,
|
IntoAnyElement, MouseDownEvent, MouseEventListeners, MouseUpEvent, ParentElement, Pixels,
|
||||||
ViewContext,
|
SharedString, Styled, ViewContext,
|
||||||
};
|
};
|
||||||
use refineable::{Cascade, CascadeSlot, Refineable};
|
use refineable::{Cascade, CascadeSlot, Refineable};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
@ -54,6 +54,17 @@ impl<S: 'static + Send + Sync, E: Interactive<S> + Styled> Interactive<S> for Pr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<E> IntoAnyElement<E::ViewState> for Pressable<E>
|
||||||
|
where
|
||||||
|
E: Styled + IdentifiedElement,
|
||||||
|
<E as Styled>::Style: 'static + Refineable + Send + Sync + Default,
|
||||||
|
<<E as Styled>::Style as Refineable>::Refinement: 'static + Refineable + Send + Sync + Default,
|
||||||
|
{
|
||||||
|
fn into_any(self) -> AnyElement<E::ViewState> {
|
||||||
|
AnyElement::new(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<E> Element for Pressable<E>
|
impl<E> Element for Pressable<E>
|
||||||
where
|
where
|
||||||
E: Styled + IdentifiedElement,
|
E: Styled + IdentifiedElement,
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
use crate::{Bounds, Element, LayoutId, Pixels, SharedString, Style, Styled};
|
use crate::{
|
||||||
|
AnyElement, Bounds, Element, IntoAnyElement, LayoutId, Pixels, SharedString, Style, Styled,
|
||||||
|
};
|
||||||
use refineable::Cascade;
|
use refineable::Cascade;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use util::ResultExt;
|
use util::ResultExt;
|
||||||
|
@ -24,6 +26,15 @@ impl<S> Svg<S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<S> IntoAnyElement<S> for Svg<S>
|
||||||
|
where
|
||||||
|
S: 'static + Send + Sync,
|
||||||
|
{
|
||||||
|
fn into_any(self) -> AnyElement<S> {
|
||||||
|
AnyElement::new(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<S: 'static + Send + Sync> Element for Svg<S> {
|
impl<S: 'static + Send + Sync> Element for Svg<S> {
|
||||||
type ViewState = S;
|
type ViewState = S;
|
||||||
type ElementState = ();
|
type ElementState = ();
|
||||||
|
|
|
@ -42,6 +42,12 @@ pub struct Text<S> {
|
||||||
state_type: PhantomData<S>,
|
state_type: PhantomData<S>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<S: 'static + Send + Sync> IntoAnyElement<S> for Text<S> {
|
||||||
|
fn into_any(self) -> AnyElement<S> {
|
||||||
|
AnyElement::new(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<S: 'static + Send + Sync> Element for Text<S> {
|
impl<S: 'static + Send + Sync> Element for Text<S> {
|
||||||
type ViewState = S;
|
type ViewState = S;
|
||||||
type ElementState = Arc<Mutex<Option<TextElementState>>>;
|
type ElementState = Arc<Mutex<Option<TextElementState>>>;
|
||||||
|
|
|
@ -1,56 +1,60 @@
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
AnyBox, AnyElement, BorrowWindow, Bounds, Element, ElementId, Handle, IdentifiedElement,
|
AnyBox, AnyElement, BorrowWindow, Bounds, Element, ElementId, EntityId, Handle,
|
||||||
IntoAnyElement, LayoutId, Pixels, ViewContext, WindowContext,
|
IdentifiedElement, IntoAnyElement, LayoutId, Pixels, ViewContext, WindowContext,
|
||||||
};
|
};
|
||||||
use std::{any::Any, marker::PhantomData, sync::Arc};
|
use std::{any::Any, marker::PhantomData, sync::Arc};
|
||||||
|
|
||||||
pub struct View<S: Send + Sync, P> {
|
pub struct View<S: Send + Sync> {
|
||||||
state: Handle<S>,
|
state: Handle<S>,
|
||||||
render: Arc<dyn Fn(&mut S, &mut ViewContext<S>) -> AnyElement<S> + Send + Sync + 'static>,
|
render: Arc<dyn Fn(&mut S, &mut ViewContext<S>) -> AnyElement<S> + Send + Sync + 'static>,
|
||||||
parent_state_type: PhantomData<P>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: 'static + Send + Sync, P: 'static + Send + Sync> View<S, P> {
|
impl<S: 'static + Send + Sync> View<S> {
|
||||||
pub fn into_any(self) -> AnyView<P> {
|
pub fn into_any(self) -> AnyView {
|
||||||
AnyView {
|
AnyView {
|
||||||
view: Arc::new(Mutex::new(self)),
|
view: Arc::new(Mutex::new(self)),
|
||||||
parent_state_type: PhantomData,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Send + Sync, P> Clone for View<S, P> {
|
impl<S: Send + Sync> Clone for View<S> {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Self {
|
Self {
|
||||||
state: self.state.clone(),
|
state: self.state.clone(),
|
||||||
render: self.render.clone(),
|
render: self.render.clone(),
|
||||||
parent_state_type: PhantomData,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type RootView<S> = View<S, ()>;
|
pub fn view<S, E>(
|
||||||
|
|
||||||
pub fn view<S, P, E>(
|
|
||||||
state: Handle<S>,
|
state: Handle<S>,
|
||||||
render: impl Fn(&mut S, &mut ViewContext<S>) -> E + Send + Sync + 'static,
|
render: impl Fn(&mut S, &mut ViewContext<S>) -> E + Send + Sync + 'static,
|
||||||
) -> View<S, P>
|
) -> View<S>
|
||||||
where
|
where
|
||||||
S: 'static + Send + Sync,
|
S: 'static + Send + Sync,
|
||||||
P: 'static,
|
|
||||||
E: Element<ViewState = S>,
|
E: Element<ViewState = S>,
|
||||||
{
|
{
|
||||||
View {
|
View {
|
||||||
state,
|
state,
|
||||||
render: Arc::new(move |state, cx| render(state, cx).into_any()),
|
render: Arc::new(move |state, cx| render(state, cx).into_any()),
|
||||||
parent_state_type: PhantomData,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: 'static + Send + Sync, P: 'static + Send + Sync> Element for View<S, P> {
|
impl<S: 'static + Send + Sync, ParentViewState: 'static + Send + Sync>
|
||||||
type ViewState = P;
|
IntoAnyElement<ParentViewState> for View<S>
|
||||||
|
{
|
||||||
|
fn into_any(self) -> AnyElement<ParentViewState> {
|
||||||
|
AnyElement::new(EraseViewState {
|
||||||
|
view: self,
|
||||||
|
parent_view_state_type: PhantomData,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S: 'static + Send + Sync> Element for View<S> {
|
||||||
|
type ViewState = ();
|
||||||
type ElementState = AnyElement<S>;
|
type ElementState = AnyElement<S>;
|
||||||
|
|
||||||
fn element_id(&self) -> Option<crate::ElementId> {
|
fn element_id(&self) -> Option<crate::ElementId> {
|
||||||
|
@ -82,14 +86,67 @@ impl<S: 'static + Send + Sync, P: 'static + Send + Sync> Element for View<S, P>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
trait ViewObject: Send + 'static {
|
struct EraseViewState<ViewState: 'static + Send + Sync, ParentViewState> {
|
||||||
|
view: View<ViewState>,
|
||||||
|
parent_view_state_type: PhantomData<ParentViewState>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<ViewState, ParentViewState> IntoAnyElement<ParentViewState>
|
||||||
|
for EraseViewState<ViewState, ParentViewState>
|
||||||
|
where
|
||||||
|
ViewState: 'static + Send + Sync,
|
||||||
|
ParentViewState: 'static + Send + Sync,
|
||||||
|
{
|
||||||
|
fn into_any(self) -> AnyElement<ParentViewState> {
|
||||||
|
AnyElement::new(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<ViewState, ParentViewState> Element for EraseViewState<ViewState, ParentViewState>
|
||||||
|
where
|
||||||
|
ViewState: 'static + Send + Sync,
|
||||||
|
ParentViewState: 'static + Send + Sync,
|
||||||
|
{
|
||||||
|
type ViewState = ParentViewState;
|
||||||
|
type ElementState = AnyBox;
|
||||||
|
|
||||||
|
fn element_id(&self) -> Option<crate::ElementId> {
|
||||||
|
Element::element_id(&self.view)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn layout(
|
||||||
|
&mut self,
|
||||||
|
_: &mut Self::ViewState,
|
||||||
|
_: Option<Self::ElementState>,
|
||||||
|
cx: &mut ViewContext<Self::ViewState>,
|
||||||
|
) -> (LayoutId, Self::ElementState) {
|
||||||
|
ViewObject::layout(&mut self.view, cx)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn paint(
|
||||||
|
&mut self,
|
||||||
|
bounds: Bounds<Pixels>,
|
||||||
|
_: &mut Self::ViewState,
|
||||||
|
element: &mut Self::ElementState,
|
||||||
|
cx: &mut ViewContext<Self::ViewState>,
|
||||||
|
) {
|
||||||
|
ViewObject::paint(&mut self.view, bounds, element, cx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
trait ViewObject: 'static + Send + Sync {
|
||||||
|
fn entity_id(&self) -> EntityId;
|
||||||
fn layout(&mut self, cx: &mut WindowContext) -> (LayoutId, AnyBox);
|
fn layout(&mut self, cx: &mut WindowContext) -> (LayoutId, AnyBox);
|
||||||
fn paint(&mut self, bounds: Bounds<Pixels>, element: &mut dyn Any, cx: &mut WindowContext);
|
fn paint(&mut self, bounds: Bounds<Pixels>, element: &mut dyn Any, cx: &mut WindowContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Send + Sync + 'static, P: Send + Sync + 'static> IdentifiedElement for View<S, P> {}
|
impl<S: Send + Sync + 'static> IdentifiedElement for View<S> {}
|
||||||
|
|
||||||
|
impl<S: Send + Sync + 'static> ViewObject for View<S> {
|
||||||
|
fn entity_id(&self) -> EntityId {
|
||||||
|
self.state.id
|
||||||
|
}
|
||||||
|
|
||||||
impl<S: Send + Sync + 'static, P: Send + Sync + 'static> ViewObject for View<S, P> {
|
|
||||||
fn layout(&mut self, cx: &mut WindowContext) -> (LayoutId, AnyBox) {
|
fn layout(&mut self, cx: &mut WindowContext) -> (LayoutId, AnyBox) {
|
||||||
cx.with_element_id(IdentifiedElement::element_id(self), |cx| {
|
cx.with_element_id(IdentifiedElement::element_id(self), |cx| {
|
||||||
self.state.update(cx, |state, cx| {
|
self.state.update(cx, |state, cx| {
|
||||||
|
@ -111,17 +168,28 @@ impl<S: Send + Sync + 'static, P: Send + Sync + 'static> ViewObject for View<S,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct AnyView<S> {
|
pub struct AnyView {
|
||||||
view: Arc<Mutex<dyn ViewObject>>,
|
view: Arc<Mutex<dyn ViewObject>>,
|
||||||
parent_state_type: PhantomData<S>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: 'static + Send + Sync> Element for AnyView<S> {
|
impl<ParentViewState> IntoAnyElement<ParentViewState> for AnyView
|
||||||
|
where
|
||||||
|
ParentViewState: 'static + Send + Sync,
|
||||||
|
{
|
||||||
|
fn into_any(self) -> AnyElement<ParentViewState> {
|
||||||
|
AnyElement::new(EraseAnyViewState {
|
||||||
|
view: self,
|
||||||
|
parent_view_state_type: PhantomData,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Element for AnyView {
|
||||||
type ViewState = ();
|
type ViewState = ();
|
||||||
type ElementState = AnyBox;
|
type ElementState = AnyBox;
|
||||||
|
|
||||||
fn element_id(&self) -> Option<crate::ElementId> {
|
fn element_id(&self) -> Option<crate::ElementId> {
|
||||||
None
|
Some(ElementId::View(self.view.lock().entity_id()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn layout(
|
fn layout(
|
||||||
|
@ -144,11 +212,55 @@ impl<S: 'static + Send + Sync> Element for AnyView<S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S> Clone for AnyView<S> {
|
struct EraseAnyViewState<ParentViewState> {
|
||||||
|
view: AnyView,
|
||||||
|
parent_view_state_type: PhantomData<ParentViewState>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<ParentViewState> IntoAnyElement<ParentViewState> for EraseAnyViewState<ParentViewState>
|
||||||
|
where
|
||||||
|
ParentViewState: 'static + Send + Sync,
|
||||||
|
{
|
||||||
|
fn into_any(self) -> AnyElement<ParentViewState> {
|
||||||
|
AnyElement::new(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<ParentViewState> Element for EraseAnyViewState<ParentViewState>
|
||||||
|
where
|
||||||
|
ParentViewState: 'static + Send + Sync,
|
||||||
|
{
|
||||||
|
type ViewState = ParentViewState;
|
||||||
|
type ElementState = AnyBox;
|
||||||
|
|
||||||
|
fn element_id(&self) -> Option<crate::ElementId> {
|
||||||
|
Element::element_id(&self.view)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn layout(
|
||||||
|
&mut self,
|
||||||
|
_: &mut Self::ViewState,
|
||||||
|
_: Option<Self::ElementState>,
|
||||||
|
cx: &mut ViewContext<Self::ViewState>,
|
||||||
|
) -> (LayoutId, Self::ElementState) {
|
||||||
|
self.view.view.lock().layout(cx)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn paint(
|
||||||
|
&mut self,
|
||||||
|
bounds: Bounds<Pixels>,
|
||||||
|
_: &mut Self::ViewState,
|
||||||
|
element: &mut Self::ElementState,
|
||||||
|
cx: &mut ViewContext<Self::ViewState>,
|
||||||
|
) {
|
||||||
|
self.view.view.lock().paint(bounds, element, cx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Clone for AnyView {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Self {
|
Self {
|
||||||
view: self.view.clone(),
|
view: self.view.clone(),
|
||||||
parent_state_type: PhantomData,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ pub struct Window {
|
||||||
rem_size: Pixels,
|
rem_size: Pixels,
|
||||||
content_size: Size<Pixels>,
|
content_size: Size<Pixels>,
|
||||||
layout_engine: TaffyLayoutEngine,
|
layout_engine: TaffyLayoutEngine,
|
||||||
pub(crate) root_view: Option<AnyView<()>>,
|
pub(crate) root_view: Option<AnyView>,
|
||||||
pub(crate) element_id_stack: GlobalElementId,
|
pub(crate) element_id_stack: GlobalElementId,
|
||||||
prev_element_states: HashMap<GlobalElementId, AnyBox>,
|
prev_element_states: HashMap<GlobalElementId, AnyBox>,
|
||||||
element_states: HashMap<GlobalElementId, AnyBox>,
|
element_states: HashMap<GlobalElementId, AnyBox>,
|
||||||
|
@ -624,7 +624,7 @@ impl<'a, 'w> WindowContext<'a, 'w> {
|
||||||
});
|
});
|
||||||
|
|
||||||
fn draw_with_element_state(
|
fn draw_with_element_state(
|
||||||
root_view: &mut AnyView<()>,
|
root_view: &mut AnyView,
|
||||||
element_state: Option<AnyBox>,
|
element_state: Option<AnyBox>,
|
||||||
cx: &mut ViewContext<()>,
|
cx: &mut ViewContext<()>,
|
||||||
) -> AnyBox {
|
) -> AnyBox {
|
||||||
|
|
|
@ -8,7 +8,7 @@ pub struct CollabPanel {
|
||||||
scroll_state: ScrollState,
|
scroll_state: ScrollState,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn collab_panel<S: 'static>(cx: &mut WindowContext) -> View<CollabPanel, S> {
|
pub fn collab_panel(cx: &mut WindowContext) -> View<CollabPanel> {
|
||||||
view(cx.entity(|cx| CollabPanel::new(cx)), CollabPanel::render)
|
view(cx.entity(|cx| CollabPanel::new(cx)), CollabPanel::render)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,17 +3,17 @@ use crate::{
|
||||||
themes::rose_pine,
|
themes::rose_pine,
|
||||||
};
|
};
|
||||||
use gpui3::{
|
use gpui3::{
|
||||||
div, img, svg, view, Context, Element, ParentElement, RootView, StyleHelpers, Styled, View,
|
div, img, svg, view, Context, Element, ParentElement, StyleHelpers, Styled, View, ViewContext,
|
||||||
ViewContext, WindowContext,
|
WindowContext,
|
||||||
};
|
};
|
||||||
use ui::{theme, themed};
|
use ui::{theme, themed};
|
||||||
|
|
||||||
pub struct Workspace {
|
pub struct Workspace {
|
||||||
left_panel: View<CollabPanel, Self>,
|
left_panel: View<CollabPanel>,
|
||||||
right_panel: View<CollabPanel, Self>,
|
right_panel: View<CollabPanel>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn workspace(cx: &mut WindowContext) -> RootView<Workspace> {
|
pub fn workspace(cx: &mut WindowContext) -> View<Workspace> {
|
||||||
view(cx.entity(|cx| Workspace::new(cx)), Workspace::render)
|
view(cx.entity(|cx| Workspace::new(cx)), Workspace::render)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -116,7 +116,7 @@ pub struct Workspace {
|
||||||
bottom_panel_scroll_state: ScrollState,
|
bottom_panel_scroll_state: ScrollState,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn workspace<P: 'static>(cx: &mut WindowContext) -> View<Workspace, P> {
|
fn workspace<P: 'static>(cx: &mut WindowContext) -> View<Workspace> {
|
||||||
view(cx.entity(|cx| Workspace::new()), Workspace::render)
|
view(cx.entity(|cx| Workspace::new()), Workspace::render)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -377,11 +377,11 @@ mod stories {
|
||||||
// state_type: PhantomData<S>,
|
// state_type: PhantomData<S>,
|
||||||
// }
|
// }
|
||||||
|
|
||||||
pub struct WorkspaceStory<P> {
|
pub struct WorkspaceStory {
|
||||||
workspace: View<Workspace, P>,
|
workspace: View<Workspace>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn workspace_story<P: 'static + Send + Sync>(cx: &mut WindowContext) -> View<WorkspaceStory<P>, P> {
|
pub fn workspace_story(cx: &mut WindowContext) -> View<WorkspaceStory> {
|
||||||
todo!()
|
todo!()
|
||||||
// let workspace = workspace::<P>(cx);
|
// let workspace = workspace::<P>(cx);
|
||||||
// view(
|
// view(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue