What problem does this solve or what need does it fill?
In css, we have calc() expression that can auto calculate and update when value is changed (e.g. window resize event)
What solution would you like?
The define of bevy::ui::Val:
/// An enum that describes possible types of value in flexbox layout options
#[derive(Clone, PartialEq, Debug, Default, Serialize, Deserialize, Reflect)]
#[reflect_value(PartialEq, Serialize, Deserialize)]
pub enum Val {
/// No value defined
#[default]
Undefined,
/// Automatically determine this value
Auto,
/// Set this value in pixels
Px(f32),
/// Set this value in percent
Percent(f32),
/// A calc expression
Calc(CalcVal),
}
Define of CalcVal:
#[derive(Clone, PartialEq, Debug, Serialize, Deserialize, Reflect)]
// Use `Box` to avoid infinity type size, so we cannot impl `Copy`
pub enum CalcVal {
/// a + b
Add(Box<Val>, Box<Val>),
/// a - b
Sub(Box<Val>, Box<Val>),
/// a * b
Mul(Box<Val>, f32),
/// a / b
Div(Box<Val>, f32),
/// -a
Neg(Box<Val>),
}
impl Add<f32> for Val {
type Output = Val;
fn add(self, rhs: f32) -> Self::Output {
match self {
Val::Undefined => Val::Undefined,
Val::Auto => Val::Auto,
Val::Px(value) => Val::Px(value + rhs),
Val::Percent(value) => Val::Percent(value + rhs),
Val::Calc(_) => panic!(),
}
}
}
impl Add<Val> for &Val {
type Output = Val;
fn add(self, rhs: Val) -> Self::Output {
if let Val::Undefined = rhs {
return Val::Undefined;
}
match self {
Val::Undefined => Val::Undefined,
Val::Auto => match rhs {
Val::Auto => Val::Auto,
_ => Val::Calc(CalcVal::Add(Box::new(self.clone()), Box::new(rhs))),
},
Val::Px(value) => match rhs {
Val::Px(rhs) => Val::Px(value + rhs),
_ => Val::Calc(CalcVal::Add(Box::new(self.clone()), Box::new(rhs))),
},
Val::Percent(value) => match rhs {
Val::Percent(rhs) => Val::Percent(value + rhs),
_ => Val::Calc(CalcVal::Add(Box::new(self.clone()), Box::new(rhs))),
},
Val::Calc(value) => match value {
_ => Val::Calc(CalcVal::Add(Box::new(Val::Calc(value.clone())), Box::new(rhs))),
}
}
}
}
impl AddAssign<f32> for Val {
fn add_assign(&mut self, rhs: f32) {
match self {
Val::Undefined | Val::Auto => {}
Val::Px(value) | Val::Percent(value) => *value += rhs,
_ => panic!(),
}
}
}
impl Sub<Val> for &Val {
type Output = Val;
fn sub(self, rhs: Val) -> Self::Output {
if let Val::Undefined = rhs {
return Val::Undefined;
}
match self {
Val::Undefined => Val::Undefined,
Val::Auto => match rhs {
Val::Auto => Val::Auto,
_ => Val::Calc(CalcVal::Sub(Box::new(self.clone()), Box::new(rhs))),
},
Val::Px(value) => match rhs {
Val::Px(rhs) => Val::Px(value - rhs),
_ => Val::Calc(CalcVal::Sub(Box::new(self.clone()), Box::new(rhs))),
},
Val::Percent(value) => match rhs {
Val::Percent(rhs) => Val::Percent(value - rhs),
_ => Val::Calc(CalcVal::Sub(Box::new(self.clone()), Box::new(rhs))),
},
Val::Calc(value) => match value {
_ => Val::Calc(CalcVal::Sub(Box::new(Val::Calc(value.clone())), Box::new(rhs))),
},
}
}
}
impl Mul<f32> for &Val {
type Output = Val;
fn mul(self, rhs: f32) -> Self::Output {
Val::Calc(CalcVal::Mul(Box::new(self.clone()), rhs))
}
}
impl Div<f32> for &Val {
type Output = Val;
fn div(self, rhs: f32) -> Self::Output {
Val::Calc(CalcVal::Div(Box::new(self.clone()), rhs))
}
}
impl Neg for &Val {
type Output = Val;
fn neg(self) -> Self::Output {
match self {
Val::Auto | Val::Undefined => self.clone(),
Val::Px(value) => Val::Px(-value),
Val::Percent(value) => Val::Percent(-value),
Val::Calc(value) => match value.clone() {
CalcVal::Sub(a, b) => Val::Calc(CalcVal::Sub(b.clone(), a.clone())),
CalcVal::Neg(a) => *a,
_ => Val::Calc(CalcVal::Neg(Box::new(self.clone()))),
}
}
}
}
What alternative(s) have you considered?
Other solutions to solve and/or work around the problem presented.
Additional context
Any other information you would like to add such as related previous work,
screenshots, benchmarks, etc.
What problem does this solve or what need does it fill?
In css, we have
calc()expression that can auto calculate and update when value is changed (e.g. window resize event)What solution would you like?
The define of
bevy::ui::Val:Define of
CalcVal:What alternative(s) have you considered?
Other solutions to solve and/or work around the problem presented.
Additional context
Any other information you would like to add such as related previous work,
screenshots, benchmarks, etc.