From 50edbc0cc09db864835fe81a03cba8eadafe548b Mon Sep 17 00:00:00 2001 From: Jack Wills <32690432+mrjackwills@users.noreply.github.com> Date: Fri, 15 Aug 2025 01:07:34 +0000 Subject: [PATCH] feat: clear screen & redraw New keymap key to clear the screen & redraw. Useful if gui shows any glitches --- README.md | 1 + example_config/example.config.jsonc | 4 + example_config/example.config.toml | 2 + src/app_data/mod.rs | 52 +++--- src/config/config.toml | 2 + src/config/keymap_parser.rs | 27 +-- src/input_handler/mod.rs | 5 + src/main.rs | 2 +- src/ui/draw_blocks/help.rs | 163 +++++++++--------- ...blocks__help__tests__draw_blocks_help.snap | 1 + ...tests__draw_blocks_help_custom_colors.snap | 1 + ...cks_help_custom_keymap_one_definition.snap | 55 +++--- ...ks_help_custom_keymap_two_definitions.snap | 1 + ...w_blocks_help_one_and_two_definitions.snap | 99 +++++------ ...tests__draw_blocks_help_show_timezone.snap | 4 +- ...__draw_blocks_whole_layout_help_panel.snap | 14 +- src/ui/gui_state.rs | 33 ++-- src/ui/mod.rs | 25 ++- src/ui/redraw.rs | 33 +++- 19 files changed, 294 insertions(+), 230 deletions(-) diff --git a/README.md b/README.md index 2274537..fb9ef37 100644 --- a/README.md +++ b/README.md @@ -114,6 +114,7 @@ In application controls, these, amongst many other settings, can be customized w | ```( - ) ``` or ```(=)``` | Reduce or increase the height of the logs panel.| | ```( \ )``` | Toggle the visibility of the logs panel.| | ```( e )``` | Exec into the selected container - not available on Windows.| +| ```( f )``` | Force clear the screen & redraw the gui.| | ```( h )``` | Toggle help menu.| | ```( m )``` | Toggle mouse capture - if disabled, text on screen can be selected.| | ```( q )``` | Quit.| diff --git a/example_config/example.config.jsonc b/example_config/example.config.jsonc index af38848..bf0436a 100644 --- a/example_config/example.config.jsonc +++ b/example_config/example.config.jsonc @@ -166,6 +166,10 @@ // Toggle visibility of the log section "log_section_toggle": [ "\\" + ], + // Force a complete clear & redraw of the screen + "force_redraw": [ + "f" ] }, //////////////////// diff --git a/example_config/example.config.toml b/example_config/example.config.toml index 46ff71f..a7132ac 100644 --- a/example_config/example.config.toml +++ b/example_config/example.config.toml @@ -115,6 +115,8 @@ log_section_height_decrease = ["-"] log_section_height_increase = ["+"] # Toggle visibility of the log section log_section_toggle = ["\\"] +# Force a complete clear & redraw of the screen +force_redraw = ["f"] ################# # Custom Colors # diff --git a/src/app_data/mod.rs b/src/app_data/mod.rs index 0b97449..f8508ad 100644 --- a/src/app_data/mod.rs +++ b/src/app_data/mod.rs @@ -122,7 +122,7 @@ pub struct AppData { error: Option, filter: Filter, hidden_containers: Vec, - redraw: Arc, + rerender: Arc, sorted_by: Option<(Header, SortedOrder)>, current_sorted_id: Vec, pub config: Config, @@ -137,7 +137,7 @@ pub struct AppData { pub filter: Filter, pub hidden_containers: Vec, pub current_sorted_id: Vec, - pub redraw: Arc, + pub rerender: Arc, pub sorted_by: Option<(Header, SortedOrder)>, } @@ -151,7 +151,7 @@ impl AppData { error: None, filter: Filter::new(), hidden_containers: vec![], - redraw: Arc::clone(redraw), + rerender: Arc::clone(redraw), sorted_by: None, } } @@ -192,7 +192,7 @@ impl AppData { /// sets the state to start if any filtering has occurred /// Also search in the "hidden" vec for items and insert back into the main containers vec fn filter_containers(&mut self) { - self.redraw.update(); + self.rerender.update_draw(); let pre_len = self.get_container_len(); if !self.hidden_containers.is_empty() { @@ -296,7 +296,7 @@ impl AppData { /// Remove the sorted header & order, and sort by default - created datetime pub fn reset_sorted(&mut self) { self.set_sorted(None); - self.redraw.update(); + self.rerender.update_draw(); } /// Sort containers based on a given header, if headings match, and already ascending, remove sorting @@ -392,7 +392,7 @@ impl AppData { self.containers.items.sort_by(sort_closure); if pre_order != self.get_current_ids() { - self.redraw.update(); + self.rerender.update_draw(); } } else if self.current_sorted_id != self.get_current_ids() { self.containers.items.sort_by(|a, b| { @@ -400,7 +400,7 @@ impl AppData { .cmp(&b.created) .then_with(|| a.name.get().cmp(b.name.get())) }); - self.redraw.update(); + self.rerender.update_draw(); self.current_sorted_id = self.get_current_ids(); } } @@ -439,25 +439,25 @@ impl AppData { /// Select the first container pub fn containers_start(&mut self) { self.containers.start(); - self.redraw.update(); + self.rerender.update_draw(); } /// select the last container pub fn containers_end(&mut self) { self.containers.end(); - self.redraw.update(); + self.rerender.update_draw(); } /// Select the next container pub fn containers_next(&mut self) { self.containers.next(); - self.redraw.update(); + self.rerender.update_draw(); } /// select the previous container pub fn containers_previous(&mut self) { self.containers.previous(); - self.redraw.update(); + self.rerender.update_draw(); } /// Get ListState of containers @@ -579,7 +579,7 @@ impl AppData { pub fn docker_controls_next(&mut self) { if let Some(i) = self.get_mut_selected_container() { i.docker_controls.next(); - self.redraw.update(); + self.rerender.update_draw(); } } @@ -587,7 +587,7 @@ impl AppData { pub fn docker_controls_previous(&mut self) { if let Some(i) = self.get_mut_selected_container() { i.docker_controls.previous(); - self.redraw.update(); + self.rerender.update_draw(); } } @@ -595,7 +595,7 @@ impl AppData { pub fn docker_controls_start(&mut self) { if let Some(i) = self.get_mut_selected_container() { i.docker_controls.start(); - self.redraw.update(); + self.rerender.update_draw(); } } @@ -603,7 +603,7 @@ impl AppData { pub fn docker_controls_end(&mut self) { if let Some(i) = self.get_mut_selected_container() { i.docker_controls.end(); - self.redraw.update(); + self.rerender.update_draw(); } } @@ -647,7 +647,7 @@ impl AppData { pub fn log_back(&mut self) { if let Some(i) = self.get_mut_selected_container() { i.logs.back(); - self.redraw.update(); + self.rerender.update_draw(); } } @@ -655,7 +655,7 @@ impl AppData { pub fn log_forward(&mut self, width: u16) { if let Some(i) = self.get_mut_selected_container() { i.logs.forward(width); - self.redraw.update(); + self.rerender.update_draw(); } } @@ -663,7 +663,7 @@ impl AppData { pub fn log_next(&mut self) { if let Some(i) = self.get_mut_selected_container() { i.logs.next(); - self.redraw.update(); + self.rerender.update_draw(); } } @@ -671,7 +671,7 @@ impl AppData { pub fn log_previous(&mut self) { if let Some(i) = self.get_mut_selected_container() { i.logs.previous(); - self.redraw.update(); + self.rerender.update_draw(); } } @@ -679,7 +679,7 @@ impl AppData { pub fn log_end(&mut self) { if let Some(i) = self.get_mut_selected_container() { i.logs.end(); - self.redraw.update(); + self.rerender.update_draw(); } } @@ -687,7 +687,7 @@ impl AppData { pub fn log_start(&mut self) { if let Some(i) = self.get_mut_selected_container() { i.logs.start(); - self.redraw.update(); + self.rerender.update_draw(); } } @@ -728,14 +728,14 @@ impl AppData { /// Remove single app_state error pub fn remove_error(&mut self) { self.error = None; - self.redraw.update(); + self.rerender.update_draw(); } /// Insert single app_state error pub fn set_error(&mut self, error: AppError, gui_state: &Arc>, status: Status) { gui_state.lock().status_push(status); self.error = Some(error); - self.redraw.update(); + self.rerender.update_draw(); } /// Check if the selected container is a dockerised version of oxker @@ -825,7 +825,7 @@ impl AppData { container.mem_limit.update(mem_limit); } if self.is_selected_container(id) { - self.redraw.update(); + self.rerender.update_draw(); } self.sort_containers(); } @@ -863,7 +863,7 @@ impl AppData { if self.containers.items.get(index).is_some() { self.containers.items.remove(index); if self.is_selected_container(id) { - self.redraw.update(); + self.rerender.update_draw(); } } } @@ -992,7 +992,7 @@ impl AppData { } } if self.is_selected_container(id) { - self.redraw.update(); + self.rerender.update_draw(); } } } diff --git a/src/config/config.toml b/src/config/config.toml index 37dbd13..25ee594 100644 --- a/src/config/config.toml +++ b/src/config/config.toml @@ -114,6 +114,8 @@ log_section_height_decrease = ["-"] log_section_height_increase = ["+"] # Toggle visibility of the log section log_section_toggle = ["\\"] +# Force a complete clear & redraw of the screen +force_redraw = ["f"] ################# # Custom Colors # diff --git a/src/config/keymap_parser.rs b/src/config/keymap_parser.rs index e66acef..808cc18 100644 --- a/src/config/keymap_parser.rs +++ b/src/config/keymap_parser.rs @@ -35,6 +35,7 @@ macro_rules! config_struct { optional_config_struct!( ConfigKeymap, clear, + force_redraw, delete_deny, delete_confirm, exec, @@ -75,6 +76,7 @@ config_struct!( delete_confirm, exec, filter_mode, + force_redraw, log_section_height_increase, log_section_height_decrease, log_section_toggle, @@ -112,6 +114,7 @@ impl Keymap { delete_deny: (KeyCode::Char('n'), None), exec: (KeyCode::Char('e'), None), filter_mode: (KeyCode::Char('/'), Some(KeyCode::F(1))), + force_redraw: (KeyCode::Char('f'), None), log_section_height_decrease: (KeyCode::Char('-'), None), log_section_height_increase: (KeyCode::Char('='), None), log_section_toggle: (KeyCode::Char('\\'), None), @@ -195,6 +198,7 @@ impl From> for Keymap { update_keymap(ck.exec, &mut keymap.exec, &mut clash); update_keymap(ck.filter_mode, &mut keymap.filter_mode, &mut clash); + update_keymap(ck.force_redraw, &mut keymap.force_redraw, &mut clash); update_keymap(ck.quit, &mut keymap.quit, &mut clash); update_keymap(ck.save_logs, &mut keymap.save_logs, &mut clash); update_keymap( @@ -376,11 +380,13 @@ mod tests { delete_deny: Some(vec!["s".to_owned()]), delete_confirm: None, exec: None, + filter_mode: None, + force_redraw: None, + log_scroll_back: None, + log_scroll_forward: None, log_section_height_decrease: None, log_section_height_increase: None, - log_scroll_forward: None, - log_scroll_back: None, - filter_mode: None, + log_section_toggle: None, quit: None, save_logs: None, scroll_down_many: None, @@ -390,16 +396,15 @@ mod tests { scroll_up_many: None, scroll_up_one: None, select_next_panel: None, - log_section_toggle: None, select_previous_panel: None, - sort_by_name: None, - sort_by_state: None, - sort_by_status: None, sort_by_cpu: None, - sort_by_memory: None, sort_by_id: None, sort_by_image: None, + sort_by_memory: None, + sort_by_name: None, sort_by_rx: None, + sort_by_state: None, + sort_by_status: None, sort_by_tx: None, sort_reset: None, toggle_help: None, @@ -422,6 +427,7 @@ mod tests { delete_deny: gen_v(("c", "d")), exec: gen_v(("g", "h")), filter_mode: gen_v(("i", "j")), + force_redraw: gen_v(("F1", "F2")), log_section_height_decrease: gen_v(("-", "Z")), log_section_height_increase: gen_v(("=", "X")), log_scroll_forward: gen_v(("right", "R")), @@ -437,7 +443,7 @@ mod tests { scroll_up_one: gen_v(("y", "z")), select_next_panel: gen_v(("0", "1")), select_previous_panel: gen_v(("2", "3")), - sort_by_cpu: gen_v(("F1", "F12")), + sort_by_cpu: gen_v(("F11", "F12")), sort_by_id: gen_v(("[", "]")), sort_by_image: gen_v(("A", "B")), sort_by_memory: gen_v(("/", "\\")), @@ -457,6 +463,7 @@ mod tests { clear: (KeyCode::Char('a'), Some(KeyCode::Char('b'))), delete_deny: (KeyCode::Char('c'), Some(KeyCode::Char('d'))), delete_confirm: (KeyCode::Char('e'), Some(KeyCode::Char('f'))), + force_redraw: (KeyCode::F(1), Some(KeyCode::F(2))), log_section_height_decrease: (KeyCode::Char('-'), Some(KeyCode::Char('Z'))), log_section_height_increase: (KeyCode::Char('='), Some(KeyCode::Char('X'))), log_section_toggle: (KeyCode::Char('Y'), Some(KeyCode::Char('W'))), @@ -477,7 +484,7 @@ mod tests { sort_by_name: (KeyCode::Char('4'), Some(KeyCode::Char('5'))), sort_by_state: (KeyCode::Char('6'), Some(KeyCode::Char('7'))), sort_by_status: (KeyCode::Char('8'), Some(KeyCode::Char('9'))), - sort_by_cpu: (KeyCode::F(1), Some(KeyCode::F(12))), + sort_by_cpu: (KeyCode::F(11), Some(KeyCode::F(12))), sort_by_memory: (KeyCode::Char('/'), Some(KeyCode::Char('\\'))), sort_by_id: (KeyCode::Char('['), Some(KeyCode::Char(']'))), sort_by_image: (KeyCode::Char('A'), Some(KeyCode::Char('B'))), diff --git a/src/input_handler/mod.rs b/src/input_handler/mod.rs index 1d5c22b..d45b472 100644 --- a/src/input_handler/mod.rs +++ b/src/input_handler/mod.rs @@ -408,6 +408,11 @@ impl InputHandler { /// Handle input that refers to the sorting of columns fn handle_sort(&self, key_code: KeyCode) { match key_code { + _ if self.keymap.force_redraw.0 == key_code + || self.keymap.force_redraw.1 == Some(key_code) => + { + self.gui_state.lock().set_clear(); + } _ if self.keymap.sort_reset.0 == key_code || self.keymap.sort_reset.1 == Some(key_code) => { diff --git a/src/main.rs b/src/main.rs index e7b77e5..665aa4b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -210,7 +210,7 @@ mod tests { current_sorted_id: vec![], error: None, sorted_by: None, - redraw: Arc::new(Rerender::new()), + rerender: Arc::new(Rerender::new()), filter: Filter::new(), config: gen_config(), } diff --git a/src/ui/draw_blocks/help.rs b/src/ui/draw_blocks/help.rs index c861996..0694ddd 100644 --- a/src/ui/draw_blocks/help.rs +++ b/src/ui/draw_blocks/help.rs @@ -84,7 +84,6 @@ impl HelpInfo { } } - // todo ← → for log moving /// Generate the button information span + metadata #[allow(clippy::too_many_lines)] fn gen_keymap_info(colors: AppColors, zone: Option<&TimeZone>, show_timestamp: bool) -> Self { @@ -129,6 +128,11 @@ impl HelpInfo { #[cfg(target_os = "windows")] button_desc(" - not available on Windows"), ]), + Line::from(vec![ + space(), + button_item("f"), + button_desc("force clear the screen & redraw the gui"), + ]), Line::from(vec![ space(), button_item("h"), @@ -285,6 +289,7 @@ impl HelpInfo { or_secondary(km.exec, "exec into a container"), #[cfg(target_os = "windows")] or_secondary(km.exec, "exec into a container - not available on Windows"), + or_secondary(km.force_redraw, "force clear the screen & redraw the gui"), or_secondary( km.toggle_help, "toggle this help information - or click heading", @@ -445,9 +450,8 @@ mod tests { #[test] /// This will cause issues once the version has more than the current 5 chars (0.5.0) /// println!("{} {} {} {} {}", row_index, result_cell_index, result_cell.symbol(), result_cell.bg, result_cell.fg); - /// TODO broken wihh the horizonal scrolls! fn test_draw_blocks_help() { - let mut setup = test_setup(87, 35, true, true); + let mut setup = test_setup(87, 36, true, true); let tz = setup.app_data.lock().config.timezone.clone(); setup @@ -469,12 +473,12 @@ mod tests { for (result_cell_index, result_cell) in result_row.iter().enumerate() { match (row_index, result_cell_index) { // first & last row, and first & last char on each row, is reset/reset, making sure that the help info is centered in the given area - (0 | 34, _) | (0..=33, 0 | 86) => { + (0 | 35, _) | (0..=34, 0 | 86) => { assert_eq!(result_cell.bg, Color::Reset); assert_eq!(result_cell.fg, Color::Reset); } // border is red on black - (1 | 32, _) | (1..=31, 1 | 85) => { + (1 | 34, _) | (1..=31, 1 | 85) => { assert_eq!(result_cell.bg, Color::Magenta); assert_eq!(result_cell.fg, Color::Black); } @@ -483,15 +487,15 @@ mod tests { | (12, 19..=66) | (14, 2..=10 | 13..=27) | (15, 2..=10 | 13..=21 | 24..=40 | 43..=56) - | (16 | 25 | 27, 2..=10) - | (17 | 24, 2..=12) - | (18 | 19 | 20 | 21 | 23 | 26 | 28, 2..=8) - | (22, 2..=9 | 12..=18) => { + | (16 | 26 | 28, 2..=10) + | (17 | 25, 2..=12) + | (18 | 19 | 20 | 21 | 22 | 24 | 27 | 29, 2..=8) + | (23, 2..=9 | 12..=18) => { assert_eq!(result_cell.bg, Color::Magenta); assert_eq!(result_cell.fg, Color::White); } // The URL is yellow and underlined - (31, 25..=60) => { + (32, 25..=60) => { assert_eq!(result_cell.bg, Color::Magenta); assert_eq!(result_cell.fg, Color::White); assert_eq!(result_cell.modifier, Modifier::UNDERLINED); @@ -508,10 +512,9 @@ mod tests { #[test] /// Test that the help panel gets drawn with custom colors - /// This test is annoying /// println!("{} {} {} {} {}", row_index, result_cell_index, result_cell.symbol(), result_cell.bg, result_cell.fg); fn test_draw_blocks_help_custom_colors() { - let mut setup = test_setup(87, 35, true, true); + let mut setup = test_setup(87, 36, true, true); let mut colors = AppColors::new(); let tz = setup.app_data.lock().config.timezone.clone(); @@ -533,17 +536,16 @@ mod tests { .unwrap(); assert_snapshot!(setup.terminal.backend()); - for (row_index, result_row) in get_result(&setup) { for (result_cell_index, result_cell) in result_row.iter().enumerate() { match (row_index, result_cell_index) { // first & last row, and first & last char on each row, is reset/reset, making sure that the help info is centered in the given area - (0 | 34, _) | (0..=33, 0 | 86) => { + (0 | 35, _) | (0..=34, 0 | 86) => { assert_eq!(result_cell.bg, Color::Reset); assert_eq!(result_cell.fg, Color::Reset); } // border is red on black - (1 | 32, _) | (1..=31, 1 | 85) => { + (1 | 34, _) | (1..=31, 1 | 85) => { assert_eq!(result_cell.bg, Color::Black); assert_eq!(result_cell.fg, Color::Red); } @@ -552,15 +554,15 @@ mod tests { | (12, 19..=66) | (14, 2..=10 | 13..=27) | (15, 2..=10 | 13..=21 | 24..=40 | 43..=56) - | (16 | 25 | 27, 2..=10) - | (17 | 24, 2..=12) - | (18 | 19 | 20 | 21 | 23 | 26 | 28, 2..=8) - | (22, 2..=9 | 12..=18) => { + | (16 | 26 | 28, 2..=10) + | (17 | 25, 2..=12) + | (18 | 19 | 20 | 21 | 22 | 24 | 27 | 29, 2..=8) + | (23, 2..=9 | 12..=18) => { assert_eq!(result_cell.bg, Color::Black); assert_eq!(result_cell.fg, Color::Yellow); } // The URL is yellow and underlined - (31, 25..=60) => { + (32, 25..=60) => { assert_eq!(result_cell.bg, Color::Black); assert_eq!(result_cell.fg, Color::Yellow); assert_eq!(result_cell.modifier, Modifier::UNDERLINED); @@ -578,7 +580,7 @@ mod tests { #[test] /// Help panel will show custom keymap if in use, with one definition for each entry fn test_draw_blocks_help_custom_keymap_one_definition() { - let mut setup = test_setup(98, 49, true, true); + let mut setup = test_setup(98, 50, true, true); let input = Keymap { clear: (KeyCode::Char('a'), None), @@ -586,33 +588,34 @@ mod tests { delete_deny: (KeyCode::Char('c'), None), exec: (KeyCode::Char('d'), None), filter_mode: (KeyCode::Char('e'), None), - log_scroll_back: (KeyCode::Char('f'), None), - log_scroll_forward: (KeyCode::Char('g'), None), - log_section_height_decrease: (KeyCode::Char('h'), None), - log_section_height_increase: (KeyCode::Char('i'), None), - log_section_toggle: (KeyCode::Char('j'), None), - quit: (KeyCode::Char('k'), None), - save_logs: (KeyCode::Char('l'), None), - scroll_down_many: (KeyCode::Char('m'), None), - scroll_down_one: (KeyCode::Char('n'), None), - scroll_end: (KeyCode::Char('o'), None), - scroll_start: (KeyCode::Char('p'), None), - scroll_up_many: (KeyCode::Char('q'), None), - scroll_up_one: (KeyCode::Char('r'), None), - select_next_panel: (KeyCode::Char('s'), None), - select_previous_panel: (KeyCode::Char('t'), None), - sort_by_cpu: (KeyCode::Char('u'), None), - sort_by_id: (KeyCode::Char('v'), None), - sort_by_image: (KeyCode::Char('w'), None), - sort_by_memory: (KeyCode::Char('x'), None), - sort_by_name: (KeyCode::Char('y'), None), - sort_by_rx: (KeyCode::Char('z'), None), - sort_by_state: (KeyCode::Char('0'), None), - sort_by_status: (KeyCode::Char('1'), None), - sort_by_tx: (KeyCode::Char('2'), None), - sort_reset: (KeyCode::Char('3'), None), - toggle_help: (KeyCode::Char('4'), None), - toggle_mouse_capture: (KeyCode::Char('5'), None), + force_redraw: (KeyCode::Char('f'), None), + log_scroll_back: (KeyCode::Char('g'), None), + log_scroll_forward: (KeyCode::Char('h'), None), + log_section_height_decrease: (KeyCode::Char('i'), None), + log_section_height_increase: (KeyCode::Char('j'), None), + log_section_toggle: (KeyCode::Char('k'), None), + quit: (KeyCode::Char('l'), None), + save_logs: (KeyCode::Char('m'), None), + scroll_down_many: (KeyCode::Char('n'), None), + scroll_down_one: (KeyCode::Char('o'), None), + scroll_end: (KeyCode::Char('p'), None), + scroll_start: (KeyCode::Char('q'), None), + scroll_up_many: (KeyCode::Char('r'), None), + scroll_up_one: (KeyCode::Char('s'), None), + select_next_panel: (KeyCode::Char('t'), None), + select_previous_panel: (KeyCode::Char('u'), None), + sort_by_cpu: (KeyCode::Char('v'), None), + sort_by_id: (KeyCode::Char('w'), None), + sort_by_image: (KeyCode::Char('x'), None), + sort_by_memory: (KeyCode::Char('y'), None), + sort_by_name: (KeyCode::Char('z'), None), + sort_by_rx: (KeyCode::Char('0'), None), + sort_by_state: (KeyCode::Char('1'), None), + sort_by_status: (KeyCode::Char('2'), None), + sort_by_tx: (KeyCode::Char('3'), None), + sort_reset: (KeyCode::Char('4'), None), + toggle_help: (KeyCode::Char('5'), None), + toggle_mouse_capture: (KeyCode::Char('6'), None), }; setup @@ -628,7 +631,7 @@ mod tests { #[test] /// Help panel will show custom keymap if in use, with two definition for each entry fn test_draw_blocks_help_custom_keymap_two_definitions() { - let mut setup = test_setup(110, 49, true, true); + let mut setup = test_setup(110, 50, true, true); let keymap = Keymap { clear: (KeyCode::Char('a'), Some(KeyCode::Char('A'))), @@ -636,6 +639,7 @@ mod tests { delete_deny: (KeyCode::Char('c'), Some(KeyCode::Char('C'))), exec: (KeyCode::Char('d'), Some(KeyCode::Char('D'))), filter_mode: (KeyCode::Char('e'), Some(KeyCode::Char('E'))), + force_redraw: (KeyCode::Char('f'), Some(KeyCode::Char('F'))), log_scroll_back: (KeyCode::Char('f'), Some(KeyCode::Char('F'))), log_scroll_forward: (KeyCode::Char('g'), Some(KeyCode::Char('G'))), log_section_height_decrease: (KeyCode::Char('h'), Some(KeyCode::Char('H'))), @@ -678,7 +682,7 @@ mod tests { #[test] /// Help panel will show custom keymap if in use, with either one or two definition for each entry fn test_draw_blocks_help_one_and_two_definitions() { - let mut setup = test_setup(110, 49, true, true); + let mut setup = test_setup(110, 50, true, true); let keymap = Keymap { clear: (KeyCode::Char('a'), Some(KeyCode::Char('A'))), @@ -686,33 +690,34 @@ mod tests { delete_deny: (KeyCode::Char('c'), Some(KeyCode::Char('C'))), exec: (KeyCode::Char('d'), None), filter_mode: (KeyCode::Char('e'), Some(KeyCode::Char('E'))), - log_scroll_back: (KeyCode::Char('f'), None), - log_scroll_forward: (KeyCode::Char('g'), Some(KeyCode::Char('G'))), - log_section_height_decrease: (KeyCode::Char('h'), None), - log_section_height_increase: (KeyCode::Char('i'), Some(KeyCode::Char('I'))), - log_section_toggle: (KeyCode::Char('j'), None), - quit: (KeyCode::Char('k'), Some(KeyCode::Char('K'))), - save_logs: (KeyCode::Char('l'), None), - scroll_down_many: (KeyCode::Char('m'), Some(KeyCode::Char('M'))), - scroll_down_one: (KeyCode::Char('n'), None), - scroll_end: (KeyCode::Char('o'), Some(KeyCode::Char('O'))), - scroll_start: (KeyCode::Char('p'), None), - scroll_up_many: (KeyCode::Char('q'), Some(KeyCode::Char('Q'))), - scroll_up_one: (KeyCode::Char('r'), None), - select_next_panel: (KeyCode::Char('s'), Some(KeyCode::Char('S'))), - select_previous_panel: (KeyCode::Char('t'), None), - sort_by_cpu: (KeyCode::Char('u'), Some(KeyCode::Char('U'))), - sort_by_id: (KeyCode::Char('v'), None), - sort_by_image: (KeyCode::Char('w'), Some(KeyCode::Char('W'))), - sort_by_memory: (KeyCode::Char('x'), None), - sort_by_name: (KeyCode::Char('y'), Some(KeyCode::Char('Y'))), - sort_by_rx: (KeyCode::Char('z'), None), - sort_by_state: (KeyCode::Char('0'), Some(KeyCode::Char('9'))), - sort_by_status: (KeyCode::Char('1'), None), - sort_by_tx: (KeyCode::Char('2'), Some(KeyCode::Char('7'))), - sort_reset: (KeyCode::Char('3'), None), - toggle_help: (KeyCode::Char('4'), Some(KeyCode::Char('5'))), - toggle_mouse_capture: (KeyCode::Char('5'), None), + force_redraw: (KeyCode::Char('f'), None), + log_scroll_back: (KeyCode::Char('g'), Some(KeyCode::Char('G'))), + log_scroll_forward: (KeyCode::Char('h'), None), + log_section_height_decrease: (KeyCode::Char('i'), Some(KeyCode::Char('I'))), + log_section_height_increase: (KeyCode::Char('j'), None), + log_section_toggle: (KeyCode::Char('k'), Some(KeyCode::Char('K'))), + quit: (KeyCode::Char('l'), None), + save_logs: (KeyCode::Char('m'), Some(KeyCode::Char('M'))), + scroll_down_many: (KeyCode::Char('n'), None), + scroll_down_one: (KeyCode::Char('o'), Some(KeyCode::Char('O'))), + scroll_end: (KeyCode::Char('p'), None), + scroll_start: (KeyCode::Char('q'), Some(KeyCode::Char('Q'))), + scroll_up_many: (KeyCode::Char('r'), None), + scroll_up_one: (KeyCode::Char('s'), Some(KeyCode::Char('S'))), + select_next_panel: (KeyCode::Char('t'), None), + select_previous_panel: (KeyCode::Char('u'), Some(KeyCode::Char('U'))), + sort_by_cpu: (KeyCode::Char('v'), None), + sort_by_id: (KeyCode::Char('w'), Some(KeyCode::Char('W'))), + sort_by_image: (KeyCode::Char('x'), None), + sort_by_memory: (KeyCode::Char('y'), Some(KeyCode::Char('Y'))), + sort_by_name: (KeyCode::Char('z'), None), + sort_by_rx: (KeyCode::Char('0'), Some(KeyCode::Char('9'))), + sort_by_state: (KeyCode::Char('1'), None), + sort_by_status: (KeyCode::Char('2'), Some(KeyCode::Char('7'))), + sort_by_tx: (KeyCode::Char('3'), None), + sort_reset: (KeyCode::Char('4'), Some(KeyCode::Char('5'))), + toggle_help: (KeyCode::Char('5'), None), + toggle_mouse_capture: (KeyCode::Char('6'), Some(KeyCode::Char('7'))), }; let tz = setup.app_data.lock().config.timezone.clone(); @@ -749,10 +754,10 @@ mod tests { for (row_index, result_row) in get_result(&setup) { for (result_cell_index, result_cell) in result_row.iter().enumerate() { match (row_index, result_cell_index) { - (14, 31..=45) => { + (13, 31..=45) => { assert_eq!(result_cell.fg, AppColors::new().popup_help.text); } - (14, 46..=55) => { + (13, 46..=55) => { assert_eq!(result_cell.fg, AppColors::new().popup_help.text_highlight); } _ => (), diff --git a/src/ui/draw_blocks/snapshots/oxker__ui__draw_blocks__help__tests__draw_blocks_help.snap b/src/ui/draw_blocks/snapshots/oxker__ui__draw_blocks__help__tests__draw_blocks_help.snap index 8b03bdd..de059d4 100644 --- a/src/ui/draw_blocks/snapshots/oxker__ui__draw_blocks__help__tests__draw_blocks_help.snap +++ b/src/ui/draw_blocks/snapshots/oxker__ui__draw_blocks__help__tests__draw_blocks_help.snap @@ -21,6 +21,7 @@ expression: setup.terminal.backend() " │ ( ← → ) horizontal scroll across logs │ " " │ ( enter ) send docker container command │ " " │ ( e ) exec into a container │ " +" │ ( f ) force clear the screen & redraw the gui │ " " │ ( h ) toggle this help information - or click heading │ " " │ ( s ) save logs to file │ " " │ ( m ) toggle mouse capture - if disabled, text on screen can be selected & copied │ " diff --git a/src/ui/draw_blocks/snapshots/oxker__ui__draw_blocks__help__tests__draw_blocks_help_custom_colors.snap b/src/ui/draw_blocks/snapshots/oxker__ui__draw_blocks__help__tests__draw_blocks_help_custom_colors.snap index 8b03bdd..de059d4 100644 --- a/src/ui/draw_blocks/snapshots/oxker__ui__draw_blocks__help__tests__draw_blocks_help_custom_colors.snap +++ b/src/ui/draw_blocks/snapshots/oxker__ui__draw_blocks__help__tests__draw_blocks_help_custom_colors.snap @@ -21,6 +21,7 @@ expression: setup.terminal.backend() " │ ( ← → ) horizontal scroll across logs │ " " │ ( enter ) send docker container command │ " " │ ( e ) exec into a container │ " +" │ ( f ) force clear the screen & redraw the gui │ " " │ ( h ) toggle this help information - or click heading │ " " │ ( s ) save logs to file │ " " │ ( m ) toggle mouse capture - if disabled, text on screen can be selected & copied │ " diff --git a/src/ui/draw_blocks/snapshots/oxker__ui__draw_blocks__help__tests__draw_blocks_help_custom_keymap_one_definition.snap b/src/ui/draw_blocks/snapshots/oxker__ui__draw_blocks__help__tests__draw_blocks_help_custom_keymap_one_definition.snap index fe00d6a..eee704c 100644 --- a/src/ui/draw_blocks/snapshots/oxker__ui__draw_blocks__help__tests__draw_blocks_help_custom_keymap_one_definition.snap +++ b/src/ui/draw_blocks/snapshots/oxker__ui__draw_blocks__help__tests__draw_blocks_help_custom_keymap_one_definition.snap @@ -15,37 +15,38 @@ expression: setup.terminal.backend() " │ │ " " │ A simple tui to view & control docker containers │ " " │ │ " -" │ ( s ) select next panel │ " -" │ ( t ) select previous panel │ " -" │ ( n ) scroll list down by one │ " -" │ ( r ) scroll list up by one │ " -" │ ( m ) scroll list down by many │ " -" │ ( q ) scroll list by up many │ " -" │ ( o ) scroll list to end │ " -" │ ( p ) scroll list to start │ " -" │ ( g ) horizontal scroll logs right │ " -" │ ( f ) horizontal scroll logs left │ " +" │ ( t ) select next panel │ " +" │ ( u ) select previous panel │ " +" │ ( o ) scroll list down by one │ " +" │ ( s ) scroll list up by one │ " +" │ ( n ) scroll list down by many │ " +" │ ( r ) scroll list by up many │ " +" │ ( p ) scroll list to end │ " +" │ ( q ) scroll list to start │ " +" │ ( h ) horizontal scroll logs right │ " +" │ ( g ) horizontal scroll logs left │ " " │ ( enter ) send docker container command │ " " │ ( d ) exec into a container │ " -" │ ( 4 ) toggle this help information - or click heading │ " -" │ ( l ) save logs to file │ " -" │ ( 5 ) toggle mouse capture - if disabled, text on screen can be selected & copied │ " +" │ ( f ) force clear the screen & redraw the gui │ " +" │ ( 5 ) toggle this help information - or click heading │ " +" │ ( m ) save logs to file │ " +" │ ( 6 ) toggle mouse capture - if disabled, text on screen can be selected & copied │ " " │ ( e ) enter filter mode │ " -" │ ( 3 ) reset container sorting │ " -" │ ( y ) sort containers by name │ " -" │ ( 0 ) sort containers by state │ " -" │ ( 1 ) sort containers by status │ " -" │ ( u ) sort containers by cpu │ " -" │ ( x ) sort containers by memory │ " -" │ ( v ) sort containers by id │ " -" │ ( w ) sort containers by image │ " -" │ ( z ) sort containers by rx │ " -" │ ( 2 ) sort containers by tx │ " -" │ ( h ) decrease log section height │ " -" │ ( i ) increase log section height │ " -" │ ( j ) toggle log section visibility │ " +" │ ( 4 ) reset container sorting │ " +" │ ( z ) sort containers by name │ " +" │ ( 1 ) sort containers by state │ " +" │ ( 2 ) sort containers by status │ " +" │ ( v ) sort containers by cpu │ " +" │ ( y ) sort containers by memory │ " +" │ ( w ) sort containers by id │ " +" │ ( x ) sort containers by image │ " +" │ ( 0 ) sort containers by rx │ " +" │ ( 3 ) sort containers by tx │ " +" │ ( i ) decrease log section height │ " +" │ ( j ) increase log section height │ " +" │ ( k ) toggle log section visibility │ " " │ ( a ) close dialog │ " -" │ ( k ) quit at any time │ " +" │ ( l ) quit at any time │ " " │ │ " " │ currently an early work in progress, all and any input appreciated │ " " │ https://github.com/mrjackwills/oxker │ " diff --git a/src/ui/draw_blocks/snapshots/oxker__ui__draw_blocks__help__tests__draw_blocks_help_custom_keymap_two_definitions.snap b/src/ui/draw_blocks/snapshots/oxker__ui__draw_blocks__help__tests__draw_blocks_help_custom_keymap_two_definitions.snap index 6ae3453..418e684 100644 --- a/src/ui/draw_blocks/snapshots/oxker__ui__draw_blocks__help__tests__draw_blocks_help_custom_keymap_two_definitions.snap +++ b/src/ui/draw_blocks/snapshots/oxker__ui__draw_blocks__help__tests__draw_blocks_help_custom_keymap_two_definitions.snap @@ -27,6 +27,7 @@ expression: setup.terminal.backend() " │ ( f ) or ( F ) horizontal scroll logs left │ " " │ ( enter ) send docker container command │ " " │ ( d ) or ( D ) exec into a container │ " +" │ ( f ) or ( F ) force clear the screen & redraw the gui │ " " │ ( 4 ) or ( 5 ) toggle this help information - or click heading │ " " │ ( l ) or ( L ) save logs to file │ " " │ ( 5 ) or ( Page Down ) toggle mouse capture - if disabled, text on screen can be selected & copied │ " diff --git a/src/ui/draw_blocks/snapshots/oxker__ui__draw_blocks__help__tests__draw_blocks_help_one_and_two_definitions.snap b/src/ui/draw_blocks/snapshots/oxker__ui__draw_blocks__help__tests__draw_blocks_help_one_and_two_definitions.snap index 1b760e1..15f2de0 100644 --- a/src/ui/draw_blocks/snapshots/oxker__ui__draw_blocks__help__tests__draw_blocks_help_one_and_two_definitions.snap +++ b/src/ui/draw_blocks/snapshots/oxker__ui__draw_blocks__help__tests__draw_blocks_help_one_and_two_definitions.snap @@ -2,52 +2,53 @@ source: src/ui/draw_blocks/help.rs expression: setup.terminal.backend() --- -" ╭ 0.00.000 ──────────────────────────────────────────────────────────────────────────╮ " -" │ │ " -" │ 88 │ " -" │ 88 │ " -" │ 88 │ " -" │ ,adPPYba, 8b, ,d8 88 ,d8 ,adPPYba, 8b,dPPYba, │ " -" │ a8" "8a `Y8, ,8P' 88 ,a8" a8P_____88 88P' "Y8 │ " -" │ 8b d8 )888( 8888[ 8PP""""""" 88 │ " -" │ "8a, ,a8" ,d8" "8b, 88`"Yba, "8b, ,aa 88 │ " -" │ `"YbbdP"' 8P' `Y8 88 `Y8a `"Ybbd8"' 88 │ " -" │ │ " -" │ A simple tui to view & control docker containers │ " -" │ │ " -" │ ( s ) or ( S ) select next panel │ " -" │ ( t ) select previous panel │ " -" │ ( n ) scroll list down by one │ " -" │ ( r ) scroll list up by one │ " -" │ ( m ) or ( M ) scroll list down by many │ " -" │ ( q ) or ( Q ) scroll list by up many │ " -" │ ( o ) or ( O ) scroll list to end │ " -" │ ( p ) scroll list to start │ " -" │ ( g ) or ( G ) horizontal scroll logs right │ " -" │ ( f ) horizontal scroll logs left │ " -" │ ( enter ) send docker container command │ " -" │ ( d ) exec into a container │ " -" │ ( 4 ) or ( 5 ) toggle this help information - or click heading │ " -" │ ( l ) save logs to file │ " -" │ ( 5 ) toggle mouse capture - if disabled, text on screen can be selected & copied │ " -" │ ( e ) or ( E ) enter filter mode │ " -" │ ( 3 ) reset container sorting │ " -" │ ( y ) or ( Y ) sort containers by name │ " -" │ ( 0 ) or ( 9 ) sort containers by state │ " -" │ ( 1 ) sort containers by status │ " -" │ ( u ) or ( U ) sort containers by cpu │ " -" │ ( x ) sort containers by memory │ " -" │ ( v ) sort containers by id │ " -" │ ( w ) or ( W ) sort containers by image │ " -" │ ( z ) sort containers by rx │ " -" │ ( 2 ) or ( 7 ) sort containers by tx │ " -" │ ( h ) decrease log section height │ " -" │ ( i ) or ( I ) increase log section height │ " -" │ ( j ) toggle log section visibility │ " -" │ ( a ) or ( A ) close dialog │ " -" │ ( k ) or ( K ) quit at any time │ " -" │ │ " -" │ currently an early work in progress, all and any input appreciated │ " -" │ https://github.com/mrjackwills/oxker │ " -" │ │ " -" ╰────────────────────────────────────────────────────────────────────────────────────╯ " +" ╭ 0.00.000 ──────────────────────────────────────────────────────────────────────────────────╮ " +" │ │ " +" │ 88 │ " +" │ 88 │ " +" │ 88 │ " +" │ ,adPPYba, 8b, ,d8 88 ,d8 ,adPPYba, 8b,dPPYba, │ " +" │ a8" "8a `Y8, ,8P' 88 ,a8" a8P_____88 88P' "Y8 │ " +" │ 8b d8 )888( 8888[ 8PP""""""" 88 │ " +" │ "8a, ,a8" ,d8" "8b, 88`"Yba, "8b, ,aa 88 │ " +" │ `"YbbdP"' 8P' `Y8 88 `Y8a `"Ybbd8"' 88 │ " +" │ │ " +" │ A simple tui to view & control docker containers │ " +" │ │ " +" │ ( t ) select next panel │ " +" │ ( u ) or ( U ) select previous panel │ " +" │ ( o ) or ( O ) scroll list down by one │ " +" │ ( s ) or ( S ) scroll list up by one │ " +" │ ( n ) scroll list down by many │ " +" │ ( r ) scroll list by up many │ " +" │ ( p ) scroll list to end │ " +" │ ( q ) or ( Q ) scroll list to start │ " +" │ ( h ) horizontal scroll logs right │ " +" │ ( g ) or ( G ) horizontal scroll logs left │ " +" │ ( enter ) send docker container command │ " +" │ ( d ) exec into a container │ " +" │ ( f ) force clear the screen & redraw the gui │ " +" │ ( 5 ) toggle this help information - or click heading │ " +" │ ( m ) or ( M ) save logs to file │ " +" │ ( 6 ) or ( 7 ) toggle mouse capture - if disabled, text on screen can be selected & copied │ " +" │ ( e ) or ( E ) enter filter mode │ " +" │ ( 4 ) or ( 5 ) reset container sorting │ " +" │ ( z ) sort containers by name │ " +" │ ( 1 ) sort containers by state │ " +" │ ( 2 ) or ( 7 ) sort containers by status │ " +" │ ( v ) sort containers by cpu │ " +" │ ( y ) or ( Y ) sort containers by memory │ " +" │ ( w ) or ( W ) sort containers by id │ " +" │ ( x ) sort containers by image │ " +" │ ( 0 ) or ( 9 ) sort containers by rx │ " +" │ ( 3 ) sort containers by tx │ " +" │ ( i ) or ( I ) decrease log section height │ " +" │ ( j ) increase log section height │ " +" │ ( k ) or ( K ) toggle log section visibility │ " +" │ ( a ) or ( A ) close dialog │ " +" │ ( l ) quit at any time │ " +" │ │ " +" │ currently an early work in progress, all and any input appreciated │ " +" │ https://github.com/mrjackwills/oxker │ " +" │ │ " +" ╰────────────────────────────────────────────────────────────────────────────────────────────╯ " diff --git a/src/ui/draw_blocks/snapshots/oxker__ui__draw_blocks__help__tests__draw_blocks_help_show_timezone.snap b/src/ui/draw_blocks/snapshots/oxker__ui__draw_blocks__help__tests__draw_blocks_help_show_timezone.snap index ceed130..82193cb 100644 --- a/src/ui/draw_blocks/snapshots/oxker__ui__draw_blocks__help__tests__draw_blocks_help_show_timezone.snap +++ b/src/ui/draw_blocks/snapshots/oxker__ui__draw_blocks__help__tests__draw_blocks_help_show_timezone.snap @@ -2,7 +2,6 @@ source: src/ui/draw_blocks/help.rs expression: setup.terminal.backend() --- -" " " ╭ 0.00.000 ─────────────────────────────────────────────────────────────────────────╮ " " │ │ " " │ 88 │ " @@ -23,6 +22,7 @@ expression: setup.terminal.backend() " │ ( ← → ) horizontal scroll across logs │ " " │ ( enter ) send docker container command │ " " │ ( e ) exec into a container │ " +" │ ( f ) force clear the screen & redraw the gui │ " " │ ( h ) toggle this help information - or click heading │ " " │ ( s ) save logs to file │ " " │ ( m ) toggle mouse capture - if disabled, text on screen can be selected & copied │ " @@ -37,5 +37,5 @@ expression: setup.terminal.backend() " │ currently an early work in progress, all and any input appreciated │ " " │ https://github.com/mrjackwills/oxker │ " " │ │ " +" │ │ " " ╰───────────────────────────────────────────────────────────────────────────────────╯ " -" " diff --git a/src/ui/draw_blocks/snapshots/oxker__ui__draw_blocks__tests__draw_blocks_whole_layout_help_panel.snap b/src/ui/draw_blocks/snapshots/oxker__ui__draw_blocks__tests__draw_blocks_whole_layout_help_panel.snap index ad38e21..65aed11 100644 --- a/src/ui/draw_blocks/snapshots/oxker__ui__draw_blocks__tests__draw_blocks_whole_layout_help_panel.snap +++ b/src/ui/draw_blocks/snapshots/oxker__ui__draw_blocks__tests__draw_blocks_whole_layout_help_panel.snap @@ -23,6 +23,7 @@ expression: setup.terminal.backend() "│ │ ( ← → ) horizontal scroll across logs │ │" "│ │ ( enter ) send docker container command │ │" "│ │ ( e ) exec into a container │ │" +"│ │ ( f ) force clear the screen & redraw the gui │ │" "│ │ ( h ) toggle this help information - or click heading │ │" "│ │ ( s ) save logs to file │ │" "│ │ ( m ) toggle mouse capture - if disabled, text on screen can be selected & copied │ │" @@ -30,13 +31,12 @@ expression: setup.terminal.backend() "│ │ ( 0 ) stop sort │ │" "│ │ ( 1 - 9 ) sort by header - or click header │ │" "│ │ ( - = ) change log section height │ │" -"│ │ ( \ ) toggle log section visibility │ │" -"╰────────────────────────────────────│ ( esc ) close dialog │────────────────────────────────────╯" -"╭───────────────────────── cpu 03.00%│ ( q ) quit at any time │──────╮╭────────── ports ───────────╮" -"│10.00%│ •• │ │ ││ ip private public│" -"│ │ • • │ currently an early work in progress, all and any input appreciated │ ││ 8001 │" -"│ │ •• • │ https://github.com/mrjackwills/oxker │ ││127.0.0.1 8003 8003│" -"│ │ • • │ │ ││ │" +"╰────────────────────────────────────│ ( \ ) toggle log section visibility │────────────────────────────────────╯" +"╭───────────────────────── cpu 03.00%│ ( esc ) close dialog │──────╮╭────────── ports ───────────╮" +"│10.00%│ •• │ ( q ) quit at any time │ ││ ip private public│" +"│ │ • • │ │ ││ 8001 │" +"│ │ •• • │ currently an early work in progress, all and any input appreciated │ ││127.0.0.1 8003 8003│" +"│ │ • • │ https://github.com/mrjackwills/oxker │ ││ │" "│ │ •• • • │ │ ││ │" "│ │• •• ╰────────────────────────────────────────────────────────────────────────────────────╯ ││ │" "│ │• • ││ │• • ││ │" diff --git a/src/ui/gui_state.rs b/src/ui/gui_state.rs index 5915363..dd0aac9 100644 --- a/src/ui/gui_state.rs +++ b/src/ui/gui_state.rs @@ -217,7 +217,7 @@ impl GuiState { pub fn log_height_increase(&mut self) { if self.show_logs && self.log_height <= 75 { self.log_height = self.log_height.saturating_add(5); - self.rerender.update(); + self.rerender.update_draw(); } } @@ -230,7 +230,7 @@ impl GuiState { self.show_logs = false; self.selected_panel = SelectablePanel::Containers; } - self.rerender.update(); + self.rerender.update_draw(); } } @@ -253,7 +253,7 @@ impl GuiState { if !self.show_logs && self.selected_panel == SelectablePanel::Logs { self.selected_panel = SelectablePanel::Containers; } - self.rerender.update(); + self.rerender.update_draw(); } /// Set the log_height to zero, for now only used by tests @@ -272,6 +272,11 @@ impl GuiState { self.intersect_panel.clear(); } + /// Set the rerender clear to true, to flush the screen and redraw + pub fn set_clear(&self) { + self.rerender.set_clear(); + } + /// Get the currently selected panel pub const fn get_selected_panel(&self) -> SelectablePanel { self.selected_panel @@ -287,7 +292,7 @@ impl GuiState { .first() { self.selected_panel = *data.0; - self.rerender.update(); + self.rerender.update_draw(); } } @@ -360,7 +365,7 @@ impl GuiState { self.status_del(Status::DeleteConfirm); } self.delete_container_id = id; - self.rerender.update(); + self.rerender.update_draw(); } /// Return a copy of the Status HashSet @@ -381,7 +386,7 @@ impl GuiState { } _ => (), } - self.rerender.update(); + self.rerender.update_draw(); } /// Inset the ExecMode into self, and set the Status as exec @@ -390,7 +395,7 @@ impl GuiState { pub fn set_exec_mode(&mut self, mode: ExecMode) { self.exec_mode = Some(mode); self.status.insert(Status::Exec); - self.rerender.update(); + self.rerender.update_draw(); } pub fn get_exec_mode(&self) -> Option { @@ -402,7 +407,7 @@ impl GuiState { pub fn status_push(&mut self, status: Status) { if status != Status::Exec { self.status.insert(status); - self.rerender.update(); + self.rerender.update_draw(); } } @@ -415,7 +420,7 @@ impl GuiState { { self.selected_panel = self.selected_panel.next(); } - self.rerender.update(); + self.rerender.update_draw(); } /// Change to previous selectable panel @@ -427,7 +432,7 @@ impl GuiState { { self.selected_panel = self.selected_panel.prev(); } - self.rerender.update(); + self.rerender.update_draw(); } /// Insert a new loading_uuid into HashSet, and advance the loading_index by one frame, or reset to 0 if at end of array @@ -438,7 +443,7 @@ impl GuiState { self.loading_index += 1; } self.loading_set.insert(uuid); - self.rerender.update(); + self.rerender.update_draw(); } pub fn is_loading(&self) -> bool { @@ -471,7 +476,7 @@ impl GuiState { /// Stop the loading_spin function, and reset gui loading status pub fn stop_loading_animation(&mut self, loading_uuid: Uuid) { self.loading_set.remove(&loading_uuid); - self.rerender.update(); + self.rerender.update_draw(); if self.loading_set.is_empty() { self.loading_index = 0; if let Some(h) = &self.loading_handle { @@ -484,12 +489,12 @@ impl GuiState { /// Set info box content pub fn set_info_box(&mut self, text: &str) { self.info_box_text = Some((text.to_owned(), std::time::Instant::now())); - self.rerender.update(); + self.rerender.update_draw(); } /// Remove info box content pub fn reset_info_box(&mut self) { self.info_box_text = None; - self.rerender.update(); + self.rerender.update_draw(); } } diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 412a6be..b749aed 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -50,7 +50,7 @@ pub struct Ui { input_tx: Sender, is_running: Arc, now: Instant, - redraw: Arc, + rerender: Arc, terminal: Terminal>, } @@ -73,7 +73,7 @@ impl Ui { gui_state: Arc>, input_tx: Sender, is_running: Arc, - redraw: Arc, + rerender: Arc, ) { match Self::setup_terminal() { Ok(mut terminal) => { @@ -85,7 +85,7 @@ impl Ui { input_tx, is_running, now: Instant::now(), - redraw, + rerender, terminal, }; if let Err(e) = ui.draw_ui().await { @@ -169,6 +169,13 @@ impl Ui { Ok(()) } + /// Check if the user has attempt to clear the screen, and if so clear and redraw + fn check_clear(&mut self) { + if self.rerender.get_clear() { + self.terminal.clear().ok(); + self.rerender.update_draw(); + } + } /// Use external docker cli to exec into a container async fn exec(&mut self) { let exec_mode = self.gui_state.lock().get_exec_mode(); @@ -191,7 +198,8 @@ impl Ui { /// Use the previously redrawn time, the current time, the docker_interval, and the redraw struct, to calculate /// if the screen should be redrawn or not fn should_redraw(&self, previous: &mut Instant, docker_interval_ms: u128) -> bool { - let result = self.redraw.swap() || previous.elapsed().as_millis() >= docker_interval_ms; + let result = + self.rerender.swap_draw() || previous.elapsed().as_millis() >= docker_interval_ms; if result { *previous = std::time::Instant::now(); } @@ -210,6 +218,10 @@ impl Ui { } while self.is_running.load(Ordering::SeqCst) { + // if self.redraw.get_clear() { + // self.terminal.clear().ok(); + // continue; + // } if self.should_redraw(&mut drawn_at, docker_interval_ms) { let fd = FrameData::from(&*self); @@ -249,15 +261,12 @@ impl Ui { } } else if let Event::Resize(width, _) = event { self.gui_state.lock().clear_area_map(); - - // self.gui_state.lock().set_window_height(row); - self.terminal.autoresize().ok(); - // todo set screen width self.gui_state.lock().set_screen_width(width); } } } + self.check_clear(); } Ok(()) } diff --git a/src/ui/redraw.rs b/src/ui/redraw.rs index 4fd40d2..0647853 100644 --- a/src/ui/redraw.rs +++ b/src/ui/redraw.rs @@ -1,21 +1,40 @@ use std::sync::atomic::{AtomicBool, Ordering}; #[derive(Debug)] -pub struct Rerender(AtomicBool); +pub struct Rerender { + draw: AtomicBool, + clear: AtomicBool, +} impl Rerender { pub const fn new() -> Self { - Self(AtomicBool::new(true)) + Self { + draw: AtomicBool::new(true), + clear: AtomicBool::new(false), + } } - pub fn update(&self) { - self.0.store(true, Ordering::SeqCst); + pub fn update_draw(&self) { + self.draw.store(true, Ordering::SeqCst); } - /// Return the value of the self, and set to false - pub fn swap(&self) -> bool { + pub fn get_clear(&self) -> bool { + if self.clear.load(Ordering::SeqCst) { + self.clear.store(false, Ordering::SeqCst); + true + } else { + false + } + } + + pub fn set_clear(&self) { + self.clear.store(true, Ordering::SeqCst); + } + + /// Return the value of the draw, and set to false + pub fn swap_draw(&self) -> bool { match self - .0 + .draw .compare_exchange(true, false, Ordering::SeqCst, Ordering::SeqCst) { Ok(previous_value) => previous_value,