1use {Location, UIButton};
2
3const DECORATION_SIZE: i32 = 8;
4const DECORATION_TOP_SIZE: i32 = 32;
5
6#[cfg(target_endian = "little")]
7macro_rules! auto_endian(
8 ($a: expr, $r: expr, $g: expr, $b: expr) => {
9 [$b, $g, $r, $a]
10 }
11);
12
13#[cfg(target_endian = "big")]
14macro_rules! auto_endian(
15 ($a: expr, $r: expr, $g: expr, $b: expr) => {
16 [$a, $r, $g, $b]
17 }
18);
19
20const INACTIVE_BORDER: [u8; 4] = auto_endian!(0xFF, 0x60, 0x60, 0x60);
22const ACTIVE_BORDER: [u8; 4] = auto_endian!(0xFF, 0x80, 0x80, 0x80);
23const RED_BUTTON_REGULAR: [u8; 4] = auto_endian!(0xFF, 0xB0, 0x40, 0x40);
24const RED_BUTTON_HOVER: [u8; 4] = auto_endian!(0xFF, 0xFF, 0x40, 0x40);
25const GREEN_BUTTON_REGULAR: [u8; 4] = auto_endian!(0xFF, 0x40, 0xB0, 0x40);
26const GREEN_BUTTON_HOVER: [u8; 4] = auto_endian!(0xFF, 0x40, 0xFF, 0x40);
27const YELLOW_BUTTON_REGULAR: [u8; 4] = auto_endian!(0xFF, 0xB0, 0xB0, 0x40);
28const YELLOW_BUTTON_HOVER: [u8; 4] = auto_endian!(0xFF, 0xFF, 0xFF, 0x40);
29const YELLOW_BUTTON_DISABLED: [u8; 4] = auto_endian!(0xFF, 0x80, 0x80, 0x20);
30
31pub(crate) fn compute_location((x, y): (f64, f64), (w, h): (i32, i32)) -> Location {
33 if y <= DECORATION_TOP_SIZE as f64 {
34 if x <= DECORATION_SIZE as f64 {
36 Location::TopLeft
37 } else if x <= (w + DECORATION_SIZE) as f64 {
38 if y <= DECORATION_SIZE as f64 {
39 Location::Top
40 } else {
41 if (w >= 24) && (x > (w + DECORATION_SIZE - 24) as f64) && (x <= (w + DECORATION_SIZE) as f64)
43 && (y > DECORATION_SIZE as f64) && (y <= (DECORATION_SIZE + 16) as f64)
44 {
45 Location::Button(UIButton::Close)
46 } else if (w >= 56) && (x > (w + DECORATION_SIZE - 56) as f64)
47 && (x <= (w + DECORATION_SIZE - 32) as f64)
48 && (y > DECORATION_SIZE as f64)
49 && (y <= (DECORATION_SIZE + 16) as f64)
50 {
51 Location::Button(UIButton::Maximize)
52 } else if (w >= 88) && (x > (w + DECORATION_SIZE - 88) as f64)
53 && (x <= (w + DECORATION_SIZE - 64) as f64)
54 && (y > DECORATION_SIZE as f64)
55 && (y <= (DECORATION_SIZE + 16) as f64)
56 {
57 Location::Button(UIButton::Minimize)
58 } else {
59 Location::TopBar
60 }
61 }
62 } else {
63 Location::TopRight
64 }
65 } else if y <= (DECORATION_TOP_SIZE + h) as f64 {
66 if x <= DECORATION_SIZE as f64 {
67 Location::Left
68 } else if x <= (w + DECORATION_SIZE) as f64 {
69 Location::Inside
70 } else {
71 Location::Right
72 }
73 } else {
74 if x <= DECORATION_SIZE as f64 {
75 Location::BottomLeft
76 } else if x <= (w + DECORATION_SIZE) as f64 {
77 Location::Bottom
78 } else {
79 Location::BottomRight
80 }
81 }
82}
83
84pub(crate) fn subsurface_offset() -> (i32, i32) {
87 (DECORATION_SIZE, DECORATION_TOP_SIZE)
88}
89
90pub fn subtract_borders(width: i32, height: i32) -> (i32, i32) {
92 (
93 width - 2 * (DECORATION_SIZE as i32),
94 height - DECORATION_SIZE as i32 - DECORATION_TOP_SIZE as i32,
95 )
96}
97
98pub fn add_borders(width: i32, height: i32) -> (i32, i32) {
100 (
101 width + 2 * (DECORATION_SIZE as i32),
102 height + DECORATION_SIZE as i32 + DECORATION_TOP_SIZE as i32,
103 )
104}
105
106pub(crate) fn pxcount(w: i32, h: i32) -> i32 {
109 (w + 2 * DECORATION_SIZE) * (h + DECORATION_SIZE + DECORATION_TOP_SIZE)
110}
111
112pub(crate) fn draw_contents(canvas: &mut [u8], w: u32, h: u32, activated: bool, _maximized: bool,
116 maximizable: bool, ptr_location: Location) {
117 let ds = DECORATION_SIZE as u32;
118 let dts = DECORATION_TOP_SIZE as u32;
119 let mut canvas = Canvas::new(w + 2 * ds, h + ds + dts, canvas);
120 let border_rectangles = [
122 (0, 0, w + 2 * ds, dts+1), (0, dts, ds+1, h), (w + ds-1, dts, ds+1, h), (0, h + dts-1, w + 2 * ds, ds+1), ];
127
128 let border_color = if activated {
135 ACTIVE_BORDER
136 } else {
137 INACTIVE_BORDER
138 };
139 for &(x, y, w, h) in &border_rectangles {
140 for xx in x..(x + w) {
141 for yy in y..(y + h) {
142 canvas.put_pixel(xx, yy, border_color);
143 }
144 }
145 }
146
147 if w >= 24 {
149 let button_color = if let Location::Button(UIButton::Close) = ptr_location {
150 RED_BUTTON_HOVER
151 } else {
152 RED_BUTTON_REGULAR
153 };
154 for xx in (w + ds - 24)..(w + ds) {
155 for yy in ds..(ds + 16) {
156 canvas.put_pixel(xx, yy, button_color);
157 }
158 }
159 }
160
161 if w >= 56 {
163 let button_color = if maximizable {
164 if let Location::Button(UIButton::Maximize) = ptr_location {
165 YELLOW_BUTTON_HOVER
166 } else {
167 YELLOW_BUTTON_REGULAR
168 }
169 } else {
170 YELLOW_BUTTON_DISABLED
171 };
172 for xx in (w + ds - 56)..(w + ds - 32) {
173 for yy in ds..(ds + 16) {
174 canvas.put_pixel(xx, yy, button_color);
175 }
176 }
177 }
178
179 if w >= 88 {
181 let button_color = if let Location::Button(UIButton::Minimize) = ptr_location {
182 GREEN_BUTTON_HOVER
183 } else {
184 GREEN_BUTTON_REGULAR
185 };
186 for xx in (w + ds - 88)..(w + ds - 64) {
187 for yy in ds..(ds + 16) {
188 canvas.put_pixel(xx, yy, button_color);
189 }
190 }
191 }
192}
193
194struct Canvas<'a> {
195 width: u32,
196 contents: &'a mut [u8]
197}
198
199impl<'a> Canvas<'a> {
200 fn new(width: u32, height: u32, contents: &mut[u8]) -> Canvas {
201 debug_assert!(contents.len() == (width*height*4) as usize);
202 Canvas { width, contents }
203 }
204
205 #[inline]
206 fn put_pixel(&mut self, x: u32, y: u32, val: [u8; 4]) {
207 let idx = ((y*self.width + x)*4) as usize;
208 self.contents[idx + 0] = val[0];
209 self.contents[idx + 1] = val[1];
210 self.contents[idx + 2] = val[2];
211 self.contents[idx + 3] = val[3];
212 }
213}