diff options
Diffstat (limited to 'src/widget.rs')
-rw-r--r-- | src/widget.rs | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/src/widget.rs b/src/widget.rs new file mode 100644 index 0000000..5749ae2 --- /dev/null +++ b/src/widget.rs | |||
@@ -0,0 +1,131 @@ | |||
1 | use crate::rect; | ||
2 | |||
3 | use sdl2::{rect::Rect, render::Canvas, video::Window}; | ||
4 | |||
5 | #[derive(Debug, Clone)] | ||
6 | pub struct Container { | ||
7 | pub start: (i32, i32), | ||
8 | pub width: u32, | ||
9 | pub height: u32, | ||
10 | } | ||
11 | |||
12 | pub enum Size { | ||
13 | Max, | ||
14 | Absolute(u32), | ||
15 | } | ||
16 | |||
17 | #[derive(Debug, Copy, PartialEq, Clone)] | ||
18 | pub enum Offset { | ||
19 | Top(u32), | ||
20 | Left(u32), | ||
21 | Bottom(u32), | ||
22 | Right(u32), | ||
23 | } | ||
24 | |||
25 | #[derive(Debug, Copy, PartialEq, Clone)] | ||
26 | pub enum HorAlign { | ||
27 | Left, | ||
28 | Center, | ||
29 | Right, | ||
30 | } | ||
31 | |||
32 | #[derive(Debug, Copy, PartialEq, Clone)] | ||
33 | pub enum VertAlign { | ||
34 | Top, | ||
35 | Center, | ||
36 | Bottom, | ||
37 | } | ||
38 | |||
39 | impl Offset { | ||
40 | fn apply(self, size: u32) -> u32 { | ||
41 | match self { | ||
42 | Self::Top(t) => t, | ||
43 | Self::Left(l) => l, | ||
44 | Self::Bottom(b) => size - b, | ||
45 | Self::Right(r) => size - r, | ||
46 | } | ||
47 | } | ||
48 | } | ||
49 | |||
50 | impl Container { | ||
51 | pub fn uninit() -> Self { | ||
52 | Self { | ||
53 | start: (0, 0), | ||
54 | width: 0, | ||
55 | height: 0, | ||
56 | } | ||
57 | } | ||
58 | |||
59 | pub fn new(start_x: Offset, start_y: Offset, canvas: &Canvas<Window>) -> Self { | ||
60 | let (winsize_x, winsize_y) = canvas.window().size(); | ||
61 | Self { | ||
62 | start: ( | ||
63 | start_x.apply(winsize_x) as i32, | ||
64 | start_y.apply(winsize_y) as i32, | ||
65 | ), | ||
66 | width: 0, | ||
67 | height: 0, | ||
68 | } | ||
69 | } | ||
70 | |||
71 | pub fn width(mut self, size: Size, canvas: &Canvas<Window>) -> Self { | ||
72 | match size { | ||
73 | Size::Max => { | ||
74 | let (winsize_x, _) = canvas.window().size(); | ||
75 | self.width = winsize_x; | ||
76 | } | ||
77 | Size::Absolute(x) => { | ||
78 | self.width = x; | ||
79 | } | ||
80 | } | ||
81 | self | ||
82 | } | ||
83 | |||
84 | pub fn height(mut self, size: Size, canvas: &Canvas<Window>) -> Self { | ||
85 | match size { | ||
86 | Size::Max => { | ||
87 | let (_, winsize_y) = canvas.window().size(); | ||
88 | self.height = winsize_y; | ||
89 | } | ||
90 | Size::Absolute(y) => { | ||
91 | self.height = y; | ||
92 | } | ||
93 | } | ||
94 | self | ||
95 | } | ||
96 | |||
97 | pub fn place(&self, widget: &mut Container, hor_align: HorAlign, vert_align: VertAlign) { | ||
98 | let x = self.start.0 | ||
99 | + match hor_align { | ||
100 | HorAlign::Left => 0, | ||
101 | HorAlign::Center => ((self.width / 2).saturating_sub(widget.width / 2)) as i32, | ||
102 | HorAlign::Right => (self.width - widget.width) as i32, | ||
103 | }; | ||
104 | let y = self.start.1 | ||
105 | + match vert_align { | ||
106 | VertAlign::Top => 0, | ||
107 | VertAlign::Center => ((self.height / 2).saturating_sub(widget.height / 2)) as i32, | ||
108 | VertAlign::Bottom => (self.height - widget.height) as i32, | ||
109 | }; | ||
110 | widget.start = (x, y); | ||
111 | } | ||
112 | |||
113 | pub fn area(&self) -> Rect { | ||
114 | rect!(self.start.0, self.start.1, self.width, self.height) | ||
115 | } | ||
116 | } | ||
117 | |||
118 | #[derive(Debug, Copy, Clone)] | ||
119 | pub struct Widget { | ||
120 | width: u32, | ||
121 | height: u32, | ||
122 | } | ||
123 | |||
124 | impl Widget { | ||
125 | pub fn linear_layout(widgets: &[Widget], padding: u32) -> Widget { | ||
126 | Widget { | ||
127 | width: widgets.iter().fold(0, |acc, x| acc + x.width + padding), | ||
128 | height: widgets.iter().map(|x| x.height).max().unwrap_or(0), | ||
129 | } | ||
130 | } | ||
131 | } | ||