mirror of
https://github.com/ClementTsang/bottom.git
synced 2025-07-22 13:14:40 +02:00
Add scrolling to CPU list.
This commit is contained in:
parent
4e6e32a0ea
commit
2c138378fc
29
src/app.rs
29
src/app.rs
@ -29,13 +29,15 @@ pub struct App {
|
|||||||
pub process_sorting_reverse: bool,
|
pub process_sorting_reverse: bool,
|
||||||
pub to_be_resorted: bool,
|
pub to_be_resorted: bool,
|
||||||
// Positioning
|
// Positioning
|
||||||
|
pub scroll_direction: ScrollDirection,
|
||||||
pub currently_selected_process_position: i64,
|
pub currently_selected_process_position: i64,
|
||||||
pub currently_selected_disk_position: i64,
|
pub currently_selected_disk_position: i64,
|
||||||
pub currently_selected_temperature_position: i64,
|
pub currently_selected_temperature_position: i64,
|
||||||
pub scroll_direction: ScrollDirection,
|
pub currently_selected_cpu_table_position: i64,
|
||||||
pub previous_disk_position: i64,
|
pub previous_disk_position: i64,
|
||||||
pub previous_temp_position: i64,
|
pub previous_temp_position: i64,
|
||||||
pub previous_process_position: i64,
|
pub previous_process_position: i64,
|
||||||
|
pub previous_cpu_table_position: i64,
|
||||||
pub temperature_type: temperature::TemperatureType,
|
pub temperature_type: temperature::TemperatureType,
|
||||||
pub update_rate_in_milliseconds: u64,
|
pub update_rate_in_milliseconds: u64,
|
||||||
pub show_average_cpu: bool,
|
pub show_average_cpu: bool,
|
||||||
@ -60,17 +62,19 @@ impl App {
|
|||||||
process_sorting_type: processes::ProcessSorting::CPU,
|
process_sorting_type: processes::ProcessSorting::CPU,
|
||||||
process_sorting_reverse: true,
|
process_sorting_reverse: true,
|
||||||
to_be_resorted: false,
|
to_be_resorted: false,
|
||||||
currently_selected_process_position: 0,
|
|
||||||
currently_selected_disk_position: 0,
|
|
||||||
currently_selected_temperature_position: 0,
|
|
||||||
temperature_type,
|
temperature_type,
|
||||||
update_rate_in_milliseconds,
|
update_rate_in_milliseconds,
|
||||||
show_average_cpu,
|
show_average_cpu,
|
||||||
current_application_position: ApplicationPosition::Process,
|
current_application_position: ApplicationPosition::Process,
|
||||||
scroll_direction: ScrollDirection::DOWN,
|
scroll_direction: ScrollDirection::DOWN,
|
||||||
|
currently_selected_process_position: 0,
|
||||||
|
currently_selected_disk_position: 0,
|
||||||
|
currently_selected_temperature_position: 0,
|
||||||
|
currently_selected_cpu_table_position: 0,
|
||||||
previous_process_position: 0,
|
previous_process_position: 0,
|
||||||
previous_disk_position: 0,
|
previous_disk_position: 0,
|
||||||
previous_temp_position: 0,
|
previous_temp_position: 0,
|
||||||
|
previous_cpu_table_position: 0,
|
||||||
data: data_collection::Data::default(),
|
data: data_collection::Data::default(),
|
||||||
awaiting_second_char: false,
|
awaiting_second_char: false,
|
||||||
second_char: ' ',
|
second_char: ' ',
|
||||||
@ -274,6 +278,7 @@ impl App {
|
|||||||
ApplicationPosition::Process => self.change_process_position(-1),
|
ApplicationPosition::Process => self.change_process_position(-1),
|
||||||
ApplicationPosition::Temp => self.change_temp_position(-1),
|
ApplicationPosition::Temp => self.change_temp_position(-1),
|
||||||
ApplicationPosition::Disk => self.change_disk_position(-1),
|
ApplicationPosition::Disk => self.change_disk_position(-1),
|
||||||
|
ApplicationPosition::Cpu => self.change_cpu_table_position(-1), // TODO: Temporary
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
self.scroll_direction = ScrollDirection::UP;
|
self.scroll_direction = ScrollDirection::UP;
|
||||||
@ -285,12 +290,28 @@ impl App {
|
|||||||
ApplicationPosition::Process => self.change_process_position(1),
|
ApplicationPosition::Process => self.change_process_position(1),
|
||||||
ApplicationPosition::Temp => self.change_temp_position(1),
|
ApplicationPosition::Temp => self.change_temp_position(1),
|
||||||
ApplicationPosition::Disk => self.change_disk_position(1),
|
ApplicationPosition::Disk => self.change_disk_position(1),
|
||||||
|
ApplicationPosition::Cpu => self.change_cpu_table_position(1), // TODO: Temporary
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
self.scroll_direction = ScrollDirection::DOWN;
|
self.scroll_direction = ScrollDirection::DOWN;
|
||||||
self.reset_multi_tap_keys();
|
self.reset_multi_tap_keys();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn change_cpu_table_position(&mut self, num_to_change_by: i64) {
|
||||||
|
if let Some(cpu_package) = self.data.list_of_cpu_packages.last() {
|
||||||
|
if self.currently_selected_cpu_table_position + num_to_change_by >= 0
|
||||||
|
&& self.currently_selected_cpu_table_position + num_to_change_by
|
||||||
|
< if self.show_average_cpu {
|
||||||
|
cpu_package.cpu_vec.len()
|
||||||
|
} else {
|
||||||
|
cpu_package.cpu_vec.len() - 1
|
||||||
|
} as i64
|
||||||
|
{
|
||||||
|
self.currently_selected_cpu_table_position += num_to_change_by;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn change_process_position(&mut self, num_to_change_by: i64) {
|
fn change_process_position(&mut self, num_to_change_by: i64) {
|
||||||
if self.currently_selected_process_position + num_to_change_by >= 0
|
if self.currently_selected_process_position + num_to_change_by >= 0
|
||||||
&& self.currently_selected_process_position + num_to_change_by < self.data.list_of_processes.len() as i64
|
&& self.currently_selected_process_position + num_to_change_by < self.data.list_of_processes.len() as i64
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
use crate::{app, constants, utils::error, utils::gen_util::*};
|
use crate::{app, constants, utils::error, utils::gen_util::*};
|
||||||
use tui::{
|
use tui::{
|
||||||
backend,
|
backend,
|
||||||
layout::{Alignment, Constraint, Corner, Direction, Layout, Rect},
|
layout::{Alignment, Constraint, Direction, Layout, Rect},
|
||||||
style::{Color, Modifier, Style},
|
style::{Color, Modifier, Style},
|
||||||
terminal::Frame,
|
terminal::Frame,
|
||||||
widgets::{Axis, Block, Borders, Chart, Dataset, List, Marker, Paragraph, Row, Table, Text, Widget},
|
widgets::{Axis, Block, Borders, Chart, Dataset, Marker, Paragraph, Row, Table, Text, Widget},
|
||||||
Terminal,
|
Terminal,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -81,14 +81,7 @@ fn gen_n_colours(num_to_gen: i32) -> Vec<Color> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Generate colours
|
// Generate colours
|
||||||
let mut colour_vec: Vec<Color> = vec![
|
let mut colour_vec: Vec<Color> = vec![Color::LightCyan, Color::LightYellow, Color::Red, Color::Green, Color::LightMagenta];
|
||||||
Color::LightBlue,
|
|
||||||
Color::LightYellow,
|
|
||||||
Color::Red,
|
|
||||||
Color::Green,
|
|
||||||
Color::LightCyan,
|
|
||||||
Color::LightMagenta,
|
|
||||||
];
|
|
||||||
|
|
||||||
let mut h: f32 = 0.4; // We don't need random colours... right?
|
let mut h: f32 = 0.4; // We don't need random colours... right?
|
||||||
for _i in 0..num_to_gen {
|
for _i in 0..num_to_gen {
|
||||||
@ -183,8 +176,8 @@ pub fn draw_data<B: backend::Backend>(terminal: &mut Terminal<B>, app_state: &mu
|
|||||||
// CPU graph
|
// CPU graph
|
||||||
draw_cpu_graph(&mut f, &app_state, &canvas_data.cpu_data, cpu_chunk[graph_index]);
|
draw_cpu_graph(&mut f, &app_state, &canvas_data.cpu_data, cpu_chunk[graph_index]);
|
||||||
|
|
||||||
// CPU label
|
// CPU legend
|
||||||
draw_cpu_legend(&mut f, &app_state, &canvas_data.cpu_data, cpu_chunk[legend_index]);
|
draw_cpu_legend(&mut f, app_state, &canvas_data.cpu_data, cpu_chunk[legend_index]);
|
||||||
|
|
||||||
//Memory usage graph
|
//Memory usage graph
|
||||||
draw_memory_graph(
|
draw_memory_graph(
|
||||||
@ -219,6 +212,16 @@ pub fn draw_data<B: backend::Backend>(terminal: &mut Terminal<B>, app_state: &mu
|
|||||||
canvas_data.total_tx_display.clone(),
|
canvas_data.total_tx_display.clone(),
|
||||||
network_chunk[1],
|
network_chunk[1],
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
draw_network_labels(
|
||||||
|
&mut f,
|
||||||
|
app_state,
|
||||||
|
canvas_data.rx_display.clone(),
|
||||||
|
canvas_data.tx_display.clone(),
|
||||||
|
"N/A".to_string(),
|
||||||
|
"N/A".to_string(),
|
||||||
|
network_chunk[1],
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Temperature table
|
// Temperature table
|
||||||
@ -293,14 +296,42 @@ fn draw_cpu_graph<B: backend::Backend>(f: &mut Frame<B>, app_state: &app::App, c
|
|||||||
.render(f, draw_loc);
|
.render(f, draw_loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_cpu_legend<B: backend::Backend>(f: &mut Frame<B>, app_state: &app::App, cpu_data: &[(String, Vec<(f64, f64)>)], draw_loc: Rect) {
|
fn draw_cpu_legend<B: backend::Backend>(f: &mut Frame<B>, app_state: &mut app::App, cpu_data: &[(String, Vec<(f64, f64)>)], draw_loc: Rect) {
|
||||||
let mut itx = 0;
|
let num_rows = i64::from(draw_loc.height) - 4;
|
||||||
let label_map = cpu_data.iter().map(|cpu| {
|
let start_position = get_start_position(
|
||||||
itx += 1;
|
num_rows,
|
||||||
Text::styled(&cpu.0, Style::default().fg(COLOUR_LIST[(itx - 1) % COLOUR_LIST.len()]))
|
&(app_state.scroll_direction),
|
||||||
|
&mut app_state.previous_cpu_table_position,
|
||||||
|
&mut app_state.currently_selected_cpu_table_position,
|
||||||
|
);
|
||||||
|
|
||||||
|
let sliced_cpu_data = (&cpu_data[start_position as usize..]).to_vec();
|
||||||
|
let mut stringified_cpu_data: Vec<Vec<String>> = Vec::new();
|
||||||
|
|
||||||
|
for cpu in sliced_cpu_data {
|
||||||
|
if let Some(cpu_data) = cpu.1.last() {
|
||||||
|
stringified_cpu_data.push(vec![cpu.0.clone(), format!("{:.0}%", cpu_data.1.round())]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut cpu_row_counter = 0;
|
||||||
|
|
||||||
|
let cpu_rows = stringified_cpu_data.iter().enumerate().map(|(itx, cpu_string_row)| {
|
||||||
|
Row::StyledData(
|
||||||
|
cpu_string_row.iter(),
|
||||||
|
if cpu_row_counter == app_state.currently_selected_cpu_table_position - start_position {
|
||||||
|
cpu_row_counter = -1;
|
||||||
|
Style::default().fg(Color::Black).bg(Color::Cyan)
|
||||||
|
} else {
|
||||||
|
if cpu_row_counter >= 0 {
|
||||||
|
cpu_row_counter += 1;
|
||||||
|
}
|
||||||
|
Style::default().fg(COLOUR_LIST[itx % COLOUR_LIST.len()])
|
||||||
|
},
|
||||||
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
List::new(label_map)
|
Table::new(["CPU", "Use%"].iter(), cpu_rows)
|
||||||
.block(
|
.block(
|
||||||
Block::default()
|
Block::default()
|
||||||
.borders(Borders::ALL)
|
.borders(Borders::ALL)
|
||||||
@ -309,7 +340,8 @@ fn draw_cpu_legend<B: backend::Backend>(f: &mut Frame<B>, app_state: &app::App,
|
|||||||
_ => *CANVAS_BORDER_STYLE,
|
_ => *CANVAS_BORDER_STYLE,
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.start_corner(Corner::TopLeft)
|
.header_style(Style::default().fg(Color::LightBlue))
|
||||||
|
.widths(&[Constraint::Percentage(50), Constraint::Percentage(50)])
|
||||||
.render(f, draw_loc);
|
.render(f, draw_loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -446,17 +478,17 @@ fn draw_temp_table<B: backend::Backend>(f: &mut Frame<B>, app_state: &mut app::A
|
|||||||
);
|
);
|
||||||
|
|
||||||
let sliced_vec: Vec<Vec<String>> = (&temp_sensor_data[start_position as usize..]).to_vec();
|
let sliced_vec: Vec<Vec<String>> = (&temp_sensor_data[start_position as usize..]).to_vec();
|
||||||
let mut disk_counter = 0;
|
let mut temp_row_counter = 0;
|
||||||
|
|
||||||
let temperature_rows = sliced_vec.iter().map(|disk| {
|
let temperature_rows = sliced_vec.iter().map(|temp_row| {
|
||||||
Row::StyledData(
|
Row::StyledData(
|
||||||
disk.iter(),
|
temp_row.iter(),
|
||||||
if disk_counter == app_state.currently_selected_temperature_position - start_position {
|
if temp_row_counter == app_state.currently_selected_temperature_position - start_position {
|
||||||
disk_counter = -1;
|
temp_row_counter = -1;
|
||||||
Style::default().fg(Color::Black).bg(Color::Cyan)
|
Style::default().fg(Color::Black).bg(Color::Cyan)
|
||||||
} else {
|
} else {
|
||||||
if disk_counter >= 0 {
|
if temp_row_counter >= 0 {
|
||||||
disk_counter += 1;
|
temp_row_counter += 1;
|
||||||
}
|
}
|
||||||
Style::default().fg(TEXT_COLOUR)
|
Style::default().fg(TEXT_COLOUR)
|
||||||
},
|
},
|
||||||
|
@ -5,6 +5,15 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use constants::*;
|
use constants::*;
|
||||||
|
|
||||||
|
pub struct ConvertedNetworkData {
|
||||||
|
pub rx: Vec<(f64, f64)>,
|
||||||
|
pub tx: Vec<(f64, f64)>,
|
||||||
|
pub rx_display: String,
|
||||||
|
pub tx_display: String,
|
||||||
|
pub total_rx_display: String,
|
||||||
|
pub total_tx_display: String,
|
||||||
|
}
|
||||||
|
|
||||||
pub fn update_temp_row(app_data: &data_collection::Data, temp_type: &data_collection::temperature::TemperatureType) -> Vec<Vec<String>> {
|
pub fn update_temp_row(app_data: &data_collection::Data, temp_type: &data_collection::temperature::TemperatureType) -> Vec<Vec<String>> {
|
||||||
let mut sensor_vector: Vec<Vec<String>> = Vec::new();
|
let mut sensor_vector: Vec<Vec<String>> = Vec::new();
|
||||||
|
|
||||||
@ -103,6 +112,7 @@ pub fn update_process_row(app_data: &data_collection::Data) -> Vec<Vec<String>>
|
|||||||
process_vector
|
process_vector
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: You should really make this a struct...
|
||||||
pub fn update_cpu_data_points(show_avg_cpu: bool, app_data: &data_collection::Data) -> Vec<(String, Vec<(f64, f64)>)> {
|
pub fn update_cpu_data_points(show_avg_cpu: bool, app_data: &data_collection::Data) -> Vec<(String, Vec<(f64, f64)>)> {
|
||||||
let mut cpu_data_vector: Vec<(String, Vec<(f64, f64)>)> = Vec::new();
|
let mut cpu_data_vector: Vec<(String, Vec<(f64, f64)>)> = Vec::new();
|
||||||
let mut cpu_collection: Vec<Vec<(f64, f64)>> = Vec::new();
|
let mut cpu_collection: Vec<Vec<(f64, f64)>> = Vec::new();
|
||||||
@ -141,15 +151,28 @@ pub fn update_cpu_data_points(show_avg_cpu: bool, app_data: &data_collection::Da
|
|||||||
// Finally, add it all onto the end
|
// Finally, add it all onto the end
|
||||||
for (i, data) in cpu_collection.iter().enumerate() {
|
for (i, data) in cpu_collection.iter().enumerate() {
|
||||||
if !app_data.list_of_cpu_packages.is_empty() {
|
if !app_data.list_of_cpu_packages.is_empty() {
|
||||||
|
// Commented out: this version includes the percentage in the label...
|
||||||
|
// cpu_data_vector.push((
|
||||||
|
// // + 1 to skip total CPU if show_avg_cpu is false
|
||||||
|
// format!(
|
||||||
|
// "{:4}: ",
|
||||||
|
// &*(app_data.list_of_cpu_packages.last().unwrap().cpu_vec[i + if show_avg_cpu { 0 } else { 1 }].cpu_name)
|
||||||
|
// )
|
||||||
|
// .to_uppercase() + &format!("{:3}%", (data.last().unwrap_or(&(0_f64, 0_f64)).1.round() as u64)),
|
||||||
|
// data.clone(),
|
||||||
|
// ))
|
||||||
cpu_data_vector.push((
|
cpu_data_vector.push((
|
||||||
// + 1 to skip total CPU if show_avg_cpu is false
|
|
||||||
format!(
|
format!(
|
||||||
"{:4}: ",
|
"{} ",
|
||||||
&*(app_data.list_of_cpu_packages.last().unwrap().cpu_vec[i + if show_avg_cpu { 0 } else { 1 }].cpu_name)
|
if show_avg_cpu && i == 0 {
|
||||||
|
"AVG"
|
||||||
|
} else {
|
||||||
|
&*(app_data.list_of_cpu_packages.last().unwrap().cpu_vec[i + if show_avg_cpu { 0 } else { 1 }].cpu_name)
|
||||||
|
}
|
||||||
)
|
)
|
||||||
.to_uppercase() + &format!("{:3}%", (data.last().unwrap_or(&(0_f64, 0_f64)).1.round() as u64)),
|
.to_uppercase(),
|
||||||
data.clone(),
|
data.clone(),
|
||||||
))
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -217,15 +240,6 @@ fn convert_mem_data(mem_data: &[data_collection::mem::MemData]) -> Vec<(f64, f64
|
|||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ConvertedNetworkData {
|
|
||||||
pub rx: Vec<(f64, f64)>,
|
|
||||||
pub tx: Vec<(f64, f64)>,
|
|
||||||
pub rx_display: String,
|
|
||||||
pub tx_display: String,
|
|
||||||
pub total_rx_display: String,
|
|
||||||
pub total_tx_display: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn update_network_data_points(app_data: &data_collection::Data) -> ConvertedNetworkData {
|
pub fn update_network_data_points(app_data: &data_collection::Data) -> ConvertedNetworkData {
|
||||||
convert_network_data_points(&app_data.network)
|
convert_network_data_points(&app_data.network)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user