-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Open
Labels
A-UIGraphical user interfaces, styles, layouts, and widgetsGraphical user interfaces, styles, layouts, and widgetsC-UsabilityA targeted quality-of-life change that makes Bevy easier to useA targeted quality-of-life change that makes Bevy easier to use
Description
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.
muttering-oldman
Metadata
Metadata
Assignees
Labels
A-UIGraphical user interfaces, styles, layouts, and widgetsGraphical user interfaces, styles, layouts, and widgetsC-UsabilityA targeted quality-of-life change that makes Bevy easier to useA targeted quality-of-life change that makes Bevy easier to use