1use crate::pair::{Pair, Pos, Size};
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq)]
4pub struct Rect {
5 pub pos: Pair<Pos>,
6 pub size: Pair<Size>,
7}
8
9impl Rect {
10 pub fn new(pos: Pair<Pos>, size: Pair<Size>) -> Self {
11 Self { pos, size }
12 }
13
14 pub fn from_size(size: Pair<Size>) -> Self {
15 Self {
16 pos: Pair::fill(0),
17 size,
18 }
19 }
20
21 pub fn with_pos(&self, pos: Pair<Pos>) -> Self {
22 Self {
23 pos,
24 size: self.size,
25 }
26 }
27
28 pub fn with_size(&self, size: Pair<Size>) -> Self {
29 Self {
30 pos: self.pos,
31 size,
32 }
33 }
34
35 pub fn map_pos(&self, f: impl Fn(Pair<Pos>) -> Pair<Pos>) -> Self {
36 Self {
37 pos: f(self.pos),
38 size: self.size,
39 }
40 }
41
42 pub fn map_size(&self, f: impl Fn(Pair<Size>) -> Pair<Size>) -> Self {
43 Self {
44 pos: self.pos,
45 size: f(self.size),
46 }
47 }
48
49 pub fn pad(&self, padding: u16) -> Self {
50 self.pad_x(padding).pad_y(padding)
51 }
52
53 pub fn pad_x(&self, padding: u16) -> Self {
54 self.pad_left(padding).pad_right(padding)
55 }
56
57 pub fn pad_y(&self, padding: u16) -> Self {
58 self.pad_top(padding).pad_bottom(padding)
59 }
60
61 pub fn pad_left(&self, padding: u16) -> Self {
62 self.map_pos(|pos| pos.map_x(|x| x + padding))
63 }
64
65 pub fn pad_right(&self, padding: u16) -> Self {
66 self.map_size(|size| size.map_x(|x| x - padding))
67 }
68
69 pub fn pad_top(&self, padding: u16) -> Self {
70 self.map_pos(|pos| pos.map_y(|y| y + padding))
71 }
72
73 pub fn pad_bottom(&self, padding: u16) -> Self {
74 self.map_size(|size| size.map_y(|y| y - padding))
75 }
76
77 pub fn center_in(&self, outer: Self) -> Self {
78 self.with_pos(outer.center() - self.center())
79 }
80
81 pub fn center(&self) -> Pair<Pos> {
82 self.pos + self.size.map(|xy| xy / 2).into()
83 }
84
85 pub fn corner(&self) -> Pair<Pos> {
86 self.pos + self.size.into() - Pair::fill(1)
87 }
88
89 pub fn is_inside(&self, outer: Self) -> bool {
90 let corner = self.corner();
91 let outer_corner = outer.corner();
92
93 self.pos.x >= outer.pos.x
94 && self.pos.y >= outer.pos.y
95 && corner.x <= outer_corner.x
96 && corner.y <= outer_corner.y
97 }
98}