diff --git a/crates/gpui2/src/element.rs b/crates/gpui2/src/element.rs index 8fdc17de07..775b3b8a89 100644 --- a/crates/gpui2/src/element.rs +++ b/crates/gpui2/src/element.rs @@ -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 AnyElement { pub fn paint(&mut self, view_state: &mut V, cx: &mut ViewContext) { 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, + view_state: &mut V, + cx: &mut ViewContext, + ) -> Size { + 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, + available_space: Size, + view_state: &mut V, + cx: &mut ViewContext, + ) { + 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 { diff --git a/crates/gpui2/src/elements/uniform_list.rs b/crates/gpui2/src/elements/uniform_list.rs index e116022763..a4524d5496 100644 --- a/crates/gpui2/src/elements/uniform_list.rs +++ b/crates/gpui2/src/elements/uniform_list.rs @@ -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 Element for UniformList { 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 UniformList { cx: &mut ViewContext, ) -> 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 {