Added scrolling for temp and disk list.
This commit is contained in:
parent
1112ae714e
commit
34c102195d
|
@ -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.
|
- `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
|
#### Processes Panel
|
||||||
|
|
||||||
|
|
20
TODO.md
20
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.
|
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
|
- Scrolling support for temp/disk
|
||||||
|
|
||||||
- Travis
|
- Travis
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
max_width = 175
|
max_width = 150
|
||||||
reorder_imports = true
|
reorder_imports = true
|
||||||
control_brace_style = "ClosingNextLine"
|
control_brace_style = "ClosingNextLine"
|
||||||
fn_args_layout = "Compressed"
|
fn_args_layout = "Compressed"
|
||||||
|
|
14
src/app.rs
14
src/app.rs
|
@ -35,6 +35,8 @@ pub struct App {
|
||||||
pub current_zoom_level_percent : f64, // Make at most 200, least 50?
|
pub current_zoom_level_percent : f64, // Make at most 200, least 50?
|
||||||
pub data : data_collection::Data,
|
pub data : data_collection::Data,
|
||||||
pub scroll_direction : ScrollDirection,
|
pub scroll_direction : ScrollDirection,
|
||||||
|
pub previous_disk_position : i64,
|
||||||
|
pub previous_temp_position : i64,
|
||||||
pub previous_process_position : i64,
|
pub previous_process_position : i64,
|
||||||
awaiting_second_d : bool,
|
awaiting_second_d : bool,
|
||||||
pub use_dot : bool,
|
pub use_dot : bool,
|
||||||
|
@ -58,6 +60,8 @@ impl App {
|
||||||
data : data_collection::Data::default(),
|
data : data_collection::Data::default(),
|
||||||
scroll_direction : ScrollDirection::DOWN,
|
scroll_direction : ScrollDirection::DOWN,
|
||||||
previous_process_position : 0,
|
previous_process_position : 0,
|
||||||
|
previous_disk_position : 0,
|
||||||
|
previous_temp_position : 0,
|
||||||
awaiting_second_d : false,
|
awaiting_second_d : false,
|
||||||
use_dot,
|
use_dot,
|
||||||
}
|
}
|
||||||
|
@ -210,16 +214,18 @@ impl App {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn change_temp_position(&mut self, num_to_change_by : i64) {
|
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;
|
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) {
|
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;
|
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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
150
src/canvas.rs
150
src/canvas.rs
|
@ -8,7 +8,14 @@ use tui_temp_fork::{
|
||||||
|
|
||||||
use crate::{app, utils::error};
|
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 TEXT_COLOUR : Color = Color::Gray;
|
||||||
const GRAPH_COLOUR : Color = Color::Gray;
|
const GRAPH_COLOUR : Color = Color::Gray;
|
||||||
const BORDER_STYLE_COLOUR : Color = Color::Gray;
|
const BORDER_STYLE_COLOUR : Color = Color::Gray;
|
||||||
|
@ -32,12 +39,6 @@ pub fn draw_data<B : backend::Backend>(terminal : &mut Terminal<B>, app_state :
|
||||||
let border_style : Style = Style::default().fg(BORDER_STYLE_COLOUR);
|
let border_style : Style = Style::default().fg(BORDER_STYLE_COLOUR);
|
||||||
let highlighted_border_style : Style = Style::default().fg(HIGHLIGHTED_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| {
|
terminal.draw(|mut f| {
|
||||||
//debug!("Drawing!");
|
//debug!("Drawing!");
|
||||||
let vertical_chunks = Layout::default()
|
let vertical_chunks = Layout::default()
|
||||||
|
@ -68,7 +69,10 @@ pub fn draw_data<B : backend::Backend>(terminal : &mut Terminal<B>, app_state :
|
||||||
// CPU usage graph
|
// CPU usage graph
|
||||||
{
|
{
|
||||||
let x_axis : Axis<String> = Axis::default().style(Style::default().fg(GRAPH_COLOUR)).bounds([0.0, 600_000.0]);
|
let x_axis : Axis<String> = 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<Dataset> = Vec::new();
|
let mut dataset_vector : Vec<Dataset> = Vec::new();
|
||||||
|
|
||||||
|
@ -122,7 +126,10 @@ pub fn draw_data<B : backend::Backend>(terminal : &mut Terminal<B>, app_state :
|
||||||
//Memory usage graph
|
//Memory usage graph
|
||||||
{
|
{
|
||||||
let x_axis : Axis<String> = Axis::default().style(Style::default().fg(GRAPH_COLOUR)).bounds([0.0, 600_000.0]);
|
let x_axis : Axis<String> = 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 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));
|
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<B : backend::Backend>(terminal : &mut Terminal<B>, app_state :
|
||||||
|
|
||||||
// Temperature table
|
// 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<Vec<String>> = (&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);
|
let width = f64::from(middle_divided_chunk_2[0].width);
|
||||||
Table::new(["Sensor", "Temp"].iter(), temperature_rows)
|
Table::new(["Sensor", "Temp"].iter(), temperature_rows)
|
||||||
.block(
|
.block(
|
||||||
|
@ -178,6 +213,34 @@ pub fn draw_data<B : backend::Backend>(terminal : &mut Terminal<B>, app_state :
|
||||||
|
|
||||||
// Disk usage table
|
// 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<Vec<String>> = (&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...
|
// 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);
|
let width = f64::from(middle_divided_chunk_2[1].width);
|
||||||
Table::new(["Disk", "Mount", "Used", "Total", "Free", "R/s", "W/s"].iter(), disk_rows)
|
Table::new(["Disk", "Mount", "Used", "Total", "Free", "R/s", "W/s"].iter(), disk_rows)
|
||||||
|
@ -206,7 +269,10 @@ pub fn draw_data<B : backend::Backend>(terminal : &mut Terminal<B>, app_state :
|
||||||
// Network graph
|
// Network graph
|
||||||
{
|
{
|
||||||
let x_axis : Axis<String> = Axis::default().style(Style::default().fg(GRAPH_COLOUR)).bounds([0.0, 600_000.0]);
|
let x_axis : Axis<String> = 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()
|
Chart::default()
|
||||||
.block(
|
.block(
|
||||||
Block::default()
|
Block::default()
|
||||||
|
@ -244,36 +310,13 @@ pub fn draw_data<B : backend::Backend>(terminal : &mut Terminal<B>, 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
|
// 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!
|
// do so by hiding some elements!
|
||||||
let num_rows = i64::from(bottom_chunks[1].height) - 3;
|
let num_rows = i64::from(bottom_chunks[1].height) - 3;
|
||||||
let mut process_counter = 0;
|
|
||||||
|
|
||||||
let start_position = match app_state.scroll_direction {
|
let start_position = get_start_position(
|
||||||
app::ScrollDirection::DOWN => {
|
num_rows,
|
||||||
if app_state.currently_selected_process_position < num_rows {
|
&(app_state.scroll_direction),
|
||||||
0
|
&mut app_state.previous_process_position,
|
||||||
}
|
&mut app_state.currently_selected_process_position,
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/*debug!(
|
/*debug!(
|
||||||
"START POSN: {}, PREV POSN: {}, CURRENT SELECTED POSN: {}, NUM ROWS: {}",
|
"START POSN: {}, PREV POSN: {}, CURRENT SELECTED POSN: {}, NUM ROWS: {}",
|
||||||
|
@ -281,6 +324,7 @@ pub fn draw_data<B : backend::Backend>(terminal : &mut Terminal<B>, app_state :
|
||||||
);*/
|
);*/
|
||||||
|
|
||||||
let sliced_vec : Vec<Vec<String>> = (&canvas_data.process_data[start_position as usize..]).to_vec();
|
let sliced_vec : Vec<Vec<String>> = (&canvas_data.process_data[start_position as usize..]).to_vec();
|
||||||
|
let mut process_counter = 0;
|
||||||
|
|
||||||
let process_rows = sliced_vec.iter().map(|process| {
|
let process_rows = sliced_vec.iter().map(|process| {
|
||||||
Row::StyledData(
|
Row::StyledData(
|
||||||
|
@ -319,3 +363,31 @@ pub fn draw_data<B : backend::Backend>(terminal : &mut Terminal<B>, app_state :
|
||||||
|
|
||||||
Ok(())
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
12
src/main.rs
12
src/main.rs
|
@ -195,7 +195,11 @@ fn main() -> error::Result<()> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if app.to_be_resorted {
|
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);
|
canvas_data.process_data = update_process_row(&app.data);
|
||||||
app.to_be_resorted = false;
|
app.to_be_resorted = false;
|
||||||
}
|
}
|
||||||
|
@ -221,7 +225,11 @@ fn main() -> error::Result<()> {
|
||||||
Event::Update(data) => {
|
Event::Update(data) => {
|
||||||
// debug!("Update event fired!");
|
// debug!("Update event fired!");
|
||||||
app.data = *data;
|
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
|
// Convert all data into tui components
|
||||||
let network_data = update_network_data_points(&app.data);
|
let network_data = update_network_data_points(&app.data);
|
||||||
|
|
Loading…
Reference in New Issue