diff --git a/crates/state/src/values/size.rs b/crates/state/src/values/size.rs index 1d3a175e2..51948aa67 100644 --- a/crates/state/src/values/size.rs +++ b/crates/state/src/values/size.rs @@ -2,16 +2,10 @@ use nom::{ branch::alt, bytes::complete::tag, character::complete::multispace0, - combinator::{ - map, - opt, - }, + combinator::map, multi::many1, number::complete::float, - sequence::{ - preceded, - tuple, - }, + sequence::preceded, IResult, }; use torin::{ @@ -99,6 +93,31 @@ pub fn parse_calc(mut value: &str) -> Result, ParseError map(tag("clamp"), |_| { DynamicCalculation::Function(LexFunction::Clamp) }), + map(tag("scale"), |_| DynamicCalculation::ScalingFactor), + map(tag("parent.width"), |_| { + DynamicCalculation::Parent(Dimension::Width) + }), + map(tag("parent.height"), |_| { + DynamicCalculation::Parent(Dimension::Height) + }), + map(tag("parent.other"), |_| { + DynamicCalculation::Parent(Dimension::Other) + }), + map(tag("parent"), |_| { + DynamicCalculation::Parent(Dimension::Current) + }), + map(tag("root.width"), |_| { + DynamicCalculation::Parent(Dimension::Width) + }), + map(tag("root.height"), |_| { + DynamicCalculation::Parent(Dimension::Height) + }), + map(tag("root.other"), |_| { + DynamicCalculation::Parent(Dimension::Other) + }), + map(tag("root"), |_| { + DynamicCalculation::Parent(Dimension::Current) + }), map(tag("+"), |_| DynamicCalculation::Add), map(tag("-"), |_| DynamicCalculation::Sub), map(tag("*"), |_| DynamicCalculation::Mul), @@ -106,26 +125,6 @@ pub fn parse_calc(mut value: &str) -> Result, ParseError map(tag("("), |_| DynamicCalculation::OpenParenthesis), map(tag(")"), |_| DynamicCalculation::ClosedParenthesis), map(tag(","), |_| DynamicCalculation::FunctionSeparator), - map( - tuple((float, tag("%"), opt(tag("'")))), - |(v, _, inv): (f32, _, Option<&str>)| { - if inv.is_some() { - DynamicCalculation::Percentage(Dimension::Other(v)) - } else { - DynamicCalculation::Percentage(Dimension::Current(v)) - } - }, - ), - map( - tuple((float, tag("v"), opt(tag("'")))), - |(v, _, inv): (f32, _, Option<&str>)| { - if inv.is_some() { - DynamicCalculation::RootPercentage(Dimension::Other(v)) - } else { - DynamicCalculation::RootPercentage(Dimension::Current(v)) - } - }, - ), map(float, DynamicCalculation::Pixels), )), ))(value) diff --git a/crates/state/tests/parse_size.rs b/crates/state/tests/parse_size.rs index adc4c8c0c..aaa49d888 100644 --- a/crates/state/tests/parse_size.rs +++ b/crates/state/tests/parse_size.rs @@ -29,44 +29,51 @@ fn parse_auto_size() { #[test] fn parse_calc_size() { - let size = Size::parse("calc(90%- 5%* 123.6/ 50v(5 + 6) - min(50v, 50v', 100%, 100%') max(50v) clamp(50v, 5.0, 100%))"); + let size = Size::parse("calc(min(max(clamp(1, 2, 3), 4), parent.width + root.height - root.other * 2 / 1, scale, parent, root, parent.height, parent.other, +5.0, -3.0))"); assert_eq!( size, Ok(Size::DynamicCalculations(Box::new(vec![ - DynamicCalculation::Percentage(Dimension::Current(90.0)), - DynamicCalculation::Sub, - DynamicCalculation::Percentage(Dimension::Current(5.0)), - DynamicCalculation::Mul, - DynamicCalculation::Pixels(123.6), - DynamicCalculation::Div, - DynamicCalculation::RootPercentage(Dimension::Current(50.0)), - DynamicCalculation::OpenParenthesis, - DynamicCalculation::Pixels(5.0), - DynamicCalculation::Add, - DynamicCalculation::Pixels(6.0), - DynamicCalculation::ClosedParenthesis, - DynamicCalculation::Sub, DynamicCalculation::Function(LexFunction::Min), DynamicCalculation::OpenParenthesis, - DynamicCalculation::RootPercentage(Dimension::Current(50.0)), - DynamicCalculation::FunctionSeparator, - DynamicCalculation::RootPercentage(Dimension::Other(50.0)), - DynamicCalculation::FunctionSeparator, - DynamicCalculation::Percentage(Dimension::Current(100.0)), - DynamicCalculation::FunctionSeparator, - DynamicCalculation::Percentage(Dimension::Other(100.0)), - DynamicCalculation::ClosedParenthesis, DynamicCalculation::Function(LexFunction::Max), DynamicCalculation::OpenParenthesis, - DynamicCalculation::RootPercentage(Dimension::Current(50.0)), - DynamicCalculation::ClosedParenthesis, DynamicCalculation::Function(LexFunction::Clamp), DynamicCalculation::OpenParenthesis, - DynamicCalculation::RootPercentage(Dimension::Current(50.0)), + DynamicCalculation::Pixels(1.0), + DynamicCalculation::FunctionSeparator, + DynamicCalculation::Pixels(2.0), + DynamicCalculation::FunctionSeparator, + DynamicCalculation::Pixels(3.0), + DynamicCalculation::ClosedParenthesis, + DynamicCalculation::FunctionSeparator, + DynamicCalculation::Pixels(4.0), + DynamicCalculation::ClosedParenthesis, + DynamicCalculation::FunctionSeparator, + DynamicCalculation::Parent(Dimension::Width), + DynamicCalculation::Add, + DynamicCalculation::Root(Dimension::Height), + DynamicCalculation::Sub, + DynamicCalculation::Root(Dimension::Other), + DynamicCalculation::Mul, + DynamicCalculation::Pixels(2.0), + DynamicCalculation::Div, + DynamicCalculation::Pixels(1.0), DynamicCalculation::FunctionSeparator, + DynamicCalculation::ScalingFactor, + DynamicCalculation::FunctionSeparator, + DynamicCalculation::Parent(Dimension::Current), + DynamicCalculation::FunctionSeparator, + DynamicCalculation::Root(Dimension::Current), + DynamicCalculation::FunctionSeparator, + DynamicCalculation::Parent(Dimension::Height), + DynamicCalculation::FunctionSeparator, + DynamicCalculation::Parent(Dimension::Other), + DynamicCalculation::FunctionSeparator, + DynamicCalculation::Add, DynamicCalculation::Pixels(5.0), DynamicCalculation::FunctionSeparator, - DynamicCalculation::Percentage(Dimension::Current(100.0)), + DynamicCalculation::Sub, + DynamicCalculation::Pixels(3.0), DynamicCalculation::ClosedParenthesis, ]))) ); diff --git a/crates/torin/src/measure.rs b/crates/torin/src/measure.rs index 887c86bb6..a83f62acc 100644 --- a/crates/torin/src/measure.rs +++ b/crates/torin/src/measure.rs @@ -23,6 +23,7 @@ use crate::{ Length, Torin, }, + size::EvalDimension, }; /// Some layout strategies require two-phase measurements @@ -84,28 +85,26 @@ where // Compute the width and height given the size, the minimum size, the maximum size and margins area_size.width = node.width.min_max( area_size.width, - parent_area.size.width, - parent_area.size.height, - available_parent_area.size.width, + EvalDimension::Width, + parent_area, + available_parent_area.width(), node.margin.left(), node.margin.horizontal(), &node.minimum_width, &node.maximum_width, - self.layout_metadata.root_area.width(), - self.layout_metadata.root_area.height(), + &self.layout_metadata.root_area, phase, ); area_size.height = node.height.min_max( area_size.height, - parent_area.size.height, - parent_area.size.width, - available_parent_area.size.height, + EvalDimension::Height, + parent_area, + available_parent_area.height(), node.margin.top(), node.margin.vertical(), &node.minimum_height, &node.maximum_height, - self.layout_metadata.root_area.height(), - self.layout_metadata.root_area.width(), + &self.layout_metadata.root_area, phase, ); @@ -128,30 +127,28 @@ where if node.width.inner_sized() { area_size.width = node.width.min_max( custom_size.width, - parent_area.size.width, - parent_area.size.height, - available_parent_area.size.width, + EvalDimension::Width, + parent_area, + available_parent_area.width(), node.margin.left(), node.margin.horizontal(), &node.minimum_width, &node.maximum_width, - self.layout_metadata.root_area.width(), - self.layout_metadata.root_area.height(), + &self.layout_metadata.root_area, phase, ); } if node.height.inner_sized() { area_size.height = node.height.min_max( custom_size.height, - parent_area.size.height, - parent_area.size.width, - available_parent_area.size.height, + EvalDimension::Height, + parent_area, + available_parent_area.height(), node.margin.top(), node.margin.vertical(), &node.minimum_height, &node.maximum_height, - self.layout_metadata.root_area.height(), - self.layout_metadata.root_area.width(), + &self.layout_metadata.root_area, phase, ); } @@ -181,30 +178,28 @@ where if node.width.inner_sized() { inner_size.width = node.width.min_max( available_parent_area.width(), - parent_area.size.width, - parent_area.size.height, + EvalDimension::Width, + parent_area, available_parent_area.width(), node.margin.left(), node.margin.horizontal(), &node.minimum_width, &node.maximum_width, - self.layout_metadata.root_area.width(), - self.layout_metadata.root_area.height(), + &self.layout_metadata.root_area, phase, ); } if node.height.inner_sized() { inner_size.height = node.height.min_max( available_parent_area.height(), - parent_area.size.height, - parent_area.size.width, + EvalDimension::Height, + parent_area, available_parent_area.height(), node.margin.top(), node.margin.vertical(), &node.minimum_height, &node.maximum_height, - self.layout_metadata.root_area.height(), - self.layout_metadata.root_area.width(), + &self.layout_metadata.root_area, phase, ); } diff --git a/crates/torin/src/values/size.rs b/crates/torin/src/values/size.rs index a6e776495..96b993b55 100644 --- a/crates/torin/src/values/size.rs +++ b/crates/torin/src/values/size.rs @@ -8,6 +8,7 @@ pub use euclid::Rect; use crate::{ geometry::Length, measure::Phase, + prelude::Area, scaled::Scaled, }; @@ -78,30 +79,31 @@ impl Size { #[allow(clippy::too_many_arguments)] pub fn eval( &self, - parent_value: f32, - other_parent_value: f32, + dimension: EvalDimension, + parent_value: &Area, available_parent_value: f32, parent_margin: f32, - root_value: f32, - other_root_value: f32, + root_value: &Area, phase: Phase, ) -> Option { + let current_parent_value = match dimension { + EvalDimension::Width => parent_value.width(), + EvalDimension::Height => parent_value.height(), + }; + let current_root_value = match dimension { + EvalDimension::Width => root_value.width(), + EvalDimension::Height => root_value.height(), + }; match self { Size::Pixels(px) => Some(px.get() + parent_margin), - Size::Percentage(per) => Some(parent_value / 100.0 * per.get()), + Size::Percentage(per) => Some(current_parent_value / 100.0 * per.get()), Size::DynamicCalculations(calculations) => Some( - run_calculations( - calculations.deref(), - parent_value, - other_parent_value, - root_value, - other_root_value, - ) - .unwrap_or(0.0), + run_calculations(calculations.deref(), parent_value, root_value, dimension) + .unwrap_or(0.0), ), Size::Fill => Some(available_parent_value), Size::FillMinimum if phase == Phase::Final => Some(available_parent_value), - Size::RootPercentage(per) => Some(root_value / 100.0 * per.get()), + Size::RootPercentage(per) => Some(current_root_value / 100.0 * per.get()), Size::Flex(_) if phase == Phase::Final => Some(available_parent_value), _ => None, } @@ -111,47 +113,43 @@ impl Size { pub fn min_max( &self, value: f32, - parent_value: f32, - other_parent_value: f32, + dimension: EvalDimension, + parent_value: &Area, available_parent_value: f32, single_margin: f32, margin: f32, minimum: &Self, maximum: &Self, - root_value: f32, - other_root_value: f32, + root_value: &Area, phase: Phase, ) -> f32 { let value = self .eval( + dimension, parent_value, - other_parent_value, available_parent_value, margin, root_value, - other_root_value, phase, ) .unwrap_or(value + margin); let minimum_value = minimum .eval( + dimension, parent_value, - other_parent_value, available_parent_value, margin, root_value, - other_root_value, phase, ) .map(|v| v + single_margin); let maximum_value = maximum.eval( + dimension, parent_value, - other_parent_value, available_parent_value, margin, root_value, - other_root_value, phase, ); @@ -184,12 +182,11 @@ impl Scaled for Size { fn scale(&mut self, scale_factor: f32) { match self { Size::Pixels(s) => *s *= scale_factor, - Size::DynamicCalculations(calcs) => { - calcs.insert(0, DynamicCalculation::OpenParenthesis); - calcs.push(DynamicCalculation::ClosedParenthesis); - calcs.push(DynamicCalculation::Mul); - calcs.push(DynamicCalculation::Pixels(scale_factor)); - } + Size::DynamicCalculations(calcs) => calcs.iter_mut().for_each(|v| { + if v == &mut DynamicCalculation::ScalingFactor { + *v = DynamicCalculation::Pixels(scale_factor); + } + }), _ => (), } } @@ -204,9 +201,11 @@ pub enum DynamicCalculation { OpenParenthesis, ClosedParenthesis, FunctionSeparator, - Percentage(Dimension), - RootPercentage(Dimension), - // no dimension because this isnt using any parent value + // this one works real weird, we actually replace it with a pixel value when we run the scale + // function + ScalingFactor, + Parent(Dimension), + Root(Dimension), Pixels(f32), Function(LexFunction), } @@ -236,8 +235,10 @@ pub enum LexFunction { /// ``` #[derive(Copy, Clone, Debug, PartialEq)] pub enum Dimension { - Current(f32), - Other(f32), + Current, + Other, + Width, + Height, } impl std::fmt::Display for DynamicCalculation { @@ -250,22 +251,19 @@ impl std::fmt::Display for DynamicCalculation { DynamicCalculation::OpenParenthesis => f.write_str("("), DynamicCalculation::ClosedParenthesis => f.write_str(")"), DynamicCalculation::FunctionSeparator => f.write_str(","), - DynamicCalculation::Percentage(Dimension::Current(p)) => { - f.write_fmt(format_args!("{p}%")) - } - DynamicCalculation::Percentage(Dimension::Other(p)) => { - f.write_fmt(format_args!("{p}%'")) - } - DynamicCalculation::RootPercentage(Dimension::Current(p)) => { - f.write_fmt(format_args!("{p}v")) - } - DynamicCalculation::RootPercentage(Dimension::Other(p)) => { - f.write_fmt(format_args!("{p}v")) - } DynamicCalculation::Pixels(s) => f.write_fmt(format_args!("{s}")), DynamicCalculation::Function(LexFunction::Min) => f.write_str("min"), DynamicCalculation::Function(LexFunction::Max) => f.write_str("max"), DynamicCalculation::Function(LexFunction::Clamp) => f.write_str("clamp"), + DynamicCalculation::ScalingFactor => f.write_str("scale"), + DynamicCalculation::Parent(Dimension::Current) => f.write_str("parent"), + DynamicCalculation::Parent(Dimension::Other) => f.write_str("parent.other"), + DynamicCalculation::Parent(Dimension::Width) => f.write_str("parent.width"), + DynamicCalculation::Parent(Dimension::Height) => f.write_str("parent.height"), + DynamicCalculation::Root(Dimension::Current) => f.write_str("root"), + DynamicCalculation::Root(Dimension::Other) => f.write_str("root.other"), + DynamicCalculation::Root(Dimension::Width) => f.write_str("root.width"), + DynamicCalculation::Root(Dimension::Height) => f.write_str("root.height"), } } } @@ -273,27 +271,30 @@ impl std::fmt::Display for DynamicCalculation { /// [Operator-precedence parser](https://en.wikipedia.org/wiki/Operator-precedence_parser#Precedence_climbing_method) struct DynamicCalculationEvaluator<'a> { calcs: Iter<'a, DynamicCalculation>, - parent_value: f32, - other_parent_value: f32, - root_value: f32, - other_root_value: f32, + dimension: EvalDimension, + parent_value: &'a Area, + root_value: &'a Area, current: Option<&'a DynamicCalculation>, } +#[derive(Copy, Clone, Debug, PartialEq)] +pub enum EvalDimension { + Width, + Height, +} + impl<'a> DynamicCalculationEvaluator<'a> { pub fn new( calcs: Iter<'a, DynamicCalculation>, - parent_value: f32, - other_parent_value: f32, - root_value: f32, - other_root_value: f32, + dimension: EvalDimension, + parent_value: &'a Area, + root_value: &'a Area, ) -> Self { Self { calcs, parent_value, - other_parent_value, + dimension, root_value, - other_root_value, current: None, } } @@ -384,21 +385,53 @@ impl<'a> DynamicCalculationEvaluator<'a> { /// ` fn parse_value(&mut self) -> Option<(f32, bool)> { match self.current? { - DynamicCalculation::Percentage(Dimension::Current(value)) => { + DynamicCalculation::Root(Dimension::Current) => { + self.current = self.calcs.next(); + match self.dimension { + EvalDimension::Width => Some((self.root_value.width(), true)), + EvalDimension::Height => Some((self.root_value.height(), true)), + } + } + DynamicCalculation::Root(Dimension::Other) => { self.current = self.calcs.next(); - Some(((self.parent_value / 100.0 * value).round(), false)) + match self.dimension { + EvalDimension::Width => Some((self.root_value.height(), true)), + EvalDimension::Height => Some((self.root_value.width(), true)), + } + } + DynamicCalculation::Root(Dimension::Width) => { + self.current = self.calcs.next(); + Some((self.root_value.width(), true)) + } + DynamicCalculation::Root(Dimension::Height) => { + self.current = self.calcs.next(); + Some((self.root_value.height(), true)) + } + DynamicCalculation::Parent(Dimension::Current) => { + self.current = self.calcs.next(); + match self.dimension { + EvalDimension::Width => Some((self.parent_value.width(), true)), + EvalDimension::Height => Some((self.parent_value.height(), true)), + } + } + DynamicCalculation::Parent(Dimension::Other) => { + self.current = self.calcs.next(); + match self.dimension { + EvalDimension::Width => Some((self.parent_value.height(), true)), + EvalDimension::Height => Some((self.parent_value.width(), true)), + } } - DynamicCalculation::Percentage(Dimension::Other(value)) => { + DynamicCalculation::Parent(Dimension::Width) => { self.current = self.calcs.next(); - Some(((self.other_parent_value / 100.0 * value).round(), false)) + Some((self.parent_value.width(), true)) } - DynamicCalculation::RootPercentage(Dimension::Current(value)) => { + DynamicCalculation::Parent(Dimension::Height) => { self.current = self.calcs.next(); - Some(((self.root_value / 100.0 * value).round(), false)) + Some((self.parent_value.height(), true)) } - DynamicCalculation::RootPercentage(Dimension::Other(value)) => { + DynamicCalculation::ScalingFactor => { self.current = self.calcs.next(); - Some(((self.other_root_value / 100.0 * value).round(), false)) + Some((1.0, true)) } DynamicCalculation::Pixels(value) => { self.current = self.calcs.next(); @@ -483,17 +516,9 @@ impl<'a> DynamicCalculationEvaluator<'a> { /// This value could be for example the width of a node's parent area. pub fn run_calculations( calcs: &[DynamicCalculation], - parent_value: f32, - other_parent_value: f32, - root_value: f32, - other_root_value: f32, + parent_value: &Area, + root_value: &Area, + dimension: EvalDimension, ) -> Option { - DynamicCalculationEvaluator::new( - calcs.iter(), - parent_value, - other_parent_value, - root_value, - other_root_value, - ) - .evaluate() + DynamicCalculationEvaluator::new(calcs.iter(), dimension, parent_value, root_value).evaluate() } diff --git a/crates/torin/tests/size.rs b/crates/torin/tests/size.rs index cf05bb6e9..2f579d59e 100644 --- a/crates/torin/tests/size.rs +++ b/crates/torin/tests/size.rs @@ -780,458 +780,67 @@ pub fn inner_percentage() { #[test] pub fn test_calc() { - const PARENT_VALUE: f32 = 500.0; - const OTHER_PARENT_VALUE: f32 = 100.0; - - assert_eq!( - run_calculations( - &[DynamicCalculation::Pixels(10.0)], - PARENT_VALUE, - OTHER_PARENT_VALUE, - PARENT_VALUE, - OTHER_PARENT_VALUE, - ), - Some(10.0) - ); - - assert_eq!( - run_calculations( - &[DynamicCalculation::Percentage(Dimension::Current(87.5))], - PARENT_VALUE, - OTHER_PARENT_VALUE, - PARENT_VALUE, - OTHER_PARENT_VALUE, - ), - Some((87.5 / 100.0 * PARENT_VALUE).round()) - ); - - assert_eq!( - run_calculations( - &[DynamicCalculation::Percentage(Dimension::Other(87.5))], - PARENT_VALUE, - OTHER_PARENT_VALUE, - PARENT_VALUE, - OTHER_PARENT_VALUE, - ), - Some((87.5 / 100.0 * OTHER_PARENT_VALUE).round()) - ); - - assert_eq!( - run_calculations( - &[DynamicCalculation::RootPercentage(Dimension::Current(87.5))], - PARENT_VALUE, - OTHER_PARENT_VALUE, - PARENT_VALUE, - OTHER_PARENT_VALUE, - ), - Some((87.5 / 100.0 * PARENT_VALUE).round()) - ); - - assert_eq!( - run_calculations( - &[DynamicCalculation::RootPercentage(Dimension::Other(87.5))], - PARENT_VALUE, - OTHER_PARENT_VALUE, - PARENT_VALUE, - OTHER_PARENT_VALUE, - ), - Some((87.5 / 100.0 * OTHER_PARENT_VALUE).round()) - ); - - assert_eq!( - run_calculations( - &[ - DynamicCalculation::Pixels(10.0), - DynamicCalculation::Add, - DynamicCalculation::Pixels(20.0), - DynamicCalculation::Mul, - DynamicCalculation::Percentage(Dimension::Current(50.0)) - ], - PARENT_VALUE, - OTHER_PARENT_VALUE, - PARENT_VALUE, - OTHER_PARENT_VALUE, - ), - Some(10.0 + 20.0 * (50.0 / 100.0 * PARENT_VALUE).round()) - ); - - assert_eq!( - run_calculations( - &[ - DynamicCalculation::Pixels(10.0), - DynamicCalculation::Add, - DynamicCalculation::Percentage(Dimension::Current(10.0)), - DynamicCalculation::Add, - DynamicCalculation::Pixels(30.0), - DynamicCalculation::Mul, - DynamicCalculation::Pixels(10.0), - DynamicCalculation::Add, - DynamicCalculation::Pixels(75.0), - DynamicCalculation::Mul, - DynamicCalculation::Pixels(2.0) - ], - PARENT_VALUE, - OTHER_PARENT_VALUE, - PARENT_VALUE, - OTHER_PARENT_VALUE, - ), - Some(10.0 + (10.0 / 100.0 * PARENT_VALUE).round() + 30.0 * 10.0 + 75.0 * 2.0) - ); - - assert_eq!( - run_calculations( - &[ - DynamicCalculation::Pixels(10.0), - DynamicCalculation::Pixels(20.0) - ], - PARENT_VALUE, - OTHER_PARENT_VALUE, - PARENT_VALUE, - OTHER_PARENT_VALUE, - ), - None - ); - - assert_eq!( - run_calculations( - &[DynamicCalculation::Pixels(10.0), DynamicCalculation::Add], - PARENT_VALUE, - OTHER_PARENT_VALUE, - PARENT_VALUE, - OTHER_PARENT_VALUE, - ), - None - ); - - assert_eq!( - run_calculations( - &[DynamicCalculation::Add, DynamicCalculation::Pixels(10.0)], - PARENT_VALUE, - OTHER_PARENT_VALUE, - PARENT_VALUE, - OTHER_PARENT_VALUE, - ), - // Because +10 is just 10 - Some(10.0) - ); - - assert_eq!( - run_calculations( - &[ - DynamicCalculation::Pixels(10.0), - DynamicCalculation::Add, - // counts as a prefix - DynamicCalculation::Add, - DynamicCalculation::Pixels(10.0) - ], - PARENT_VALUE, - OTHER_PARENT_VALUE, - PARENT_VALUE, - OTHER_PARENT_VALUE, - ), - Some(20.0) - ); - - assert_eq!( - run_calculations( - &[ - DynamicCalculation::Percentage(Dimension::Current(50.0)), - DynamicCalculation::Sub, - DynamicCalculation::RootPercentage(Dimension::Current(20.0)) - ], - PARENT_VALUE, - OTHER_PARENT_VALUE, - PARENT_VALUE, - OTHER_PARENT_VALUE, - ), - Some((PARENT_VALUE * 0.5) - (PARENT_VALUE * 0.20)) - ); + const PARENT_VALUE: &Area = &Area::new(Point2D::new(0.0, 0.0), Size2D::new(500.0, 100.0)); assert_eq!( run_calculations( + // so many features... i wish nobody else has to test so many things ever again + // if you want to make this test better, do it... i date you + // represents `calc((10)(5) * scale(2 * (5 + min(root, parent.other)))` &[ DynamicCalculation::OpenParenthesis, DynamicCalculation::Pixels(10.0), - DynamicCalculation::ClosedParenthesis - ], - PARENT_VALUE, - OTHER_PARENT_VALUE, - PARENT_VALUE, - OTHER_PARENT_VALUE, - ), - Some(10.0) - ); - - assert_eq!( - run_calculations( - &[ - DynamicCalculation::Pixels(10.0), - DynamicCalculation::OpenParenthesis, - DynamicCalculation::Pixels(10.0), - DynamicCalculation::Add, - DynamicCalculation::Pixels(20.0), DynamicCalculation::ClosedParenthesis, - DynamicCalculation::Pixels(10.0), - DynamicCalculation::Add, - DynamicCalculation::Pixels(10.0), DynamicCalculation::OpenParenthesis, - DynamicCalculation::Pixels(10.0), + DynamicCalculation::Pixels(5.0), DynamicCalculation::ClosedParenthesis, - DynamicCalculation::Pixels(10.0) - ], - PARENT_VALUE, - OTHER_PARENT_VALUE, - PARENT_VALUE, - OTHER_PARENT_VALUE, - ), - Some((10.0 * (10.0 + 20.0) * 10.0) + (10.0 * (10.0) * 10.0)) - ); - - assert_eq!( - run_calculations( - &[ - DynamicCalculation::Sub, + DynamicCalculation::Mul, + DynamicCalculation::ScalingFactor, DynamicCalculation::OpenParenthesis, - DynamicCalculation::Pixels(10.0), - DynamicCalculation::ClosedParenthesis, - DynamicCalculation::Pixels(20.0) - ], - PARENT_VALUE, - OTHER_PARENT_VALUE, - PARENT_VALUE, - OTHER_PARENT_VALUE, - ), - Some(-1.0 * 10.0 * 20.0) - ); - - assert_eq!( - run_calculations( - &[ + DynamicCalculation::Pixels(2.0), + DynamicCalculation::Mul, DynamicCalculation::OpenParenthesis, - DynamicCalculation::Pixels(10.0) - ], - PARENT_VALUE, - OTHER_PARENT_VALUE, - PARENT_VALUE, - OTHER_PARENT_VALUE, - ), - None - ); - - assert_eq!( - run_calculations( - &[ + DynamicCalculation::Pixels(5.0), + DynamicCalculation::Add, DynamicCalculation::Function(LexFunction::Min), DynamicCalculation::OpenParenthesis, - DynamicCalculation::Pixels(10.0), + DynamicCalculation::Root(Dimension::Current), DynamicCalculation::FunctionSeparator, - DynamicCalculation::Pixels(20.0), + DynamicCalculation::Parent(Dimension::Other), DynamicCalculation::ClosedParenthesis, - ], - PARENT_VALUE, - OTHER_PARENT_VALUE, - PARENT_VALUE, - OTHER_PARENT_VALUE, - ), - Some(10.0) - ); - - assert_eq!( - run_calculations( - &[ - DynamicCalculation::Function(LexFunction::Max), - DynamicCalculation::OpenParenthesis, - DynamicCalculation::Pixels(10.0), - DynamicCalculation::FunctionSeparator, - DynamicCalculation::Pixels(30.0), - DynamicCalculation::FunctionSeparator, - DynamicCalculation::Pixels(20.0), - DynamicCalculation::ClosedParenthesis, - ], - PARENT_VALUE, - OTHER_PARENT_VALUE, - PARENT_VALUE, - OTHER_PARENT_VALUE, - ), - Some(30.0) - ); - - assert_eq!( - run_calculations( - &[ - DynamicCalculation::Function(LexFunction::Max), - DynamicCalculation::OpenParenthesis, - DynamicCalculation::Pixels(10.0), - DynamicCalculation::FunctionSeparator, DynamicCalculation::ClosedParenthesis, - ], - PARENT_VALUE, - OTHER_PARENT_VALUE, - PARENT_VALUE, - OTHER_PARENT_VALUE, - ), - None - ); - - assert_eq!( - run_calculations( - &[ - DynamicCalculation::Function(LexFunction::Max), - DynamicCalculation::OpenParenthesis, - DynamicCalculation::Pixels(10.0), - ], - PARENT_VALUE, - OTHER_PARENT_VALUE, - PARENT_VALUE, - OTHER_PARENT_VALUE, - ), - None - ); - - assert_eq!( - run_calculations( - &[ - DynamicCalculation::Function(LexFunction::Clamp), - DynamicCalculation::OpenParenthesis, - DynamicCalculation::Pixels(10.0), - DynamicCalculation::FunctionSeparator, - DynamicCalculation::Pixels(30.0), - DynamicCalculation::FunctionSeparator, - DynamicCalculation::Pixels(20.0), DynamicCalculation::ClosedParenthesis, ], PARENT_VALUE, - OTHER_PARENT_VALUE, PARENT_VALUE, - OTHER_PARENT_VALUE, + EvalDimension::Width, ), - Some(20.0) - ); - - assert_eq!( - run_calculations( - &[ - DynamicCalculation::Function(LexFunction::Clamp), - DynamicCalculation::OpenParenthesis, - DynamicCalculation::Pixels(10.0), - DynamicCalculation::FunctionSeparator, - DynamicCalculation::Pixels(5.0), - DynamicCalculation::FunctionSeparator, - DynamicCalculation::Pixels(20.0), - DynamicCalculation::ClosedParenthesis, - ], - PARENT_VALUE, - OTHER_PARENT_VALUE, - PARENT_VALUE, - OTHER_PARENT_VALUE, - ), - Some(10.0) - ); - - assert_eq!( - run_calculations( - &[ - DynamicCalculation::Function(LexFunction::Clamp), - DynamicCalculation::OpenParenthesis, - DynamicCalculation::Pixels(10.0), - DynamicCalculation::FunctionSeparator, - DynamicCalculation::Pixels(30.0), - DynamicCalculation::ClosedParenthesis, - ], - PARENT_VALUE, - OTHER_PARENT_VALUE, - PARENT_VALUE, - OTHER_PARENT_VALUE, - ), - None + Some(10.0 * 5.0 * 1.0 * (2.0 * (5.0 + PARENT_VALUE.width().min(PARENT_VALUE.height())))) ); } #[test] pub fn test_scaling_factor() { - const PARENT_VALUE: f32 = 500.0; - const OTHER_PARENT_VALUE: f32 = 500.0; - - assert_eq!( - { - let mut size = - Size::DynamicCalculations(Box::new(vec![DynamicCalculation::Pixels(10.0)])); - size.scale(1.5); - size - } - .eval( - PARENT_VALUE, - OTHER_PARENT_VALUE, - PARENT_VALUE, - 0.0, - PARENT_VALUE, - OTHER_PARENT_VALUE, - Phase::Initial - ), - Some((10.0) * 1.5) - ); + const PARENT_VALUE: &Area = &Area::new(Point2D::new(0.0, 0.0), Size2D::new(500.0, 500.0)); assert_eq!( { let mut size = Size::DynamicCalculations(Box::new(vec![ DynamicCalculation::Pixels(10.0), - DynamicCalculation::OpenParenthesis, - DynamicCalculation::Pixels(10.0), - DynamicCalculation::Add, - DynamicCalculation::Pixels(20.0), - DynamicCalculation::ClosedParenthesis, - DynamicCalculation::Pixels(10.0), - DynamicCalculation::Add, - DynamicCalculation::Pixels(10.0), - DynamicCalculation::OpenParenthesis, - DynamicCalculation::Pixels(10.0), - DynamicCalculation::ClosedParenthesis, - DynamicCalculation::Pixels(10.0), + DynamicCalculation::Mul, + DynamicCalculation::ScalingFactor, ])); size.scale(1.5); size } .eval( + EvalDimension::Width, PARENT_VALUE, - OTHER_PARENT_VALUE, - PARENT_VALUE, - 0.0, - PARENT_VALUE, - OTHER_PARENT_VALUE, - Phase::Initial - ), - Some(((10.0 * (10.0 + 20.0) * 10.0) + (10.0 * (10.0) * 10.0)) * 1.5) - ); - - assert_eq!( - { - let mut size = Size::DynamicCalculations(Box::new(vec![ - DynamicCalculation::Pixels(10.0), - DynamicCalculation::OpenParenthesis, - DynamicCalculation::Pixels(10.0), - DynamicCalculation::Add, - DynamicCalculation::Pixels(20.0), - DynamicCalculation::ClosedParenthesis, - DynamicCalculation::Pixels(10.0), - DynamicCalculation::Add, - DynamicCalculation::Pixels(10.0), - DynamicCalculation::OpenParenthesis, - DynamicCalculation::Pixels(10.0), - DynamicCalculation::ClosedParenthesis, - DynamicCalculation::Pixels(10.0), - ])); - size.scale(1.2); - size - } - .eval( - PARENT_VALUE, - OTHER_PARENT_VALUE, - PARENT_VALUE, + PARENT_VALUE.width(), 0.0, PARENT_VALUE, - OTHER_PARENT_VALUE, Phase::Initial ), - Some(((10.0 * (10.0 + 20.0) * 10.0) + (10.0 * (10.0) * 10.0)) * 1.2) + Some((10.0) * 1.5) ); }