diff options
author | ClementTsang <cjhtsang@uwaterloo.ca> | 2020-03-07 23:47:53 -0500 |
---|---|---|
committer | ClementTsang <cjhtsang@uwaterloo.ca> | 2020-03-07 23:47:53 -0500 |
commit | 03ec52c5b16d8968e14e1a648bd2ef4b9489380e (patch) | |
tree | 2de0ee608bbf72255be03b3fab35f87ab14fd11a /src/canvas/widgets/cpu_basic.rs | |
parent | 132a5a2170294f0d5c463ecba77de1aab32183db (diff) |
Split up widgets to make it a bit easier to work with.
Diffstat (limited to 'src/canvas/widgets/cpu_basic.rs')
-rw-r--r-- | src/canvas/widgets/cpu_basic.rs | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/src/canvas/widgets/cpu_basic.rs b/src/canvas/widgets/cpu_basic.rs new file mode 100644 index 00000000..464d8423 --- /dev/null +++ b/src/canvas/widgets/cpu_basic.rs @@ -0,0 +1,129 @@ +use std::cmp::{max, min}; + +use crate::{ + app::{App, WidgetPosition}, + canvas::{drawing_utils::*, Painter}, + constants::*, + data_conversion::ConvertedCpuData, +}; + +use tui::{ + backend::Backend, + layout::{Constraint, Direction, Layout, Rect}, + terminal::Frame, + widgets::{Block, Paragraph, Text, Widget}, +}; + +pub trait CpuBasicWidget { + fn draw_basic_cpu<B: Backend>(&self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect); +} + +impl CpuBasicWidget for Painter { + fn draw_basic_cpu<B: Backend>( + &self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect, + ) { + let cpu_data: &[ConvertedCpuData] = &app_state.canvas_data.cpu_data; + + // This is a bit complicated, but basically, we want to draw SOME number + // of columns to draw all CPUs. Ideally, as well, we want to not have + // to ever scroll. + // **General logic** - count number of elements in cpu_data. Then see how + // many rows and columns we have in draw_loc (-2 on both sides for border?). + // I think what we can do is try to fit in as many in one column as possible. + // If not, then add a new column. + // Then, from this, split the row space across ALL columns. From there, generate + // the desired lengths. + + if let WidgetPosition::BasicCpu = app_state.current_widget_selected { + Block::default() + .borders(*SIDE_BORDERS) + .border_style(self.colours.highlighted_border_style) + .render(f, draw_loc); + } + + let num_cpus = cpu_data.len(); + if draw_loc.height > 0 { + let remaining_height = draw_loc.height as usize; + const REQUIRED_COLUMNS: usize = 4; + + let chunk_vec = + vec![Constraint::Percentage((100 / REQUIRED_COLUMNS) as u16); REQUIRED_COLUMNS]; + let chunks = Layout::default() + .constraints(chunk_vec.as_ref()) + .direction(Direction::Horizontal) + .split(draw_loc); + + // +9 due to 3 + 4 + 2 columns for the name & space + percentage + bar bounds + let margin_space = 2; + let remaining_width = max( + 0, + draw_loc.width as i64 + - ((9 + margin_space) * REQUIRED_COLUMNS - margin_space) as i64, + ) as usize; + + let bar_length = remaining_width / REQUIRED_COLUMNS; + + // CPU (and RAM) percent bars are, uh, "heavily" inspired from htop. + let cpu_bars = (0..num_cpus) + .map(|cpu_index| { + let use_percentage = + if let Some(cpu_usage) = cpu_data[cpu_index].cpu_data.last() { + cpu_usage.1 + } else { + 0.0 + }; + + let num_bars = calculate_basic_use_bars(use_percentage, bar_length); + format!( + "{:3}[{}{}{:3.0}%]\n", + if app_state.app_config_fields.show_average_cpu { + if cpu_index == 0 { + "AVG".to_string() + } else { + (cpu_index - 1).to_string() + } + } else { + cpu_index.to_string() + }, + "|".repeat(num_bars), + " ".repeat(bar_length - num_bars), + use_percentage.round(), + ) + }) + .collect::<Vec<_>>(); + + let mut row_counter = num_cpus; + let mut start_index = 0; + for (itx, chunk) in chunks.iter().enumerate() { + let to_divide = REQUIRED_COLUMNS - itx; + let how_many_cpus = min( + remaining_height, + (row_counter / to_divide) + (if row_counter % to_divide == 0 { 0 } else { 1 }), + ); + row_counter -= how_many_cpus; + let end_index = min(start_index + how_many_cpus, num_cpus); + let cpu_column: Vec<Text<'_>> = (start_index..end_index) + .map(|cpu_index| { + Text::Styled( + (&cpu_bars[cpu_index]).into(), + self.colours.cpu_colour_styles + [cpu_index as usize % self.colours.cpu_colour_styles.len()], + ) + }) + .collect::<Vec<_>>(); + + start_index += how_many_cpus; + + let margined_loc = Layout::default() + .direction(Direction::Horizontal) + .constraints([Constraint::Percentage(100)].as_ref()) + .horizontal_margin(1) + .split(*chunk); + + Paragraph::new(cpu_column.iter()) + .block(Block::default()) + .render(f, margined_loc[0]); + } + } + } +} |