summaryrefslogtreecommitdiffstats
path: root/src/canvas/widgets/cpu_graph.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/canvas/widgets/cpu_graph.rs')
-rw-r--r--src/canvas/widgets/cpu_graph.rs464
1 files changed, 256 insertions, 208 deletions
diff --git a/src/canvas/widgets/cpu_graph.rs b/src/canvas/widgets/cpu_graph.rs
index 19abd62c..6fa0535a 100644
--- a/src/canvas/widgets/cpu_graph.rs
+++ b/src/canvas/widgets/cpu_graph.rs
@@ -3,7 +3,7 @@ use std::borrow::Cow;
use std::cmp::max;
use crate::{
- app::{App, WidgetPosition},
+ app::App,
canvas::{
drawing_utils::{get_start_position, get_variable_intrinsic_widths},
Painter,
@@ -14,7 +14,7 @@ use crate::{
use tui::{
backend::Backend,
- layout::{Constraint, Rect},
+ layout::{Constraint, Direction, Layout, Rect},
terminal::Frame,
widgets::{Axis, Block, Borders, Chart, Dataset, Marker, Row, Table, Widget},
};
@@ -33,259 +33,307 @@ lazy_static! {
}
pub trait CpuGraphWidget {
- fn draw_cpu_graph<B: Backend>(&self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect);
+ fn draw_cpu<B: Backend>(
+ &self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect, widget_id: u64,
+ );
+ fn draw_cpu_graph<B: Backend>(
+ &self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect, widget_id: u64,
+ );
fn draw_cpu_legend<B: Backend>(
- &self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect,
+ &self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect, widget_id: u64,
);
}
impl CpuGraphWidget for Painter {
+ fn draw_cpu<B: Backend>(
+ &self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect, widget_id: u64,
+ ) {
+ if draw_loc.width as f64 * 0.15 <= 6.0 {
+ // Skip drawing legend
+ if app_state.current_widget.widget_id == (widget_id + 1) {
+ if app_state.app_config_fields.left_legend {
+ app_state.move_widget_selection_right();
+ } else {
+ app_state.move_widget_selection_left();
+ }
+ }
+ self.draw_cpu_graph(f, app_state, draw_loc, widget_id);
+ if let Some(cpu_widget_state) = app_state.cpu_state.widget_states.get_mut(&widget_id) {
+ cpu_widget_state.is_legend_hidden = true;
+ }
+ } else {
+ let (graph_index, legend_index, constraints) =
+ if app_state.app_config_fields.left_legend {
+ (
+ 1,
+ 0,
+ [Constraint::Percentage(15), Constraint::Percentage(85)],
+ )
+ } else {
+ (
+ 0,
+ 1,
+ [Constraint::Percentage(85), Constraint::Percentage(15)],
+ )
+ };
+
+ let partitioned_draw_loc = Layout::default()
+ .margin(0)
+ .direction(Direction::Horizontal)
+ .constraints(constraints.as_ref())
+ .split(draw_loc);
+
+ self.draw_cpu_graph(f, app_state, partitioned_draw_loc[graph_index], widget_id);
+ self.draw_cpu_legend(
+ f,
+ app_state,
+ partitioned_draw_loc[legend_index],
+ widget_id + 1,
+ );
+ }
+ }
+
fn draw_cpu_graph<B: Backend>(
- &self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect,
+ &self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect, widget_id: u64,
) {
- let cpu_data: &[ConvertedCpuData] = &app_state.canvas_data.cpu_data;
+ if let Some(cpu_widget_state) = app_state.cpu_state.widget_states.get_mut(&widget_id) {
+ let cpu_data: &mut [ConvertedCpuData] = &mut app_state.canvas_data.cpu_data;
- let display_time_labels = [
- format!("{}s", app_state.cpu_state.current_display_time / 1000),
- "0s".to_string(),
- ];
+ let display_time_labels = [
+ format!("{}s", cpu_widget_state.current_display_time / 1000),
+ "0s".to_string(),
+ ];
- let x_axis = if app_state.app_config_fields.hide_time
- || (app_state.app_config_fields.autohide_time
- && app_state.cpu_state.autohide_timer.is_none())
- {
- Axis::default().bounds([0.0, app_state.cpu_state.current_display_time as f64])
- } else if let Some(time) = app_state.cpu_state.autohide_timer {
- if std::time::Instant::now().duration_since(time).as_millis()
- < AUTOHIDE_TIMEOUT_MILLISECONDS as u128
+ let x_axis = if app_state.app_config_fields.hide_time
+ || (app_state.app_config_fields.autohide_time
+ && cpu_widget_state.autohide_timer.is_none())
{
+ Axis::default().bounds([-(cpu_widget_state.current_display_time as f64), 0.0])
+ } else if let Some(time) = cpu_widget_state.autohide_timer {
+ if std::time::Instant::now().duration_since(time).as_millis()
+ < AUTOHIDE_TIMEOUT_MILLISECONDS as u128
+ {
+ Axis::default()
+ .bounds([-(cpu_widget_state.current_display_time as f64), 0.0])
+ .style(self.colours.graph_style)
+ .labels_style(self.colours.graph_style)
+ .labels(&display_time_labels)
+ } else {
+ cpu_widget_state.autohide_timer = None;
+ Axis::default().bounds([-(cpu_widget_state.current_display_time as f64), 0.0])
+ }
+ } else {
Axis::default()
- .bounds([0.0, app_state.cpu_state.current_display_time as f64])
+ .bounds([-(cpu_widget_state.current_display_time as f64), 0.0])
.style(self.colours.graph_style)
.labels_style(self.colours.graph_style)
.labels(&display_time_labels)
- } else {
- app_state.cpu_state.autohide_timer = None;
- Axis::default().bounds([0.0, app_state.cpu_state.current_display_time as f64])
- }
- } else {
- Axis::default()
- .bounds([0.0, app_state.cpu_state.current_display_time as f64])
+ };
+
+ // Note this is offset as otherwise the 0 value is not drawn!
+ let y_axis = Axis::default()
.style(self.colours.graph_style)
.labels_style(self.colours.graph_style)
- .labels(&display_time_labels)
- };
-
- // Note this is offset as otherwise the 0 value is not drawn!
- let y_axis = Axis::default()
- .style(self.colours.graph_style)
- .labels_style(self.colours.graph_style)
- .bounds([-0.5, 100.5])
- .labels(&["0%", "100%"]);
+ .bounds([-0.5, 100.5])
+ .labels(&["0%", "100%"]);
- let dataset_vector: Vec<Dataset<'_>> = cpu_data
- .iter()
- .enumerate()
- .rev()
- .filter_map(|(itx, cpu)| {
- if app_state.cpu_state.core_show_vec[itx] {
- Some(
- Dataset::default()
- .marker(if app_state.app_config_fields.use_dot {
- Marker::Dot
- } else {
- Marker::Braille
- })
- .style(
- if app_state.app_config_fields.show_average_cpu && itx == 0 {
+ let use_dot = app_state.app_config_fields.use_dot;
+ let show_avg_cpu = app_state.app_config_fields.show_average_cpu;
+ let dataset_vector: Vec<Dataset<'_>> = cpu_data
+ .iter()
+ .enumerate()
+ .rev()
+ .filter_map(|(itx, cpu)| {
+ if cpu_widget_state.core_show_vec[itx] {
+ Some(
+ Dataset::default()
+ .marker(if use_dot {
+ Marker::Dot
+ } else {
+ Marker::Braille
+ })
+ .style(if show_avg_cpu && itx == 0 {
self.colours.avg_colour_style
} else {
self.colours.cpu_colour_styles
[itx % self.colours.cpu_colour_styles.len()]
- },
- )
- .data(&cpu.cpu_data[..]),
- )
- } else {
- None
- }
- })
- .collect();
+ })
+ .data(&cpu.cpu_data[..]),
+ )
+ } else {
+ None
+ }
+ })
+ .collect();
- let title = if app_state.is_expanded && !app_state.cpu_state.is_showing_tray {
- const TITLE_BASE: &str = " CPU ── Esc to go back ";
- let repeat_num = max(
- 0,
- draw_loc.width as i32 - TITLE_BASE.chars().count() as i32 - 2,
- );
- let result_title =
- format!(" CPU ─{}─ Esc to go back ", "─".repeat(repeat_num as usize));
+ let title = if app_state.is_expanded && !cpu_widget_state.is_showing_tray {
+ const TITLE_BASE: &str = " CPU ── Esc to go back ";
+ let repeat_num = max(
+ 0,
+ draw_loc.width as i32 - TITLE_BASE.chars().count() as i32 - 2,
+ );
+ let result_title =
+ format!(" CPU ─{}─ Esc to go back ", "─".repeat(repeat_num as usize));
- result_title
- } else {
- " CPU ".to_string()
- };
+ result_title
+ } else {
+ " CPU ".to_string()
+ };
- let border_style = match app_state.current_widget_selected {
- WidgetPosition::Cpu => self.colours.highlighted_border_style,
- _ => self.colours.border_style,
- };
+ let border_style = if app_state.current_widget.widget_id == widget_id {
+ self.colours.highlighted_border_style
+ } else {
+ self.colours.border_style
+ };
- Chart::default()
- .block(
- Block::default()
- .title(&title)
- .title_style(if app_state.is_expanded {
- border_style
- } else {
- self.colours.widget_title_style
- })
- .borders(Borders::ALL)
- .border_style(border_style),
- )
- .x_axis(x_axis)
- .y_axis(y_axis)
- .datasets(&dataset_vector)
- .render(f, draw_loc);
+ Chart::default()
+ .block(
+ Block::default()
+ .title(&title)
+ .title_style(if app_state.is_expanded {
+ border_style
+ } else {
+ self.colours.widget_title_style
+ })
+ .borders(Borders::ALL)
+ .border_style(border_style),
+ )
+ .x_axis(x_axis)
+ .y_axis(y_axis)
+ .datasets(&dataset_vector)
+ .render(f, draw_loc);
+ }
}
fn draw_cpu_legend<B: Backend>(
- &self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect,
+ &self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect, widget_id: u64,
) {
- let cpu_data: &[ConvertedCpuData] = &app_state.canvas_data.cpu_data;
+ if let Some(cpu_widget_state) = app_state.cpu_state.widget_states.get_mut(&(widget_id - 1))
+ {
+ cpu_widget_state.is_legend_hidden = false;
+ let cpu_data: &mut [ConvertedCpuData] = &mut app_state.canvas_data.cpu_data;
- let num_rows = max(0, i64::from(draw_loc.height) - 5) as u64;
- let start_position = get_start_position(
- num_rows,
- &app_state.app_scroll_positions.scroll_direction,
- &mut app_state
- .app_scroll_positions
- .cpu_scroll_state
- .previous_scroll_position,
- app_state
- .app_scroll_positions
- .cpu_scroll_state
- .current_scroll_position,
- app_state.is_resized,
- );
+ let num_rows = max(0, i64::from(draw_loc.height) - 5) as u64;
+ let start_position = get_start_position(
+ num_rows,
+ &cpu_widget_state.scroll_state.scroll_direction,
+ &mut cpu_widget_state.scroll_state.previous_scroll_position,
+ cpu_widget_state.scroll_state.current_scroll_position,
+ app_state.is_resized,
+ );
- let sliced_cpu_data = &cpu_data[start_position as usize..];
+ let sliced_cpu_data = &cpu_data[start_position as usize..];
- let mut offset_scroll_index = (app_state
- .app_scroll_positions
- .cpu_scroll_state
- .current_scroll_position
- - start_position) as usize;
- let cpu_rows = sliced_cpu_data.iter().enumerate().filter_map(|(itx, cpu)| {
- let cpu_string_row: Vec<Cow<'_, str>> = if app_state.cpu_state.is_showing_tray {
- vec![
- Cow::Borrowed(&cpu.cpu_name),
- if app_state.cpu_state.core_show_vec[itx + start_position as usize] {
- "[*]".into()
- } else {
- "[ ]".into()
- },
- ]
- } else if app_state.app_config_fields.show_disabled_data
- || app_state.cpu_state.core_show_vec[itx]
- {
- vec![
- Cow::Borrowed(&cpu.cpu_name),
- Cow::Borrowed(&cpu.legend_value),
- ]
- } else {
- Vec::new()
- };
+ let mut offset_scroll_index =
+ (cpu_widget_state.scroll_state.current_scroll_position - start_position) as usize;
+ let show_disabled_data = app_state.app_config_fields.show_disabled_data;
+ let current_widget_id = app_state.current_widget.widget_id;
+ let show_avg_cpu = app_state.app_config_fields.show_average_cpu;
- if cpu_string_row.is_empty() {
- offset_scroll_index += 1;
- None
- } else {
- Some(Row::StyledData(
- cpu_string_row.into_iter(),
- match app_state.current_widget_selected {
- WidgetPosition::CpuLegend => {
+ let cpu_rows = sliced_cpu_data.iter().enumerate().filter_map(|(itx, cpu)| {
+ let cpu_string_row: Vec<Cow<'_, str>> = if cpu_widget_state.is_showing_tray {
+ vec![
+ Cow::Borrowed(&cpu.cpu_name),
+ if cpu_widget_state.core_show_vec[itx + start_position as usize] {
+ "[*]".into()
+ } else {
+ "[ ]".into()
+ },
+ ]
+ } else if show_disabled_data || cpu_widget_state.core_show_vec[itx] {
+ vec![
+ Cow::Borrowed(&cpu.cpu_name),
+ Cow::Borrowed(&cpu.legend_value),
+ ]
+ } else {
+ Vec::new()
+ };
+
+ if cpu_string_row.is_empty() {
+ offset_scroll_index += 1;
+ None
+ } else {
+ Some(Row::StyledData(
+ cpu_string_row.into_iter(),
+ if current_widget_id == widget_id {
if itx == offset_scroll_index {
self.colours.currently_selected_text_style
- } else if app_state.app_config_fields.show_average_cpu && itx == 0 {
+ } else if show_avg_cpu && itx == 0 {
self.colours.avg_colour_style
} else {
self.colours.cpu_colour_styles[itx
+ start_position as usize
% self.colours.cpu_colour_styles.len()]
}
- }
- _ => {
- if app_state.app_config_fields.show_average_cpu && itx == 0 {
- self.colours.avg_colour_style
- } else {
- self.colours.cpu_colour_styles[itx
- + start_position as usize
- % self.colours.cpu_colour_styles.len()]
- }
- }
- },
- ))
- }
- });
-
- // Calculate widths
- let width = f64::from(draw_loc.width);
- let width_ratios = vec![0.5, 0.5];
+ } else if show_avg_cpu && itx == 0 {
+ self.colours.avg_colour_style
+ } else {
+ self.colours.cpu_colour_styles[itx
+ + start_position as usize % self.colours.cpu_colour_styles.len()]
+ },
+ ))
+ }
+ });
- let variable_intrinsic_results = get_variable_intrinsic_widths(
- width as u16,
- &width_ratios,
- if app_state.cpu_state.is_showing_tray {
- &CPU_SELECT_LEGEND_HEADER_LENS
- } else {
- &CPU_LEGEND_HEADER_LENS
- },
- );
- let intrinsic_widths = &(variable_intrinsic_results.0)[0..variable_intrinsic_results.1];
+ // Calculate widths
+ let width = f64::from(draw_loc.width);
+ let width_ratios = vec![0.5, 0.5];
- let title = if app_state.cpu_state.is_showing_tray {
- const TITLE_BASE: &str = " Esc to close ";
- let repeat_num = max(
- 0,
- draw_loc.width as i32 - TITLE_BASE.chars().count() as i32 - 2,
+ let variable_intrinsic_results = get_variable_intrinsic_widths(
+ width as u16,
+ &width_ratios,
+ if cpu_widget_state.is_showing_tray {
+ &CPU_SELECT_LEGEND_HEADER_LENS
+ } else {
+ &CPU_LEGEND_HEADER_LENS
+ },
);
- let result_title = format!("{} Esc to close ", "─".repeat(repeat_num as usize));
+ let intrinsic_widths = &(variable_intrinsic_results.0)[0..variable_intrinsic_results.1];
- result_title
- } else {
- "".to_string()
- };
+ let title = if cpu_widget_state.is_showing_tray {
+ const TITLE_BASE: &str = " Esc to close ";
+ let repeat_num = max(
+ 0,
+ draw_loc.width as i32 - TITLE_BASE.chars().count() as i32 - 2,
+ );
+ let result_title = format!("{} Esc to close ", "─".repeat(repeat_num as usize));
- let title_and_border_style = match app_state.current_widget_selected {
- WidgetPosition::CpuLegend => self.colours.highlighted_border_style,
- _ => self.colours.border_style,
- };
+ result_title
+ } else {
+ "".to_string()
+ };
- // Draw
- Table::new(
- if app_state.cpu_state.is_showing_tray {
- CPU_SELECT_LEGEND_HEADER
+ let title_and_border_style = if app_state.current_widget.widget_id == widget_id {
+ self.colours.highlighted_border_style
} else {
- CPU_LEGEND_HEADER
- }
- .iter(),
- cpu_rows,
- )
- .block(
- Block::default()
- .title(&title)
- .title_style(title_and_border_style)
- .borders(Borders::ALL)
- .border_style(title_and_border_style),
- )
- .header_style(self.colours.table_header_style)
- .widths(
- &(intrinsic_widths
- .iter()
- .map(|calculated_width| Constraint::Length(*calculated_width as u16))
- .collect::<Vec<_>>()),
- )
- .render(f, draw_loc);
+ self.colours.border_style
+ };
+
+ // Draw
+ Table::new(
+ if cpu_widget_state.is_showing_tray {
+ CPU_SELECT_LEGEND_HEADER
+ } else {
+ CPU_LEGEND_HEADER
+ }
+ .iter(),
+ cpu_rows,
+ )
+ .block(
+ Block::default()
+ .title(&title)
+ .title_style(title_and_border_style)
+ .borders(Borders::ALL)
+ .border_style(title_and_border_style),
+ )
+ .header_style(self.colours.table_header_style)
+ .widths(
+ &(intrinsic_widths
+ .iter()
+ .map(|calculated_width| Constraint::Length(*calculated_width as u16))
+ .collect::<Vec<_>>()),
+ )
+ .render(f, draw_loc);
+ }
}
}