use crate::{
element::InnerElement,
var::{Arg, Val},
Element,
};
impl Element {
#[must_use]
pub fn center(&self) -> Self {
let inner = match &self.0 {
InnerElement::Cube { x, y, z, .. } => InnerElement::Cube {
x: x.clone(),
y: y.clone(),
z: z.clone(),
centered: true,
},
InnerElement::Cylinder { h, r, .. } => InnerElement::Cylinder {
h: h.clone(),
r: r.clone(),
centered: true,
},
other => panic!("center() is not allowed for type {other}"),
};
Element(inner)
}
#[must_use]
pub fn margin(&self, margin: impl Arg) -> Self {
Element(self.0.clone().margin(margin.val()))
}
}
impl InnerElement {
#[must_use]
fn margin(self, margin: Val) -> Self {
match self {
InnerElement::Cube { x, y, z, centered } => margin_cube(x, y, z, centered, margin),
Self::Translate { x, y, z, child } => Self::Translate {
x,
y,
z,
child: Box::new(child.margin(margin)),
},
other => panic!("margin() is not allowed for type {other}"),
}
}
}
fn margin_cube(x: Val, y: Val, z: Val, centered: bool, margin: Val) -> InnerElement {
let cube = InnerElement::Cube {
x: Val::Calc(x + margin.clone() * 2),
y: Val::Calc(y + margin.clone() * 2),
z: Val::Calc(z + margin.clone() * 2),
centered,
};
if centered {
cube
} else {
InnerElement::Translate {
x: Val::Calc(-margin.clone()),
y: Val::Calc(-margin.clone()),
z: Val::Calc(-margin),
child: Box::new(cube),
}
}
}