diff options
author | Aram Drevekenin <aram@poor.dev> | 2020-07-04 13:38:31 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-07-04 13:38:31 +0200 |
commit | d317ea45ef590a49e1573691baf901c5d051b198 (patch) | |
tree | d44f342ddb4430cbc64f97b27b4744e6a71f83af | |
parent | 356904fa04e1b8cc0881e9c522e26b21f3592512 (diff) |
feat(ui): allow zooming in/out/reset (#61)
* feat(ui): allow zooming in/out/reset
* style(format): rustfmt
* refactor(state): consolidate percentage calculation
* style(format): rustfmt
* fix(tests): clean up temporary files in specific test
40 files changed, 665 insertions, 51 deletions
@@ -164,15 +164,14 @@ where self.render(); } pub fn enter_selected(&mut self) { - if let Some(index) = &self.board.get_selected_index() { - &self.board.push_previous_index(&index); - } + self.board.record_current_index_and_zoom_level(); if let Some(tile) = &self.board.currently_selected() { let selected_name = &tile.name; if let Some(file_or_folder) = self.file_tree.item_in_current_folder(&selected_name) { match file_or_folder { FileOrFolder::Folder(_) => { self.file_tree.enter_folder(&selected_name); + self.board.reset_zoom_index(); self.board.reset_selected_index(); self.render_and_update_board(); } @@ -182,10 +181,13 @@ where } } pub fn go_up(&mut self) { - if let Some(index) = self.board.pop_previous_index() { - self.board.set_selected_index(&index); - } let succeeded = self.file_tree.leave_folder(); + if let Some((index, zoom_level)) = self.board.pop_previous_index_and_zoom_level() { + if let Some(index) = index { + self.board.set_selected_index(&index); + } + self.board.set_zoom_index(zoom_level); + } self.render_and_update_board(); if !succeeded { let _ = self.event_sender.try_send(Event::PathError); @@ -250,6 +252,21 @@ where pub fn increment_failed_to_read(&mut self) { self.file_tree.failed_to_read += 1; } + pub fn zoom_in(&mut self) { + let current_folder = self.file_tree.get_current_folder(); + self.board.zoom_in(current_folder); + self.render(); + } + pub fn zoom_out(&mut self) { + let current_folder = self.file_tree.get_current_folder(); + self.board.zoom_out(current_folder); + self.render(); + } + pub fn reset_zoom(&mut self) { + let current_folder = self.file_tree.get_current_folder(); + self.board.reset_zoom(current_folder); + self.render(); + } fn remove_file_from_ui(&mut self, file_to_delete: &FileToDelete) { self.file_tree.space_freed += file_to_delete.size; self.file_tree.delete_file(file_to_delete); diff --git a/src/input/controls.rs b/src/input/controls.rs index 14b8ee1..4adaca9 100644 --- a/src/input/controls.rs +++ b/src/input/controls.rs @@ -49,6 +49,15 @@ pub fn handle_keypress_loading_mode<B: Backend>(evt: Event, app: &mut App<B>) { key!(char 'k') | key!(Up) | key!(ctrl 'p') => { app.move_selected_up(); } + key!(char '+') => { + app.zoom_in(); + } + key!(char '-') => { + app.zoom_out(); + } + key!(char '0') => { + app.reset_zoom(); + } key!(char '\n') => { app.handle_enter(); } @@ -82,6 +91,15 @@ pub fn handle_keypress_normal_mode<B: Backend>(evt: Event, app: &mut App<B>) { key!(char 'k') | key!(Up) | key!(ctrl 'p') => { app.move_selected_up(); } + key!(char '+') => { + app.zoom_in(); + } + key!(char '-') => { + app.zoom_out(); + } + key!(char '0') => { + app.reset_zoom(); + } key!(char '\n') => { app.handle_enter(); } diff --git a/src/state/tiles/board.rs b/src/state/tiles/board.rs index 851a6f9..6537371 100644 --- a/src/state/tiles/board.rs +++ b/src/state/tiles/board.rs @@ -8,7 +8,8 @@ pub struct Board { pub tiles: Vec<Tile>, pub unrenderable_tile_coordinates: Option<(u16, u16)>, pub selected_index: Option<usize>, // None means nothing is selected - pub previous_indices: Vec<usize>, // Stack of previously selected indices + pub previous_indices_and_zoom_level: Vec<(Option<usize>, usize)>, // Stack of previous stats + pub zoom_level: usize, area: Rect, files: Vec<FileMetadata>, } @@ -18,9 +19,10 @@ impl Board { Board { tiles: vec![], unrenderable_tile_coordinates: None, - files: files_in_folder(folder), + files: files_in_folder(folder, 0), selected_index: None, - previous_indices: vec![], + previous_indices_and_zoom_level: vec![], + zoom_level: 0, area: Rect { x: 0, y: 0, @@ -30,7 +32,7 @@ impl Board { } } pub fn change_files(&mut self, folder: &Folder) { - self.files = files_in_folder(folder); + self.files = files_in_folder(folder, self.zoom_level); self.fill(); } pub fn change_area(&mut self, area: &Rect) { @@ -63,11 +65,8 @@ impl Board { None => None, } } - pub fn push_previous_index(&mut self, index: &usize) { - self.previous_indices.push(*index); - } - pub fn pop_previous_index(&mut self) -> Option<usize> { - self.previous_indices.pop() + pub fn pop_previous_index_and_zoom_level(&mut self) -> Option<(Option<usize>, usize)> { + self.previous_indices_and_zoom_level.pop() } pub fn move_to_largest_folder(&mut self) { let next_index = self @@ -170,4 +169,33 @@ impl Board { None => self.set_selected_index(&0), } } + pub fn zoom_in(&mut self, folder: &Folder) { + if self.zoom_level < self.files.len() { + self.zoom_level += 1; + self.files = files_in_folder(folder, self.zoom_level); + self.fill(); + } + } + pub fn zoom_out(&mut self, folder: &Folder) { + if self.zoom_level > 0 { + self.zoom_level -= 1; + self.files = files_in_folder(folder, self.zoom_level); + self.fill(); + } + } + pub fn reset_zoom(&mut self, folder: &Folder) { + self.zoom_level = 0; + self.files = files_in_folder(folder, self.zoom_level); + self.fill(); + } + pub fn reset_zoom_index(&mut self) { + self.zoom_level = 0; + } + pub fn set_zoom_index(&mut self, index: usize) { + self.zoom_level = index; + } + pub fn record_current_index_and_zoom_level(&mut self) { + self.previous_indices_and_zoom_level + .push((self.get_selected_index(), self.zoom_level)); + } } diff --git a/src/state/tiles/files_in_folder.rs b/src/state/tiles/files_in_folder.rs index e6c696f..a8a0065 100644 --- a/src/state/tiles/files_in_folder.rs +++ b/src/state/tiles/files_in_folder.rs @@ -17,7 +17,17 @@ pub struct FileMetadata { pub file_type: FileType, } -pub fn files_in_folder(folder: &Folder) -> Vec<FileMetadata> { +fn calculate_percentage(size: u64, total_size: u64, total_files_in_parent: usize) -> f64 { + if size == 0 && total_size == 0 { + // if all files in the folder are of size 0, we'll want to display them all as + // the same size + 1.0 / total_files_in_parent as f64 + } else { + size as f64 / total_size as f64 + } +} + +pub fn files_in_folder(folder: &Folder, offset: usize) -> Vec<FileMetadata> { let mut files = Vec::new(); let total_size = folder.size; for (name, file_or_folder) in &folder.contents { @@ -28,13 +38,7 @@ pub fn files_in_folder(folder: &Folder) -> Vec<FileMetadata> { FileOrFolder::Folder(folder) => (Some(folder.num_descendants), FileType::Folder), FileOrFolder::File(_file) => (None, FileType::File), }; - let percentage = if size == 0 && total_size == 0 { - // if all files in the folder are of size 0, we'll want to display them all as - // the same size - 1.0 / folder.contents.len() as f64 - } else { - size as f64 / total_size as f64 - }; + let percentage = calculate_percentage(size, total_size, folder.contents.len()); FileMetadata { size, name, @@ -53,5 +57,18 @@ pub fn files_in_folder(folder: &Folder) -> Vec<FileMetadata> { .expect("could not compare percentage") } }); + if offset > 0 { + let removed_items = files.drain(..offset); + let number_of_files_without_removed_contents = folder.contents.len() - removed_items.len(); + let removed_size = removed_items.fold(0, |acc, file| acc + file.size); + let size_without_removed_items = total_size - removed_size; + for i in 0..files.len() { + files[i].percentage = calculate_percentage( + files[i].size, + size_without_removed_items, + number_of_files_without_removed_contents, + ); + } + } files } diff --git a/src/tests/cases/snapshots/diskonaut__tests__cases__ui__cannot_move_into_small_files.snap b/src/tests/cases/snapshots/diskonaut__tests__cases__ui__cannot_move_into_small_files.snap index a08c8fd..1e4b6fe 100644 --- a/src/tests/cases/snapshots/diskonaut__tests__cases__ui__cannot_move_into_small_files.snap +++ b/src/tests/cases/snapshots/diskonaut__tests__cases__ui__cannot_move_into_small_files.snap @@ -51,5 +51,5 @@ expression: "&terminal_draw_events_mirror[0]" │ │xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx│ └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┴─────────────────────────────────┘ (x = Small files) - <arrows> - move around, <ENTER> - enter folder, <ESC> - parent folder, <DELETE> - delete, <q> - quit + <arrows> - move around, <ENTER> - enter folder, <ESC> - parent folder, <DELETE> - delete, <+/-/0> - zoom in/out/reset, <q> - quit diff --git a/src/tests/cases/snapshots/diskonaut__tests__cases__ui__clear_selection_when_moving_off_screen_edges.snap b/src/tests/cases/snapshots/diskonaut__tests__cases__ui__clear_selection_when_moving_off_screen_edges.snap index 149da00..f5f0d6a 100644 --- a/src/tests/cases/snapshots/diskonaut__tests__cases__ui__clear_selection_when_moving_off_screen_edges.snap +++ b/src/tests/cases/snapshots/diskonaut__tests__cases__ui__clear_selection_when_moving_off_screen_edges.snap @@ -51,5 +51,5 @@ expression: "&terminal_draw_events_mirror[0]" │ │ │ └─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┴──────────────────────────────────────────────────────────────┘ (x = Small files) - <arrows> - move around, <ENTER> - enter folder, <ESC> - parent folder, <DELETE> - delete, <q> - quit + <arrows> - move around, <ENTER> - enter folder, <ESC> - parent folder, <DELETE> - delete, <+/-/0> - zoom in/out/reset, <q> - quit diff --git a/src/tests/cases/snapshots/diskonaut__tests__cases__ui__delete_file.snap b/src/tests/cases/snapshots/diskonaut__tests__cases__ui__delete_file.snap index e13f850..3f86673 100644 --- a/src/tests/cases/snapshots/diskonaut__tests__cases__ui__delete_file.snap +++ b/src/tests/cases/snapshots/diskonaut__tests__cases__ui__delete_file.snap @@ -51,5 +51,5 @@ expression: "&terminal_draw_events_mirror[0]" │ │ │ └─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┴──────────────────────────────────────────────────────────────┘ (x = Small files) - <arrows> - move around, <ENTER> - enter folder, <ESC> - parent folder, <DELETE> - delete, <q> - quit + <arrows> - move around, <ENTER> - enter folder, <ESC> - parent folder, <DELETE> - delete, <+/-/0> - zoom in/out/reset, <q> - quit diff --git a/src/tests/cases/snapshots/diskonaut__tests__cases__ui__delete_file_press_n.snap b/src/tests/cases/snapshots/diskonaut__tests__cases__ui__delete_file_press_n.snap index 8c5cc1f..901267c 100644 --- a/src/tests/cases/snapshots/diskonaut__tests__cases__ui__delete_file_press_n.snap +++ b/src/tests/cases/snapshots/diskonaut__tests__cases__ui__delete_file_press_n.snap @@ -51,5 +51,5 @@ expression: "&terminal_draw_events_mirror[0]" │ │ │ └─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┴──────────────────────────────────────────────────────────────┘ (x = Small files) - <arrows> - move around, <ENTER> - enter folder, <ESC> - parent folder, <DELETE> - delete, <q> - quit + <arrows> - move around, <ENTER> - enter folder, <ESC> - parent folder, <DELETE> - delete, <+/-/0> - zoom in/out/reset, <q> - quit diff --git a/src/tests/cases/snapshots/diskonaut__tests__cases__ui__delete_folder.snap b/src/tests/cases/snapshots/diskonaut__tests__cases__ui__delete_folder.snap index cf2d4a0..dade986 100644 --- a/src/tests/cases/snapshots/diskonaut__tests__cases__ui__delete_folder.snap +++ b/src/tests/cases/snapshots/diskonaut__tests__cases__ui__delete_folder.snap @@ -51,5 +51,5 @@ expression: "&terminal_draw_events_mirror[0]" │ │ │ └─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┴──────────────────────────────────────────────────────────────┘ (x = Small files) - <arrows> - move around, <ENTER> - enter folder, <ESC> - parent folder, <DELETE> - delete, <q> - quit + <arrows> - move around, <ENTER> - enter folder, <ESC> - parent folder, <DELETE> - delete, <+/-/0> - zoom in/out/reset, <q> - quit diff --git a/src/tests/cases/snapshots/diskonaut__tests__cases__ui__delete_folder_with_multiple_children.snap b/src/tests/cases/snapshots/diskonaut__tests__cases__ui__delete_folder_with_multiple_children.snap index c1b9450..7ee834d 100644 --- a/src/tests/cases/snapshots/diskonaut__tests__cases__ui__delete_folder_with_multiple_children.snap +++ b/src/tests/cases/snapshots/diskonaut__tests__cases__ui__delete_folder_with_multiple_children.snap @@ -51,5 +51,5 @@ expression: "&terminal_draw_events_mirror[0]" │ │ │ └────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┴───────────────────────────────────────────────────┘ (x = Small files) - <arrows> - move around, <ENTER> - enter folder, <ESC> - parent folder, <DELETE> - delete, <q> - quit + <arrows> - move around, <ENTER> - enter folder, <ESC> - parent folder, <DELETE> - delete, <+/-/0> - zoom in/out/reset, <q> - quit diff --git a/src/tests/cases/snapshots/diskonaut__tests__cases__ui__eleven_files.snap b/src/tests/cases/snapshots/diskonaut__tests__cases__ui__eleven_files.snap index dceda71..5bcf46e 100644 --- a/src/tests/cases/snapshots/diskonaut__tests__cases__ui__eleven_files.snap +++ b/src/tests/cases/snapshots/diskonaut__tests__cases__ui__eleven_files.snap @@ -51,5 +51,5 @@ expression: "&terminal_draw_events_mirror[0]" │ │ │ 8.0K (2%) │ └─────────────────────────────────────────────────────────────────────────────────────────────────────────┴──────────────────────────────────────────────┴───────────────────────────────────┘ (x = Small files) - <arrows> - move around, <ENTER> - enter folder, <ESC> - parent folder, <DELETE> - delete, <q> - quit + <arrows> - move around, <ENTER> - enter folder, <ESC> - parent folder, <DELETE> - delete, <+/-/0> - zoom in/out/reset, <q> - quit diff --git a/src/tests/cases/snapshots/diskonaut__tests__cases__ui__empty_folder.snap b/src/tests/cases/snapshots/diskonaut__tests__cases__ui__empty_folder.snap index b61e3bf..e561220 100644 --- a/src/tests/cases/snapshots/diskonaut__tests__cases__ui__empty_folder.snap +++ b/src/tests/cases/snapshots/diskonaut__tests__cases__ui__empty_folder.snap @@ -51,5 +51,5 @@ expression: "&terminal_draw_events_mirror[0]" │████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████│ └────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ (x = Small files) - <arrows> - move around, <ENTER> - enter folder, <ESC> - parent folder, <DELETE> - delete, <q> - quit + <arrows> - move around, <ENTER> - enter folder, <ESC> - parent folder, <DELETE> - delete, <+/-/0> - zoom in/out/reset, <q> - quit diff --git a/src/tests/cases/snapshots/diskonaut__tests__cases__ui__enter_folder.snap b/src/tests/cases/snapshots/diskonaut__tests__cases__ui__enter_folder.snap index 7d7fad2..2de6006 100644 --- a/src/tests/cases/snapshots/diskonaut__tests__cases__ui__enter_folder.snap +++ b/src/tests/cases/snapshots/diskonaut__tests__cases__ui__enter_folder.snap @@ -51,5 +51,5 @@ expression: "&terminal_draw_events_mirror[0]" │ │ │ └─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┴──────────────────────────────────────────────┘ (x = Small files) - <arrows> - move around, <ENTER> - enter folder, <ESC> - parent folder, <DELETE> - delete, <q> - quit + <arrows> - move around, <ENTER> - enter folder, <ESC> - parent folder, <DELETE> - delete, <+/-/0> - zoom in/out/reset, <q> - quit diff --git a/src/tests/cases/snapshots/diskonaut__tests__cases__ui__enter_largest_folder_with_no_selected_tile.snap b/src/tests/cases/snapshots/diskonaut__tests__cases__ui__enter_largest_folder_with_no_selected_tile.snap index 5f82bd2..deafd8c 100644 --- a/src/tests/cases/snapshots/diskonaut__tests__cases__ui__enter_largest_folder_with_no_selected_tile.snap +++ b/src/tests/cases/snapshots/diskonaut__tests__cases__ui__enter_largest_folder_with_no_selected_tile.snap @@ -51,5 +51,5 @@ expression: "&terminal_draw_events_mirror[0]" │ │ │ └─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┴──────────────────────────────────────────────┘ (x = Small files) - <arrows> - move around, <ENTER> - enter folder, <ESC> - parent folder, <DELETE> - delete, <q> - quit + <arrows> - move around, <ENTER> - enter folder, <ESC> - parent folder, <DELETE> - delete, <+/-/0> - zoom in/out/reset, <q> - quit diff --git a/src/tests/cases/snapshots/diskonaut__tests__cases__ui__esc_to_go_up.snap b/src/tests/cases/snapshots/diskonaut__tests__cases__ui__esc_to_go_up.snap index 47ff99c..79bae57 100644 --- a/src/tests/cases/sna |