summaryrefslogtreecommitdiffstats
path: root/src/content_window.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/content_window.rs')
-rw-r--r--src/content_window.rs86
1 files changed, 59 insertions, 27 deletions
diff --git a/src/content_window.rs b/src/content_window.rs
index 6c0ac1c..a734387 100644
--- a/src/content_window.rs
+++ b/src/content_window.rs
@@ -1,6 +1,5 @@
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.
@@ -8,37 +7,59 @@ pub const RESERVED_ROWS: usize = 3;
/// methods.
#[derive(Debug, Clone)]
pub struct ContentWindow {
- /// The index of the first displayed file.
+ /// The index of the first displayed element.
pub top: usize,
- /// The index of the last displayed file.
+ /// The index of the last displayed element + 1.
pub bottom: usize,
- /// The number of displayble file in the current folder.
+ /// The number of displayble elements.
pub len: usize,
/// The height of the terminal.
pub height: usize,
}
impl ContentWindow {
+ /// 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 for the header ?
+ pub const HEADER_ROWS: usize = 3;
+ /// How many rows are reserved for the footer ?
+ const FOOTER_ROWS: usize = 1;
+ /// Footer and bottom padding
+ const BOTTOM_ROWS: usize = 2;
+
+ /// How many rows could be displayed with given height ?
+ /// It's not the number of rows displayed since the content may
+ /// not be long enough to fill the window.
+ fn nb_displayed_rows(height: usize) -> usize {
+ height - Self::HEADER_ROWS - Self::FOOTER_ROWS
+ }
+
+ /// Default value for the bottom index.
+ /// minimum of terminal height minus reserved rows and the length of the content.
+ fn default_bottom(len: usize, height: usize) -> usize {
+ min(height - Self::BOTTOM_ROWS, len)
+ }
+
/// 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 {
+ /// number of displayable elements and height of the terminal screen.
+ pub fn new(len: usize, terminal_height: usize) -> Self {
+ let height = Self::nb_displayed_rows(terminal_height);
+ let top = 0;
+ let bottom = Self::default_bottom(len, height);
ContentWindow {
- top: 0,
- bottom: min(len, height - RESERVED_ROWS),
+ top,
+ bottom,
len,
- height: height - RESERVED_ROWS,
+ height,
}
}
- /// 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;
+ pub fn set_height(&mut self, terminal_height: usize) {
+ self.height = Self::nb_displayed_rows(terminal_height);
+ self.bottom = Self::default_bottom(self.len, self.height);
}
/// Move the window one line up if possible.
@@ -61,23 +82,34 @@ impl ContentWindow {
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 {
+ if self.len < self.height {
+ return;
+ }
+ if self.is_index_outside_window(index) {
self.top = max(index, Self::WINDOW_PADDING) - Self::WINDOW_PADDING;
- self.bottom = self.top + min(self.len, self.height - 3);
+ self.bottom = (self.top + Self::default_bottom(self.height, self.len))
+ .checked_sub(Self::BOTTOM_ROWS)
+ .unwrap_or(2);
}
}
+
+ /// Reset the window to the first item of the content.
+ pub fn reset(&mut self, len: usize) {
+ self.len = len;
+ self.top = 0;
+ self.bottom = Self::default_bottom(self.len, self.height);
+ }
+
+ /// True iff the index is outside the displayed window or
+ /// too close from the border.
+ /// User shouldn't be able to reach the last elements
+ fn is_index_outside_window(&self, index: usize) -> bool {
+ index < self.top || index >= self.bottom
+ }
}