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}