Move self in Element::paint
Remove mutable state borrows in favor of state ownership in render processes to streamline element rendering.
This commit is contained in:
@@ -600,7 +600,7 @@ impl<V: 'static> ParentComponent<V> for Div<V> {
|
||||
}
|
||||
|
||||
impl<V: 'static> Element<V> for Div<V> {
|
||||
type ElementState = DivState;
|
||||
type State = DivState;
|
||||
|
||||
fn element_id(&self) -> Option<ElementId> {
|
||||
self.interactivity.element_id.clone()
|
||||
@@ -609,9 +609,9 @@ impl<V: 'static> Element<V> for Div<V> {
|
||||
fn layout(
|
||||
&mut self,
|
||||
view_state: &mut V,
|
||||
element_state: Option<Self::ElementState>,
|
||||
element_state: Option<Self::State>,
|
||||
cx: &mut ViewContext<V>,
|
||||
) -> (LayoutId, Self::ElementState) {
|
||||
) -> (LayoutId, Self::State) {
|
||||
let mut child_layout_ids = SmallVec::new();
|
||||
let mut interactivity = mem::take(&mut self.interactivity);
|
||||
let (layout_id, interactive_state) = interactivity.layout(
|
||||
@@ -639,10 +639,10 @@ impl<V: 'static> Element<V> for Div<V> {
|
||||
}
|
||||
|
||||
fn paint(
|
||||
&mut self,
|
||||
self,
|
||||
bounds: Bounds<Pixels>,
|
||||
view_state: &mut V,
|
||||
element_state: &mut Self::ElementState,
|
||||
element_state: &mut Self::State,
|
||||
cx: &mut ViewContext<V>,
|
||||
) {
|
||||
let mut child_min = point(Pixels::MAX, Pixels::MAX);
|
||||
@@ -658,8 +658,7 @@ impl<V: 'static> Element<V> for Div<V> {
|
||||
(child_max - child_min).into()
|
||||
};
|
||||
|
||||
let mut interactivity = mem::take(&mut self.interactivity);
|
||||
interactivity.paint(
|
||||
self.interactivity.paint(
|
||||
bounds,
|
||||
content_size,
|
||||
&mut element_state.interactive_state,
|
||||
@@ -679,7 +678,7 @@ impl<V: 'static> Element<V> for Div<V> {
|
||||
cx.with_text_style(style.text_style().cloned(), |cx| {
|
||||
cx.with_content_mask(style.overflow_mask(bounds), |cx| {
|
||||
cx.with_element_offset(scroll_offset, |cx| {
|
||||
for child in &mut self.children {
|
||||
for child in self.children {
|
||||
child.paint(view_state, cx);
|
||||
}
|
||||
})
|
||||
@@ -689,7 +688,6 @@ impl<V: 'static> Element<V> for Div<V> {
|
||||
})
|
||||
},
|
||||
);
|
||||
self.interactivity = interactivity;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -770,7 +768,7 @@ where
|
||||
}
|
||||
|
||||
pub fn paint(
|
||||
&mut self,
|
||||
mut self,
|
||||
bounds: Bounds<Pixels>,
|
||||
content_size: Size<Pixels>,
|
||||
element_state: &mut InteractiveElementState,
|
||||
@@ -786,25 +784,25 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
for listener in self.mouse_down_listeners.drain(..) {
|
||||
for listener in self.mouse_down_listeners {
|
||||
cx.on_mouse_event(move |state, event: &MouseDownEvent, phase, cx| {
|
||||
listener(state, event, &bounds, phase, cx);
|
||||
})
|
||||
}
|
||||
|
||||
for listener in self.mouse_up_listeners.drain(..) {
|
||||
for listener in self.mouse_up_listeners {
|
||||
cx.on_mouse_event(move |state, event: &MouseUpEvent, phase, cx| {
|
||||
listener(state, event, &bounds, phase, cx);
|
||||
})
|
||||
}
|
||||
|
||||
for listener in self.mouse_move_listeners.drain(..) {
|
||||
for listener in self.mouse_move_listeners {
|
||||
cx.on_mouse_event(move |state, event: &MouseMoveEvent, phase, cx| {
|
||||
listener(state, event, &bounds, phase, cx);
|
||||
})
|
||||
}
|
||||
|
||||
for listener in self.scroll_wheel_listeners.drain(..) {
|
||||
for listener in self.scroll_wheel_listeners {
|
||||
cx.on_mouse_event(move |state, event: &ScrollWheelEvent, phase, cx| {
|
||||
listener(state, event, &bounds, phase, cx);
|
||||
})
|
||||
@@ -840,7 +838,7 @@ where
|
||||
}
|
||||
|
||||
if cx.active_drag.is_some() {
|
||||
let drop_listeners = mem::take(&mut self.drop_listeners);
|
||||
let drop_listeners = self.drop_listeners;
|
||||
cx.on_mouse_event(move |view, event: &MouseUpEvent, phase, cx| {
|
||||
if phase == DispatchPhase::Bubble && bounds.contains_point(&event.position) {
|
||||
if let Some(drag_state_type) =
|
||||
@@ -1062,24 +1060,24 @@ where
|
||||
self.key_context.clone(),
|
||||
element_state.focus_handle.clone(),
|
||||
|_, cx| {
|
||||
for listener in self.key_down_listeners.drain(..) {
|
||||
for listener in self.key_down_listeners {
|
||||
cx.on_key_event(move |state, event: &KeyDownEvent, phase, cx| {
|
||||
listener(state, event, phase, cx);
|
||||
})
|
||||
}
|
||||
|
||||
for listener in self.key_up_listeners.drain(..) {
|
||||
for listener in self.key_up_listeners {
|
||||
cx.on_key_event(move |state, event: &KeyUpEvent, phase, cx| {
|
||||
listener(state, event, phase, cx);
|
||||
})
|
||||
}
|
||||
|
||||
for (action_type, listener) in self.action_listeners.drain(..) {
|
||||
for (action_type, listener) in self.action_listeners {
|
||||
cx.on_action(action_type, listener)
|
||||
}
|
||||
|
||||
if let Some(focus_handle) = element_state.focus_handle.as_ref() {
|
||||
for listener in self.focus_listeners.drain(..) {
|
||||
for listener in self.focus_listeners {
|
||||
let focus_handle = focus_handle.clone();
|
||||
cx.on_focus_changed(move |view, event, cx| {
|
||||
listener(view, &focus_handle, event, cx)
|
||||
@@ -1291,7 +1289,7 @@ where
|
||||
V: 'static,
|
||||
E: Element<V>,
|
||||
{
|
||||
type ElementState = E::ElementState;
|
||||
type State = E::State;
|
||||
|
||||
fn element_id(&self) -> Option<ElementId> {
|
||||
self.element.element_id()
|
||||
@@ -1300,20 +1298,20 @@ where
|
||||
fn layout(
|
||||
&mut self,
|
||||
view_state: &mut V,
|
||||
element_state: Option<Self::ElementState>,
|
||||
element_state: Option<Self::State>,
|
||||
cx: &mut ViewContext<V>,
|
||||
) -> (LayoutId, Self::ElementState) {
|
||||
) -> (LayoutId, Self::State) {
|
||||
self.element.layout(view_state, element_state, cx)
|
||||
}
|
||||
|
||||
fn paint(
|
||||
&mut self,
|
||||
self,
|
||||
bounds: Bounds<Pixels>,
|
||||
view_state: &mut V,
|
||||
element_state: &mut Self::ElementState,
|
||||
element_state: &mut Self::State,
|
||||
cx: &mut ViewContext<V>,
|
||||
) {
|
||||
self.element.paint(bounds, view_state, element_state, cx);
|
||||
self.element.paint(bounds, view_state, element_state, cx)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1377,7 +1375,7 @@ where
|
||||
V: 'static,
|
||||
E: Element<V>,
|
||||
{
|
||||
type ElementState = E::ElementState;
|
||||
type State = E::State;
|
||||
|
||||
fn element_id(&self) -> Option<ElementId> {
|
||||
self.element.element_id()
|
||||
@@ -1386,17 +1384,17 @@ where
|
||||
fn layout(
|
||||
&mut self,
|
||||
view_state: &mut V,
|
||||
element_state: Option<Self::ElementState>,
|
||||
element_state: Option<Self::State>,
|
||||
cx: &mut ViewContext<V>,
|
||||
) -> (LayoutId, Self::ElementState) {
|
||||
) -> (LayoutId, Self::State) {
|
||||
self.element.layout(view_state, element_state, cx)
|
||||
}
|
||||
|
||||
fn paint(
|
||||
&mut self,
|
||||
self,
|
||||
bounds: Bounds<Pixels>,
|
||||
view_state: &mut V,
|
||||
element_state: &mut Self::ElementState,
|
||||
element_state: &mut Self::State,
|
||||
cx: &mut ViewContext<V>,
|
||||
) {
|
||||
self.element.paint(bounds, view_state, element_state, cx)
|
||||
|
||||
@@ -42,7 +42,7 @@ impl<V> Component<V> for Img<V> {
|
||||
}
|
||||
|
||||
impl<V> Element<V> for Img<V> {
|
||||
type ElementState = InteractiveElementState;
|
||||
type State = InteractiveElementState;
|
||||
|
||||
fn element_id(&self) -> Option<crate::ElementId> {
|
||||
self.interactivity.element_id.clone()
|
||||
@@ -51,19 +51,19 @@ impl<V> Element<V> for Img<V> {
|
||||
fn layout(
|
||||
&mut self,
|
||||
_view_state: &mut V,
|
||||
element_state: Option<Self::ElementState>,
|
||||
element_state: Option<Self::State>,
|
||||
cx: &mut ViewContext<V>,
|
||||
) -> (LayoutId, Self::ElementState) {
|
||||
) -> (LayoutId, Self::State) {
|
||||
self.interactivity.layout(element_state, cx, |style, cx| {
|
||||
cx.request_layout(&style, None)
|
||||
})
|
||||
}
|
||||
|
||||
fn paint(
|
||||
&mut self,
|
||||
self,
|
||||
bounds: Bounds<Pixels>,
|
||||
_view_state: &mut V,
|
||||
element_state: &mut Self::ElementState,
|
||||
element_state: &mut Self::State,
|
||||
cx: &mut ViewContext<V>,
|
||||
) {
|
||||
self.interactivity.paint(
|
||||
|
||||
@@ -64,7 +64,7 @@ impl<V: 'static> Component<V> for Overlay<V> {
|
||||
}
|
||||
|
||||
impl<V: 'static> Element<V> for Overlay<V> {
|
||||
type ElementState = OverlayState;
|
||||
type State = OverlayState;
|
||||
|
||||
fn element_id(&self) -> Option<crate::ElementId> {
|
||||
None
|
||||
@@ -73,9 +73,9 @@ impl<V: 'static> Element<V> for Overlay<V> {
|
||||
fn layout(
|
||||
&mut self,
|
||||
view_state: &mut V,
|
||||
_: Option<Self::ElementState>,
|
||||
_: Option<Self::State>,
|
||||
cx: &mut crate::ViewContext<V>,
|
||||
) -> (crate::LayoutId, Self::ElementState) {
|
||||
) -> (crate::LayoutId, Self::State) {
|
||||
let child_layout_ids = self
|
||||
.children
|
||||
.iter_mut()
|
||||
@@ -92,10 +92,10 @@ impl<V: 'static> Element<V> for Overlay<V> {
|
||||
}
|
||||
|
||||
fn paint(
|
||||
&mut self,
|
||||
self,
|
||||
bounds: crate::Bounds<crate::Pixels>,
|
||||
view_state: &mut V,
|
||||
element_state: &mut Self::ElementState,
|
||||
element_state: &mut Self::State,
|
||||
cx: &mut crate::ViewContext<V>,
|
||||
) {
|
||||
if element_state.child_layout_ids.is_empty() {
|
||||
@@ -156,7 +156,7 @@ impl<V: 'static> Element<V> for Overlay<V> {
|
||||
}
|
||||
|
||||
cx.with_element_offset(desired.origin - bounds.origin, |cx| {
|
||||
for child in &mut self.children {
|
||||
for child in self.children {
|
||||
child.paint(view_state, cx);
|
||||
}
|
||||
})
|
||||
|
||||
@@ -31,7 +31,7 @@ impl<V> Component<V> for Svg<V> {
|
||||
}
|
||||
|
||||
impl<V> Element<V> for Svg<V> {
|
||||
type ElementState = InteractiveElementState;
|
||||
type State = InteractiveElementState;
|
||||
|
||||
fn element_id(&self) -> Option<ElementId> {
|
||||
self.interactivity.element_id.clone()
|
||||
@@ -40,19 +40,19 @@ impl<V> Element<V> for Svg<V> {
|
||||
fn layout(
|
||||
&mut self,
|
||||
_view_state: &mut V,
|
||||
element_state: Option<Self::ElementState>,
|
||||
element_state: Option<Self::State>,
|
||||
cx: &mut ViewContext<V>,
|
||||
) -> (LayoutId, Self::ElementState) {
|
||||
) -> (LayoutId, Self::State) {
|
||||
self.interactivity.layout(element_state, cx, |style, cx| {
|
||||
cx.request_layout(&style, None)
|
||||
})
|
||||
}
|
||||
|
||||
fn paint(
|
||||
&mut self,
|
||||
self,
|
||||
bounds: Bounds<Pixels>,
|
||||
_view_state: &mut V,
|
||||
element_state: &mut Self::ElementState,
|
||||
element_state: &mut Self::State,
|
||||
cx: &mut ViewContext<V>,
|
||||
) where
|
||||
Self: Sized,
|
||||
|
||||
@@ -9,7 +9,7 @@ use std::{cell::Cell, rc::Rc, sync::Arc};
|
||||
use util::ResultExt;
|
||||
|
||||
impl<V: 'static> Element<V> for &'static str {
|
||||
type ElementState = TextState;
|
||||
type State = TextState;
|
||||
|
||||
fn element_id(&self) -> Option<ElementId> {
|
||||
None
|
||||
@@ -18,16 +18,16 @@ impl<V: 'static> Element<V> for &'static str {
|
||||
fn layout(
|
||||
&mut self,
|
||||
_: &mut V,
|
||||
_: Option<Self::ElementState>,
|
||||
_: Option<Self::State>,
|
||||
cx: &mut ViewContext<V>,
|
||||
) -> (LayoutId, Self::ElementState) {
|
||||
) -> (LayoutId, Self::State) {
|
||||
let mut state = TextState::default();
|
||||
let layout_id = state.layout(SharedString::from(*self), None, cx);
|
||||
(layout_id, state)
|
||||
}
|
||||
|
||||
fn paint(
|
||||
&mut self,
|
||||
self,
|
||||
bounds: Bounds<Pixels>,
|
||||
_: &mut V,
|
||||
state: &mut TextState,
|
||||
@@ -38,7 +38,7 @@ impl<V: 'static> Element<V> for &'static str {
|
||||
}
|
||||
|
||||
impl<V: 'static> Element<V> for SharedString {
|
||||
type ElementState = TextState;
|
||||
type State = TextState;
|
||||
|
||||
fn element_id(&self) -> Option<ElementId> {
|
||||
Some(self.clone().into())
|
||||
@@ -47,16 +47,16 @@ impl<V: 'static> Element<V> for SharedString {
|
||||
fn layout(
|
||||
&mut self,
|
||||
_: &mut V,
|
||||
_: Option<Self::ElementState>,
|
||||
_: Option<Self::State>,
|
||||
cx: &mut ViewContext<V>,
|
||||
) -> (LayoutId, Self::ElementState) {
|
||||
) -> (LayoutId, Self::State) {
|
||||
let mut state = TextState::default();
|
||||
let layout_id = state.layout(self.clone(), None, cx);
|
||||
(layout_id, state)
|
||||
}
|
||||
|
||||
fn paint(
|
||||
&mut self,
|
||||
self,
|
||||
bounds: Bounds<Pixels>,
|
||||
_: &mut V,
|
||||
state: &mut TextState,
|
||||
@@ -93,7 +93,7 @@ impl<V: 'static> Component<V> for Text {
|
||||
}
|
||||
|
||||
impl<V: 'static> Element<V> for Text {
|
||||
type ElementState = TextState;
|
||||
type State = TextState;
|
||||
|
||||
fn element_id(&self) -> Option<crate::ElementId> {
|
||||
None
|
||||
@@ -102,9 +102,9 @@ impl<V: 'static> Element<V> for Text {
|
||||
fn layout(
|
||||
&mut self,
|
||||
_view: &mut V,
|
||||
element_state: Option<Self::ElementState>,
|
||||
element_state: Option<Self::State>,
|
||||
cx: &mut ViewContext<V>,
|
||||
) -> (LayoutId, Self::ElementState) {
|
||||
) -> (LayoutId, Self::State) {
|
||||
let element_state = element_state.unwrap_or_default();
|
||||
let text_system = cx.text_system().clone();
|
||||
let text_style = cx.text_style();
|
||||
@@ -160,10 +160,10 @@ impl<V: 'static> Element<V> for Text {
|
||||
}
|
||||
|
||||
fn paint(
|
||||
&mut self,
|
||||
self,
|
||||
bounds: Bounds<Pixels>,
|
||||
_: &mut V,
|
||||
element_state: &mut Self::ElementState,
|
||||
element_state: &mut Self::State,
|
||||
cx: &mut ViewContext<V>,
|
||||
) {
|
||||
let element_state = element_state.lock();
|
||||
@@ -280,7 +280,7 @@ struct InteractiveTextState {
|
||||
}
|
||||
|
||||
impl<V: 'static> Element<V> for InteractiveText {
|
||||
type ElementState = InteractiveTextState;
|
||||
type State = InteractiveTextState;
|
||||
|
||||
fn element_id(&self) -> Option<ElementId> {
|
||||
Some(self.id.clone())
|
||||
@@ -289,9 +289,9 @@ impl<V: 'static> Element<V> for InteractiveText {
|
||||
fn layout(
|
||||
&mut self,
|
||||
view_state: &mut V,
|
||||
element_state: Option<Self::ElementState>,
|
||||
element_state: Option<Self::State>,
|
||||
cx: &mut ViewContext<V>,
|
||||
) -> (LayoutId, Self::ElementState) {
|
||||
) -> (LayoutId, Self::State) {
|
||||
if let Some(InteractiveTextState {
|
||||
text_state,
|
||||
clicked_range_ixs,
|
||||
@@ -314,10 +314,10 @@ impl<V: 'static> Element<V> for InteractiveText {
|
||||
}
|
||||
|
||||
fn paint(
|
||||
&mut self,
|
||||
self,
|
||||
bounds: Bounds<Pixels>,
|
||||
view_state: &mut V,
|
||||
element_state: &mut Self::ElementState,
|
||||
element_state: &mut Self::State,
|
||||
cx: &mut ViewContext<V>,
|
||||
) {
|
||||
self.text
|
||||
|
||||
@@ -4,7 +4,7 @@ use crate::{
|
||||
Point, Size, StyleRefinement, Styled, ViewContext,
|
||||
};
|
||||
use smallvec::SmallVec;
|
||||
use std::{cell::RefCell, cmp, mem, ops::Range, rc::Rc};
|
||||
use std::{cell::RefCell, cmp, ops::Range, rc::Rc};
|
||||
use taffy::style::Overflow;
|
||||
|
||||
/// uniform_list provides lazy rendering for a set of items that are of uniform height.
|
||||
@@ -102,7 +102,7 @@ pub struct UniformListState {
|
||||
}
|
||||
|
||||
impl<V: 'static> Element<V> for UniformList<V> {
|
||||
type ElementState = UniformListState;
|
||||
type State = UniformListState;
|
||||
|
||||
fn element_id(&self) -> Option<crate::ElementId> {
|
||||
Some(self.id.clone())
|
||||
@@ -111,9 +111,9 @@ impl<V: 'static> Element<V> for UniformList<V> {
|
||||
fn layout(
|
||||
&mut self,
|
||||
view_state: &mut V,
|
||||
element_state: Option<Self::ElementState>,
|
||||
element_state: Option<Self::State>,
|
||||
cx: &mut ViewContext<V>,
|
||||
) -> (LayoutId, Self::ElementState) {
|
||||
) -> (LayoutId, Self::State) {
|
||||
let max_items = self.item_count;
|
||||
let rem_size = cx.rem_size();
|
||||
let item_size = element_state
|
||||
@@ -159,10 +159,10 @@ impl<V: 'static> Element<V> for UniformList<V> {
|
||||
}
|
||||
|
||||
fn paint(
|
||||
&mut self,
|
||||
self,
|
||||
bounds: Bounds<crate::Pixels>,
|
||||
view_state: &mut V,
|
||||
element_state: &mut Self::ElementState,
|
||||
element_state: &mut Self::State,
|
||||
cx: &mut ViewContext<V>,
|
||||
) {
|
||||
let style =
|
||||
@@ -183,14 +183,17 @@ impl<V: 'static> Element<V> for UniformList<V> {
|
||||
height: item_size.height * self.item_count,
|
||||
};
|
||||
|
||||
let mut interactivity = mem::take(&mut self.interactivity);
|
||||
let shared_scroll_offset = element_state
|
||||
.interactive
|
||||
.scroll_offset
|
||||
.get_or_insert_with(Rc::default)
|
||||
.clone();
|
||||
|
||||
interactivity.paint(
|
||||
let item_height = self
|
||||
.measure_item(view_state, Some(padded_bounds.size.width), cx)
|
||||
.height;
|
||||
|
||||
self.interactivity.paint(
|
||||
bounds,
|
||||
content_size,
|
||||
&mut element_state.interactive,
|
||||
@@ -209,9 +212,6 @@ impl<V: 'static> Element<V> for UniformList<V> {
|
||||
style.paint(bounds, cx);
|
||||
|
||||
if self.item_count > 0 {
|
||||
let item_height = self
|
||||
.measure_item(view_state, Some(padded_bounds.size.width), cx)
|
||||
.height;
|
||||
if let Some(scroll_handle) = self.scroll_handle.clone() {
|
||||
scroll_handle.0.borrow_mut().replace(ScrollHandleState {
|
||||
item_height,
|
||||
@@ -233,9 +233,9 @@ impl<V: 'static> Element<V> for UniformList<V> {
|
||||
self.item_count,
|
||||
);
|
||||
|
||||
let mut items = (self.render_items)(view_state, visible_range.clone(), cx);
|
||||
let items = (self.render_items)(view_state, visible_range.clone(), cx);
|
||||
cx.with_z_index(1, |cx| {
|
||||
for (item, ix) in items.iter_mut().zip(visible_range) {
|
||||
for (item, ix) in items.into_iter().zip(visible_range) {
|
||||
let item_origin = padded_bounds.origin
|
||||
+ point(px(0.), item_height * ix + scroll_offset.y);
|
||||
let available_space = size(
|
||||
@@ -249,7 +249,6 @@ impl<V: 'static> Element<V> for UniformList<V> {
|
||||
})
|
||||
},
|
||||
);
|
||||
self.interactivity = interactivity;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user