Move to stateful except for CPU

This commit is contained in:
ClementTsang 2020-04-19 23:39:24 -04:00
parent 83dad154b9
commit 0574678746
8 changed files with 100 additions and 137 deletions

View file

@ -3,6 +3,8 @@ use std::{cmp::max, collections::HashMap, time::Instant};
use unicode_segmentation::GraphemeCursor;
use unicode_width::{UnicodeWidthChar, UnicodeWidthStr};
use tui::widgets::TableState;
use typed_builder::*;
use data_farmer::*;
@ -47,6 +49,7 @@ pub struct AppScrollWidgetState {
pub current_scroll_position: u64,
pub previous_scroll_position: u64,
pub scroll_direction: ScrollDirection,
pub table_state: TableState,
}
#[derive(Default)]
@ -91,7 +94,7 @@ pub struct AppConfigFields {
pub hide_time: bool,
pub autohide_time: bool,
pub use_old_network_legend: bool,
pub table_gap: u16
pub table_gap: u16,
}
/// AppSearchState deals with generic searching (I might do this in the future).

View file

@ -69,10 +69,11 @@ pub struct Painter {
layout_constraints: Vec<Vec<Vec<Vec<Constraint>>>>,
widget_layout: BottomLayout,
derived_widget_draw_locs: Vec<Vec<Vec<Vec<Rect>>>>,
table_height_offset: i64,
}
impl Painter {
pub fn init(widget_layout: BottomLayout) -> Self {
pub fn init(widget_layout: BottomLayout, table_gap: u16) -> Self {
// Now for modularity; we have to also initialize the base layouts!
// We want to do this ONCE and reuse; after this we can just construct
// based on the console size.
@ -154,6 +155,7 @@ impl Painter {
layout_constraints,
widget_layout,
derived_widget_draw_locs: Vec::new(),
table_height_offset: 4 + table_gap as i64,
}
}

View file

@ -217,7 +217,7 @@ impl CpuGraphWidget for Painter {
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 num_rows = max(0, i64::from(draw_loc.height) - self.table_height_offset) as u64;
let start_position = get_start_position(
num_rows,
&cpu_widget_state.scroll_state.scroll_direction,
@ -225,13 +225,13 @@ impl CpuGraphWidget for Painter {
cpu_widget_state.scroll_state.current_scroll_position,
app_state.is_resized,
);
let is_on_widget = widget_id == app_state.current_widget.widget_id;
let sliced_cpu_data = &cpu_data[start_position as usize..];
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;
let cpu_rows = sliced_cpu_data.iter().enumerate().filter_map(|(itx, cpu)| {
@ -267,7 +267,7 @@ impl CpuGraphWidget for Painter {
} else {
Some(Row::StyledData(
cpu_string_row.into_iter(),
if current_widget_id == widget_id {
if is_on_widget {
if itx == offset_scroll_index {
self.colours.currently_selected_text_style
} else if show_avg_cpu && itx == 0 {
@ -315,10 +315,13 @@ impl CpuGraphWidget for Painter {
"".to_string()
};
let title_and_border_style = if app_state.current_widget.widget_id == widget_id {
self.colours.highlighted_border_style
let (border_and_title_style, highlight_style) = if is_on_widget {
(
self.colours.highlighted_border_style,
self.colours.currently_selected_text_style,
)
} else {
self.colours.border_style
(self.colours.border_style, self.colours.text_style)
};
// Draw
@ -335,11 +338,12 @@ impl CpuGraphWidget for Painter {
.block(
Block::default()
.title(&title)
.title_style(title_and_border_style)
.title_style(border_and_title_style)
.borders(Borders::ALL)
.border_style(title_and_border_style),
.border_style(border_and_title_style),
)
.header_style(self.colours.table_header_style)
.highlight_style(highlight_style)
.widths(
&(intrinsic_widths
.iter()

View file

@ -39,7 +39,7 @@ impl DiskTableWidget for Painter {
) {
if let Some(disk_widget_state) = app_state.disk_state.widget_states.get_mut(&widget_id) {
let disk_data: &mut [Vec<String>] = &mut app_state.canvas_data.disk_data;
let num_rows = max(0, i64::from(draw_loc.height) - 5) as u64;
let num_rows = max(0, i64::from(draw_loc.height) - self.table_height_offset) as u64;
let start_position = get_start_position(
num_rows,
&disk_widget_state.scroll_state.scroll_direction,
@ -47,34 +47,14 @@ impl DiskTableWidget for Painter {
disk_widget_state.scroll_state.current_scroll_position,
app_state.is_resized,
);
let is_on_widget = app_state.current_widget.widget_id == widget_id;
let disk_table_state = &mut disk_widget_state.scroll_state.table_state;
disk_table_state.select(Some(
(disk_widget_state.scroll_state.current_scroll_position - start_position) as usize,
));
let sliced_vec = &mut disk_data[start_position as usize..];
let mut disk_counter: i64 = 0;
let current_widget_id = app_state.current_widget.widget_id;
let disk_rows = sliced_vec.iter().map(|disk| {
Row::StyledData(
disk.iter(),
if current_widget_id == widget_id
&& disk_widget_state.scroll_state.current_scroll_position >= start_position
{
if disk_counter as u64
== disk_widget_state.scroll_state.current_scroll_position
- start_position
{
disk_counter = -1;
self.colours.currently_selected_text_style
} else {
if disk_counter >= 0 {
disk_counter += 1;
}
self.colours.text_style
}
} else {
self.colours.text_style
},
)
});
let disk_rows = sliced_vec.iter().map(|disk| Row::Data(disk.iter()));
// Calculate widths
// TODO: [PRETTY] Ellipsis on strings?
@ -101,10 +81,13 @@ impl DiskTableWidget for Painter {
" Disk ".to_string()
};
let border_and_title_style = if app_state.current_widget.widget_id == widget_id {
self.colours.highlighted_border_style
let (border_and_title_style, highlight_style) = if is_on_widget {
(
self.colours.highlighted_border_style,
self.colours.currently_selected_text_style,
)
} else {
self.colours.border_style
(self.colours.border_style, self.colours.text_style)
};
let disk_block = if draw_border {
@ -117,7 +100,7 @@ impl DiskTableWidget for Painter {
})
.borders(Borders::ALL)
.border_style(border_and_title_style)
} else if app_state.current_widget.widget_id == widget_id {
} else if is_on_widget {
Block::default()
.borders(*SIDE_BORDERS)
.border_style(self.colours.highlighted_border_style)
@ -127,21 +110,17 @@ impl DiskTableWidget for Painter {
let margined_draw_loc = Layout::default()
.constraints([Constraint::Percentage(100)].as_ref())
.horizontal_margin(
if app_state.current_widget.widget_id == widget_id || draw_border {
0
} else {
1
},
)
.horizontal_margin(if is_on_widget || draw_border { 0 } else { 1 })
.direction(Direction::Horizontal)
.split(draw_loc);
// Draw!
f.render_widget(
f.render_stateful_widget(
Table::new(DISK_HEADERS.iter(), disk_rows)
.block(disk_block)
.header_style(self.colours.table_header_style)
.highlight_style(highlight_style)
.style(self.colours.text_style)
.widths(
&(intrinsic_widths
.iter()
@ -150,6 +129,7 @@ impl DiskTableWidget for Painter {
)
.header_gap(app_state.app_config_fields.table_gap),
margined_draw_loc[0],
disk_table_state,
);
}
}

View file

@ -83,7 +83,7 @@ impl ProcessTableWidget for Painter {
// 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 = max(0, i64::from(draw_loc.height) - 5) as u64;
let num_rows = max(0, i64::from(draw_loc.height) - self.table_height_offset) as u64;
let is_on_widget = widget_id == app_state.current_widget.widget_id;
let position = get_start_position(
@ -102,43 +102,32 @@ impl ProcessTableWidget for Painter {
};
let sliced_vec = &process_data[start_position as usize..];
let mut process_counter: i64 = 0;
let proc_table_state = &mut proc_widget_state.scroll_state.table_state;
proc_table_state.select(Some(
(proc_widget_state.scroll_state.current_scroll_position - start_position)
as usize,
));
// Draw!
let is_proc_widget_grouped = proc_widget_state.is_grouped;
let process_rows = sliced_vec.iter().map(|process| {
let stringified_process_vec: Vec<String> = vec![
if proc_widget_state.is_grouped {
process.group_pids.len().to_string()
} else {
process.pid.to_string()
},
process.name.clone(),
format!("{:.1}%", process.cpu_usage),
format!("{:.1}%", process.mem_usage),
process.read_per_sec.to_string(),
process.write_per_sec.to_string(),
process.total_read.to_string(),
process.total_write.to_string(),
process.process_states.to_string(),
];
Row::StyledData(
stringified_process_vec.into_iter(),
if is_on_widget {
if process_counter as u64
== proc_widget_state.scroll_state.current_scroll_position
- start_position
{
process_counter = -1;
self.colours.currently_selected_text_style
Row::Data(
vec![
if is_proc_widget_grouped {
process.group_pids.len().to_string()
} else {
if process_counter >= 0 {
process_counter += 1;
}
self.colours.text_style
}
} else {
self.colours.text_style
},
process.pid.to_string()
},
process.name.clone(),
format!("{:.1}%", process.cpu_usage),
format!("{:.1}%", process.mem_usage),
process.read_per_sec.to_string(),
process.write_per_sec.to_string(),
process.total_read.to_string(),
process.total_write.to_string(),
process.process_states.to_string(),
]
.into_iter(),
)
});
@ -223,10 +212,13 @@ impl ProcessTableWidget for Painter {
String::default()
};
let border_and_title_style = if is_on_widget {
self.colours.highlighted_border_style
let (border_and_title_style, highlight_style) = if is_on_widget {
(
self.colours.highlighted_border_style,
self.colours.currently_selected_text_style,
)
} else {
self.colours.border_style
(self.colours.border_style, self.colours.text_style)
};
let process_block = if draw_border {
@ -253,10 +245,12 @@ impl ProcessTableWidget for Painter {
.direction(Direction::Horizontal)
.split(draw_loc);
f.render_widget(
f.render_stateful_widget(
Table::new(process_headers.iter(), process_rows)
.block(process_block)
.header_style(self.colours.table_header_style)
.highlight_style(highlight_style)
.style(self.colours.text_style)
.widths(
&(intrinsic_widths
.iter()
@ -267,6 +261,7 @@ impl ProcessTableWidget for Painter {
)
.header_gap(app_state.app_config_fields.table_gap),
margined_draw_loc[0],
proc_table_state,
);
}
}

View file

@ -40,7 +40,7 @@ impl TempTableWidget for Painter {
if let Some(temp_widget_state) = app_state.temp_state.widget_states.get_mut(&widget_id) {
let temp_sensor_data: &mut [Vec<String>] = &mut app_state.canvas_data.temp_sensor_data;
let num_rows = max(0, i64::from(draw_loc.height) - 5) as u64;
let num_rows = max(0, i64::from(draw_loc.height) - self.table_height_offset) as u64;
let start_position = get_start_position(
num_rows,
&temp_widget_state.scroll_state.scroll_direction,
@ -48,32 +48,14 @@ impl TempTableWidget for Painter {
temp_widget_state.scroll_state.current_scroll_position,
app_state.is_resized,
);
let is_on_widget = widget_id == app_state.current_widget.widget_id;
let temp_table_state = &mut temp_widget_state.scroll_state.table_state;
temp_table_state.select(Some(
(temp_widget_state.scroll_state.current_scroll_position - start_position) as usize,
));
let sliced_vec = &temp_sensor_data[start_position as usize..];
let mut temp_row_counter: i64 = 0;
let current_widget_id = app_state.current_widget.widget_id;
let temperature_rows = sliced_vec.iter().map(|temp_row| {
Row::StyledData(
temp_row.iter(),
if current_widget_id == widget_id {
if temp_row_counter as u64
== temp_widget_state.scroll_state.current_scroll_position
- start_position
{
temp_row_counter = -1;
self.colours.currently_selected_text_style
} else {
if temp_row_counter >= 0 {
temp_row_counter += 1;
}
self.colours.text_style
}
} else {
self.colours.text_style
},
)
});
let temperature_rows = sliced_vec.iter().map(|temp_row| Row::Data(temp_row.iter()));
// Calculate widths
let width = f64::from(draw_loc.width);
@ -100,25 +82,22 @@ impl TempTableWidget for Painter {
" Temperatures ".to_string()
};
let (border_and_title_style, highlight_style) = if is_on_widget {
(
self.colours.highlighted_border_style,
self.colours.currently_selected_text_style,
)
} else {
(self.colours.border_style, self.colours.text_style)
};
let temp_block = if draw_border {
Block::default()
.title(&title)
.title_style(if app_state.is_expanded {
if app_state.current_widget.widget_id == widget_id {
self.colours.highlighted_border_style
} else {
self.colours.border_style
}
} else {
self.colours.widget_title_style
})
.title_style(border_and_title_style)
.borders(Borders::ALL)
.border_style(if app_state.current_widget.widget_id == widget_id {
self.colours.highlighted_border_style
} else {
self.colours.border_style
})
} else if app_state.current_widget.widget_id == widget_id {
.border_style(border_and_title_style)
} else if is_on_widget {
Block::default()
.borders(*SIDE_BORDERS)
.border_style(self.colours.highlighted_border_style)
@ -128,21 +107,17 @@ impl TempTableWidget for Painter {
let margined_draw_loc = Layout::default()
.constraints([Constraint::Percentage(100)].as_ref())
.horizontal_margin(
if app_state.current_widget.widget_id == widget_id || draw_border {
0
} else {
1
},
)
.horizontal_margin(if is_on_widget || draw_border { 0 } else { 1 })
.direction(Direction::Horizontal)
.split(draw_loc);
// Draw
f.render_widget(
f.render_stateful_widget(
Table::new(TEMP_HEADERS.iter(), temperature_rows)
.block(temp_block)
.header_style(self.colours.table_header_style)
.highlight_style(highlight_style)
.style(self.colours.text_style)
.widths(
&(intrinsic_widths
.iter()
@ -151,6 +126,7 @@ impl TempTableWidget for Painter {
)
.header_gap(app_state.app_config_fields.table_gap),
margined_draw_loc[0],
temp_table_state,
);
}
}

View file

@ -151,7 +151,10 @@ pub const DEFAULT_CONFIG_CONTENT: &str = r##"
#basic = false
# Use the old network legend style
#use_old_network_legend = true
#use_old_network_legend = false
# Remove space in tables
#hide_table_gap = false
##########################################################

View file

@ -145,7 +145,7 @@ fn main() -> error::Result<()> {
app.used_widgets.clone(),
);
let mut painter = canvas::Painter::init(widget_layout);
let mut painter = canvas::Painter::init(widget_layout, app.app_config_fields.table_gap);
if let Err(config_check) = generate_config_colours(&config, &mut painter) {
cleanup_terminal(&mut terminal)?;
return Err(config_check);