diff options
author | Clement Tsang <34804052+ClementTsang@users.noreply.github.com> | 2022-10-13 10:17:26 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-10-13 10:17:26 -0400 |
commit | b6a75db1b48e19ca85c00e88554b5132b543f1c7 (patch) | |
tree | 1c3195b4ed5dc4aab20f6f99e8826d2e55247a79 /src/canvas/widgets/cpu_basic.rs | |
parent | 436dadb683cc82b8d2310a3a015c66bf08398432 (diff) |
refactor: switch to pipe gauge implementation for basic cpu + mem (#829)
* refactor: switch to pipe gauge implementation for basic cpu + mem
* fix incorrect new basic cpu chunking scheme, revert to old one
Diffstat (limited to 'src/canvas/widgets/cpu_basic.rs')
-rw-r--r-- | src/canvas/widgets/cpu_basic.rs | 197 |
1 files changed, 67 insertions, 130 deletions
diff --git a/src/canvas/widgets/cpu_basic.rs b/src/canvas/widgets/cpu_basic.rs index 4296b967..1ca75a90 100644 --- a/src/canvas/widgets/cpu_basic.rs +++ b/src/canvas/widgets/cpu_basic.rs @@ -1,8 +1,9 @@ use std::cmp::min; use crate::{ - app::App, - canvas::{drawing_utils::*, Painter}, + app::{data_harvester::cpu::CpuDataType, App}, + canvas::Painter, + components::tui_widget::pipe_gauge::{LabelLimit, PipeGauge}, constants::*, data_conversion::CpuWidgetData, }; @@ -11,11 +12,11 @@ use tui::{ backend::Backend, layout::{Constraint, Direction, Layout, Rect}, terminal::Frame, - text::{Span, Spans}, - widgets::{Block, Paragraph}, + widgets::Block, }; impl Painter { + /// Inspired by htop. pub fn draw_basic_cpu<B: Backend>( &self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect, widget_id: u64, ) { @@ -42,148 +43,84 @@ impl Painter { ); } - let num_cpus = cpu_data.len(); - let show_avg_cpu = app_state.app_config_fields.show_average_cpu; - if draw_loc.height > 0 { let remaining_height = usize::from(draw_loc.height); const REQUIRED_COLUMNS: usize = 4; - let chunk_vec = + let col_constraints = vec![Constraint::Percentage((100 / REQUIRED_COLUMNS) as u16); REQUIRED_COLUMNS]; - let chunks = Layout::default() - .constraints(chunk_vec) + let columns = Layout::default() + .constraints(col_constraints) .direction(Direction::Horizontal) .split(draw_loc); - const CPU_NAME_SPACE: usize = 3; - const BAR_BOUND_SPACE: usize = 2; - const PERCENTAGE_SPACE: usize = 4; - const MARGIN_SPACE: usize = 2; - - const COMBINED_SPACING: usize = - CPU_NAME_SPACE + BAR_BOUND_SPACE + PERCENTAGE_SPACE + MARGIN_SPACE; - const REDUCED_SPACING: usize = CPU_NAME_SPACE + PERCENTAGE_SPACE + MARGIN_SPACE; - let chunk_width: usize = chunks[0].width.into(); - - // Inspired by htop. - // We do +4 as if it's too few bars in the bar length, it's kinda pointless. - let cpu_bars = if chunk_width >= COMBINED_SPACING + 4 { - let bar_length = chunk_width - COMBINED_SPACING; - cpu_data - .iter() - .enumerate() - .filter_map(|(index, cpu)| match &cpu { - CpuWidgetData::All => None, - CpuWidgetData::Entry { - data_type: _, - data: _, - last_entry, - } => { - let num_bars = calculate_basic_use_bars(*last_entry, bar_length); - Some(format!( - "{:3}[{}{}{:3.0}%]", - if app_state.app_config_fields.show_average_cpu { - if index == 0 { - "AVG".to_string() - } else { - (index - 1).to_string() - } - } else { - index.to_string() - }, - "|".repeat(num_bars), - " ".repeat(bar_length - num_bars), - last_entry.round(), - )) - } - }) - .collect::<Vec<_>>() - } else if chunk_width >= REDUCED_SPACING { - cpu_data - .iter() - .enumerate() - .filter_map(|(index, cpu)| match &cpu { - CpuWidgetData::All => None, - CpuWidgetData::Entry { - data_type: _, - data: _, - last_entry, - } => Some(format!( - "{:3} {:3.0}%", - if app_state.app_config_fields.show_average_cpu { - if index == 0 { - "AVG".to_string() - } else { - (index - 1).to_string() - } - } else { - index.to_string() - }, - last_entry.round(), - )), - }) - .collect::<Vec<_>>() - } else { - cpu_data - .iter() - .filter_map(|cpu| match &cpu { - CpuWidgetData::All => None, - CpuWidgetData::Entry { - data_type: _, - data: _, - last_entry, - } => Some(format!("{:3.0}%", last_entry.round())), - }) - .collect::<Vec<_>>() - }; - - let mut row_counter = num_cpus; - let mut start_index = 0; - for (itx, chunk) in chunks.iter().enumerate() { - // Explicitly check... don't want an accidental DBZ or underflow, this ensures - // to_divide is > 0 + let mut gauge_info = cpu_data.iter().map(|cpu| match cpu { + CpuWidgetData::All => unreachable!(), + CpuWidgetData::Entry { + data_type, + data: _, + last_entry, + } => { + let (outer, style) = match data_type { + CpuDataType::Avg => ("AVG".to_string(), self.colours.avg_colour_style), + CpuDataType::Cpu(index) => ( + format!("{index:<3}",), + self.colours.cpu_colour_styles + [index % self.colours.cpu_colour_styles.len()], + ), + }; + let inner = format!("{:>3.0}%", last_entry.round()); + let ratio = last_entry / 100.0; + + (outer, inner, ratio, style) + } + }); + + // Very ugly way to sync the gauge limit across all gauges. + let hide_parts = columns + .get(0) + .map(|col| { + if col.width >= 12 { + LabelLimit::None + } else if col.width >= 10 { + LabelLimit::Bars + } else { + LabelLimit::StartLabel + } + }) + .unwrap_or_default(); + + let num_entries = cpu_data.len(); + let mut row_counter = num_entries; + for (itx, column) in columns.into_iter().enumerate() { if REQUIRED_COLUMNS > itx { let to_divide = REQUIRED_COLUMNS - itx; - let how_many_cpus = min( + let num_taken = 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); + row_counter -= num_taken; + let chunk = (&mut gauge_info).take(num_taken); - let cpu_column = (start_index..end_index) - .map(|itx| { - Spans::from(Span { - content: (&cpu_bars[itx]).into(), - style: if show_avg_cpu { - if itx == 0 { - self.colours.avg_colour_style - } else { - self.colours.cpu_colour_styles - [(itx - 1) % self.colours.cpu_colour_styles.len()] - } - } else { - self.colours.cpu_colour_styles - [itx % 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)]) + let rows = Layout::default() + .direction(Direction::Vertical) + .constraints(vec![Constraint::Length(1); remaining_height]) .horizontal_margin(1) - .split(*chunk)[0]; - - f.render_widget( - Paragraph::new(cpu_column).block(Block::default()), - margined_loc, - ); + .split(column); + + for ((start_label, inner_label, ratio, style), row) in chunk.zip(rows) { + f.render_widget( + PipeGauge::default() + .gauge_style(style) + .label_style(style) + .inner_label(inner_label) + .start_label(start_label) + .ratio(ratio) + .hide_parts(hide_parts), + row, + ); + } } } } |