diff options
author | Caleb Bassi <calebjbassi@gmail.com> | 2019-02-15 04:43:09 -0800 |
---|---|---|
committer | Caleb Bassi <calebjbassi@gmail.com> | 2019-02-15 05:56:09 -0800 |
commit | 29b3922f9efb9f277641a63f8f1719a15cbb8d16 (patch) | |
tree | d919ba11fa5c754565c64c43cb1614f7ae4d2546 /src/window | |
parent | 3853eef2d052460982903038daac7abd2b71d12e (diff) |
refactor: project layout
Diffstat (limited to 'src/window')
-rw-r--r-- | src/window/mod.rs | 7 | ||||
-rw-r--r-- | src/window/page_state.rs | 168 | ||||
-rw-r--r-- | src/window/panel.rs | 115 | ||||
-rw-r--r-- | src/window/view.rs | 70 |
4 files changed, 360 insertions, 0 deletions
diff --git a/src/window/mod.rs b/src/window/mod.rs new file mode 100644 index 0000000..dcffe17 --- /dev/null +++ b/src/window/mod.rs @@ -0,0 +1,7 @@ +pub mod page_state; +pub mod panel; +pub mod view; + +pub use self::page_state::JoshutoPageState; +pub use self::panel::JoshutoPanel; +pub use self::view::JoshutoView; diff --git a/src/window/page_state.rs b/src/window/page_state.rs new file mode 100644 index 0000000..19967b2 --- /dev/null +++ b/src/window/page_state.rs @@ -0,0 +1,168 @@ +#[derive(Clone, Debug)] +pub struct JoshutoPageState { + pub start: usize, + pub end: usize, +} + +impl JoshutoPageState { + pub fn new() -> Self { + JoshutoPageState { start: 0, end: 0 } + } + + pub fn update_page_state( + &mut self, + index: usize, + win_rows: i32, + vec_len: usize, + offset: usize, + ) { + if self.end != win_rows as usize + self.start { + self.end = self.start + win_rows as usize; + } + if self.end > vec_len { + self.end = vec_len + } + + if self.start + offset >= index { + self.start = if index as usize <= offset { + 0 + } else { + index as usize - offset + }; + self.end = if self.start + win_rows as usize >= vec_len { + vec_len + } else { + self.start + win_rows as usize + }; + self.start = if self.end <= win_rows as usize { + 0 + } else { + self.end - win_rows as usize + }; + } + if self.end <= index + offset { + self.end = if index as usize + offset >= vec_len { + vec_len + } else { + index as usize + offset + }; + self.start = if self.end <= win_rows as usize { + 0 + } else { + self.end - win_rows as usize + }; + self.end = if self.start + win_rows as usize >= vec_len { + vec_len + } else { + self.start + win_rows as usize + }; + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + #[test] + fn shorter_than_viewable_region() { + let mut page_state = JoshutoPageState::new(); + let index = 5; + let win_rows = 37; + let vec_len = 12; + let offset = 6; + page_state.update_page_state(index, win_rows, vec_len, offset); + assert_eq!(0, page_state.start); + assert_eq!(12, page_state.end); + let index = 30; + let win_rows = 37; + let vec_len = 12; + let offset = 6; + page_state.update_page_state(index, win_rows, vec_len, offset); + assert_eq!(0, page_state.start); + assert_eq!(12, page_state.end); + } + #[test] + fn test_01() { + let mut page_state = JoshutoPageState::new(); + let index = 3; + let win_rows = 25; + let vec_len = 40; + let offset = 6; + page_state.update_page_state(index, win_rows, vec_len, offset); + assert_eq!(0, page_state.start); + assert_eq!(25, page_state.end); + } + #[test] + fn test_02() { + let mut page_state = JoshutoPageState::new(); + let index = 12; + let win_rows = 25; + let vec_len = 40; + let offset = 6; + page_state.update_page_state(index, win_rows, vec_len, offset); + assert_eq!(0, page_state.start); + assert_eq!(25, page_state.end); + } + #[test] + fn test_inside_top_offset() { + let mut page_state = JoshutoPageState::new(); + page_state.start = 10; + let index = 12; + let win_rows = 25; + let vec_len = 40; + let offset = 6; + page_state.update_page_state(index, win_rows, vec_len, offset); + assert_eq!(6, page_state.start); + assert_eq!(31, page_state.end); + } + #[test] + fn test_inside_bottom_offset() { + let mut page_state = JoshutoPageState::new(); + page_state.start = 36; + let index = 34; + let win_rows = 25; + let vec_len = 40; + let offset = 6; + page_state.update_page_state(index, win_rows, vec_len, offset); + assert_eq!(15, page_state.start); + assert_eq!(40, page_state.end); + } + #[test] + fn test_small_size() { + let mut page_state = JoshutoPageState::new(); + let index = 3; + let win_rows = 6; + let vec_len = 6; + let offset = 6; + page_state.update_page_state(index, win_rows, vec_len, offset); + assert_eq!(0, page_state.start); + assert_eq!(6, page_state.end); + let index = 0; + let win_rows = 6; + let vec_len = 6; + let offset = 6; + page_state.update_page_state(index, win_rows, vec_len, offset); + assert_eq!(0, page_state.start); + assert_eq!(6, page_state.end); + let index = 6; + let win_rows = 6; + let vec_len = 6; + let offset = 6; + page_state.update_page_state(index, win_rows, vec_len, offset); + assert_eq!(0, page_state.start); + assert_eq!(6, page_state.end); + } + #[test] + fn test_negative() { + let mut page_state = JoshutoPageState::new(); + page_state.start = 10; + page_state.end = 5; + let index = 7; + let win_rows = 30; + let vec_len = 35; + let offset = 6; + page_state.update_page_state(index, win_rows, vec_len, offset); + assert_eq!(1, page_state.start); + assert_eq!(31, page_state.end); + } +} diff --git a/src/window/panel.rs b/src/window/panel.rs new file mode 100644 index 0000000..65ab704 --- /dev/null +++ b/src/window/panel.rs @@ -0,0 +1,115 @@ +extern crate ncurses; + +use structs; +use ui; + +#[derive(Debug, Clone)] +pub struct JoshutoPanel { + pub win: ncurses::WINDOW, + pub panel: ncurses::PANEL, + pub rows: i32, + pub cols: i32, + /* coords (y, x) */ + pub coords: (usize, usize), +} + +impl std::ops::Drop for JoshutoPanel { + fn drop(&mut self) { + ncurses::del_panel(self.panel); + ncurses::delwin(self.win); + ncurses::update_panels(); + } +} + +impl JoshutoPanel { + pub fn new(rows: i32, cols: i32, coords: (usize, usize)) -> Self { + let win = ncurses::newwin(rows, cols, coords.0 as i32, coords.1 as i32); + let panel = ncurses::new_panel(win); + ncurses::leaveok(win, true); + + ncurses::wnoutrefresh(win); + JoshutoPanel { + win, + panel, + rows, + cols, + coords, + } + } + + pub fn move_to_top(&self) { + ncurses::top_panel(self.panel); + } + pub fn queue_for_refresh(&self) { + ncurses::wnoutrefresh(self.win); + } + + pub fn display_contents(&self, dirlist: &mut structs::JoshutoDirList, scroll_offset: usize) { + if self.non_empty_dir_checks(dirlist, scroll_offset) { + Self::draw_dir_list(self, dirlist, ui::wprint_entry); + } + } + + pub fn display_contents_detailed( + &self, + dirlist: &mut structs::JoshutoDirList, + scroll_offset: usize, + ) { + if self.non_empty_dir_checks(dirlist, scroll_offset) { + Self::draw_dir_list(self, dirlist, ui::wprint_entry_detailed); + } + } + + pub fn draw_dir_list( + win: &JoshutoPanel, + dirlist: &structs::JoshutoDirList, + draw_func: fn(&JoshutoPanel, &structs::JoshutoDirEntry, (usize, &str), (i32, i32)), + ) { + let dir_contents = &dirlist.contents; + let (start, end) = (dirlist.pagestate.start, dirlist.pagestate.end); + + let curr_index = dirlist.index as usize; + + for i in start..end { + let coord: (i32, i32) = (i as i32 - start as i32, 0); + + ncurses::wmove(win.win, coord.0, coord.1); + let entry = &dir_contents[i]; + + let mut attr: ncurses::attr_t = 0; + if i == curr_index { + attr = attr | ncurses::A_STANDOUT(); + } + let attrs = ui::get_theme_attr(attr, entry); + + draw_func(win, entry, attrs.0, coord); + + ncurses::mvwchgat(win.win, coord.0, coord.1, -1, attrs.1, attrs.2); + } + } + + fn non_empty_dir_checks( + &self, + dirlist: &mut structs::JoshutoDirList, + scroll_offset: usize, + ) -> bool { + if self.cols < 8 { + return false; + } + let index = dirlist.index; + let vec_len = dirlist.contents.len(); + if vec_len == 0 { + ui::wprint_empty(self, "empty"); + return false; + } + ncurses::werase(self.win); + + if index >= 0 { + dirlist + .pagestate + .update_page_state(index as usize, self.rows, vec_len, scroll_offset); + } + ncurses::wmove(self.win, 0, 0); + return true; + } +} diff --git a/src/window/view.rs b/src/window/view.rs new file mode 100644 index 0000000..ead7f0d --- /dev/null +++ b/src/window/view.rs @@ -0,0 +1,70 @@ +extern crate ncurses; + +use window::JoshutoPanel; + +#[derive(Debug)] +pub struct JoshutoView { + pub top_win: JoshutoPanel, + pub tab_win: JoshutoPanel, + pub left_win: JoshutoPanel, + pub mid_win: JoshutoPanel, + pub right_win: JoshutoPanel, + pub bot_win: JoshutoPanel, + pub win_ratio: (usize, usize, usize), +} + +impl JoshutoView { + pub fn new(win_ratio: (usize, usize, usize)) -> Self { + let sum_ratio: usize = win_ratio.0 + win_ratio.1 + win_ratio.2; + + let mut term_rows: i32 = 0; + let mut term_cols: i32 = 0; + ncurses::getmaxyx(ncurses::stdscr(), &mut term_rows, &mut term_cols); + let term_divide: i32 = term_cols / sum_ratio as i32; + + let win_xy: (i32, i32) = (1, term_cols - 5); + let win_coord: (usize, usize) = (0, 0); + let top_win = JoshutoPanel::new(win_xy.0, win_xy.1, win_coord); + + let win_xy: (i32, i32) = (1, 5); + let win_coord: (usize, usize) = (0, term_cols as usize - 5); + let tab_win = JoshutoPanel::new(win_xy.0, win_xy.1, win_coord); + + let win_xy: (i32, i32) = (term_rows - 2, (term_divide * win_ratio.0 as i32) - 1); + let win_coord: (usize, usize) = (1, 0); + let left_win = JoshutoPanel::new(win_xy.0, win_xy.1, win_coord); + + let win_xy: (i32, i32) = (term_rows - 2, (term_divide * win_ratio.1 as i32) - 1); + let win_coord: (usize, usize) = (1, term_divide as usize * win_ratio.0); + let mid_win = JoshutoPanel::new(win_xy.0, win_xy.1, win_coord); + + let win_xy: (i32, i32) = (term_rows - 2, (term_divide * win_ratio.2 as i32) - 1); + let win_coord: (usize, usize) = (1, term_divide as usize * win_ratio.2); + let right_win = JoshutoPanel::new(win_xy.0, win_xy.1, win_coord); + + let win_xy: (i32, i32) = (1, term_cols); + let win_coord: (usize, usize) = (term_rows as usize - 1, 0); + let bot_win = JoshutoPanel::new(win_xy.0, win_xy.1, win_coord); + + JoshutoView { + top_win, + tab_win, + left_win, + mid_win, + right_win, + bot_win, + win_ratio, + } + } + + pub fn resize_views(&mut self) { + let new_view = Self::new(self.win_ratio); + + self.top_win = new_view.top_win; + self.bot_win = new_view.bot_win; + self.tab_win = new_view.tab_win; + self.left_win = new_view.left_win; + self.mid_win = new_view.mid_win; + self.right_win = new_view.right_win; + } +} |