summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClement Tsang <34804052+ClementTsang@users.noreply.github.com>2024-01-08 02:35:32 -0500
committerGitHub <noreply@github.com>2024-01-08 02:35:32 -0500
commit0f969fcfd4409f8045357298c5229500cf720cba (patch)
tree00b8f45372a177ab9402b695de1adfa2a0308526
parent0c161ae77e92580541ae19e3bd4363216be5b5e8 (diff)
refactor: clean up help drawing code (#1374)
* refactor: clean up the help drawing * a bit cleaner * add test * some fmt
-rw-r--r--src/canvas.rs104
-rw-r--r--src/canvas/dialogs/help_dialog.rs40
-rw-r--r--src/canvas/widgets/battery_display.rs2
-rw-r--r--src/canvas/widgets/process_table.rs2
-rw-r--r--src/constants.rs11
5 files changed, 71 insertions, 88 deletions
diff --git a/src/canvas.rs b/src/canvas.rs
index 38194f04..3a02803b 100644
--- a/src/canvas.rs
+++ b/src/canvas.rs
@@ -11,7 +11,7 @@ use styling::*;
use tui::{
backend::Backend,
layout::{Constraint, Direction, Layout, Rect},
- text::{Line, Span},
+ text::Span,
widgets::Paragraph,
Frame, Terminal,
};
@@ -58,9 +58,8 @@ impl FromStr for ColourScheme {
/// Handles the canvas' state.
pub struct Painter {
pub colours: CanvasStyling,
- height: u16,
- width: u16,
- styled_help_text: Vec<Line<'static>>,
+ previous_height: u16,
+ previous_width: u16,
// TODO: Redo this entire thing.
row_constraints: Vec<LayoutConstraint>,
@@ -151,11 +150,10 @@ impl Painter {
col_constraints.push(new_col_constraints);
});
- let mut painter = Painter {
+ let painter = Painter {
colours: styling,
- height: 0,
- width: 0,
- styled_help_text: Vec::default(),
+ previous_height: 0,
+ previous_width: 0,
row_constraints,
col_constraints,
col_row_constraints,
@@ -164,8 +162,6 @@ impl Painter {
derived_widget_draw_locs: Vec::default(),
};
- painter.complete_painter_init();
-
Ok(painter)
}
@@ -179,40 +175,6 @@ impl Painter {
}
}
- /// Must be run once before drawing, but after setting colours.
- /// This is to set some remaining styles and text.
- fn complete_painter_init(&mut self) {
- let mut styled_help_spans = Vec::new();
-
- // Init help text:
- HELP_TEXT.iter().enumerate().for_each(|(itx, section)| {
- if itx == 0 {
- styled_help_spans.extend(
- section
- .iter()
- .map(|&text| Span::styled(text, self.colours.text_style))
- .collect::<Vec<_>>(),
- );
- } else {
- // Not required check but it runs only a few times... so whatever ig, prevents me from
- // being dumb and leaving a help text section only one line long.
- if section.len() > 1 {
- styled_help_spans.push(Span::raw(""));
- styled_help_spans
- .push(Span::styled(section[0], self.colours.table_header_style));
- styled_help_spans.extend(
- section[1..]
- .iter()
- .map(|&text| Span::styled(text, self.colours.text_style))
- .collect::<Vec<_>>(),
- );
- }
- }
- });
-
- self.styled_help_text = styled_help_spans.into_iter().map(Line::from).collect();
- }
-
fn draw_frozen_indicator(&self, f: &mut Frame<'_>, draw_loc: Rect) {
f.render_widget(
Paragraph::new(Span::styled(
@@ -244,12 +206,13 @@ impl Painter {
let terminal_height = terminal_size.height;
let terminal_width = terminal_size.width;
- if (self.height == 0 && self.width == 0)
- || (self.height != terminal_height || self.width != terminal_width)
+ if (self.previous_height == 0 && self.previous_width == 0)
+ || (self.previous_height != terminal_height
+ || self.previous_width != terminal_width)
{
app_state.is_force_redraw = true;
- self.height = terminal_height;
- self.width = terminal_width;
+ self.previous_height = terminal_height;
+ self.previous_width = terminal_width;
}
if app_state.should_get_widget_bounds() {
@@ -389,9 +352,9 @@ impl Painter {
_ => 0,
};
- self.draw_process_widget(f, app_state, rect[0], true, widget_id);
+ self.draw_process(f, app_state, rect[0], true, widget_id);
}
- Battery => self.draw_battery_display(
+ Battery => self.draw_battery(
f,
app_state,
rect[0],
@@ -495,18 +458,12 @@ impl Painter {
ProcSort => 2,
_ => 0,
};
- self.draw_process_widget(
- f,
- app_state,
- vertical_chunks[3],
- false,
- wid,
- );
+ self.draw_process(f, app_state, vertical_chunks[3], false, wid);
}
Temp => {
self.draw_temp_table(f, app_state, vertical_chunks[3], widget_id)
}
- Battery => self.draw_battery_display(
+ Battery => self.draw_battery(
f,
app_state,
vertical_chunks[3],
@@ -775,29 +732,16 @@ impl Painter {
widget_draw_locs: &[Rect],
) {
use BottomWidgetType::*;
- for (widget, widget_draw_loc) in widgets.children.iter().zip(widget_draw_locs) {
- if widget_draw_loc.width >= 2 && widget_draw_loc.height >= 2 {
+ for (widget, draw_loc) in widgets.children.iter().zip(widget_draw_locs) {
+ if draw_loc.width >= 2 && draw_loc.height >= 2 {
match &widget.widget_type {
- Empty => {}
- Cpu => self.draw_cpu(f, app_state, *widget_draw_loc, widget.widget_id),
- Mem => self.draw_memory_graph(f, app_state, *widget_draw_loc, widget.widget_id),
- Net => self.draw_network(f, app_state, *widget_draw_loc, widget.widget_id),
- Temp => self.draw_temp_table(f, app_state, *widget_draw_loc, widget.widget_id),
- Disk => self.draw_disk_table(f, app_state, *widget_draw_loc, widget.widget_id),
- Proc => self.draw_process_widget(
- f,
- app_state,
- *widget_draw_loc,
- true,
- widget.widget_id,
- ),
- Battery => self.draw_battery_display(
- f,
- app_state,
- *widget_draw_loc,
- true,
- widget.widget_id,
- ),
+ Cpu => self.draw_cpu(f, app_state, *draw_loc, widget.widget_id),
+ Mem => self.draw_memory_graph(f, app_state, *draw_loc, widget.widget_id),
+ Net => self.draw_network(f, app_state, *draw_loc, widget.widget_id),
+ Temp => self.draw_temp_table(f, app_state, *draw_loc, widget.widget_id),
+ Disk => self.draw_disk_table(f, app_state, *draw_loc, widget.widget_id),
+ Proc => self.draw_process(f, app_state, *draw_loc, true, widget.widget_id),
+ Battery => self.draw_battery(f, app_state, *draw_loc, true, widget.widget_id),
_ => {}
}
}
diff --git a/src/canvas/dialogs/help_dialog.rs b/src/canvas/dialogs/help_dialog.rs
index 082aeb6e..9dafeb2e 100644
--- a/src/canvas/dialogs/help_dialog.rs
+++ b/src/canvas/dialogs/help_dialog.rs
@@ -8,13 +8,41 @@ use tui::{
};
use unicode_width::UnicodeWidthStr;
-use crate::{app::App, canvas::Painter, constants};
+use crate::{
+ app::App,
+ canvas::Painter,
+ constants::{self, HELP_TEXT},
+};
const HELP_BASE: &str = " Help ── Esc to close ";
// TODO: [REFACTOR] Make generic dialog boxes to build off of instead?
impl Painter {
+ fn help_text_lines(&self) -> Vec<Line<'_>> {
+ let mut styled_help_spans = Vec::new();
+
+ // Init help text:
+ HELP_TEXT.iter().enumerate().for_each(|(itx, section)| {
+ let mut section = section.iter();
+
+ if itx > 0 {
+ if let Some(header) = section.next() {
+ styled_help_spans.push(Span::default());
+ styled_help_spans.push(Span::styled(*header, self.colours.table_header_style));
+ }
+ }
+
+ section.for_each(|&text| {
+ styled_help_spans.push(Span::styled(text, self.colours.text_style))
+ });
+ });
+
+ styled_help_spans.into_iter().map(Line::from).collect()
+ }
+
pub fn draw_help_dialog(&self, f: &mut Frame<'_>, app_state: &mut App, draw_loc: Rect) {
+ let styled_help_text = self.help_text_lines();
+
let help_title = Line::from(vec![
Span::styled(" Help ", self.colours.widget_title_style),
Span::styled(
@@ -35,11 +63,11 @@ impl Painter {
.border_style(self.colours.border_style);
if app_state.should_get_widget_bounds() {
- app_state.help_dialog_state.height = block.inner(draw_loc).height;
-
// We must also recalculate how many lines are wrapping to properly get scrolling to work on
// small terminal sizes... oh joy.
+ app_state.help_dialog_state.height = block.inner(draw_loc).height;
+
let mut overflow_buffer = 0;
let paragraph_width = max(draw_loc.width.saturating_sub(2), 1);
let mut prev_section_len = 0;
@@ -73,10 +101,10 @@ impl Painter {
});
let max_scroll_index = &mut app_state.help_dialog_state.scroll_state.max_scroll_index;
- *max_scroll_index = (self.styled_help_text.len() as u16 + 3 + overflow_buffer)
+ *max_scroll_index = (styled_help_text.len() as u16 + 3 + overflow_buffer)
.saturating_sub(draw_loc.height + 1);
- // Fix if over-scrolled
+ // Fix the scroll index if it is over-scrolled
let index = &mut app_state
.help_dialog_state
.scroll_state
@@ -86,7 +114,7 @@ impl Painter {
}
f.render_widget(
- Paragraph::new(self.styled_help_text.clone())
+ Paragraph::new(styled_help_text.clone())
.block(block)
.style(self.colours.text_style)
.alignment(Alignment::Left)
diff --git a/src/canvas/widgets/battery_display.rs b/src/canvas/widgets/battery_display.rs
index 4cd5c23b..316d3693 100644
--- a/src/canvas/widgets/battery_display.rs
+++ b/src/canvas/widgets/battery_display.rs
@@ -15,7 +15,7 @@ use crate::{
};
impl Painter {
- pub fn draw_battery_display(
+ pub fn draw_battery(
&self, f: &mut Frame<'_>, app_state: &mut App, draw_loc: Rect, draw_border: bool,
widget_id: u64,
) {
diff --git a/src/canvas/widgets/process_table.rs b/src/canvas/widgets/process_table.rs
index 6ccb2dce..0bf698d6 100644
--- a/src/canvas/widgets/process_table.rs
+++ b/src/canvas/widgets/process_table.rs
@@ -21,7 +21,7 @@ const SORT_MENU_WIDTH: u16 = 7;
impl Painter {
/// Draws and handles all process-related drawing. Use this.
/// - `widget_id` here represents the widget ID of the process widget itself!
- pub fn draw_process_widget(
+ pub fn draw_process(
&self, f: &mut Frame<'_>, app_state: &mut App, draw_loc: Rect, draw_border: bool,
widget_id: u64,
) {
diff --git a/src/constants.rs b/src/constants.rs
index d736e928..f09a5d5b 100644
--- a/src/constants.rs
+++ b/src/constants.rs
@@ -752,6 +752,7 @@ mod test {
#[test]
fn help_menu_matches_entry_len() {
+ // The two match since HELP_TEXT contains HELP_CONTENTS_TEXT as an entry
assert_eq!(
HELP_CONTENTS_TEXT.len(),
HELP_TEXT.len(),
@@ -759,6 +760,16 @@ mod test {
)
}
+ #[test]
+ fn help_menu_text_has_sections() {
+ for (itx, line) in HELP_TEXT.iter().enumerate() {
+ if itx > 0 {
+ assert!(line.len() >= 2, "each section should be at least 2 lines");
+ assert!(line[0].contains(" - "), "each section should have a header");
+ }
+ }
+ }
+
/// This test exists because previously, [`SIDE_BORDERS`] was set incorrectly after I moved from
/// tui-rs to ratatui.
#[test]