More useful Spec
helpers
This commit is contained in:
parent
564cb7e989
commit
feff013abb
@ -31,6 +31,23 @@ impl<T> Spec<T> {
|
||||
Spec { x: f(self.x), y: f(self.y) }
|
||||
}
|
||||
|
||||
/// Zip two instances into an instance over a tuple.
|
||||
pub fn zip<U>(self, other: impl Into<Spec<U>>) -> Spec<(T, U)> {
|
||||
let other = other.into();
|
||||
Spec {
|
||||
x: (self.x, other.x),
|
||||
y: (self.y, other.y),
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether a condition is true for both fields.
|
||||
pub fn all<F>(self, mut f: F) -> bool
|
||||
where
|
||||
F: FnMut(&T) -> bool,
|
||||
{
|
||||
f(&self.x) && f(&self.y)
|
||||
}
|
||||
|
||||
/// Convert to the generic representation.
|
||||
pub fn to_gen(self, block: SpecAxis) -> Gen<T> {
|
||||
match block {
|
||||
@ -38,14 +55,11 @@ impl<T> Spec<T> {
|
||||
SpecAxis::Vertical => Gen::new(self.x, self.y),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Compares if this instance's field are equal to that of another with
|
||||
/// respect to `eq`.
|
||||
pub fn eq_by<U, F>(&self, other: &Spec<U>, eq: F) -> bool
|
||||
where
|
||||
F: Fn(&T, &U) -> bool,
|
||||
{
|
||||
eq(&self.x, &other.x) && eq(&self.y, &other.y)
|
||||
impl From<Size> for Spec<Length> {
|
||||
fn from(size: Size) -> Self {
|
||||
size.to_spec()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,23 +40,15 @@ impl Constraints {
|
||||
/// Check whether the constraints are fullfilled in a region with the given
|
||||
/// properties.
|
||||
pub fn check(&self, current: Size, base: Size, expand: Spec<bool>) -> bool {
|
||||
let current = current.to_spec();
|
||||
let base = base.to_spec();
|
||||
self.expand == expand
|
||||
&& current.eq_by(&self.min, |x, y| y.map_or(true, |y| x.fits(y)))
|
||||
&& current.eq_by(&self.max, |x, y| y.map_or(true, |y| x < &y))
|
||||
&& current.eq_by(&self.exact, |x, y| y.map_or(true, |y| x.approx_eq(y)))
|
||||
&& base.eq_by(&self.base, |x, y| y.map_or(true, |y| x.approx_eq(y)))
|
||||
}
|
||||
|
||||
/// Set the appropriate base constraints for linear width and height sizing.
|
||||
pub fn set_base_if_linear(&mut self, base: Size, sizing: Spec<Option<Linear>>) {
|
||||
// The full sizes need to be equal if there is a relative component in the sizes.
|
||||
if sizing.x.map_or(false, |l| l.is_relative()) {
|
||||
self.base.x = Some(base.w);
|
||||
}
|
||||
if sizing.y.map_or(false, |l| l.is_relative()) {
|
||||
self.base.y = Some(base.h);
|
||||
}
|
||||
&& verify(self.min, current, |m, c| c.fits(m))
|
||||
&& verify(self.max, current, |m, c| m.fits(c))
|
||||
&& verify(self.exact, current, Length::approx_eq)
|
||||
&& verify(self.base, base, Length::approx_eq)
|
||||
}
|
||||
}
|
||||
|
||||
/// Verify a single constraint.
|
||||
fn verify(spec: Spec<Option<Length>>, size: Size, f: fn(Length, Length) -> bool) -> bool {
|
||||
spec.zip(size).all(|&(opt, s)| opt.map_or(true, |m| f(m, s)))
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user