yakui_core/geometry/
constraints.rs

1use glam::Vec2;
2
3/// Defines box constraints used for layout.
4#[derive(Debug, Clone, Copy)]
5pub struct Constraints {
6    /// The minimum size that is allowed by these constraints.
7    pub min: Vec2,
8
9    /// The maximum size that is allowed by these constraints.
10    pub max: Vec2,
11}
12
13impl Constraints {
14    /// Create a new `Constraints` with a minimum size of zero and the given
15    /// maximum.
16    pub fn loose(max: Vec2) -> Self {
17        Self {
18            min: Vec2::ZERO,
19            max,
20        }
21    }
22
23    /// Create a new `Constraints` whose minimum and maximum constraints are the
24    /// given value.
25    pub fn tight(value: Vec2) -> Self {
26        Self {
27            min: value,
28            max: value,
29        }
30    }
31
32    /// Create a new `Constraints` whose minimum size is zero and whose maximum
33    /// is infinite.
34    pub fn none() -> Self {
35        Self {
36            min: Vec2::ZERO,
37            max: Vec2::new(f32::INFINITY, f32::INFINITY),
38        }
39    }
40
41    /// Returns the size closest to the given size that satisfies the minimun
42    /// constraints.
43    pub fn constrain_min(&self, base: Vec2) -> Vec2 {
44        base.max(self.min)
45    }
46
47    /// Returns the size closest to the given size that fits the constraints.
48    pub fn constrain(&self, base: Vec2) -> Vec2 {
49        base.max(self.min).min(self.max)
50    }
51
52    /// Returns the width closest to the given width that fits the constraints.
53    pub fn constrain_width(&self, width: f32) -> f32 {
54        width.max(self.min.x).min(self.max.x)
55    }
56
57    /// Returns the height closest to the given height that fits the constraints.
58    pub fn constrain_height(&self, height: f32) -> f32 {
59        height.max(self.min.y).min(self.max.y)
60    }
61
62    /// Constraints are loose if there is no minimum size.
63    pub fn is_loose(&self) -> bool {
64        self.min == Vec2::ZERO
65    }
66
67    /// Constraints are tight if the minimum size and maximum size are the same.
68    /// This means that there is exactly only size that satisfies the
69    /// constraints.
70    pub fn is_tight(&self) -> bool {
71        self.min == self.max
72    }
73
74    /// Constraints are bounded if the maximum size on both axes is finite.
75    pub fn is_bounded(&self) -> bool {
76        self.max.is_finite() && is_nonmax(self.max)
77    }
78
79    /// Constraints are unbounded if the maximum size on either axis is
80    /// infinite.
81    pub fn is_unbounded(&self) -> bool {
82        !self.is_bounded()
83    }
84}
85
86fn is_nonmax(value: Vec2) -> bool {
87    value.x < f32::MAX && value.y < f32::MAX
88}