1use core::ops::{Add, Sub};
2
3use embedded_graphics::geometry::Point;
4
5use crate::{align::Axis, size::Size};
6
7#[derive(Clone, Copy, Default)]
8pub struct Padding {
9 pub left: u32,
10 pub right: u32,
11 pub top: u32,
12 pub bottom: u32,
13}
14
15impl Padding {
16 pub fn new(top: u32, right: u32, bottom: u32, left: u32) -> Self {
17 Self { left, right, top, bottom }
18 }
19
20 pub fn new_equal(padding: u32) -> Self {
21 Self::new(padding, padding, padding, padding)
22 }
23
24 pub fn new_axis(padding_y: u32, padding_x: u32) -> Self {
25 Self::new(padding_y, padding_x, padding_y, padding_x)
26 }
27
28 pub fn zero() -> Self {
29 Self::new_equal(0)
30 }
31
32 pub fn total_x(&self) -> u32 {
33 self.left + self.right
34 }
35
36 pub fn total_y(&self) -> u32 {
37 self.top + self.bottom
38 }
39
40 pub fn top_left(&self) -> Point {
41 Point::new(self.left as i32, self.top as i32)
42 }
43
44 pub fn total_axis(&self, axis: Axis) -> u32 {
45 match axis {
46 Axis::X => self.total_x(),
47 Axis::Y => self.total_y(),
48 }
49 }
50
51 pub fn fit(self, inner: Size, outer: Size) -> Self {
52 let free = outer - inner;
53 let fit_left = self.top.min(free.width);
54 let fit_right = self.right.min(free.width - fit_left);
55 let fit_top = self.top.min(free.height);
56 let fit_bottom = self.bottom.min(free.height - fit_top);
57
58 Self { left: fit_left, right: fit_right, top: fit_top, bottom: fit_bottom }
59 }
60}
61
62impl Into<Size> for Padding {
63 fn into(self) -> Size {
64 Size::new(self.total_x(), self.total_y())
65 }
66}
67
68impl From<u32> for Padding {
69 fn from(value: u32) -> Self {
70 Self::new_equal(value)
71 }
72}
73
74impl From<[u32; 2]> for Padding {
75 fn from(value: [u32; 2]) -> Self {
76 Self::new_axis(value[0], value[1])
77 }
78}
79
80impl From<[u32; 4]> for Padding {
81 fn from(value: [u32; 4]) -> Self {
82 Self::new(value[0], value[1], value[2], value[3])
83 }
84}
85
86impl Add for Padding {
87 type Output = Self;
88
89 fn add(self, rhs: Self) -> Self::Output {
90 Self::new(
91 self.top.saturating_add(rhs.top),
92 self.right.saturating_add(rhs.right),
93 self.bottom.saturating_add(rhs.bottom),
94 self.left.saturating_add(rhs.left),
95 )
96 }
97}
98
99impl Sub for Padding {
100 type Output = Self;
101
102 fn sub(self, rhs: Self) -> Self::Output {
103 Self::new(
104 self.top.saturating_sub(rhs.top),
105 self.right.saturating_sub(rhs.right),
106 self.bottom.saturating_sub(rhs.bottom),
107 self.left.saturating_sub(rhs.left),
108 )
109 }
110}