Skip to content

Commit

Permalink
feat: New fill mode for width and height
Browse files Browse the repository at this point in the history
  • Loading branch information
marc2332 committed Nov 2, 2023
1 parent dacf9fc commit c0d128b
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 4 deletions.
2 changes: 2 additions & 0 deletions crates/state/src/values/size.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ impl Parse for Size {
fn parse(value: &str) -> Result<Self, Self::Err> {
if value == "auto" {
Ok(Size::Inner)
} else if value == "fill" {
Ok(Size::Fill)
} else if value.contains("calc") {
Ok(Size::DynamicCalculations(parse_calc(value)?))
} else if value.contains('%') {
Expand Down
6 changes: 6 additions & 0 deletions crates/torin/src/measure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ pub fn measure_node<Key: NodeKey>(
area.size.width = node.width.min_max(
area.size.width,
parent_area.size.width,
available_parent_area.size.width,
node.margin.left(),
node.margin.horizontal(),
&node.minimum_width,
Expand All @@ -47,6 +48,7 @@ pub fn measure_node<Key: NodeKey>(
area.size.height = node.height.min_max(
area.size.height,
parent_area.size.height,
available_parent_area.size.height,
node.margin.top(),
node.margin.vertical(),
&node.minimum_height,
Expand All @@ -66,6 +68,7 @@ pub fn measure_node<Key: NodeKey>(
area.size.width = node.width.min_max(
custom_area.width(),
parent_area.size.width,
available_parent_area.size.width,
node.margin.left(),
node.margin.horizontal(),
&node.minimum_width,
Expand All @@ -76,6 +79,7 @@ pub fn measure_node<Key: NodeKey>(
area.size.height = node.height.min_max(
custom_area.height(),
parent_area.size.height,
available_parent_area.size.height,
node.margin.top(),
node.margin.vertical(),
&node.minimum_height,
Expand All @@ -99,6 +103,7 @@ pub fn measure_node<Key: NodeKey>(
inner_area.size.width = node.width.min_max(
available_parent_area.width(),
parent_area.size.width,
available_parent_area.width(),
node.margin.left(),
node.margin.horizontal(),
&node.minimum_width,
Expand All @@ -109,6 +114,7 @@ pub fn measure_node<Key: NodeKey>(
inner_area.size.height = node.height.min_max(
available_parent_area.height(),
parent_area.size.height,
available_parent_area.height(),
node.margin.top(),
node.margin.vertical(),
&node.minimum_height,
Expand Down
20 changes: 16 additions & 4 deletions crates/torin/src/values/size.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ pub enum Size {
Percentage(Length),
Pixels(Length),
DynamicCalculations(Vec<DynamicCalculation>),
Fill,
}

impl Default for Size {
Expand All @@ -31,35 +32,46 @@ impl Size {
.join(" ")
),
Size::Percentage(p) => format!("{}%", p.get()),
Size::Fill => "fill".to_string(),
}
}

pub fn eval(&self, parent_value: f32, parent_margin: f32) -> Option<f32> {
pub fn eval(
&self,
parent_value: f32,
available_parent_value: f32,
parent_margin: f32,
) -> Option<f32> {
match self {
Size::Pixels(px) => Some(px.get() + parent_margin),
Size::Percentage(per) => Some(parent_value / 100.0 * per.get()),
Size::DynamicCalculations(calculations) => {
Some(run_calculations(calculations, parent_value))
}
Size::Fill => Some(available_parent_value),
_ => None,
}
}

#[allow(clippy::too_many_arguments)]
pub fn min_max(
&self,
value: f32,
parent_value: f32,
available_parent_value: f32,
single_margin: f32,
margin: f32,
minimum: &Self,
maximum: &Self,
) -> f32 {
let value = self.eval(parent_value, margin).unwrap_or(value + margin);
let value = self
.eval(parent_value, available_parent_value, margin)
.unwrap_or(value + margin);

let minimum_value = minimum
.eval(parent_value, margin)
.eval(parent_value, available_parent_value, margin)
.map(|v| v + single_margin);
let maximum_value = maximum.eval(parent_value, margin);
let maximum_value = maximum.eval(parent_value, available_parent_value, margin);

let mut final_value = value;

Expand Down
54 changes: 54 additions & 0 deletions crates/torin/tests/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1364,3 +1364,57 @@ pub fn unsized_parent_with_padding() {
Rect::new(Point2D::new(40.0, 10.0), Size2D::new(940.0, 960.0)),
);
}

#[test]
pub fn fill_size() {
let (mut layout, mut measurer) = test_utils();

let mut mocked_dom = TestingDOM::default();
mocked_dom.add(
0,
None,
vec![1, 2],
Node::from_size_and_direction(
Size::Percentage(Length::new(100.0)),
Size::Percentage(Length::new(100.0)),
DirectionMode::Vertical,
),
);
mocked_dom.add(
1,
Some(0),
vec![],
Node::from_size_and_direction(
Size::Percentage(Length::new(100.0)),
Size::Pixels(Length::new(300.0)),
DirectionMode::Vertical,
),
);
mocked_dom.add(
2,
Some(0),
vec![],
Node::from_size_and_direction(
Size::Percentage(Length::new(100.0)),
Size::Fill,
DirectionMode::Vertical,
),
);

layout.measure(
0,
Rect::new(Point2D::new(0.0, 0.0), Size2D::new(1000.0, 1000.0)),
&mut measurer,
&mut mocked_dom,
);

assert_eq!(
layout.get(1).unwrap().visible_area().round(),
Rect::new(Point2D::new(0.0, 0.0), Size2D::new(1000.0, 300.0)),
);

assert_eq!(
layout.get(2).unwrap().visible_area().round(),
Rect::new(Point2D::new(0.0, 300.0), Size2D::new(1000.0, 700.0)),
);
}
27 changes: 27 additions & 0 deletions examples/fill_size.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#![cfg_attr(
all(not(debug_assertions), target_os = "windows"),
windows_subsystem = "windows"
)]

use freya::prelude::*;

fn main() {
launch_with_props(app, "Counter", (400.0, 350.0));
}

fn app(cx: Scope) -> Element {
render!(
rect {
height: "50%",
min_height: "150",
max_height: "300",
width: "100%",
background: "rgb(0, 119, 182)",
}
rect {
height: "fill",
width: "100%",
background: "rgb(20, 150, 220)",
}
)
}

0 comments on commit c0d128b

Please sign in to comment.