1use saudade::Rect;
8
9pub const MENU_H: i32 = 20;
13pub const TOOLBAR_H: i32 = 26;
15pub const FILES_W: i32 = 300;
17pub const HISTORY_FRAC: f32 = 0.46;
19pub const BROWSE_PAD: i32 = 4;
23pub const NARROW_W: i32 = 800;
27
28fn narrow_left_cap(b: Rect) -> Option<i32> {
31 (b.w <= NARROW_W).then_some(b.w / 3)
32}
33
34pub fn browse_menu(b: Rect) -> Rect {
35 Rect::new(b.x, b.y, b.w, MENU_H)
36}
37
38pub fn browse_toolbar(b: Rect) -> Rect {
39 Rect::new(b.x, b.y + MENU_H, b.w, TOOLBAR_H)
40}
41
42fn content_y(b: Rect) -> i32 {
44 b.y + MENU_H + TOOLBAR_H + BROWSE_PAD
45}
46
47fn content_h(b: Rect) -> i32 {
49 (b.h - MENU_H - TOOLBAR_H - 2 * BROWSE_PAD).max(0)
50}
51
52fn history_h(b: Rect) -> i32 {
55 let avail = (content_h(b) - BROWSE_PAD).max(0);
56 (avail as f32 * HISTORY_FRAC).round() as i32
57}
58
59pub fn browse_history(b: Rect) -> Rect {
60 Rect::new(
61 b.x + BROWSE_PAD,
62 content_y(b),
63 (b.w - 2 * BROWSE_PAD).max(0),
64 history_h(b),
65 )
66}
67
68pub fn browse_files(b: Rect) -> Rect {
69 let (lower_y, lower_h) = lower_band(b);
70 Rect::new(b.x + BROWSE_PAD, lower_y, clamp_files_w(b), lower_h)
71}
72
73pub fn browse_diff(b: Rect) -> Rect {
74 let (lower_y, lower_h) = lower_band(b);
75 let files_w = clamp_files_w(b);
76 let diff_x = b.x + 2 * BROWSE_PAD + files_w;
77 let diff_w = (b.w - files_w - 3 * BROWSE_PAD).max(0);
78 Rect::new(diff_x, lower_y, diff_w, lower_h)
79}
80
81fn lower_band(b: Rect) -> (i32, i32) {
84 let lower_y = content_y(b) + history_h(b) + BROWSE_PAD;
85 let lower_h = (content_h(b) - history_h(b) - BROWSE_PAD).max(0);
86 (lower_y, lower_h)
87}
88
89fn clamp_files_w(b: Rect) -> i32 {
93 let w = FILES_W.min((b.w - 3 * BROWSE_PAD - 80).max(0));
94 match narrow_left_cap(b) {
95 Some(cap) => w.min(cap),
96 None => w,
97 }
98}
99
100pub fn review_menu(b: Rect) -> Rect {
107 browse_menu(b)
108}
109
110fn review_content_y(b: Rect) -> i32 {
112 b.y + MENU_H + BROWSE_PAD
113}
114
115fn review_content_h(b: Rect) -> i32 {
117 (b.h - MENU_H - 2 * BROWSE_PAD).max(0)
118}
119
120fn review_branches_h(b: Rect) -> i32 {
123 let avail = (review_content_h(b) - BROWSE_PAD).max(0);
124 (avail as f32 * HISTORY_FRAC).round() as i32
125}
126
127pub fn review_branches(b: Rect) -> Rect {
128 Rect::new(
129 b.x + BROWSE_PAD,
130 review_content_y(b),
131 (b.w - 2 * BROWSE_PAD).max(0),
132 review_branches_h(b),
133 )
134}
135
136fn review_lower_band(b: Rect) -> (i32, i32) {
138 let lower_y = review_content_y(b) + review_branches_h(b) + BROWSE_PAD;
139 let lower_h = (review_content_h(b) - review_branches_h(b) - BROWSE_PAD).max(0);
140 (lower_y, lower_h)
141}
142
143pub fn review_files(b: Rect) -> Rect {
144 let (lower_y, lower_h) = review_lower_band(b);
145 Rect::new(b.x + BROWSE_PAD, lower_y, clamp_files_w(b), lower_h)
146}
147
148pub fn review_diff(b: Rect) -> Rect {
149 let (lower_y, lower_h) = review_lower_band(b);
150 let files_w = clamp_files_w(b);
151 let diff_x = b.x + 2 * BROWSE_PAD + files_w;
152 let diff_w = (b.w - files_w - 3 * BROWSE_PAD).max(0);
153 Rect::new(diff_x, lower_y, diff_w, lower_h)
154}
155
156const LEFT_W: i32 = 320;
165const PAD: i32 = 6;
167const GUTTER: i32 = 6;
170const HEADING_H: i32 = 18;
171const BTN_BAND_H: i32 = 34;
173const BTN_GAP: i32 = 4;
174const LEFT_BTN_H: i32 = 24;
175const AMEND_H: i32 = 24;
176const COMMIT_BTN_H: i32 = 26;
177
178pub fn commit_menu(b: Rect) -> Rect {
179 Rect::new(b.x, b.y, b.w, MENU_H)
180}
181
182fn content_top(b: Rect) -> i32 {
183 b.y + MENU_H
184}
185fn content_height(b: Rect) -> i32 {
186 (b.h - MENU_H).max(0)
187}
188
189fn sections_h(b: Rect) -> i32 {
193 (content_height(b) - BTN_BAND_H).max(0)
194}
195fn section_h(b: Rect) -> i32 {
197 sections_h(b) / 2
198}
199fn top_label_y(b: Rect) -> i32 {
200 content_top(b) + 2
201}
202fn top_pane_y(b: Rect) -> i32 {
203 top_label_y(b) + HEADING_H
204}
205fn top_pane_h(b: Rect) -> i32 {
206 (section_h(b) - HEADING_H - 4).max(0)
207}
208fn bottom_label_y(b: Rect) -> i32 {
209 content_top(b) + section_h(b) + 2
210}
211fn bottom_pane_y(b: Rect) -> i32 {
212 bottom_label_y(b) + HEADING_H
213}
214fn bottom_pane_h(b: Rect) -> i32 {
215 (sections_h(b) - section_h(b) - HEADING_H - 4).max(0)
216}
217fn btn_y(b: Rect, bh: i32) -> i32 {
220 content_top(b) + sections_h(b) + ((BTN_BAND_H - bh) / 2).max(0)
221}
222
223fn left_x(b: Rect) -> i32 {
226 b.x + PAD
227}
228fn left_col_w(b: Rect) -> i32 {
232 match narrow_left_cap(b) {
233 Some(cap) => LEFT_W.min(cap),
234 None => LEFT_W,
235 }
236}
237fn left_w(b: Rect) -> i32 {
238 (left_col_w(b) - PAD - GUTTER / 2).max(0)
239}
240
241pub fn commit_unstaged_label(b: Rect) -> Rect {
242 Rect::new(left_x(b), top_label_y(b), left_w(b), HEADING_H)
243}
244
245pub fn commit_unstaged_list(b: Rect) -> Rect {
246 Rect::new(left_x(b), top_pane_y(b), left_w(b), top_pane_h(b))
247}
248
249pub fn commit_staged_label(b: Rect) -> Rect {
250 Rect::new(left_x(b), bottom_label_y(b), left_w(b), HEADING_H)
251}
252
253pub fn commit_staged_list(b: Rect) -> Rect {
254 Rect::new(left_x(b), bottom_pane_y(b), left_w(b), bottom_pane_h(b))
255}
256
257fn left_btn_w(b: Rect) -> i32 {
261 ((left_w(b) - 2 * BTN_GAP) / 3).max(0)
262}
263
264fn left_btn_x(b: Rect, slot: i32) -> i32 {
266 left_x(b) + slot * (left_btn_w(b) + BTN_GAP)
267}
268
269pub fn commit_stage_btn(b: Rect) -> Rect {
270 Rect::new(
271 left_btn_x(b, 0),
272 btn_y(b, LEFT_BTN_H),
273 left_btn_w(b),
274 LEFT_BTN_H,
275 )
276}
277
278pub fn commit_unstage_btn(b: Rect) -> Rect {
279 Rect::new(
280 left_btn_x(b, 1),
281 btn_y(b, LEFT_BTN_H),
282 left_btn_w(b),
283 LEFT_BTN_H,
284 )
285}
286
287pub fn commit_rescan_btn(b: Rect) -> Rect {
288 Rect::new(
289 left_btn_x(b, 2),
290 btn_y(b, LEFT_BTN_H),
291 left_btn_w(b),
292 LEFT_BTN_H,
293 )
294}
295
296fn right_inner_x(b: Rect) -> i32 {
301 b.x + left_col_w(b) + GUTTER / 2
302}
303fn right_inner_w(b: Rect) -> i32 {
305 (b.x + b.w - PAD - right_inner_x(b)).max(0)
306}
307
308pub fn commit_diff_label(b: Rect) -> Rect {
309 Rect::new(
310 right_inner_x(b),
311 top_label_y(b),
312 right_inner_w(b),
313 HEADING_H,
314 )
315}
316
317pub fn commit_diff(b: Rect) -> Rect {
318 Rect::new(
319 right_inner_x(b),
320 top_pane_y(b),
321 right_inner_w(b),
322 top_pane_h(b),
323 )
324}
325
326pub fn commit_msg_label(b: Rect) -> Rect {
327 Rect::new(
328 right_inner_x(b),
329 bottom_label_y(b),
330 right_inner_w(b),
331 HEADING_H,
332 )
333}
334
335pub fn commit_editor(b: Rect) -> Rect {
336 Rect::new(
337 right_inner_x(b),
338 bottom_pane_y(b),
339 right_inner_w(b),
340 bottom_pane_h(b),
341 )
342}
343
344pub fn commit_amend(b: Rect) -> Rect {
345 Rect::new(right_inner_x(b), btn_y(b, AMEND_H), 180, AMEND_H)
346}
347
348pub fn commit_commit_btn(b: Rect) -> Rect {
349 let w = 110;
350 Rect::new(
351 right_inner_x(b) + right_inner_w(b) - w,
352 btn_y(b, COMMIT_BTN_H),
353 w,
354 COMMIT_BTN_H,
355 )
356}