mirror of
https://github.com/ClementTsang/bottom
synced 2024-11-10 14:44:18 +00:00
Added scrolling for temp and disk list.
This commit is contained in:
parent
1112ae714e
commit
34c102195d
7 changed files with 141 additions and 68 deletions
|
@ -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
|
||||
|
||||
|
|
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.
|
||||
|
||||
## 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
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
max_width = 175
|
||||
max_width = 150
|
||||
reorder_imports = true
|
||||
control_brace_style = "ClosingNextLine"
|
||||
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 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
|
||||
}
|
||||
}
|
||||
|
|
150
src/canvas.rs
150
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<B : backend::Backend>(terminal : &mut Terminal<B>, 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<B : backend::Backend>(terminal : &mut Terminal<B>, app_state :
|
|||
// CPU usage graph
|
||||
{
|
||||
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();
|
||||
|
||||
|
@ -122,7 +126,10 @@ pub fn draw_data<B : backend::Backend>(terminal : &mut Terminal<B>, app_state :
|
|||
//Memory usage graph
|
||||
{
|
||||
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 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
|
||||
{
|
||||
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);
|
||||
Table::new(["Sensor", "Temp"].iter(), temperature_rows)
|
||||
.block(
|
||||
|
@ -178,6 +213,34 @@ pub fn draw_data<B : backend::Backend>(terminal : &mut Terminal<B>, 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<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...
|
||||
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<B : backend::Backend>(terminal : &mut Terminal<B>, app_state :
|
|||
// Network graph
|
||||
{
|
||||
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()
|
||||
.block(
|
||||
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
|
||||
// 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<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 mut process_counter = 0;
|
||||
|
||||
let process_rows = sliced_vec.iter().map(|process| {
|
||||
Row::StyledData(
|
||||
|
@ -319,3 +363,31 @@ pub fn draw_data<B : backend::Backend>(terminal : &mut Terminal<B>, 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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
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);
|
||||
|
|
Loading…
Reference in a new issue