Skip to content

Commit

Permalink
Only treat definite available grid space as indefinite when container…
Browse files Browse the repository at this point in the history
… size

is indefinite, and only do so for the final two track sizing steps.
  • Loading branch information
nicoburns committed Aug 13, 2023
1 parent ae53106 commit be7aeb1
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 16 deletions.
17 changes: 9 additions & 8 deletions src/compute/grid/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,14 +162,10 @@ pub fn compute(

let constrained_available_space = known_dimensions
.or(size)
.maybe_clamp(min_size, max_size)
.map(|size| size.map(AvailableSpace::Definite))
.unwrap_or(available_space.map(|space| match space {
// Available grid space should not depend on Definite available space as a grid is allowed
// to expand beyond it's available space
AvailableSpace::Definite(_) => AvailableSpace::MaxContent,
_ => space,
}));
.unwrap_or(available_space)
.maybe_clamp(min_size, max_size)
.maybe_max(padding_border_size);

let available_grid_space = Size {
width: constrained_available_space
Expand All @@ -180,7 +176,7 @@ pub fn compute(
.map_definite_value(|space| space - content_box_inset.vertical_axis_sum()),
};

let outer_node_size = known_dimensions.or(size.maybe_clamp(min_size, max_size).or(min_size));
let outer_node_size = known_dimensions.or(size).maybe_clamp(min_size, max_size).maybe_max(padding_border_size);
let mut inner_node_size = Size {
width: outer_node_size.width.map(|space| space - content_box_inset.horizontal_axis_sum()),
height: outer_node_size.height.map(|space| space - content_box_inset.vertical_axis_sum()),
Expand Down Expand Up @@ -245,6 +241,11 @@ pub fn compute(
let initial_row_sum = rows.iter().map(|track| track.base_size).sum::<f32>();
inner_node_size.height = inner_node_size.height.or_else(|| initial_row_sum.into());

#[cfg(feature = "debug")]
NODE_LOGGER.labelled_debug_log("initial_column_sum", initial_column_sum);
#[cfg(feature = "debug")]
NODE_LOGGER.labelled_debug_log("initial_row_sum", initial_row_sum);

// 6. Compute container size
let resolved_style_size = known_dimensions.or(style.size.maybe_resolve(parent_size));
let container_border_box = Size {
Expand Down
28 changes: 20 additions & 8 deletions src/compute/grid/track_sizing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,19 @@ pub(super) fn track_sizing_algorithm<Tree: LayoutTree>(
// Distributes free space (if any) to tracks with FINITE growth limits, up to their limits.
maximise_tracks(axis_tracks, inner_node_size.get(axis), available_grid_space.get(axis));

// For the purpose of the final two expansion steps ("Expand Flexible Tracks" and "Stretch auto Tracks"), we only want to expand
// into space generated by the grid container's size (as defined by either it's preferred size style or by it's parent node through
// something like stretch alignment), not just any available space. To do this we map definite available space to AvailableSpace::MaxContent
// in the case that inner_node_size is None
let axis_available_space_for_expansion = if let Some(available_space) = inner_node_size.get(axis) {
AvailableSpace::Definite(available_space)
} else {
match available_grid_space.get(axis) {
AvailableSpace::MinContent => AvailableSpace::MinContent,
AvailableSpace::MaxContent | AvailableSpace::Definite(_) => AvailableSpace::MaxContent,
}
};

// 11.7. Expand Flexible Tracks
// This step sizes flexible tracks using the largest value it can assign to an fr without exceeding the available space.
expand_flexible_tracks(
Expand All @@ -335,13 +348,13 @@ pub(super) fn track_sizing_algorithm<Tree: LayoutTree>(
items,
axis_min_size,
axis_max_size,
available_grid_space,
axis_available_space_for_expansion,
inner_node_size,
);

// 11.8. Stretch auto Tracks
// This step expands tracks that have an auto max track sizing function by dividing any remaining positive, definite free space equally amongst them.
stretch_auto_tracks(axis, axis_tracks, axis_min_size, available_grid_space);
stretch_auto_tracks(axis_tracks, axis_min_size, axis_available_space_for_expansion);
}

/// Whether it is a minimum or maximum size's space being distributed
Expand Down Expand Up @@ -1133,11 +1146,11 @@ fn expand_flexible_tracks(
items: &mut [GridItem],
axis_min_size: Option<f32>,
axis_max_size: Option<f32>,
available_grid_space: Size<AvailableSpace>,
axis_available_space_for_expansion: AvailableSpace,
inner_node_size: Size<Option<f32>>,
) {
// First, find the grid’s used flex fraction:
let flex_fraction = match available_grid_space.get(axis) {
let flex_fraction = match axis_available_space_for_expansion {
// If the free space is zero:
// The used flex fraction is zero.
// Otherwise, if the free space is a definite length:
Expand Down Expand Up @@ -1287,10 +1300,9 @@ fn find_size_of_fr(tracks: &[GridTrack], space_to_fill: f32) -> f32 {
/// This step expands tracks that have an auto max track sizing function by dividing any remaining positive, definite free space equally amongst them.
#[inline(always)]
fn stretch_auto_tracks(
axis: AbstractAxis,
axis_tracks: &mut [GridTrack],
axis_min_size: Option<f32>,
available_grid_space: Size<AvailableSpace>,
axis_available_space_for_expansion: AvailableSpace,
) {
let num_auto_tracks =
axis_tracks.iter().filter(|track| track.max_track_sizing_function == MaxTrackSizingFunction::Auto).count();
Expand All @@ -1299,8 +1311,8 @@ fn stretch_auto_tracks(

// If the free space is indefinite, but the grid container has a definite min-width/height
// use that size to calculate the free space for this step instead.
let free_space = if available_grid_space.get(axis).is_definite() {
available_grid_space.get(axis).compute_free_space(used_space)
let free_space = if axis_available_space_for_expansion.is_definite() {
axis_available_space_for_expansion.compute_free_space(used_space)
} else {
match axis_min_size {
Some(size) => size - used_space,
Expand Down

0 comments on commit be7aeb1

Please sign in to comment.