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
|
use std::cmp::{max, min};
pub const RESERVED_ROWS: usize = 3;
/// Holds the information about the displayed window of lines.
/// When there's too much lines to display in one screen, we can scroll
/// and this struct is responsible for that.
/// Scrolling is done with `scroll_to`, `scroll_up_one`, `scroll_down_one`
/// methods.
#[derive(Debug, Clone)]
pub struct ContentWindow {
/// The index of the first displayed file.
pub top: usize,
/// The index of the last displayed file.
pub bottom: usize,
/// The number of displayble file in the current folder.
pub len: usize,
/// The height of the terminal.
pub height: usize,
}
impl ContentWindow {
/// Returns a new `ContentWindow` instance with values depending of
/// number of files and height of the terminal screen.
pub fn new(len: usize, height: usize) -> Self {
ContentWindow {
top: 0,
bottom: min(len, height - RESERVED_ROWS),
len,
height: height - RESERVED_ROWS,
}
}
/// The padding around the last displayed filename
const WINDOW_PADDING: usize = 4;
/// The space of the top element
pub const WINDOW_MARGIN_TOP: usize = 2;
/// How many rows are reserved at bottom
/// Set the height of file window.
pub fn set_height(&mut self, height: usize) {
self.height = height - RESERVED_ROWS;
}
/// Move the window one line up if possible.
/// Does nothing if the index can't be reached.
pub fn scroll_up_one(&mut self, index: usize) {
if (index < self.top + Self::WINDOW_PADDING || index > self.bottom) && self.top > 0 {
self.top -= 1;
self.bottom -= 1;
}
self.scroll_to(index)
}
/// Move the window one line down if possible.
/// Does nothing if the index can't be reached.
pub fn scroll_down_one(&mut self, index: usize) {
if self.len < self.height {
return;
}
if index < self.top || index > self.bottom - Self::WINDOW_PADDING {
self.top += 1;
self.bottom += 1;
}
self.scroll_to(index)
}
/// Reset the window to the first files of the current directory.
pub fn reset(&mut self, len: usize) {
self.len = len;
self.top = 0;
self.bottom = min(len, self.height);
}
/// Scroll the window to this index if possible.
/// Does nothing if the index can't be reached.
pub fn scroll_to(&mut self, index: usize) {
if index < self.top || index > self.bottom {
self.top = max(index, Self::WINDOW_PADDING) - Self::WINDOW_PADDING;
self.bottom = self.top + min(self.len, self.height - 3);
}
}
}
|