Perform a full layout of List when width changes

Co-Authored-By: Nathan Sobo <nathan@zed.dev>
This commit is contained in:
Antonio Scandurra 2021-08-23 16:04:23 +02:00
parent 03b7c3c8c6
commit bd89dc4114

View file

@ -59,36 +59,44 @@ impl Element for List {
constraint: crate::SizeConstraint,
cx: &mut crate::LayoutContext,
) -> (Vector2F, Self::LayoutState) {
// TODO: Fully invalidate if width has changed since the last layout.
let state = &mut *self.state.0.lock();
let mut old_heights = state.heights.cursor::<PendingCount, ElementHeightSummary>();
let mut new_heights = old_heights.slice(&PendingCount(1), sum_tree::Bias::Left, &());
let mut item_constraint = constraint;
item_constraint.min.set_y(0.);
item_constraint.max.set_y(f32::INFINITY);
while let Some(height) = old_heights.item() {
if height.is_pending() {
let size =
state.elements[old_heights.sum_start().count].layout(item_constraint, cx);
new_heights.push(ElementHeight::Ready(size.y()), &());
old_heights.next(&());
} else {
new_heights.push_tree(
old_heights.slice(
&PendingCount(old_heights.sum_start().pending_count + 1),
Bias::Left,
if state.last_layout_width == constraint.max.x() {
let mut old_heights = state.heights.cursor::<PendingCount, ElementHeightSummary>();
let mut new_heights = old_heights.slice(&PendingCount(1), sum_tree::Bias::Left, &());
while let Some(height) = old_heights.item() {
if height.is_pending() {
let size =
state.elements[old_heights.sum_start().count].layout(item_constraint, cx);
new_heights.push(ElementHeight::Ready(size.y()), &());
old_heights.next(&());
} else {
new_heights.push_tree(
old_heights.slice(
&PendingCount(old_heights.sum_start().pending_count + 1),
Bias::Left,
&(),
),
&(),
),
&(),
);
);
}
}
drop(old_heights);
state.heights = new_heights;
} else {
state.heights = SumTree::new();
for element in &mut state.elements {
let size = element.layout(item_constraint, cx);
state.heights.push(ElementHeight::Ready(size.y()), &());
}
state.last_layout_width = constraint.max.x();
}
drop(old_heights);
state.heights = new_heights;
(constraint.max, ())
}