Extract AnyElement::{measure,draw}

Co-Authored-By: Nathan Sobo <nathan@zed.dev>
This commit is contained in:
Antonio Scandurra 2023-11-09 17:30:41 +01:00
parent ad3b0bd227
commit cfee1401ed
2 changed files with 44 additions and 25 deletions

View file

@ -1,4 +1,6 @@
use crate::{BorrowWindow, Bounds, ElementId, LayoutId, Pixels, ViewContext};
use crate::{
AvailableSpace, BorrowWindow, Bounds, ElementId, LayoutId, Pixels, Point, Size, ViewContext,
};
use derive_more::{Deref, DerefMut};
pub(crate) use smallvec::SmallVec;
use std::{any::Any, mem};
@ -196,6 +198,33 @@ impl<V> AnyElement<V> {
pub fn paint(&mut self, view_state: &mut V, cx: &mut ViewContext<V>) {
self.0.paint(view_state, cx)
}
/// Initializes this element and performs layout within the given available space to determine its size.
pub fn measure(
&mut self,
available_space: Size<AvailableSpace>,
view_state: &mut V,
cx: &mut ViewContext<V>,
) -> Size<Pixels> {
self.initialize(view_state, cx);
let layout_id = self.layout(view_state, cx);
cx.compute_layout(layout_id, available_space);
cx.layout_bounds(layout_id).size
}
/// Initializes this element and performs layout in the available space, then paints it at the given origin.
pub fn draw(
&mut self,
origin: Point<Pixels>,
available_space: Size<AvailableSpace>,
view_state: &mut V,
cx: &mut ViewContext<V>,
) {
self.initialize(view_state, cx);
let layout_id = self.layout(view_state, cx);
cx.compute_layout(layout_id, available_space);
cx.with_element_offset(Some(origin), |cx| self.paint(view_state, cx))
}
}
pub trait Component<V> {

View file

@ -1,6 +1,6 @@
use crate::{
point, px, AnyElement, AvailableSpace, BorrowWindow, Bounds, Component, Element, ElementId,
ElementInteractivity, InteractiveElementState, LayoutId, Pixels, Point, Size,
point, px, size, AnyElement, AvailableSpace, BorrowWindow, Bounds, Component, Element,
ElementId, ElementInteractivity, InteractiveElementState, LayoutId, Pixels, Point, Size,
StatefulInteractive, StatefulInteractivity, StatelessInteractive, StatelessInteractivity,
StyleRefinement, Styled, ViewContext,
};
@ -165,19 +165,13 @@ impl<V: 'static> Element<V> for UniformList<V> {
cx.with_z_index(1, |cx| {
for (item, ix) in items.iter_mut().zip(visible_range) {
item.initialize(view_state, cx);
let layout_id = item.layout(view_state, cx);
cx.compute_layout(
layout_id,
Size {
width: AvailableSpace::Definite(bounds.size.width),
height: AvailableSpace::Definite(item_height),
},
);
let offset =
let item_origin =
padded_bounds.origin + point(px(0.), item_height * ix + scroll_offset);
cx.with_element_offset(Some(offset), |cx| item.paint(view_state, cx))
let available_space = size(
AvailableSpace::Definite(bounds.size.width),
AvailableSpace::Definite(item_height),
);
item.draw(item_origin, available_space, view_state, cx);
}
});
} else {
@ -205,18 +199,14 @@ impl<V> UniformList<V> {
cx: &mut ViewContext<V>,
) -> Pixels {
let mut items = (self.render_items)(view_state, 0..1, cx);
debug_assert!(items.len() == 1);
debug_assert_eq!(items.len(), 1);
let mut item_to_measure = items.pop().unwrap();
item_to_measure.initialize(view_state, cx);
let layout_id = item_to_measure.layout(view_state, cx);
cx.compute_layout(
layout_id,
Size {
width: AvailableSpace::Definite(list_bounds.size.width),
height: AvailableSpace::MinContent,
},
let available_space = size(
AvailableSpace::Definite(list_bounds.size.width),
AvailableSpace::MinContent,
);
cx.layout_bounds(layout_id).size.height
let size = item_to_measure.measure(available_space, view_state, cx);
size.height
}
pub fn track_scroll(mut self, handle: UniformListScrollHandle) -> Self {