1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
use crossterm::Terminal;
pub trait AreaContent {
fn height() -> u16;
}
#[derive(Debug, PartialEq, Eq)]
pub struct Area {
pub left: u16,
pub top: u16,
pub width: u16,
pub height: u16,
}
impl Area {
pub fn uninitialized() -> Area {
Area { left: 0, top:0, height:1, width:5 }
}
pub fn new(
left: u16,
top: u16,
width: u16,
height: u16,
) -> Area {
assert!(width > 4);
Area {
left,
top,
width,
height,
}
}
pub fn full_screen() -> Area {
let (width, height) = terminal_size();
Area {
left: 0,
top: 0,
width,
height,
}
}
pub fn pad(&mut self, dx: u16, dy: u16) {
self.left += dx;
self.top += dy;
self.width -= 2*dx;
self.height -= 2*dy;
}
pub fn scrollbar(
&self,
scroll: i32,
content_height: i32,
) -> Option<(u16, u16)> {
let h = self.height as i32;
if content_height <= h {
return None;
}
let sbh = h * h / content_height;
let sc = scroll * h / content_height;
Some((sc as u16, (sc + sbh + 1).min(h+1) as u16))
}
}
pub fn terminal_size() -> (u16, u16) {
let (w, h) = Terminal::new().terminal_size();
(w + 1, h + 1)
}