From 34c102195df146984426680ca1bceb87230bd9b8 Mon Sep 17 00:00:00 2001 From: ClementTsang Date: Wed, 25 Sep 2019 16:43:13 -0400 Subject: [PATCH] Added scrolling for temp and disk list. --- README.md | 4 +- TODO.md | 20 ------ rustfmt.toml | 2 +- src/app.rs | 14 +++-- src/canvas.rs | 150 ++++++++++++++++++++++++++++++++------------ src/convert_data.rs | 7 ++- src/main.rs | 12 +++- 7 files changed, 141 insertions(+), 68 deletions(-) diff --git a/README.md b/README.md index b3e19f06..76637f9a 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,9 @@ Currently, I'm unable to really dev or test on MacOS, so I'm not sure how well t - `q`, `Esc`, or `Ctrl-C` to quit. -- `Up/k`, `Down/j`, `Left/h`, `Right/l` to navigate between panels. This currently doesn't have much functionality but will change in the future. +- `Up/k`, `Down/j`, `Left/h`, `Right/l` to navigate between panels. + +- `Shift+Up` and `Shift+Down` scrolls through the list if the panel is a table (Temperature, Disks, Processes) #### Processes Panel diff --git a/TODO.md b/TODO.md index 546c5da2..84802cf6 100644 --- a/TODO.md +++ b/TODO.md @@ -2,26 +2,6 @@ Note this will probably migrate to GitHub's native Issues; this was mostly for personal use during early stages. -## Pre-release (bare minimum) - -- ~~Get each function working as a POC~~ - -- ~~Separate each component for readability, finalize project structure~~ - -- ~~Refreshing - how are we doing that? Are we allowing individual refresh periods per component?~~ - -- ~~Write tui display, charting~~ - -- ~~FIX PROCESSES AHHHHHH~~ - -- ~~Scrolling in at least processes~~ - -- Keybindings - I want to do at least arrow keys and dd. - -- ~~Legend gets in the way at too small of a height... maybe modify tui a bit more to fix this.~~ - -## After making public - - Scrolling support for temp/disk - Travis diff --git a/rustfmt.toml b/rustfmt.toml index 6e1fdffd..4bc25f6e 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -1,4 +1,4 @@ -max_width = 175 +max_width = 150 reorder_imports = true control_brace_style = "ClosingNextLine" fn_args_layout = "Compressed" diff --git a/src/app.rs b/src/app.rs index 921130ad..83f0a010 100644 --- a/src/app.rs +++ b/src/app.rs @@ -35,6 +35,8 @@ pub struct App { pub current_zoom_level_percent : f64, // Make at most 200, least 50? pub data : data_collection::Data, pub scroll_direction : ScrollDirection, + pub previous_disk_position : i64, + pub previous_temp_position : i64, pub previous_process_position : i64, awaiting_second_d : bool, pub use_dot : bool, @@ -58,6 +60,8 @@ impl App { data : data_collection::Data::default(), scroll_direction : ScrollDirection::DOWN, previous_process_position : 0, + previous_disk_position : 0, + previous_temp_position : 0, awaiting_second_d : false, use_dot, } @@ -210,16 +214,18 @@ impl App { } fn change_temp_position(&mut self, num_to_change_by : i64) { - if self.currently_selected_temperature_position + num_to_change_by >= 0 { + if self.currently_selected_temperature_position + num_to_change_by >= 0 + && self.currently_selected_temperature_position + num_to_change_by < self.data.list_of_temperature_sensor.len() as i64 + { self.currently_selected_temperature_position += num_to_change_by; } - // else if self.currently_selected_temperature_position < // TODO: Need to finish this! This should never go PAST the number of elements } fn change_disk_position(&mut self, num_to_change_by : i64) { - if self.currently_selected_disk_position + num_to_change_by >= 0 { + if self.currently_selected_disk_position + num_to_change_by >= 0 + && self.currently_selected_disk_position + num_to_change_by < self.data.list_of_disks.len() as i64 + { self.currently_selected_disk_position += num_to_change_by; } - // else if self.currently_selected_disk_position < // TODO: Need to finish this! This should never go PAST the number of elements } } diff --git a/src/canvas.rs b/src/canvas.rs index cb35d723..30fa374b 100644 --- a/src/canvas.rs +++ b/src/canvas.rs @@ -8,7 +8,14 @@ use tui_temp_fork::{ use crate::{app, utils::error}; -const COLOUR_LIST : [Color; 6] = [Color::Red, Color::Green, Color::LightYellow, Color::LightBlue, Color::LightCyan, Color::LightMagenta]; +const COLOUR_LIST : [Color; 6] = [ + Color::Red, + Color::Green, + Color::LightYellow, + Color::LightBlue, + Color::LightCyan, + Color::LightMagenta, +]; const TEXT_COLOUR : Color = Color::Gray; const GRAPH_COLOUR : Color = Color::Gray; const BORDER_STYLE_COLOUR : Color = Color::Gray; @@ -32,12 +39,6 @@ pub fn draw_data(terminal : &mut Terminal, app_state : let border_style : Style = Style::default().fg(BORDER_STYLE_COLOUR); let highlighted_border_style : Style = Style::default().fg(HIGHLIGHTED_BORDER_STYLE_COLOUR); - let temperature_rows = canvas_data - .temp_sensor_data - .iter() - .map(|sensor| Row::StyledData(sensor.iter(), Style::default().fg(TEXT_COLOUR))); - let disk_rows = canvas_data.disk_data.iter().map(|disk| Row::StyledData(disk.iter(), Style::default().fg(TEXT_COLOUR))); - terminal.draw(|mut f| { //debug!("Drawing!"); let vertical_chunks = Layout::default() @@ -68,7 +69,10 @@ pub fn draw_data(terminal : &mut Terminal, app_state : // CPU usage graph { let x_axis : Axis = Axis::default().style(Style::default().fg(GRAPH_COLOUR)).bounds([0.0, 600_000.0]); - let y_axis = Axis::default().style(Style::default().fg(GRAPH_COLOUR)).bounds([-0.5, 100.5]).labels(&["0%", "100%"]); + let y_axis = Axis::default() + .style(Style::default().fg(GRAPH_COLOUR)) + .bounds([-0.5, 100.5]) + .labels(&["0%", "100%"]); let mut dataset_vector : Vec = Vec::new(); @@ -122,7 +126,10 @@ pub fn draw_data(terminal : &mut Terminal, app_state : //Memory usage graph { let x_axis : Axis = Axis::default().style(Style::default().fg(GRAPH_COLOUR)).bounds([0.0, 600_000.0]); - let y_axis = Axis::default().style(Style::default().fg(GRAPH_COLOUR)).bounds([-0.5, 100.5]).labels(&["0%", "100%"]); // Offset as the zero value isn't drawn otherwise... + let y_axis = Axis::default() + .style(Style::default().fg(GRAPH_COLOUR)) + .bounds([-0.5, 100.5]) + .labels(&["0%", "100%"]); // Offset as the zero value isn't drawn otherwise... let mem_name = "RAM:".to_string() + &format!("{:3}%", (canvas_data.mem_data.last().unwrap_or(&(0_f64, 0_f64)).1.round() as u64)); let swap_name = "SWP:".to_string() + &format!("{:3}%", (canvas_data.swap_data.last().unwrap_or(&(0_f64, 0_f64)).1.round() as u64)); @@ -160,6 +167,34 @@ pub fn draw_data(terminal : &mut Terminal, app_state : // Temperature table { + let num_rows = i64::from(middle_divided_chunk_2[0].height) - 3; + let start_position = get_start_position( + num_rows, + &(app_state.scroll_direction), + &mut app_state.previous_temp_position, + &mut app_state.currently_selected_temperature_position, + ); + + let sliced_vec : Vec> = (&canvas_data.temp_sensor_data[start_position as usize..]).to_vec(); + let mut disk_counter = 0; + + let temperature_rows = sliced_vec.iter().map(|disk| { + Row::StyledData( + disk.iter(), + if disk_counter == app_state.currently_selected_temperature_position - start_position { + // TODO: This is what controls the highlighting! + disk_counter = -1; + Style::default().fg(Color::Black).bg(Color::Cyan) + } + else { + if disk_counter >= 0 { + disk_counter += 1; + } + Style::default().fg(TEXT_COLOUR) + }, + ) + }); + let width = f64::from(middle_divided_chunk_2[0].width); Table::new(["Sensor", "Temp"].iter(), temperature_rows) .block( @@ -178,6 +213,34 @@ pub fn draw_data(terminal : &mut Terminal, app_state : // Disk usage table { + let num_rows = i64::from(middle_divided_chunk_2[1].height) - 3; + let start_position = get_start_position( + num_rows, + &(app_state.scroll_direction), + &mut app_state.previous_disk_position, + &mut app_state.currently_selected_disk_position, + ); + + let sliced_vec : Vec> = (&canvas_data.disk_data[start_position as usize..]).to_vec(); + let mut disk_counter = 0; + + let disk_rows = sliced_vec.iter().map(|disk| { + Row::StyledData( + disk.iter(), + if disk_counter == app_state.currently_selected_disk_position - start_position { + // TODO: This is what controls the highlighting! + disk_counter = -1; + Style::default().fg(Color::Black).bg(Color::Cyan) + } + else { + if disk_counter >= 0 { + disk_counter += 1; + } + Style::default().fg(TEXT_COLOUR) + }, + ) + }); + // TODO: We may have to dynamically remove some of these table elements based on size... let width = f64::from(middle_divided_chunk_2[1].width); Table::new(["Disk", "Mount", "Used", "Total", "Free", "R/s", "W/s"].iter(), disk_rows) @@ -206,7 +269,10 @@ pub fn draw_data(terminal : &mut Terminal, app_state : // Network graph { let x_axis : Axis = Axis::default().style(Style::default().fg(GRAPH_COLOUR)).bounds([0.0, 600_000.0]); - let y_axis = Axis::default().style(Style::default().fg(GRAPH_COLOUR)).bounds([-0.5, 1_000_000.5]).labels(&["0GB", "1GB"]); + let y_axis = Axis::default() + .style(Style::default().fg(GRAPH_COLOUR)) + .bounds([-0.5, 1_000_000.5]) + .labels(&["0GB", "1GB"]); Chart::default() .block( Block::default() @@ -244,36 +310,13 @@ pub fn draw_data(terminal : &mut Terminal, app_state : // As such, we use a process_counter to know when we've hit the process we've currently scrolled to. We also need to move the list - we can // do so by hiding some elements! let num_rows = i64::from(bottom_chunks[1].height) - 3; - let mut process_counter = 0; - let start_position = match app_state.scroll_direction { - app::ScrollDirection::DOWN => { - if app_state.currently_selected_process_position < num_rows { - 0 - } - else if app_state.currently_selected_process_position - num_rows < app_state.previous_process_position { - app_state.previous_process_position - } - else { - app_state.previous_process_position = app_state.currently_selected_process_position - num_rows + 1; - app_state.previous_process_position - } - } - app::ScrollDirection::UP => { - if app_state.currently_selected_process_position == app_state.previous_process_position - 1 { - app_state.previous_process_position = if app_state.previous_process_position > 0 { - app_state.previous_process_position - 1 - } - else { - 0 - }; - app_state.previous_process_position - } - else { - app_state.previous_process_position - } - } - }; + let start_position = get_start_position( + num_rows, + &(app_state.scroll_direction), + &mut app_state.previous_process_position, + &mut app_state.currently_selected_process_position, + ); /*debug!( "START POSN: {}, PREV POSN: {}, CURRENT SELECTED POSN: {}, NUM ROWS: {}", @@ -281,6 +324,7 @@ pub fn draw_data(terminal : &mut Terminal, app_state : );*/ let sliced_vec : Vec> = (&canvas_data.process_data[start_position as usize..]).to_vec(); + let mut process_counter = 0; let process_rows = sliced_vec.iter().map(|process| { Row::StyledData( @@ -319,3 +363,31 @@ pub fn draw_data(terminal : &mut Terminal, app_state : Ok(()) } + +fn get_start_position( + num_rows : i64, scroll_direction : &app::ScrollDirection, previous_position : &mut i64, currently_selected_position : &mut i64, +) -> i64 { + match scroll_direction { + app::ScrollDirection::DOWN => { + if *currently_selected_position < num_rows { + 0 + } + else if *currently_selected_position - num_rows < *previous_position { + *previous_position + } + else { + *previous_position = *currently_selected_position - num_rows + 1; + *previous_position + } + } + app::ScrollDirection::UP => { + if *currently_selected_position == *previous_position - 1 { + *previous_position = if *previous_position > 0 { *previous_position - 1 } else { 0 }; + *previous_position + } + else { + *previous_position + } + } + } +} diff --git a/src/convert_data.rs b/src/convert_data.rs index 08a522e3..a230fe67 100644 --- a/src/convert_data.rs +++ b/src/convert_data.rs @@ -309,5 +309,10 @@ pub fn convert_network_data_points(network_data : &[data_collection::network::Ne } }; - ConvertedNetworkData { rx, tx, rx_display, tx_display } + ConvertedNetworkData { + rx, + tx, + rx_display, + tx_display, + } } diff --git a/src/main.rs b/src/main.rs index 2542b106..c32c4097 100644 --- a/src/main.rs +++ b/src/main.rs @@ -195,7 +195,11 @@ fn main() -> error::Result<()> { } if app.to_be_resorted { - data_collection::processes::sort_processes(&mut app.data.list_of_processes, &app.process_sorting_type, app.process_sorting_reverse); + data_collection::processes::sort_processes( + &mut app.data.list_of_processes, + &app.process_sorting_type, + app.process_sorting_reverse, + ); canvas_data.process_data = update_process_row(&app.data); app.to_be_resorted = false; } @@ -221,7 +225,11 @@ fn main() -> error::Result<()> { Event::Update(data) => { // debug!("Update event fired!"); app.data = *data; - data_collection::processes::sort_processes(&mut app.data.list_of_processes, &app.process_sorting_type, app.process_sorting_reverse); + data_collection::processes::sort_processes( + &mut app.data.list_of_processes, + &app.process_sorting_type, + app.process_sorting_reverse, + ); // Convert all data into tui components let network_data = update_network_data_points(&app.data);