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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
use std::io;
use crossterm_cursor::TerminalCursor;
use crossterm_terminal::{Terminal, ClearType};
use crate::area::Area;
use crate::displayable_line::DisplayableLine;
use crate::text::FmtText;
pub struct TextView<'a, 't> {
area: &'a Area,
text: &'t FmtText<'t, 't>,
pub scroll: i32,
pub show_scrollbar: bool,
}
impl<'a, 't> TextView<'a, 't> {
pub fn from(
area: &'a Area,
text: &'t FmtText<'_, '_>,
) -> TextView<'a, 't> {
TextView {
area,
text,
scroll: 0,
show_scrollbar: true,
}
}
#[inline(always)]
pub fn content_height(&self) -> i32 {
self.text.lines.len() as i32
}
#[inline(always)]
pub fn scrollbar(&self) -> Option<(u16, u16)> {
if self.show_scrollbar {
self.area.scrollbar(self.scroll, self.content_height())
} else {
None
}
}
pub fn write(&self) -> io::Result<()> {
let terminal = Terminal::new();
let cursor = TerminalCursor::new();
let scrollbar = self.scrollbar();
let sx = self.area.left + self.area.width;
let mut i = self.scroll as usize;
for y in 0..self.area.height {
cursor.goto(self.area.left, self.area.top+y)?;
if i < self.text.lines.len() {
let dl = DisplayableLine::new(
self.text.skin,
&self.text.lines[i],
self.text.width,
);
print!("{}", &dl);
i += 1;
} else {
terminal.clear(ClearType::UntilNewLine)?;
}
if let Some((sctop, scbottom)) = scrollbar {
cursor.goto(sx, self.area.top+y)?;
if sctop <= y && y <= scbottom {
print!("{}", self.text.skin.scrollbar.thumb);
} else {
print!("{}", self.text.skin.scrollbar.track);
}
}
}
Ok(())
}
pub fn try_scroll_lines(&mut self, lines_count: i32) {
self.scroll = (self.scroll + lines_count)
.min(self.content_height() - (self.area.height as i32) + 1)
.max(0);
}
pub fn try_scroll_pages(&mut self, pages_count: i32) {
self.try_scroll_lines(pages_count * self.area.height as i32);
}
}