Skip to content

Commit

Permalink
Fix percent sized tracks (#314)
Browse files Browse the repository at this point in the history
* Fix FromPercent implementations for Dimension and LengthPercentage(Auto)

They were previously incorrectly returning the Points variant rather
than the Percent variant.

* Add more combinator functions to AvailableSpace

* Implement re-resolving percentage track sizes in the case of indefinite container size

* Rename tests for items with percentage sizes to percent_items_*

* Adds tests for percentage sized grid tracks
  • Loading branch information
nicoburns committed Jan 5, 2023
1 parent 320118e commit 06a168c
Show file tree
Hide file tree
Showing 32 changed files with 750 additions and 21 deletions.
27 changes: 27 additions & 0 deletions benches/generated/grid_percent_tracks_definite_overflow.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

27 changes: 27 additions & 0 deletions benches/generated/grid_percent_tracks_definite_underflow.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 23 additions & 0 deletions benches/generated/grid_percent_tracks_indefinite_only.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

36 changes: 28 additions & 8 deletions benches/generated/mod.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 22 additions & 2 deletions src/compute/grid/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,27 @@ pub fn compute(
height: container_border_box.height - padding.vertical_axis_sum() - border.vertical_axis_sum(),
};

// 7. Track Alignment
// 7. Resolve percentage track base sizes
// In the case of an indefinitely sized container these resolve to zero during the "Initialise Tracks" step
// and therefore need to be re-resolved here based on the content-sized content box of the container
if !available_grid_space.width.is_definite() {
for column in &mut columns {
let min: Option<f32> =
column.min_track_sizing_function.resolved_percentage_size(container_content_box.width);
let max: Option<f32> =
column.max_track_sizing_function.resolved_percentage_size(container_content_box.width);
column.base_size = column.base_size.maybe_clamp(min, max);
}
}
if !available_grid_space.height.is_definite() {
for row in &mut rows {
let min: Option<f32> = row.min_track_sizing_function.resolved_percentage_size(container_content_box.height);
let max: Option<f32> = row.max_track_sizing_function.resolved_percentage_size(container_content_box.height);
row.base_size = row.base_size.maybe_clamp(min, max);
}
}

// 8. Track Alignment

// Align columns
align_tracks(
Expand All @@ -242,7 +262,7 @@ pub fn compute(
style.align_content.unwrap_or(AlignContent::Stretch),
);

// 8. Size, Align, and Position Grid Items
// 9. Size, Align, and Position Grid Items

// Sort items back into original order to allow them to be matched up with styles
items.sort_by_key(|item| item.source_order);
Expand Down
27 changes: 24 additions & 3 deletions src/style/dimension.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ impl FromPoints for LengthPercentage {
}
impl FromPercent for LengthPercentage {
fn from_percent<Input: Into<f32> + Copy>(percent: Input) -> Self {
Self::Points(percent.into())
Self::Percent(percent.into())
}
}

Expand Down Expand Up @@ -57,7 +57,7 @@ impl FromPoints for LengthPercentageAuto {
}
impl FromPercent for LengthPercentageAuto {
fn from_percent<Input: Into<f32> + Copy>(percent: Input) -> Self {
Self::Points(percent.into())
Self::Percent(percent.into())
}
}

Expand Down Expand Up @@ -111,7 +111,7 @@ impl FromPoints for Dimension {
}
impl FromPercent for Dimension {
fn from_percent<Input: Into<f32> + Copy>(percent: Input) -> Self {
Self::Points(percent.into())
Self::Percent(percent.into())
}
}

Expand Down Expand Up @@ -226,6 +226,27 @@ impl AvailableSpace {
self.into_option().unwrap()
}

/// Return self if definite or a default value
pub fn or(self, default: AvailableSpace) -> AvailableSpace {
match self {
AvailableSpace::Definite(_) => self,
_ => default,
}
}

/// Return self if definite or a the result of the default value callback
pub fn or_else(self, default_cb: impl FnOnce() -> AvailableSpace) -> AvailableSpace {
match self {
AvailableSpace::Definite(_) => self,
_ => default_cb(),
}
}

/// Return the definite value or the result of the default value callback
pub fn unwrap_or_else(self, default_cb: impl FnOnce() -> f32) -> f32 {
self.into_option().unwrap_or_else(default_cb)
}

/// If passed value is Some then return AvailableSpace::Definite containing that value, else return self
pub fn maybe_set(self, value: Option<f32>) -> AvailableSpace {
match value {
Expand Down
22 changes: 22 additions & 0 deletions src/style/grid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,17 @@ impl MaxTrackSizingFunction {
MinContent | MaxContent | FitContent(_) | Auto | Flex(_) => None,
}
}

/// Resolve percentage values against the passed parent_size, returning Some(value)
/// Non-percentage values always return None.
#[inline(always)]
pub fn resolved_percentage_size(self, parent_size: f32) -> Option<f32> {
use MaxTrackSizingFunction::{Auto, *};
match self {
Fixed(LengthPercentage::Percent(fraction)) => Some(fraction * parent_size),
Fixed(LengthPercentage::Points(_)) | MinContent | MaxContent | FitContent(_) | Auto | Flex(_) => None,
}
}
}

/// Minimum track sizing function
Expand Down Expand Up @@ -380,6 +391,17 @@ impl MinTrackSizingFunction {
MinContent | MaxContent | Auto => None,
}
}

/// Resolve percentage values against the passed parent_size, returning Some(value)
/// Non-percentage values always return None.
#[inline(always)]
pub fn resolved_percentage_size(self, parent_size: f32) -> Option<f32> {
use MinTrackSizingFunction::{Auto, *};
match self {
Fixed(LengthPercentage::Percent(fraction)) => Some(fraction * parent_size),
Fixed(LengthPercentage::Points(_)) | MinContent | MaxContent | Auto => None,
}
}
}

/// The sizing function for a grid track (row/column) (either auto-track or template track)
Expand Down
22 changes: 22 additions & 0 deletions test_fixtures/grid_percent_tracks_definite_overflow.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<!DOCTYPE html>
<html lang="en">
<head>
<script src="../scripts/gentest/test_helper.js"></script>
<link rel="stylesheet" type="text/css" href="../scripts/gentest/test_base_style.css">
<title>
Test description
</title>
<head/>
<body>

<div id="test-root" style="height: 60px; width: 120px; display: grid; grid-template-columns: 40% 40% 40%;grid-template-rows: 50% 80%;">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>

</body>
</html>
22 changes: 22 additions & 0 deletions test_fixtures/grid_percent_tracks_definite_underflow.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<!DOCTYPE html>
<html lang="en">
<head>
<script src="../scripts/gentest/test_helper.js"></script>
<link rel="stylesheet" type="text/css" href="../scripts/gentest/test_base_style.css">
<title>
Test description
</title>
<head/>
<body>

<div id="test-root" style="height: 60px; width: 120px; display: grid; grid-template-columns: 10% 20% 30%;grid-template-rows: 30% 60%;">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>

</body>
</html>

0 comments on commit 06a168c

Please sign in to comment.