aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main.rs2
-rw-r--r--src/widget.rs131
2 files changed, 133 insertions, 0 deletions
diff --git a/src/main.rs b/src/main.rs
index 9c186c9..304f6fc 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -6,11 +6,13 @@ mod command;
6mod consts; 6mod consts;
7mod dither; 7mod dither;
8mod error; 8mod error;
9mod guide;
9mod lisp; 10mod lisp;
10mod message; 11mod message;
11mod symmetry; 12mod symmetry;
12mod undo; 13mod undo;
13mod utils; 14mod utils;
15mod widget;
14 16
15use { 17use {
16 app::AppState, 18 app::AppState,
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 @@
1use crate::rect;
2
3use sdl2::{rect::Rect, render::Canvas, video::Window};
4
5#[derive(Debug, Clone)]
6pub struct Container {
7 pub start: (i32, i32),
8 pub width: u32,
9 pub height: u32,
10}
11
12pub enum Size {
13 Max,
14 Absolute(u32),
15}
16
17#[derive(Debug, Copy, PartialEq, Clone)]
18pub enum Offset {
19 Top(u32),
20 Left(u32),
21 Bottom(u32),
22 Right(u32),
23}
24
25#[derive(Debug, Copy, PartialEq, Clone)]
26pub enum HorAlign {
27 Left,
28 Center,
29 Right,
30}
31
32#[derive(Debug, Copy, PartialEq, Clone)]
33pub enum VertAlign {
34 Top,
35 Center,
36 Bottom,
37}
38
39impl 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
50impl 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)]
119pub struct Widget {
120 width: u32,
121 height: u32,
122}
123
124impl 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}