1
2use core::f32;
3use std::fmt::Display;
4
5use crate::Animatable;
6
7use super::{vec2, Axis, Margin, Range, Vec2};
8
9#[derive(Clone, Copy)]
10pub struct Rect {
11 min: Vec2,
12 max: Vec2
13}
14
15impl Rect {
16
17 pub const fn min_max(min: Vec2, max: Vec2) -> Self {
18 Self {
19 min,
20 max
21 }
22 }
23
24 pub fn min_size(min: Vec2, size: Vec2) -> Self {
25 Self {
26 min,
27 max: min + size
28 }
29 }
30
31 pub const fn from_ranges(x_range: Range, y_range: Range) -> Self {
32 Self {
33 min: vec2(x_range.min, y_range.min),
34 max: vec2(x_range.max, y_range.max)
35 }
36 }
37
38 pub const fn to_infinity(from: Vec2) -> Self {
39 Self {
40 min: from,
41 max: Vec2::INFINITY
42 }
43 }
44
45 pub const ZERO: Self = Self::min_max(Vec2::ZERO, Vec2::ZERO);
46
47 pub const fn tl(&self) -> Vec2 {
48 self.min
49 }
50
51 pub const fn tr(&self) -> Vec2 {
52 vec2(self.max.x, self.min.y)
53 }
54
55 pub const fn bl(&self) -> Vec2 {
56 vec2(self.min.x, self.max.y)
57 }
58
59 pub const fn br(&self) -> Vec2 {
60 self.max
61 }
62
63 pub const fn left(&self) -> f32 {
64 self.min.x
65 }
66
67 pub const fn right(&self) -> f32 {
68 self.max.x
69 }
70
71 pub const fn top(&self) -> f32 {
72 self.min.y
73 }
74
75 pub const fn bottom(&self) -> f32 {
76 self.max.y
77 }
78
79 pub fn center(&self) -> Vec2 {
80 (self.min + self.max) * 0.5
81 }
82
83 pub fn size(&self) -> Vec2 {
84 self.max - self.min
85 }
86
87 pub fn width(&self) -> f32 {
88 self.size().x
89 }
90
91 pub fn height(&self) -> f32 {
92 self.size().y
93 }
94
95 pub const fn x_range(&self) -> Range {
96 Range::new(self.min.x, self.max.x)
97 }
98
99 pub fn set_x_range(&mut self, range: Range) {
100 self.min.x = range.min;
101 self.max.x = range.max;
102 }
103
104 pub const fn y_range(&self) -> Range {
105 Range::new(self.min.y, self.max.y)
106 }
107
108 pub fn set_y_range(&mut self, range: Range) {
109 self.min.y = range.min;
110 self.max.y = range.max;
111 }
112
113 pub const fn axis_range(&self, axis: Axis) -> Range {
114 Range::new(self.min.on_axis(axis), self.max.on_axis(axis))
115 }
116
117 pub fn set_axis_range(&mut self, axis: Axis, range: Range) {
118 *self.min.on_axis_mut(axis) = range.min;
119 *self.max.on_axis_mut(axis) = range.max;
120 }
121
122 pub fn contains(&self, pt: Vec2) -> bool {
123 self.x_range().contains(pt.x) && self.y_range().contains(pt.y)
124 }
125
126 pub fn intersect(&self, other: Rect) -> Rect {
127 Self::from_ranges(
128 self.x_range().intersect(other.x_range()),
129 self.y_range().intersect(other.y_range())
130 )
131 }
132
133 pub fn shift(&self, offset: Vec2) -> Rect {
134 Self::min_max(self.min + offset, self.max + offset)
135 }
136
137 pub fn grow(&self, margin: Margin) -> Rect {
138 Self::min_max(self.min - margin.min, self.max + margin.max)
139 }
140
141 pub fn map(&self, from: Rect, to: Rect) -> Self {
142 Self::min_max(
143 self.min.map(from, to),
144 self.max.map(from, to)
145 )
146 }
147
148 pub fn area(&self) -> f32 {
149 self.width() * self.height()
150 }
151
152 pub fn left_frac(&self, frac: f32) -> Rect {
153 Self::min_max(self.tl(), self.bl().lerp(self.br(), frac))
154 }
155
156 pub fn right_frac(&self, frac: f32) -> Rect {
157 Self::min_max(self.tl().lerp(self.tr(), frac), self.br())
158 }
159
160 pub fn top_frac(&self, frac: f32) -> Rect {
161 Self::min_max(self.tl(), self.tr().lerp(self.br(), frac))
162 }
163
164 pub fn bottom_frac(&self, frac: f32) -> Rect {
165 Self::min_max(self.bl().lerp(self.tl(), frac), self.br())
166 }
167
168 pub fn left_half(&self) -> Rect {
169 self.left_frac(0.5)
170 }
171
172 pub fn right_half(&self) -> Rect {
173 self.right_frac(0.5)
174 }
175
176 pub fn top_half(&self) -> Rect {
177 self.top_frac(0.5)
178 }
179
180 pub fn bottom_half(&self) -> Rect {
181 self.bottom_frac(0.5)
182 }
183
184}
185
186impl Display for Rect {
187
188 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
189 self.tl().fmt(f)?;
190 f.write_str(" -> ")?;
191 self.br().fmt(f)
192 }
193
194}
195