milk_tea/
rect.rs

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}