WIP
This commit is contained in:
parent
759ce7440c
commit
33a808a49b
8 changed files with 96 additions and 232 deletions
|
@ -10,21 +10,12 @@ pub trait Element<V: 'static> {
|
||||||
|
|
||||||
fn element_id(&self) -> Option<ElementId>;
|
fn element_id(&self) -> Option<ElementId>;
|
||||||
|
|
||||||
/// 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,
|
|
||||||
element_state: Option<Self::ElementState>,
|
|
||||||
cx: &mut ViewContext<V>,
|
|
||||||
) -> Self::ElementState;
|
|
||||||
|
|
||||||
fn layout(
|
fn layout(
|
||||||
&mut self,
|
&mut self,
|
||||||
view_state: &mut V,
|
view_state: &mut V,
|
||||||
element_state: &mut Self::ElementState,
|
previous_element_state: Option<Self::ElementState>,
|
||||||
cx: &mut ViewContext<V>,
|
cx: &mut ViewContext<V>,
|
||||||
) -> LayoutId;
|
) -> (LayoutId, Self::ElementState);
|
||||||
|
|
||||||
fn paint(
|
fn paint(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
@ -96,7 +87,6 @@ pub trait ParentComponent<V: 'static> {
|
||||||
}
|
}
|
||||||
|
|
||||||
trait ElementObject<V> {
|
trait ElementObject<V> {
|
||||||
fn initialize(&mut self, view_state: &mut V, cx: &mut ViewContext<V>);
|
|
||||||
fn layout(&mut self, view_state: &mut V, cx: &mut ViewContext<V>) -> LayoutId;
|
fn layout(&mut self, view_state: &mut V, cx: &mut ViewContext<V>) -> LayoutId;
|
||||||
fn paint(&mut self, view_state: &mut V, cx: &mut ViewContext<V>);
|
fn paint(&mut self, view_state: &mut V, cx: &mut ViewContext<V>);
|
||||||
fn measure(
|
fn measure(
|
||||||
|
@ -123,9 +113,6 @@ struct RenderedElement<V: 'static, E: Element<V>> {
|
||||||
enum ElementRenderPhase<V> {
|
enum ElementRenderPhase<V> {
|
||||||
#[default]
|
#[default]
|
||||||
Start,
|
Start,
|
||||||
Initialized {
|
|
||||||
frame_state: Option<V>,
|
|
||||||
},
|
|
||||||
LayoutRequested {
|
LayoutRequested {
|
||||||
layout_id: LayoutId,
|
layout_id: LayoutId,
|
||||||
frame_state: Option<V>,
|
frame_state: Option<V>,
|
||||||
|
@ -157,42 +144,19 @@ where
|
||||||
E: Element<V>,
|
E: Element<V>,
|
||||||
E::ElementState: 'static,
|
E::ElementState: 'static,
|
||||||
{
|
{
|
||||||
fn initialize(&mut self, view_state: &mut V, cx: &mut ViewContext<V>) {
|
|
||||||
let frame_state = if let Some(id) = self.element.element_id() {
|
|
||||||
cx.with_element_state(id, |element_state, cx| {
|
|
||||||
let element_state = self.element.initialize(view_state, element_state, cx);
|
|
||||||
((), element_state)
|
|
||||||
});
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
let frame_state = self.element.initialize(view_state, None, cx);
|
|
||||||
Some(frame_state)
|
|
||||||
};
|
|
||||||
|
|
||||||
self.phase = ElementRenderPhase::Initialized { frame_state };
|
|
||||||
}
|
|
||||||
|
|
||||||
fn layout(&mut self, state: &mut V, cx: &mut ViewContext<V>) -> LayoutId {
|
fn layout(&mut self, state: &mut V, cx: &mut ViewContext<V>) -> LayoutId {
|
||||||
let layout_id;
|
let (layout_id, frame_state) = match mem::take(&mut self.phase) {
|
||||||
let mut frame_state;
|
ElementRenderPhase::Start => {
|
||||||
match mem::take(&mut self.phase) {
|
|
||||||
ElementRenderPhase::Initialized {
|
|
||||||
frame_state: initial_frame_state,
|
|
||||||
} => {
|
|
||||||
frame_state = initial_frame_state;
|
|
||||||
if let Some(id) = self.element.element_id() {
|
if let Some(id) = self.element.element_id() {
|
||||||
layout_id = cx.with_element_state(id, |element_state, cx| {
|
let layout_id = cx.with_element_state(id, |element_state, cx| {
|
||||||
let mut element_state = element_state.unwrap();
|
self.element.layout(state, element_state, cx)
|
||||||
let layout_id = self.element.layout(state, &mut element_state, cx);
|
|
||||||
(layout_id, element_state)
|
|
||||||
});
|
});
|
||||||
|
(layout_id, None)
|
||||||
} else {
|
} else {
|
||||||
layout_id = self
|
let (layout_id, frame_state) = self.element.layout(state, None, cx);
|
||||||
.element
|
(layout_id, Some(frame_state))
|
||||||
.layout(state, frame_state.as_mut().unwrap(), cx);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ElementRenderPhase::Start => panic!("must call initialize before layout"),
|
|
||||||
ElementRenderPhase::LayoutRequested { .. }
|
ElementRenderPhase::LayoutRequested { .. }
|
||||||
| ElementRenderPhase::LayoutComputed { .. }
|
| ElementRenderPhase::LayoutComputed { .. }
|
||||||
| ElementRenderPhase::Painted { .. } => {
|
| ElementRenderPhase::Painted { .. } => {
|
||||||
|
@ -244,10 +208,6 @@ where
|
||||||
cx: &mut ViewContext<V>,
|
cx: &mut ViewContext<V>,
|
||||||
) -> Size<Pixels> {
|
) -> Size<Pixels> {
|
||||||
if matches!(&self.phase, ElementRenderPhase::Start) {
|
if matches!(&self.phase, ElementRenderPhase::Start) {
|
||||||
self.initialize(view_state, cx);
|
|
||||||
}
|
|
||||||
|
|
||||||
if matches!(&self.phase, ElementRenderPhase::Initialized { .. }) {
|
|
||||||
self.layout(view_state, cx);
|
self.layout(view_state, cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -290,10 +250,7 @@ where
|
||||||
cx: &mut ViewContext<V>,
|
cx: &mut ViewContext<V>,
|
||||||
) {
|
) {
|
||||||
self.measure(available_space, view_state, cx);
|
self.measure(available_space, view_state, cx);
|
||||||
// Ignore the element offset when drawing this element, as the origin is already specified
|
cx.with_absolute_element_offset(origin, |cx| self.paint(view_state, cx))
|
||||||
// in absolute terms.
|
|
||||||
origin -= cx.element_offset();
|
|
||||||
cx.with_element_offset(origin, |cx| self.paint(view_state, cx))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -309,10 +266,6 @@ impl<V> AnyElement<V> {
|
||||||
AnyElement(Box::new(RenderedElement::new(element)))
|
AnyElement(Box::new(RenderedElement::new(element)))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn initialize(&mut self, view_state: &mut V, cx: &mut ViewContext<V>) {
|
|
||||||
self.0.initialize(view_state, cx);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn layout(&mut self, view_state: &mut V, cx: &mut ViewContext<V>) -> LayoutId {
|
pub fn layout(&mut self, view_state: &mut V, cx: &mut ViewContext<V>) -> LayoutId {
|
||||||
self.0.layout(view_state, cx)
|
self.0.layout(view_state, cx)
|
||||||
}
|
}
|
||||||
|
@ -393,25 +346,16 @@ where
|
||||||
None
|
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();
|
|
||||||
let mut rendered_element = (render)(view_state, cx).render();
|
|
||||||
rendered_element.initialize(view_state, cx);
|
|
||||||
rendered_element
|
|
||||||
}
|
|
||||||
|
|
||||||
fn layout(
|
fn layout(
|
||||||
&mut self,
|
&mut self,
|
||||||
view_state: &mut V,
|
view_state: &mut V,
|
||||||
rendered_element: &mut Self::ElementState,
|
_: Option<Self::ElementState>,
|
||||||
cx: &mut ViewContext<V>,
|
cx: &mut ViewContext<V>,
|
||||||
) -> LayoutId {
|
) -> (LayoutId, Self::ElementState) {
|
||||||
rendered_element.layout(view_state, cx)
|
let render = self.take().unwrap();
|
||||||
|
let mut rendered_element = (render)(view_state, cx).render();
|
||||||
|
let layout_id = rendered_element.layout(view_state, cx);
|
||||||
|
(layout_id, rendered_element)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn paint(
|
fn paint(
|
||||||
|
|
|
@ -617,46 +617,36 @@ impl<V: 'static> Element<V> for Div<V> {
|
||||||
self.interactivity.element_id.clone()
|
self.interactivity.element_id.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn initialize(
|
fn layout(
|
||||||
&mut self,
|
&mut self,
|
||||||
view_state: &mut V,
|
view_state: &mut V,
|
||||||
element_state: Option<Self::ElementState>,
|
element_state: Option<Self::ElementState>,
|
||||||
cx: &mut ViewContext<V>,
|
cx: &mut ViewContext<V>,
|
||||||
) -> Self::ElementState {
|
) -> (LayoutId, Self::ElementState) {
|
||||||
let interactive_state = self
|
let mut child_layout_ids = SmallVec::new();
|
||||||
.interactivity
|
|
||||||
.initialize(element_state.map(|s| s.interactive_state), cx);
|
|
||||||
|
|
||||||
for child in &mut self.children {
|
|
||||||
child.initialize(view_state, cx);
|
|
||||||
}
|
|
||||||
|
|
||||||
DivState {
|
|
||||||
interactive_state,
|
|
||||||
child_layout_ids: SmallVec::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn layout(
|
|
||||||
&mut self,
|
|
||||||
view_state: &mut V,
|
|
||||||
element_state: &mut Self::ElementState,
|
|
||||||
cx: &mut ViewContext<V>,
|
|
||||||
) -> crate::LayoutId {
|
|
||||||
let mut interactivity = mem::take(&mut self.interactivity);
|
let mut interactivity = mem::take(&mut self.interactivity);
|
||||||
let layout_id =
|
let (layout_id, interactive_state) = interactivity.layout(
|
||||||
interactivity.layout(&mut element_state.interactive_state, cx, |style, cx| {
|
element_state.map(|s| s.interactive_state),
|
||||||
|
cx,
|
||||||
|
|style, cx| {
|
||||||
cx.with_text_style(style.text_style().cloned(), |cx| {
|
cx.with_text_style(style.text_style().cloned(), |cx| {
|
||||||
element_state.child_layout_ids = self
|
child_layout_ids = self
|
||||||
.children
|
.children
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.map(|child| child.layout(view_state, cx))
|
.map(|child| child.layout(view_state, cx))
|
||||||
.collect::<SmallVec<_>>();
|
.collect::<SmallVec<_>>();
|
||||||
cx.request_layout(&style, element_state.child_layout_ids.iter().copied())
|
cx.request_layout(&style, child_layout_ids.iter().copied())
|
||||||
})
|
})
|
||||||
});
|
},
|
||||||
|
);
|
||||||
self.interactivity = interactivity;
|
self.interactivity = interactivity;
|
||||||
layout_id
|
(
|
||||||
|
layout_id,
|
||||||
|
DivState {
|
||||||
|
interactive_state,
|
||||||
|
child_layout_ids,
|
||||||
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn paint(
|
fn paint(
|
||||||
|
@ -766,11 +756,12 @@ impl<V> Interactivity<V>
|
||||||
where
|
where
|
||||||
V: 'static,
|
V: 'static,
|
||||||
{
|
{
|
||||||
pub fn initialize(
|
pub fn layout(
|
||||||
&mut self,
|
&mut self,
|
||||||
element_state: Option<InteractiveElementState>,
|
element_state: Option<InteractiveElementState>,
|
||||||
cx: &mut ViewContext<V>,
|
cx: &mut ViewContext<V>,
|
||||||
) -> InteractiveElementState {
|
f: impl FnOnce(Style, &mut ViewContext<V>) -> LayoutId,
|
||||||
|
) -> (LayoutId, InteractiveElementState) {
|
||||||
let mut element_state = element_state.unwrap_or_default();
|
let mut element_state = element_state.unwrap_or_default();
|
||||||
|
|
||||||
// Ensure we store a focus handle in our element state if we're focusable.
|
// Ensure we store a focus handle in our element state if we're focusable.
|
||||||
|
@ -785,17 +776,9 @@ where
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
element_state
|
let style = self.compute_style(None, &mut element_state, cx);
|
||||||
}
|
let layout_id = f(style, cx);
|
||||||
|
(layout_id, element_state)
|
||||||
pub fn layout(
|
|
||||||
&mut self,
|
|
||||||
element_state: &mut InteractiveElementState,
|
|
||||||
cx: &mut ViewContext<V>,
|
|
||||||
f: impl FnOnce(Style, &mut ViewContext<V>) -> LayoutId,
|
|
||||||
) -> LayoutId {
|
|
||||||
let style = self.compute_style(None, element_state, cx);
|
|
||||||
f(style, cx)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn paint(
|
pub fn paint(
|
||||||
|
@ -1327,21 +1310,12 @@ where
|
||||||
self.element.element_id()
|
self.element.element_id()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn initialize(
|
fn layout(
|
||||||
&mut self,
|
&mut self,
|
||||||
view_state: &mut V,
|
view_state: &mut V,
|
||||||
element_state: Option<Self::ElementState>,
|
element_state: Option<Self::ElementState>,
|
||||||
cx: &mut ViewContext<V>,
|
cx: &mut ViewContext<V>,
|
||||||
) -> Self::ElementState {
|
) -> (LayoutId, Self::ElementState) {
|
||||||
self.element.initialize(view_state, element_state, cx)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn layout(
|
|
||||||
&mut self,
|
|
||||||
view_state: &mut V,
|
|
||||||
element_state: &mut Self::ElementState,
|
|
||||||
cx: &mut ViewContext<V>,
|
|
||||||
) -> LayoutId {
|
|
||||||
self.element.layout(view_state, element_state, cx)
|
self.element.layout(view_state, element_state, cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1422,21 +1396,12 @@ where
|
||||||
self.element.element_id()
|
self.element.element_id()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn initialize(
|
fn layout(
|
||||||
&mut self,
|
&mut self,
|
||||||
view_state: &mut V,
|
view_state: &mut V,
|
||||||
element_state: Option<Self::ElementState>,
|
element_state: Option<Self::ElementState>,
|
||||||
cx: &mut ViewContext<V>,
|
cx: &mut ViewContext<V>,
|
||||||
) -> Self::ElementState {
|
) -> (LayoutId, Self::ElementState) {
|
||||||
self.element.initialize(view_state, element_state, cx)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn layout(
|
|
||||||
&mut self,
|
|
||||||
view_state: &mut V,
|
|
||||||
element_state: &mut Self::ElementState,
|
|
||||||
cx: &mut ViewContext<V>,
|
|
||||||
) -> LayoutId {
|
|
||||||
self.element.layout(view_state, element_state, cx)
|
self.element.layout(view_state, element_state, cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,21 +48,12 @@ impl<V> Element<V> for Img<V> {
|
||||||
self.interactivity.element_id.clone()
|
self.interactivity.element_id.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn initialize(
|
fn layout(
|
||||||
&mut self,
|
&mut self,
|
||||||
_view_state: &mut V,
|
_view_state: &mut V,
|
||||||
element_state: Option<Self::ElementState>,
|
element_state: Option<Self::ElementState>,
|
||||||
cx: &mut ViewContext<V>,
|
cx: &mut ViewContext<V>,
|
||||||
) -> Self::ElementState {
|
) -> (LayoutId, Self::ElementState) {
|
||||||
self.interactivity.initialize(element_state, cx)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn layout(
|
|
||||||
&mut self,
|
|
||||||
_view_state: &mut V,
|
|
||||||
element_state: &mut Self::ElementState,
|
|
||||||
cx: &mut ViewContext<V>,
|
|
||||||
) -> LayoutId {
|
|
||||||
self.interactivity.layout(element_state, cx, |style, cx| {
|
self.interactivity.layout(element_state, cx, |style, cx| {
|
||||||
cx.request_layout(&style, None)
|
cx.request_layout(&style, None)
|
||||||
})
|
})
|
||||||
|
|
|
@ -37,21 +37,12 @@ impl<V> Element<V> for Svg<V> {
|
||||||
self.interactivity.element_id.clone()
|
self.interactivity.element_id.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn initialize(
|
fn layout(
|
||||||
&mut self,
|
&mut self,
|
||||||
_view_state: &mut V,
|
_view_state: &mut V,
|
||||||
element_state: Option<Self::ElementState>,
|
element_state: Option<Self::ElementState>,
|
||||||
cx: &mut ViewContext<V>,
|
cx: &mut ViewContext<V>,
|
||||||
) -> Self::ElementState {
|
) -> (LayoutId, Self::ElementState) {
|
||||||
self.interactivity.initialize(element_state, cx)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn layout(
|
|
||||||
&mut self,
|
|
||||||
_view_state: &mut V,
|
|
||||||
element_state: &mut Self::ElementState,
|
|
||||||
cx: &mut ViewContext<V>,
|
|
||||||
) -> LayoutId {
|
|
||||||
self.interactivity.layout(element_state, cx, |style, cx| {
|
self.interactivity.layout(element_state, cx, |style, cx| {
|
||||||
cx.request_layout(&style, None)
|
cx.request_layout(&style, None)
|
||||||
})
|
})
|
||||||
|
|
|
@ -76,21 +76,13 @@ impl<V: 'static> Element<V> for Text<V> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn initialize(
|
|
||||||
&mut self,
|
|
||||||
_view_state: &mut V,
|
|
||||||
element_state: Option<Self::ElementState>,
|
|
||||||
_cx: &mut ViewContext<V>,
|
|
||||||
) -> Self::ElementState {
|
|
||||||
element_state.unwrap_or_default()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn layout(
|
fn layout(
|
||||||
&mut self,
|
&mut self,
|
||||||
_view: &mut V,
|
_view: &mut V,
|
||||||
element_state: &mut Self::ElementState,
|
element_state: Option<Self::ElementState>,
|
||||||
cx: &mut ViewContext<V>,
|
cx: &mut ViewContext<V>,
|
||||||
) -> LayoutId {
|
) -> (LayoutId, Self::ElementState) {
|
||||||
|
let element_state = element_state.unwrap_or_default();
|
||||||
let text_system = cx.text_system().clone();
|
let text_system = cx.text_system().clone();
|
||||||
let text_style = cx.text_style();
|
let text_style = cx.text_style();
|
||||||
let font_size = text_style.font_size.to_pixels(cx.rem_size());
|
let font_size = text_style.font_size.to_pixels(cx.rem_size());
|
||||||
|
@ -148,7 +140,7 @@ impl<V: 'static> Element<V> for Text<V> {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
layout_id
|
(layout_id, element_state)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn paint(
|
fn paint(
|
||||||
|
|
|
@ -131,9 +131,9 @@ impl<V: 'static> Element<V> for UniformList<V> {
|
||||||
fn layout(
|
fn layout(
|
||||||
&mut self,
|
&mut self,
|
||||||
_view_state: &mut V,
|
_view_state: &mut V,
|
||||||
element_state: &mut Self::ElementState,
|
element_state: Option<Self::ElementState>,
|
||||||
cx: &mut ViewContext<V>,
|
cx: &mut ViewContext<V>,
|
||||||
) -> LayoutId {
|
) -> (LayoutId, Self::ElementState) {
|
||||||
let max_items = self.item_count;
|
let max_items = self.item_count;
|
||||||
let item_size = element_state.item_size;
|
let item_size = element_state.item_size;
|
||||||
let rem_size = cx.rem_size();
|
let rem_size = cx.rem_size();
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
private::Sealed, AnyBox, AnyElement, AnyModel, AnyWeakModel, AppContext, AvailableSpace,
|
private::Sealed, AnyBox, AnyElement, AnyModel, AnyWeakModel, AppContext, AvailableSpace,
|
||||||
Bounds, Component, Element, ElementId, Entity, EntityId, Flatten, LayoutId, Model, Pixels,
|
BorrowWindow, Bounds, Component, Element, ElementId, Entity, EntityId, Flatten, LayoutId,
|
||||||
Size, ViewContext, VisualContext, WeakModel, WindowContext,
|
Model, Pixels, Point, Size, ViewContext, VisualContext, WeakModel, WindowContext,
|
||||||
};
|
};
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
use std::{
|
use std::{
|
||||||
|
@ -155,8 +155,7 @@ impl<V> Eq for WeakView<V> {}
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct AnyView {
|
pub struct AnyView {
|
||||||
model: AnyModel,
|
model: AnyModel,
|
||||||
initialize: fn(&AnyView, &mut WindowContext) -> AnyBox,
|
layout: fn(&AnyView, &mut WindowContext) -> (LayoutId, Box<dyn Any>),
|
||||||
layout: fn(&AnyView, &mut AnyBox, &mut WindowContext) -> LayoutId,
|
|
||||||
paint: fn(&AnyView, &mut AnyBox, &mut WindowContext),
|
paint: fn(&AnyView, &mut AnyBox, &mut WindowContext),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,7 +163,6 @@ impl AnyView {
|
||||||
pub fn downgrade(&self) -> AnyWeakView {
|
pub fn downgrade(&self) -> AnyWeakView {
|
||||||
AnyWeakView {
|
AnyWeakView {
|
||||||
model: self.model.downgrade(),
|
model: self.model.downgrade(),
|
||||||
initialize: self.initialize,
|
|
||||||
layout: self.layout,
|
layout: self.layout,
|
||||||
paint: self.paint,
|
paint: self.paint,
|
||||||
}
|
}
|
||||||
|
@ -175,7 +173,6 @@ impl AnyView {
|
||||||
Ok(model) => Ok(View { model }),
|
Ok(model) => Ok(View { model }),
|
||||||
Err(model) => Err(Self {
|
Err(model) => Err(Self {
|
||||||
model,
|
model,
|
||||||
initialize: self.initialize,
|
|
||||||
layout: self.layout,
|
layout: self.layout,
|
||||||
paint: self.paint,
|
paint: self.paint,
|
||||||
}),
|
}),
|
||||||
|
@ -186,13 +183,19 @@ impl AnyView {
|
||||||
self.model.entity_type
|
self.model.entity_type
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn draw(&self, available_space: Size<AvailableSpace>, cx: &mut WindowContext) {
|
pub(crate) fn draw(
|
||||||
let mut rendered_element = (self.initialize)(self, cx);
|
&self,
|
||||||
let layout_id = (self.layout)(self, &mut rendered_element, cx);
|
origin: Point<Pixels>,
|
||||||
cx.window
|
available_space: Size<AvailableSpace>,
|
||||||
.layout_engine
|
cx: &mut WindowContext,
|
||||||
.compute_layout(layout_id, available_space);
|
) {
|
||||||
(self.paint)(self, &mut rendered_element, cx);
|
cx.with_absolute_element_offset(origin, |cx| {
|
||||||
|
let (layout_id, mut rendered_element) = (self.layout)(self, cx);
|
||||||
|
cx.window
|
||||||
|
.layout_engine
|
||||||
|
.compute_layout(layout_id, available_space);
|
||||||
|
(self.paint)(self, &mut rendered_element, cx);
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,7 +209,6 @@ impl<V: Render> From<View<V>> for AnyView {
|
||||||
fn from(value: View<V>) -> Self {
|
fn from(value: View<V>) -> Self {
|
||||||
AnyView {
|
AnyView {
|
||||||
model: value.model.into_any(),
|
model: value.model.into_any(),
|
||||||
initialize: any_view::initialize::<V>,
|
|
||||||
layout: any_view::layout::<V>,
|
layout: any_view::layout::<V>,
|
||||||
paint: any_view::paint::<V>,
|
paint: any_view::paint::<V>,
|
||||||
}
|
}
|
||||||
|
@ -220,21 +222,12 @@ impl<ParentViewState: 'static> Element<ParentViewState> for AnyView {
|
||||||
Some(self.model.entity_id.into())
|
Some(self.model.entity_id.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn initialize(
|
|
||||||
&mut self,
|
|
||||||
_view_state: &mut ParentViewState,
|
|
||||||
_element_state: Option<Self::ElementState>,
|
|
||||||
cx: &mut ViewContext<ParentViewState>,
|
|
||||||
) -> Self::ElementState {
|
|
||||||
(self.initialize)(self, cx)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn layout(
|
fn layout(
|
||||||
&mut self,
|
&mut self,
|
||||||
_view_state: &mut ParentViewState,
|
_view_state: &mut ParentViewState,
|
||||||
rendered_element: &mut Self::ElementState,
|
rendered_element: Option<Self::ElementState>,
|
||||||
cx: &mut ViewContext<ParentViewState>,
|
cx: &mut ViewContext<ParentViewState>,
|
||||||
) -> LayoutId {
|
) -> (LayoutId, Self::ElementState) {
|
||||||
(self.layout)(self, rendered_element, cx)
|
(self.layout)(self, rendered_element, cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,8 +244,7 @@ impl<ParentViewState: 'static> Element<ParentViewState> for AnyView {
|
||||||
|
|
||||||
pub struct AnyWeakView {
|
pub struct AnyWeakView {
|
||||||
model: AnyWeakModel,
|
model: AnyWeakModel,
|
||||||
initialize: fn(&AnyView, &mut WindowContext) -> AnyBox,
|
layout: fn(&AnyView, &mut WindowContext) -> (LayoutId, Box<dyn Any>),
|
||||||
layout: fn(&AnyView, &mut AnyBox, &mut WindowContext) -> LayoutId,
|
|
||||||
paint: fn(&AnyView, &mut AnyBox, &mut WindowContext),
|
paint: fn(&AnyView, &mut AnyBox, &mut WindowContext),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,7 +253,6 @@ impl AnyWeakView {
|
||||||
let model = self.model.upgrade()?;
|
let model = self.model.upgrade()?;
|
||||||
Some(AnyView {
|
Some(AnyView {
|
||||||
model,
|
model,
|
||||||
initialize: self.initialize,
|
|
||||||
layout: self.layout,
|
layout: self.layout,
|
||||||
paint: self.paint,
|
paint: self.paint,
|
||||||
})
|
})
|
||||||
|
@ -272,7 +263,6 @@ impl<V: Render> From<WeakView<V>> for AnyWeakView {
|
||||||
fn from(view: WeakView<V>) -> Self {
|
fn from(view: WeakView<V>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
model: view.model.into(),
|
model: view.model.into(),
|
||||||
initialize: any_view::initialize::<V>,
|
|
||||||
layout: any_view::layout::<V>,
|
layout: any_view::layout::<V>,
|
||||||
paint: any_view::paint::<V>,
|
paint: any_view::paint::<V>,
|
||||||
}
|
}
|
||||||
|
@ -319,28 +309,19 @@ where
|
||||||
Some(self.view.entity_id().into())
|
Some(self.view.entity_id().into())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn initialize(
|
fn layout(
|
||||||
&mut self,
|
&mut self,
|
||||||
_: &mut ParentViewState,
|
_: &mut ParentViewState,
|
||||||
_: Option<Self::ElementState>,
|
_: Option<Self::ElementState>,
|
||||||
cx: &mut ViewContext<ParentViewState>,
|
cx: &mut ViewContext<ParentViewState>,
|
||||||
) -> Self::ElementState {
|
) -> (LayoutId, Self::ElementState) {
|
||||||
self.view.update(cx, |view, cx| {
|
self.view.update(cx, |view, cx| {
|
||||||
let mut element = self.component.take().unwrap().render();
|
let mut element = self.component.take().unwrap().render();
|
||||||
element.initialize(view, cx);
|
let layout_id = element.layout(view, cx);
|
||||||
element
|
(layout_id, element)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn layout(
|
|
||||||
&mut self,
|
|
||||||
_: &mut ParentViewState,
|
|
||||||
element: &mut Self::ElementState,
|
|
||||||
cx: &mut ViewContext<ParentViewState>,
|
|
||||||
) -> LayoutId {
|
|
||||||
self.view.update(cx, |view, cx| element.layout(view, cx))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn paint(
|
fn paint(
|
||||||
&mut self,
|
&mut self,
|
||||||
_: Bounds<Pixels>,
|
_: Bounds<Pixels>,
|
||||||
|
@ -356,27 +337,17 @@ mod any_view {
|
||||||
use crate::{AnyElement, AnyView, BorrowWindow, LayoutId, Render, WindowContext};
|
use crate::{AnyElement, AnyView, BorrowWindow, LayoutId, Render, WindowContext};
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
|
|
||||||
pub(crate) fn initialize<V: Render>(view: &AnyView, cx: &mut WindowContext) -> Box<dyn Any> {
|
|
||||||
cx.with_element_id(Some(view.model.entity_id), |cx| {
|
|
||||||
let view = view.clone().downcast::<V>().unwrap();
|
|
||||||
let element = view.update(cx, |view, cx| {
|
|
||||||
let mut element = AnyElement::new(view.render(cx));
|
|
||||||
element.initialize(view, cx);
|
|
||||||
element
|
|
||||||
});
|
|
||||||
Box::new(element)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn layout<V: Render>(
|
pub(crate) fn layout<V: Render>(
|
||||||
view: &AnyView,
|
view: &AnyView,
|
||||||
element: &mut Box<dyn Any>,
|
|
||||||
cx: &mut WindowContext,
|
cx: &mut WindowContext,
|
||||||
) -> LayoutId {
|
) -> (LayoutId, Box<dyn Any>) {
|
||||||
cx.with_element_id(Some(view.model.entity_id), |cx| {
|
cx.with_element_id(Some(view.model.entity_id), |cx| {
|
||||||
let view = view.clone().downcast::<V>().unwrap();
|
let view = view.clone().downcast::<V>().unwrap();
|
||||||
let element = element.downcast_mut::<AnyElement<V>>().unwrap();
|
view.update(cx, |view, cx| {
|
||||||
view.update(cx, |view, cx| element.layout(view, cx))
|
let mut element = AnyElement::new(view.render(cx));
|
||||||
|
let layout_id = element.layout(view, cx);
|
||||||
|
(layout_id, Box::new(element) as Box<dyn Any>)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1633,8 +1633,8 @@ pub trait BorrowWindow: BorrowMut<Window> + BorrowMut<AppContext> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update the global element offset based on the given offset. This is used to implement
|
/// Update the global element offset relative to the current offset. This is used to implement
|
||||||
/// scrolling and position drag handles.
|
/// scrolling.
|
||||||
fn with_element_offset<R>(
|
fn with_element_offset<R>(
|
||||||
&mut self,
|
&mut self,
|
||||||
offset: Point<Pixels>,
|
offset: Point<Pixels>,
|
||||||
|
@ -1644,7 +1644,17 @@ pub trait BorrowWindow: BorrowMut<Window> + BorrowMut<AppContext> {
|
||||||
return f(self);
|
return f(self);
|
||||||
};
|
};
|
||||||
|
|
||||||
let offset = self.element_offset() + offset;
|
let abs_offset = self.element_offset() + offset;
|
||||||
|
self.with_absolute_element_offset(abs_offset, f)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Update the global element offset based on the given offset. This is used to implement
|
||||||
|
/// drag handles and other manual painting of elements.
|
||||||
|
fn with_absolute_element_offset<R>(
|
||||||
|
&mut self,
|
||||||
|
offset: Point<Pixels>,
|
||||||
|
f: impl FnOnce(&mut Self) -> R,
|
||||||
|
) -> R {
|
||||||
self.window_mut()
|
self.window_mut()
|
||||||
.current_frame
|
.current_frame
|
||||||
.element_offset_stack
|
.element_offset_stack
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue