diff --git a/Cargo.lock b/Cargo.lock index a89748a1..7d2b4099 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1345,13 +1345,15 @@ checksum = "a7f741b240f1a48843f9b8e0444fb55fb2a4ff67293b50a9179dfd5ea67f8d41" [[package]] name = "tui" -version = "0.10.0" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a977b0bb2e2033a6fef950f218f13622c3c34e59754b704ce3492dedab1dfe95" +checksum = "9533d39bef0ae8f510e8a99d78702e68d1bbf0b98a78ec9740509d287010ae1e" dependencies = [ "bitflags", "cassowary", "crossterm", + "either", + "itertools", "unicode-segmentation", "unicode-width", ] diff --git a/Cargo.toml b/Cargo.toml index 1b225266..282d1e6e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,7 +39,7 @@ serde = {version = "1.0", features = ["derive"] } unicode-segmentation = "1.6.0" unicode-width = "0.1.7" # tui = {version = "0.10.0", features = ["crossterm"], default-features = false, git = "https://github.com/fdehau/tui-rs.git"} -tui = {version = "0.10.0", features = ["crossterm"], default-features = false } +tui = {version = "0.9.5", features = ["crossterm"], default-features = false } # For debugging only... fern = "0.6.0" diff --git a/src/canvas.rs b/src/canvas.rs index 8ff9c31b..563651b8 100644 --- a/src/canvas.rs +++ b/src/canvas.rs @@ -4,7 +4,7 @@ use std::collections::HashMap; use tui::{ backend::Backend, layout::{Constraint, Direction, Layout, Rect}, - text::{Span, Spans}, + widgets::Text, Frame, Terminal, }; @@ -55,7 +55,7 @@ pub struct Painter { pub colours: CanvasColours, height: u16, width: u16, - styled_help_text: Vec>, + styled_help_text: Vec>, is_mac_os: bool, row_constraints: Vec, col_constraints: Vec>, @@ -163,27 +163,28 @@ impl Painter { styled_help_spans.extend( section .iter() - .map(|&text| Span::styled(text, self.colours.text_style)) + .map(|&text| Text::styled(text, self.colours.text_style)) .collect::>(), ); } 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::from("")); + styled_help_spans.push(Text::raw("\n\n")); styled_help_spans - .push(Span::styled(section[0], self.colours.table_header_style)); + .push(Text::styled(section[0], self.colours.table_header_style)); styled_help_spans.extend( section[1..] .iter() - .map(|&text| Span::styled(text, self.colours.text_style)) + .map(|&text| Text::styled(text, self.colours.text_style)) .collect::>(), ); } } }); - self.styled_help_text = styled_help_spans.into_iter().map(Spans::from).collect(); + // self.styled_help_text = styled_help_spans.into_iter().map(Spans::from).collect(); + self.styled_help_text = styled_help_spans; } pub fn draw_data( @@ -251,36 +252,44 @@ impl Painter { let dd_text = self.get_dd_spans(app_state); - let (text_width, text_height) = if let Some(dd_text) = &dd_text { - let width = if f.size().width < 100 { + let (text_width, text_height) = ( + if f.size().width < 100 { f.size().width * 90 / 100 } else { - let min_possible_width = (f.size().width * 50 / 100) as usize; - let mut width = dd_text.width(); + f.size().width * 50 / 100 + }, + 7, + ); + // let (text_width, text_height) = if let Some(dd_text) = &dd_text { + // let width = if f.size().width < 100 { + // f.size().width * 90 / 100 + // } else { + // let min_possible_width = (f.size().width * 50 / 100) as usize; + // let mut width = dd_text.width(); - // This should theoretically never allow width to be 0... we can be safe and do an extra check though. - while width > (f.size().width as usize) && width / 2 > min_possible_width { - width /= 2; - } + // // This should theoretically never allow width to be 0... we can be safe and do an extra check though. + // while width > (f.size().width as usize) && width / 2 > min_possible_width { + // width /= 2; + // } - std::cmp::max(width, min_possible_width) as u16 - }; + // std::cmp::max(width, min_possible_width) as u16 + // }; - ( - width, - (dd_text.height() + 2 + (dd_text.width() / width as usize)) as u16, - ) - } else { - // AFAIK this shouldn't happen, unless something went wrong... - ( - if f.size().width < 100 { - f.size().width * 90 / 100 - } else { - f.size().width * 50 / 100 - }, - 7, - ) - }; + // ( + // width, + // (dd_text.height() + 2 + (dd_text.width() / width as usize)) as u16, + // ) + // } else { + // // AFAIK this shouldn't happen, unless something went wrong... + // ( + // if f.size().width < 100 { + // f.size().width * 90 / 100 + // } else { + // f.size().width * 50 / 100 + // }, + // 7, + // ) + // }; let vertical_bordering = f.size().height.saturating_sub(text_height) / 2; let vertical_dialog_chunk = Layout::default() diff --git a/src/canvas/canvas_colours.rs b/src/canvas/canvas_colours.rs index 5d0e6584..d7724568 100644 --- a/src/canvas/canvas_colours.rs +++ b/src/canvas/canvas_colours.rs @@ -85,7 +85,7 @@ impl CanvasColours { } pub fn set_table_header_colour(&mut self, colour: &str) -> error::Result<()> { - self.table_header_style = get_style_from_config(colour)?.add_modifier(Modifier::BOLD); + self.table_header_style = get_style_from_config(colour)?.modifier(Modifier::BOLD); Ok(()) } diff --git a/src/canvas/dialogs/dd_dialog.rs b/src/canvas/dialogs/dd_dialog.rs index 18f89d68..8b3f342c 100644 --- a/src/canvas/dialogs/dd_dialog.rs +++ b/src/canvas/dialogs/dd_dialog.rs @@ -2,8 +2,7 @@ use tui::{ backend::Backend, layout::{Alignment, Rect}, terminal::Frame, - text::{Span, Spans, Text}, - widgets::{Block, Borders, Paragraph, Wrap}, + widgets::{Block, Borders, Paragraph, Text}, }; use crate::{app::App, canvas::Painter}; @@ -12,61 +11,58 @@ const DD_BASE: &str = " Confirm Kill Process ── Esc to close "; const DD_ERROR_BASE: &str = " Error ── Esc to close "; pub trait KillDialog { - fn get_dd_spans(&self, app_state: &App) -> Option>; + fn get_dd_spans(&self, app_state: &App) -> Option>>; fn draw_dd_dialog( - &self, f: &mut Frame<'_, B>, dd_text: Option>, app_state: &App, draw_loc: Rect, + &self, f: &mut Frame<'_, B>, dd_text: Option>>, app_state: &App, + draw_loc: Rect, ) -> bool; } impl KillDialog for Painter { - fn get_dd_spans(&self, app_state: &App) -> Option> { + fn get_dd_spans(&self, app_state: &App) -> Option>> { if let Some(dd_err) = &app_state.dd_err { - return Some(Text::from(Spans::from(format!( - "Failure to properly kill the process - {}", - dd_err - )))); + return Some(vec![ + Text::raw("\n"), + Text::raw(format!("Failure to properly kill the process - {}", dd_err)), + ]); } else if let Some(to_kill_processes) = app_state.get_to_delete_processes() { if let Some(first_pid) = to_kill_processes.1.first() { - return Some(Text::from(vec![ - Spans::from(vec![]), - Spans::from(vec![ - if app_state.is_grouped(app_state.current_widget.widget_id) { - if to_kill_processes.1.len() != 1 { - Span::from(format!( - "Kill {} processes with the name \"{}\"?", - to_kill_processes.1.len(), - to_kill_processes.0 - )) - } else { - Span::from(format!( - "Kill 1 process with the name \"{}\"?", - to_kill_processes.0 - )) - } - } else { - Span::from(format!( - "Kill process \"{}\" with PID {}?", - to_kill_processes.0, first_pid + return Some(vec![ + Text::raw("\n"), + if app_state.is_grouped(app_state.current_widget.widget_id) { + if to_kill_processes.1.len() != 1 { + Text::raw(format!( + "Kill {} processes with the name \"{}\"?", + to_kill_processes.1.len(), + to_kill_processes.0 )) - }, - ]), - Spans::from(vec![]), - Spans::from(vec![ - if app_state.delete_dialog_state.is_on_yes { - Span::styled("Yes", self.colours.currently_selected_text_style) } else { - Span::from("Yes") - }, - Span::from(" "), - if app_state.delete_dialog_state.is_on_yes { - Span::from("No") - } else { - Span::styled("No", self.colours.currently_selected_text_style) - }, - ]), - Spans::from(vec![]), - ])); + Text::raw(format!( + "Kill 1 process with the name \"{}\"?", + to_kill_processes.0 + )) + } + } else { + Text::raw(format!( + "Kill process \"{}\" with PID {}?", + to_kill_processes.0, first_pid + )) + }, + Text::raw("\n\n"), + if app_state.delete_dialog_state.is_on_yes { + Text::styled("Yes", self.colours.currently_selected_text_style) + } else { + Text::raw("Yes") + }, + Text::raw(" "), + if app_state.delete_dialog_state.is_on_yes { + Text::raw("No") + } else { + Text::styled("No", self.colours.currently_selected_text_style) + }, + Text::raw("\n"), + ]); } } @@ -74,44 +70,63 @@ impl KillDialog for Painter { } fn draw_dd_dialog( - &self, f: &mut Frame<'_, B>, dd_text: Option>, app_state: &App, draw_loc: Rect, + &self, f: &mut Frame<'_, B>, dd_text: Option>>, app_state: &App, + draw_loc: Rect, ) -> bool { if let Some(dd_text) = dd_text { + // let dd_title = if app_state.dd_err.is_some() { + // Text::styled( + // format!( + // " Error ─{}─ Esc to close ", + // "─".repeat( + // usize::from(draw_loc.width) + // .saturating_sub(DD_ERROR_BASE.chars().count() + 2) + // ) + // ), + // self.colours.border_style, + // ) + // } else { + // Text::styled( + // format!( + // " Confirm Kill Process ─{}─ Esc to close ", + // "─".repeat( + // usize::from(draw_loc.width).saturating_sub(DD_BASE.chars().count() + 2) + // ) + // ), + // self.colours.border_style, + // ) + // }; + let dd_title = if app_state.dd_err.is_some() { - Span::styled( - format!( - " Error ─{}─ Esc to close ", - "─".repeat( - usize::from(draw_loc.width) - .saturating_sub(DD_ERROR_BASE.chars().count() + 2) - ) - ), - self.colours.border_style, + format!( + " Error ─{}─ Esc to close ", + "─".repeat( + usize::from(draw_loc.width) + .saturating_sub(DD_ERROR_BASE.chars().count() + 2) + ) ) } else { - Span::styled( - format!( - " Confirm Kill Process ─{}─ Esc to close ", - "─".repeat( - usize::from(draw_loc.width).saturating_sub(DD_BASE.chars().count() + 2) - ) - ), - self.colours.border_style, + format!( + " Confirm Kill Process ─{}─ Esc to close ", + "─".repeat( + usize::from(draw_loc.width).saturating_sub(DD_BASE.chars().count() + 2) + ) ) }; f.render_widget( - Paragraph::new(dd_text) + Paragraph::new(dd_text.iter()) .block( Block::default() - .title(dd_title) + .title(&dd_title) + .title_style(self.colours.border_style) .style(self.colours.border_style) .borders(Borders::ALL) .border_style(self.colours.border_style), ) .style(self.colours.text_style) .alignment(Alignment::Center) - .wrap(Wrap { trim: true }), + .wrap(true), draw_loc, ); diff --git a/src/canvas/dialogs/help_dialog.rs b/src/canvas/dialogs/help_dialog.rs index 138622ce..8ef4d010 100644 --- a/src/canvas/dialogs/help_dialog.rs +++ b/src/canvas/dialogs/help_dialog.rs @@ -4,8 +4,7 @@ use tui::{ backend::Backend, layout::{Alignment, Rect}, terminal::Frame, - text::Span, - widgets::{Block, Borders, Paragraph, Wrap}, + widgets::{Block, Borders, Paragraph}, }; use crate::{app::App, canvas::Painter, constants}; @@ -22,14 +21,19 @@ impl HelpDialog for Painter { fn draw_help_dialog( &self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect, ) { - let help_title = Span::styled( - format!( - " Help ─{}─ Esc to close ", - "─".repeat( - usize::from(draw_loc.width).saturating_sub(HELP_BASE.chars().count() + 2) - ) - ), - self.colours.border_style, + // let help_title = Text::styled( + // format!( + // " Help ─{}─ Esc to close ", + // "─".repeat( + // usize::from(draw_loc.width).saturating_sub(HELP_BASE.chars().count() + 2) + // ) + // ), + // self.colours.border_style, + // ); + + let help_title = format!( + " Help ─{}─ Esc to close ", + "─".repeat(usize::from(draw_loc.width).saturating_sub(HELP_BASE.chars().count() + 2)) ); if app_state.is_force_redraw { @@ -95,24 +99,24 @@ impl HelpDialog for Painter { } f.render_widget( - Paragraph::new(self.styled_help_text.clone()) + Paragraph::new(self.styled_help_text.iter()) .block( Block::default() - .title(help_title) + .title(&help_title) + .title_style(self.colours.border_style) .style(self.colours.border_style) .borders(Borders::ALL) .border_style(self.colours.border_style), ) .style(self.colours.text_style) .alignment(Alignment::Left) - .wrap(Wrap { trim: true }) - .scroll(( + .wrap(true) + .scroll( app_state .help_dialog_state .scroll_state .current_scroll_index, - 0, - )), + ), draw_loc, ); } diff --git a/src/canvas/widgets/basic_table_arrows.rs b/src/canvas/widgets/basic_table_arrows.rs index 18beab83..591f71c6 100644 --- a/src/canvas/widgets/basic_table_arrows.rs +++ b/src/canvas/widgets/basic_table_arrows.rs @@ -10,8 +10,7 @@ use tui::{ backend::Backend, layout::{Constraint, Layout, Rect}, terminal::Frame, - text::{Span, Spans}, - widgets::{Block, Paragraph}, + widgets::{Block, Paragraph, Text}, }; pub trait BasicTableArrows { @@ -98,12 +97,10 @@ impl BasicTableArrows for Painter { usize::from(draw_loc.width).saturating_sub(6 + left_name.len() + right_name.len()); let arrow_text = vec![ - Spans::from(Span::from(String::default())), - Spans::from(vec![ - Span::styled(format!("◄ {}", left_name), self.colours.text_style), - Span::from(" ".repeat(num_spaces)), - Span::styled(format!("{} ►", right_name), self.colours.text_style), - ]), + Text::raw("\n"), + Text::styled(format!("◄ {}", left_name), self.colours.text_style), + Text::raw(" ".repeat(num_spaces)), + Text::styled(format!("{} ►", right_name), self.colours.text_style), ]; let margined_draw_loc = Layout::default() @@ -112,7 +109,7 @@ impl BasicTableArrows for Painter { .split(draw_loc); f.render_widget( - Paragraph::new(arrow_text).block(Block::default()), + Paragraph::new(arrow_text.iter()).block(Block::default()), margined_draw_loc[0], ); } diff --git a/src/canvas/widgets/battery_display.rs b/src/canvas/widgets/battery_display.rs index d716b53e..7c3b7896 100644 --- a/src/canvas/widgets/battery_display.rs +++ b/src/canvas/widgets/battery_display.rs @@ -8,8 +8,7 @@ use tui::{ backend::Backend, layout::{Constraint, Rect}, terminal::Frame, - text::{Span, Spans}, - widgets::{Block, Borders, Paragraph, Row, Table, Tabs}, + widgets::{Block, Borders, Paragraph, Row, Table, Tabs, Text}, }; pub trait BatteryDisplayWidget { @@ -34,25 +33,45 @@ impl BatteryDisplayWidget for Painter { self.colours.border_style }; + // let title = if app_state.is_expanded { + // const TITLE_BASE: &str = " Battery ── Esc to go back "; + // Span::styled( + // format!( + // " Battery ─{}─ Esc to go back ", + // "─".repeat( + // usize::from(draw_loc.width) + // .saturating_sub(TITLE_BASE.chars().count() + 2) + // ) + // ), + // border_and_title_style, + // ) + // } else { + // Span::styled(" Battery ".to_string(), self.colours.widget_title_style) + // }; + let title = if app_state.is_expanded { const TITLE_BASE: &str = " Battery ── Esc to go back "; - Span::styled( - format!( - " Battery ─{}─ Esc to go back ", - "─".repeat( - usize::from(draw_loc.width) - .saturating_sub(TITLE_BASE.chars().count() + 2) - ) - ), - border_and_title_style, + + format!( + " Battery ─{}─ Esc to go back ", + "─".repeat( + usize::from(draw_loc.width).saturating_sub(TITLE_BASE.chars().count() + 2) + ) ) } else { - Span::styled(" Battery ".to_string(), self.colours.widget_title_style) + " Battery ".to_string() + }; + + let title_style = if app_state.is_expanded { + border_and_title_style + } else { + self.colours.widget_title_style }; let battery_block = if draw_border { Block::default() - .title(title) + .title(&title) + .title_style(title_style) .borders(Borders::ALL) .border_style(border_and_title_style) } else if is_on_widget { @@ -63,22 +82,32 @@ impl BatteryDisplayWidget for Painter { Block::default().borders(Borders::NONE) }; - f.render_widget( - Tabs::new( - (app_state - .canvas_data - .battery_data - .iter() - .map(|battery| Spans::from(battery.battery_name.clone()))) - .collect::>(), - ) - .block(battery_block.clone()) - .divider(tui::symbols::line::VERTICAL) - .style(self.colours.text_style) - .highlight_style(self.colours.currently_selected_text_style) - .select(battery_widget_state.currently_selected_battery_index), - draw_loc, - ); + // f.render_widget( + // // Tabs::new( + // // (app_state + // // .canvas_data + // // .battery_data + // // .iter() + // // .map(|battery| Spans::from(battery.battery_name.clone()))) + // // .collect::>(), + // // ) + // Tabs::default() + // .titles( + // app_state + // .canvas_data + // .battery_data + // .iter() + // .map(|battery| &battery.battery_name) + // .collect::>() + // .as_ref(), + // ) + // .block(battery_block) + // .divider(tui::symbols::line::VERTICAL) + // .style(self.colours.text_style) + // .highlight_style(self.colours.currently_selected_text_style) + // .select(battery_widget_state.currently_selected_battery_index), + // draw_loc, + // ); if let Some(battery_details) = app_state .canvas_data @@ -134,21 +163,52 @@ impl BatteryDisplayWidget for Painter { // Draw f.render_widget( Table::new([""].iter(), battery_rows) - .block(battery_block.clone()) + .block(battery_block) .header_style(self.colours.table_header_style) .widths([Constraint::Percentage(50), Constraint::Percentage(50)].as_ref()), draw_loc, ); } else { f.render_widget( - Paragraph::new(Spans::from(Span::styled( - "No data found for this battery", - self.colours.text_style, - ))) + Paragraph::new( + [Text::styled( + "No data found for this battery", + self.colours.text_style, + )] + .iter(), + ) .block(battery_block), draw_loc, ); } + + // Has to be placed AFTER for tui 0.9, place BEFORE for 0.10. + f.render_widget( + // Tabs::new( + // (app_state + // .canvas_data + // .battery_data + // .iter() + // .map(|battery| Spans::from(battery.battery_name.clone()))) + // .collect::>(), + // ) + Tabs::default() + .titles( + app_state + .canvas_data + .battery_data + .iter() + .map(|battery| &battery.battery_name) + .collect::>() + .as_ref(), + ) + .block(battery_block) + .divider(tui::symbols::line::VERTICAL) + .style(self.colours.text_style) + .highlight_style(self.colours.currently_selected_text_style) + .select(battery_widget_state.currently_selected_battery_index), + draw_loc, + ); } } } diff --git a/src/canvas/widgets/cpu_basic.rs b/src/canvas/widgets/cpu_basic.rs index c8db2f33..4683a677 100644 --- a/src/canvas/widgets/cpu_basic.rs +++ b/src/canvas/widgets/cpu_basic.rs @@ -11,8 +11,7 @@ use tui::{ backend::Backend, layout::{Constraint, Direction, Layout, Rect}, terminal::Frame, - text::{Span, Spans}, - widgets::{Block, Paragraph}, + widgets::{Block, Paragraph, Text}, }; pub trait CpuBasicWidget { @@ -77,10 +76,10 @@ impl CpuBasicWidget for Painter { let num_bars = calculate_basic_use_bars(use_percentage, bar_length); format!( - "{:3}[{}{}{:3.0}%]", + "{:3}[{}{}{:3.0}%]\n", if app_state.app_config_fields.show_average_cpu { if cpu_index == 0 { - " AVG".to_string() + "AVG".to_string() } else { (cpu_index - 1).to_string() } @@ -109,11 +108,16 @@ impl CpuBasicWidget for Painter { let end_index = min(start_index + how_many_cpus, num_cpus); let cpu_column = (start_index..end_index) .map(|cpu_index| { - Spans::from(Span { - content: (&cpu_bars[cpu_index]).into(), - style: self.colours.cpu_colour_styles + // Spans::from(Span { + // content: (&cpu_bars[cpu_index]).into(), + // style: self.colours.cpu_colour_styles + // [cpu_index % self.colours.cpu_colour_styles.len()], + // }) + Text::styled( + &cpu_bars[cpu_index], + self.colours.cpu_colour_styles [cpu_index % self.colours.cpu_colour_styles.len()], - }) + ) }) .collect::>(); @@ -126,7 +130,7 @@ impl CpuBasicWidget for Painter { .split(*chunk); f.render_widget( - Paragraph::new(cpu_column).block(Block::default()), + Paragraph::new(cpu_column.iter()).block(Block::default()), margined_loc[0], ); } diff --git a/src/canvas/widgets/cpu_graph.rs b/src/canvas/widgets/cpu_graph.rs index a01b7f5f..f31eb1f2 100644 --- a/src/canvas/widgets/cpu_graph.rs +++ b/src/canvas/widgets/cpu_graph.rs @@ -17,7 +17,6 @@ use tui::{ layout::{Constraint, Direction, Layout, Rect}, symbols::Marker, terminal::Frame, - text::Span, widgets::{Axis, Block, Borders, Chart, Dataset, Row, Table}, }; @@ -104,12 +103,17 @@ impl CpuGraphWidget for Painter { 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 = vec![ - Span::styled( - format!("{}s", cpu_widget_state.current_display_time / 1000), - self.colours.graph_style, - ), - Span::styled("0s".to_string(), self.colours.graph_style), + // let display_time_labels = vec![ + // Text::styled( + // format!("{}s", cpu_widget_state.current_display_time / 1000), + // self.colours.graph_style, + // ), + // Text::styled("0s".to_string(), self.colours.graph_style), + // ]; + + 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 @@ -124,7 +128,8 @@ impl CpuGraphWidget for Painter { Axis::default() .bounds([-(cpu_widget_state.current_display_time as f64), 0.0]) .style(self.colours.graph_style) - .labels(display_time_labels) + .labels(&display_time_labels) + .labels_style(self.colours.graph_style) } else { cpu_widget_state.autohide_timer = None; Axis::default().bounds([-(cpu_widget_state.current_display_time as f64), 0.0]) @@ -135,17 +140,16 @@ impl CpuGraphWidget for Painter { Axis::default() .bounds([-(cpu_widget_state.current_display_time as f64), 0.0]) .style(self.colours.graph_style) - .labels(display_time_labels) + .labels(&display_time_labels) + .labels_style(self.colours.graph_style) }; // Note this is offset as otherwise the 0 value is not drawn! let y_axis = Axis::default() .style(self.colours.graph_style) .bounds([-0.5, 100.5]) - .labels(vec![ - Span::styled("0%", self.colours.graph_style), - Span::styled("100%", self.colours.graph_style), - ]); + .labels_style(self.colours.graph_style) + .labels(&["0%", "100%"]); let use_dot = app_state.app_config_fields.use_dot; let show_avg_cpu = app_state.app_config_fields.show_average_cpu; @@ -199,17 +203,26 @@ impl CpuGraphWidget for Painter { self.colours.border_style }; - let title = if app_state.is_expanded { - Span::styled(" CPU ".to_string(), border_style) + // let title = if app_state.is_expanded { + // Span::styled(" CPU ".to_string(), border_style) + // } else { + // Span::styled(" CPU ".to_string(), self.colours.widget_title_style) + // }; + let title = " CPU "; + let title_style = if app_state.is_expanded { + border_style } else { - Span::styled(" CPU ".to_string(), self.colours.widget_title_style) + self.colours.widget_title_style }; f.render_widget( - Chart::new(dataset_vector) + // Chart::new(dataset_vector) + Chart::default() + .datasets(&dataset_vector) .block( Block::default() .title(title) + .title_style(title_style) .borders(Borders::ALL) .border_style(border_style), ) diff --git a/src/canvas/widgets/disk_table.rs b/src/canvas/widgets/disk_table.rs index 5b31314e..191e6b66 100644 --- a/src/canvas/widgets/disk_table.rs +++ b/src/canvas/widgets/disk_table.rs @@ -4,7 +4,6 @@ use tui::{ backend::Backend, layout::{Constraint, Direction, Layout, Rect}, terminal::Frame, - text::Span, widgets::{Block, Borders, Row, Table}, }; @@ -77,27 +76,48 @@ impl DiskTableWidget for Painter { (self.colours.border_style, self.colours.text_style) }; + // let title = if app_state.is_expanded { + // const TITLE_BASE: &str = " Disk ── Esc to go back "; + // Span::styled( + // format!( + // " Disk ─{}─ Esc to go back ", + // "─".repeat( + // usize::from(draw_loc.width) + // .saturating_sub(TITLE_BASE.chars().count() + 2) + // ) + // ), + // border_and_title_style, + // ) + // } else if app_state.app_config_fields.use_basic_mode { + // Span::from(String::new()) + // } else { + // Span::styled(" Disk ".to_string(), self.colours.widget_title_style) + // }; + let title = if app_state.is_expanded { const TITLE_BASE: &str = " Disk ── Esc to go back "; - Span::styled( - format!( - " Disk ─{}─ Esc to go back ", - "─".repeat( - usize::from(draw_loc.width) - .saturating_sub(TITLE_BASE.chars().count() + 2) - ) - ), - border_and_title_style, + format!( + " Disk ─{}─ Esc to go back ", + "─".repeat( + usize::from(draw_loc.width).saturating_sub(TITLE_BASE.chars().count() + 2) + ) ) } else if app_state.app_config_fields.use_basic_mode { - Span::from(String::new()) + String::new() } else { - Span::styled(" Disk ".to_string(), self.colours.widget_title_style) + " Disk ".to_string() + }; + + let title_style = if app_state.is_expanded { + border_and_title_style + } else { + self.colours.widget_title_style }; let disk_block = if draw_border { Block::default() - .title(title) + .title(&title) + .title_style(title_style) .borders(Borders::ALL) .border_style(border_and_title_style) } else if is_on_widget { diff --git a/src/canvas/widgets/mem_basic.rs b/src/canvas/widgets/mem_basic.rs index 43003e86..c4498316 100644 --- a/src/canvas/widgets/mem_basic.rs +++ b/src/canvas/widgets/mem_basic.rs @@ -8,8 +8,7 @@ use tui::{ backend::Backend, layout::{Constraint, Layout, Rect}, terminal::Frame, - text::{Span, Spans}, - widgets::{Block, Paragraph}, + widgets::{Block, Paragraph, Text}, }; pub trait MemBasicWidget { @@ -54,7 +53,7 @@ impl MemBasicWidget for Painter { let num_bars_ram = calculate_basic_use_bars(ram_use_percentage, bar_length); let num_bars_swap = calculate_basic_use_bars(swap_use_percentage, bar_length); let mem_label = format!( - "RAM[{}{}{:3.0}%]", + "RAM[{}{}{:3.0}%]\n", "|".repeat(num_bars_ram), " ".repeat(bar_length - num_bars_ram), ram_use_percentage.round(), @@ -66,13 +65,13 @@ impl MemBasicWidget for Painter { swap_use_percentage.round(), ); - let mem_text = vec![ - Spans::from(Span::styled(mem_label, self.colours.ram_style)), - Spans::from(Span::styled(swap_label, self.colours.swap_style)), + let mem_text = [ + Text::styled(mem_label, self.colours.ram_style), + Text::styled(swap_label, self.colours.swap_style), ]; f.render_widget( - Paragraph::new(mem_text).block(Block::default()), + Paragraph::new(mem_text.iter()).block(Block::default()), margined_loc[0], ); } diff --git a/src/canvas/widgets/mem_graph.rs b/src/canvas/widgets/mem_graph.rs index 24717dab..ba38b6bd 100644 --- a/src/canvas/widgets/mem_graph.rs +++ b/src/canvas/widgets/mem_graph.rs @@ -5,7 +5,6 @@ use tui::{ layout::{Constraint, Rect}, symbols::Marker, terminal::Frame, - text::Span, widgets::{Axis, Block, Borders, Chart, Dataset}, }; @@ -23,12 +22,9 @@ impl MemGraphWidget for Painter { let mem_data: &[(f64, f64)] = &app_state.canvas_data.mem_data; let swap_data: &[(f64, f64)] = &app_state.canvas_data.swap_data; - let display_time_labels = vec![ - Span::styled( - format!("{}s", mem_widget_state.current_display_time / 1000), - self.colours.graph_style, - ), - Span::styled("0s".to_string(), self.colours.graph_style), + let display_time_labels = [ + format!("{}s", mem_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 @@ -42,7 +38,8 @@ impl MemGraphWidget for Painter { Axis::default() .bounds([-(mem_widget_state.current_display_time as f64), 0.0]) .style(self.colours.graph_style) - .labels(display_time_labels) + .labels(&display_time_labels) + .labels_style(self.colours.graph_style) } else { mem_widget_state.autohide_timer = None; Axis::default().bounds([-(mem_widget_state.current_display_time as f64), 0.0]) @@ -53,17 +50,16 @@ impl MemGraphWidget for Painter { Axis::default() .bounds([-(mem_widget_state.current_display_time as f64), 0.0]) .style(self.colours.graph_style) - .labels(display_time_labels) + .labels(&display_time_labels) + .labels_style(self.colours.graph_style) }; // Offset as the zero value isn't drawn otherwise... let y_axis = Axis::default() .style(self.colours.graph_style) .bounds([-0.5, 100.5]) - .labels(vec![ - Span::styled("0%", self.colours.graph_style), - Span::styled("100%", self.colours.graph_style), - ]); + .labels(&["0%", "100%"]) + .labels_style(self.colours.graph_style); let mut mem_canvas_vec: Vec> = vec![]; @@ -95,25 +91,29 @@ impl MemGraphWidget for Painter { let title = if app_state.is_expanded { const TITLE_BASE: &str = " Memory ── Esc to go back "; - Span::styled( - format!( - " Memory ─{}─ Esc to go back ", - "─".repeat( - usize::from(draw_loc.width) - .saturating_sub(TITLE_BASE.chars().count() + 2) - ) - ), - self.colours.highlighted_border_style, + format!( + " Memory ─{}─ Esc to go back ", + "─".repeat( + usize::from(draw_loc.width).saturating_sub(TITLE_BASE.chars().count() + 2) + ) ) } else { - Span::styled(" Memory ".to_string(), self.colours.widget_title_style) + " Memory ".to_string() + }; + let title_style = if app_state.is_expanded { + self.colours.highlighted_border_style + } else { + self.colours.widget_title_style }; f.render_widget( - Chart::new(mem_canvas_vec) + // Chart::new(mem_canvas_vec) + Chart::default() + .datasets(&mem_canvas_vec) .block( Block::default() - .title(title) + .title(&title) + .title_style(title_style) .borders(Borders::ALL) .border_style(if app_state.current_widget.widget_id == widget_id { self.colours.highlighted_border_style diff --git a/src/canvas/widgets/network_basic.rs b/src/canvas/widgets/network_basic.rs index 891d8a1f..2d8c6340 100644 --- a/src/canvas/widgets/network_basic.rs +++ b/src/canvas/widgets/network_basic.rs @@ -4,8 +4,7 @@ use tui::{ backend::Backend, layout::{Constraint, Direction, Layout, Rect}, terminal::Frame, - text::{Span, Spans}, - widgets::{Block, Paragraph}, + widgets::{Block, Paragraph, Text}, }; pub trait NetworkBasicWidget { @@ -44,25 +43,28 @@ impl NetworkBasicWidget for Painter { ); } - let rx_label = format!("RX: {}", &app_state.canvas_data.rx_display); + let rx_label = format!("RX: {}\n", &app_state.canvas_data.rx_display); let tx_label = format!("TX: {}", &app_state.canvas_data.tx_display); - let total_rx_label = format!("Total RX: {}", &app_state.canvas_data.total_rx_display); + let total_rx_label = format!("Total RX: {}\n", &app_state.canvas_data.total_rx_display); let total_tx_label = format!("Total TX: {}", &app_state.canvas_data.total_tx_display); - let net_text = vec![ - Spans::from(Span::styled(rx_label, self.colours.rx_style)), - Spans::from(Span::styled(tx_label, self.colours.tx_style)), + let net_text = [ + Text::styled(rx_label, self.colours.rx_style), + Text::styled(tx_label, self.colours.tx_style), ]; - let total_net_text = vec![ - Spans::from(Span::styled(total_rx_label, self.colours.total_rx_style)), - Spans::from(Span::styled(total_tx_label, self.colours.total_tx_style)), + let total_net_text = [ + Text::styled(total_rx_label, self.colours.total_rx_style), + Text::styled(total_tx_label, self.colours.total_tx_style), ]; - f.render_widget(Paragraph::new(net_text).block(Block::default()), net_loc[0]); - f.render_widget( - Paragraph::new(total_net_text).block(Block::default()), + Paragraph::new(net_text.iter()).block(Block::default()), + net_loc[0], + ); + + f.render_widget( + Paragraph::new(total_net_text.iter()).block(Block::default()), total_loc[0], ); } diff --git a/src/canvas/widgets/network_graph.rs b/src/canvas/widgets/network_graph.rs index 27a464d8..b981c15f 100644 --- a/src/canvas/widgets/network_graph.rs +++ b/src/canvas/widgets/network_graph.rs @@ -12,7 +12,6 @@ use tui::{ layout::{Constraint, Direction, Layout, Rect}, symbols::Marker, terminal::Frame, - text::Span, widgets::{Axis, Block, Borders, Chart, Dataset, Row, Table}, }; @@ -72,12 +71,9 @@ impl NetworkGraphWidget for Painter { let network_data_rx: &[(f64, f64)] = &app_state.canvas_data.network_data_rx; let network_data_tx: &[(f64, f64)] = &app_state.canvas_data.network_data_tx; - let display_time_labels = vec![ - Span::styled( - format!("{}s", network_widget_state.current_display_time / 1000), - self.colours.graph_style, - ), - Span::styled("0s".to_string(), self.colours.graph_style), + let display_time_labels = [ + format!("{}s", network_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 @@ -91,7 +87,8 @@ impl NetworkGraphWidget for Painter { Axis::default() .bounds([-(network_widget_state.current_display_time as f64), 0.0]) .style(self.colours.graph_style) - .labels(display_time_labels) + .labels(&display_time_labels) + .labels_style(self.colours.graph_style) } else { network_widget_state.autohide_timer = None; Axis::default() @@ -103,35 +100,33 @@ impl NetworkGraphWidget for Painter { Axis::default() .bounds([-(network_widget_state.current_display_time as f64), 0.0]) .style(self.colours.graph_style) - .labels(display_time_labels) + .labels(&display_time_labels) + .labels_style(self.colours.graph_style) }; // 0 is offset. - let y_axis_labels = vec![ - Span::styled("0B", self.colours.graph_style), - Span::styled("1KiB", self.colours.graph_style), - Span::styled("1MiB", self.colours.graph_style), - Span::styled("1GiB", self.colours.graph_style), - ]; + let y_axis_labels = ["0B", "1KiB", "1MiB", "1GiB"]; let y_axis = Axis::default() .style(self.colours.graph_style) .bounds([-0.5, 30_f64]) - .labels(y_axis_labels); + .labels(&y_axis_labels) + .labels_style(self.colours.graph_style); let title = if app_state.is_expanded { const TITLE_BASE: &str = " Network ── Esc to go back "; - Span::styled( - format!( - " Network ─{}─ Esc to go back ", - "─".repeat( - usize::from(draw_loc.width) - .saturating_sub(TITLE_BASE.chars().count() + 2) - ) - ), - self.colours.highlighted_border_style, + format!( + " Network ─{}─ Esc to go back ", + "─".repeat( + usize::from(draw_loc.width).saturating_sub(TITLE_BASE.chars().count() + 2) + ) ) } else { - Span::styled(" Network ".to_string(), self.colours.widget_title_style) + " Network ".to_string() + }; + let title_style = if app_state.is_expanded { + self.colours.highlighted_border_style + } else { + self.colours.widget_title_style }; let legend_constraints = if hide_legend { @@ -142,7 +137,6 @@ impl NetworkGraphWidget for Painter { let dataset = if app_state.app_config_fields.use_old_network_legend && !hide_legend { let mut ret_val = vec![]; - ret_val.push( Dataset::default() .name(format!("RX: {:7}", app_state.canvas_data.rx_display)) @@ -220,10 +214,13 @@ impl NetworkGraphWidget for Painter { }; f.render_widget( - Chart::new(dataset) + // Chart::new(dataset) + Chart::default() + .datasets(&dataset) .block( Block::default() - .title(title) + .title(&title) + .title_style(title_style) .borders(Borders::ALL) .border_style(if app_state.current_widget.widget_id == widget_id { self.colours.highlighted_border_style diff --git a/src/canvas/widgets/process_table.rs b/src/canvas/widgets/process_table.rs index 54f0a5ad..dea0d642 100644 --- a/src/canvas/widgets/process_table.rs +++ b/src/canvas/widgets/process_table.rs @@ -13,8 +13,7 @@ use tui::{ backend::Backend, layout::{Alignment, Constraint, Direction, Layout, Rect}, terminal::Frame, - text::{Span, Spans}, - widgets::{Block, Borders, Paragraph, Row, Table}, + widgets::{Block, Borders, Paragraph, Row, Table, Text}, }; use unicode_segmentation::{GraphemeIndices, UnicodeSegmentation}; @@ -225,26 +224,30 @@ impl ProcessTableWidget for Painter { && !proc_widget_state.is_sort_open { const TITLE_BASE: &str = " Processes ── Esc to go back "; - Span::styled( - format!( - " Processes ─{}─ Esc to go back ", - "─".repeat( - usize::from(draw_loc.width) - .saturating_sub(TITLE_BASE.chars().count() + 2) - ) - ), - border_and_title_style, + format!( + " Processes ─{}─ Esc to go back ", + "─".repeat( + usize::from(draw_loc.width) + .saturating_sub(TITLE_BASE.chars().count() + 2) + ) ) } else { - Span::styled(" Processes ".to_string(), self.colours.widget_title_style) + " Processes ".to_string() } } else { - Span::from(String::default()) + String::default() + }; + + let title_style = if app_state.is_expanded { + border_and_title_style + } else { + self.colours.widget_title_style }; let process_block = if draw_border { Block::default() - .title(title) + .title(&title) + .title_style(title_style) .borders(Borders::ALL) .border_style(border_and_title_style) } else if is_on_widget { @@ -291,7 +294,7 @@ impl ProcessTableWidget for Painter { is_on_widget: bool, grapheme_indices: GraphemeIndices<'a>, start_position: usize, cursor_position: usize, query: &str, currently_selected_text_style: tui::style::Style, text_style: tui::style::Style, - ) -> Vec> { + ) -> Vec> { let mut current_grapheme_posn = 0; if is_on_widget { @@ -303,9 +306,9 @@ impl ProcessTableWidget for Painter { None } else { let styled = if grapheme.0 == cursor_position { - Span::styled(grapheme.1, currently_selected_text_style) + Text::styled(grapheme.1, currently_selected_text_style) } else { - Span::styled(grapheme.1, text_style) + Text::styled(grapheme.1, text_style) }; Some(styled) } @@ -313,7 +316,7 @@ impl ProcessTableWidget for Painter { .collect::>(); if cursor_position >= query.len() { - res.push(Span::styled(" ", currently_selected_text_style)) + res.push(Text::styled(" ", currently_selected_text_style)) } res @@ -327,7 +330,7 @@ impl ProcessTableWidget for Painter { if current_grapheme_posn <= start_position { None } else { - let styled = Span::styled(grapheme.1, text_style); + let styled = Text::styled(grapheme.1, text_style); Some(styled) } }) @@ -373,8 +376,8 @@ impl ProcessTableWidget for Painter { self.colours.text_style, ); - let mut search_text = vec![Spans::from({ - let mut search_vec = vec![Span::styled( + let mut search_text = { + let mut search_vec = vec![Text::styled( search_title, if is_on_widget { self.colours.table_header_style @@ -384,7 +387,7 @@ impl ProcessTableWidget for Painter { )]; search_vec.extend(query_with_cursor); search_vec - })]; + }; // Text options shamelessly stolen from VS Code. let case_style = if !proc_widget_state.process_search_state.is_ignoring_case { @@ -411,24 +414,25 @@ impl ProcessTableWidget for Painter { self.colours.text_style }; - let option_text = Spans::from(vec![ - Span::styled( + let option_text = vec![ + Text::raw("\n"), + Text::styled( format!("Case({})", if self.is_mac_os { "F1" } else { "Alt+C" }), case_style, ), - Span::from(" "), - Span::styled( + Text::raw(" "), + Text::styled( format!("Whole({})", if self.is_mac_os { "F2" } else { "Alt+W" }), whole_word_style, ), - Span::from(" "), - Span::styled( + Text::raw(" "), + Text::styled( format!("Regex({})", if self.is_mac_os { "F3" } else { "Alt+R" }), regex_style, ), - ]); + ]; - search_text.push(Spans::from(Span::styled( + search_text.push(Text::styled( if let Some(err) = &proc_widget_state .process_search_state .search_state @@ -439,8 +443,8 @@ impl ProcessTableWidget for Painter { "" }, self.colours.invalid_query_style, - ))); - search_text.push(option_text); + )); + search_text.extend(option_text); let current_border_style = if proc_widget_state .process_search_state @@ -459,17 +463,15 @@ impl ProcessTableWidget for Painter { let repeat_num = usize::from(draw_loc.width).saturating_sub(TITLE_BASE.chars().count() + 2); - Span::styled( - format!("{} Esc to close ", "─".repeat(repeat_num)), - current_border_style, - ) + format!("{} Esc to close ", "─".repeat(repeat_num)) } else { - Span::from(String::new()) + String::new() }; let process_search_block = if draw_border { Block::default() - .title(title) + .title(&title) + .title_style(current_border_style) .borders(Borders::ALL) .border_style(current_border_style) } else if is_on_widget { @@ -487,7 +489,7 @@ impl ProcessTableWidget for Painter { .split(draw_loc); f.render_widget( - Paragraph::new(search_text) + Paragraph::new(search_text.iter()) .block(process_search_block) .style(self.colours.text_style) .alignment(Alignment::Left), diff --git a/src/canvas/widgets/temp_table.rs b/src/canvas/widgets/temp_table.rs index 0b5bd42f..23822b68 100644 --- a/src/canvas/widgets/temp_table.rs +++ b/src/canvas/widgets/temp_table.rs @@ -5,7 +5,6 @@ use tui::{ backend::Backend, layout::{Constraint, Direction, Layout, Rect}, terminal::Frame, - text::Span, widgets::{Block, Borders, Row, Table}, }; @@ -79,28 +78,27 @@ impl TempTableWidget for Painter { let title = if app_state.is_expanded { const TITLE_BASE: &str = " Temperatures ── Esc to go back "; - Span::styled( - format!( - " Temperatures ─{}─ Esc to go back ", - "─".repeat( - usize::from(draw_loc.width) - .saturating_sub(TITLE_BASE.chars().count() + 2) - ) - ), - border_and_title_style, + format!( + " Temperatures ─{}─ Esc to go back ", + "─".repeat( + usize::from(draw_loc.width).saturating_sub(TITLE_BASE.chars().count() + 2) + ) ) } else if app_state.app_config_fields.use_basic_mode { - Span::from(String::new()) + String::new() } else { - Span::styled( - " Temperatures ".to_string(), - self.colours.widget_title_style, - ) + " Temperatures ".to_string() + }; + let title_style = if app_state.is_expanded { + border_and_title_style + } else { + self.colours.widget_title_style }; let temp_block = if draw_border { Block::default() - .title(title) + .title(&title) + .title_style(title_style) .borders(Borders::ALL) .border_style(border_and_title_style) } else if is_on_widget { diff --git a/src/constants.rs b/src/constants.rs index 572a6e5b..c2483aed 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -43,126 +43,126 @@ lazy_static! { // Help text pub const HELP_CONTENTS_TEXT: [&str; 7] = [ - "Press the corresponding numbers to jump to the section, or scroll:", - "1 - General", - "2 - CPU widget", - "3 - Process widget", - "4 - Process search widget", - "5 - Process sort widget", + "Press the corresponding numbers to jump to the section, or scroll:\n", + "1 - General\n", + "2 - CPU widget\n", + "3 - Process widget\n", + "4 - Process search widget\n", + "5 - Process sort widget\n", "6 - Battery widget", ]; pub const GENERAL_HELP_TEXT: [&str; 29] = [ - "1 - General", - "q, Ctrl-c Quit", - "Esc Close dialog windows, search, widgets, or exit expanded mode", - "Ctrl-r Reset display and any collected data", - "f Freeze/unfreeze updating with new data", - "Ctrl-Left, ", - "Shift-Left, Move widget selection left", - "H, A ", - "Ctrl-Right, ", - "Shift-Right, Move widget selection right", - "L, D ", - "Ctrl-Up, ", - "Shift-Up, Move widget selection up", - "K, W ", - "Ctrl-Down, ", - "Shift-Down, Move widget selection down", - "J, S ", - "Left, h Move left within widget", - "Down, j Move down within widget", - "Up, k Move up within widget", - "Right, l Move right within widget", - "? Open help menu", - "gg Jump to the first entry", - "G Jump to the last entry", - "e Expand the currently selected widget", - "+ Zoom in on chart (decrease time range)", - "- Zoom out on chart (increase time range)", - "= Reset zoom", + "1 - General\n", + "q, Ctrl-c Quit\n", + "Esc Close dialog windows, search, widgets, or exit expanded mode\n", + "Ctrl-r Reset display and any collected data\n", + "f Freeze/unfreeze updating with new data\n", + "Ctrl-Left, \n", + "Shift-Left, Move widget selection left\n", + "H, A \n", + "Ctrl-Right, \n", + "Shift-Right, Move widget selection right\n", + "L, D \n", + "Ctrl-Up, \n", + "Shift-Up, Move widget selection up\n", + "K, W \n", + "Ctrl-Down, \n", + "Shift-Down, Move widget selection down\n", + "J, S \n", + "Left, h Move left within widget\n", + "Down, j Move down within widget\n", + "Up, k Move up within widget\n", + "Right, l Move right within widget\n", + "? Open help menu\n", + "gg Jump to the first entry\n", + "G Jump to the last entry\n", + "e Expand the currently selected widget\n", + "+ Zoom in on chart (decrease time range)\n", + "- Zoom out on chart (increase time range)\n", + "= Reset zoom\n", "Mouse scroll Scroll through the tables or zoom in/out of charts by scrolling up/down", ]; pub const CPU_HELP_TEXT: [&str; 2] = [ - "2 - CPU widget", + "2 - CPU widget\n", "Mouse scroll Scrolling over an CPU core/average shows only that entry on the chart", ]; // TODO [Help]: Search in help? // TODO [Help]: Move to using tables for easier formatting? pub const PROCESS_HELP_TEXT: [&str; 11] = [ - "3 - Process widget", - "dd Kill the selected process", - "c Sort by CPU usage, press again to reverse sorting order", - "m Sort by memory usage, press again to reverse sorting order", - "p Sort by PID name, press again to reverse sorting order", - "n Sort by process name, press again to reverse sorting order", - "Tab Group/un-group processes with the same name", - "Ctrl-f, / Open process search widget", - "P Toggle between showing the full path or just the process name", - "s, F6 Open process sort widget", + "3 - Process widget\n", + "dd Kill the selected process\n", + "c Sort by CPU usage, press again to reverse sorting order\n", + "m Sort by memory usage, press again to reverse sorting order\n", + "p Sort by PID name, press again to reverse sorting order\n", + "n Sort by process name, press again to reverse sorting order\n", + "Tab Group/un-group processes with the same name\n", + "Ctrl-f, / Open process search widget\n", + "P Toggle between showing the full path or just the process name\n", + "s, F6 Open process sort widget\n", "I Invert current sort", ]; pub const SEARCH_HELP_TEXT: [&str; 43] = [ - "4 - Process search widget", - "Tab Toggle between searching for PID and name", - "Esc Close the search widget (retains the filter)", - "Ctrl-a Skip to the start of the search query", - "Ctrl-e Skip to the end of the search query", - "Ctrl-u Clear the current search query", - "Backspace Delete the character behind the cursor", - "Delete Delete the character at the cursor", - "Alt-c/F1 Toggle matching case", - "Alt-w/F2 Toggle matching the entire word", - "Alt-r/F3 Toggle using regex", - "Left, Alt-h Move cursor left", - "Right, Alt-l Move cursor right", - "", - "Search keywords:", - "pid ex: pid 825", - "cpu ex: cpu > 4.2", - "mem ex: mem < 4.2", - "read ex: read >= 1 b", - "write ex: write <= 1 tb", - "tread ex: tread = 1", - "twrite ex: twrite = 1", - "", - "Comparison operators:", - "= ex: cpu = 1", - "> ex: cpu > 1", - "< ex: cpu < 1", - ">= ex: cpu >= 1", - "<= ex: cpu <= 1", - "", - "Logical operators:", - "and/&&/ ex: btm and cpu > 1 and mem > 1", - "or/|| ex: btm or firefox", - "", - "Supported units:", - "B ex: read > 1 b", - "KB ex: read > 1 kb", - "MB ex: read > 1 mb", - "TB ex: read > 1 tb", - "KiB ex: read > 1 kib", - "MiB ex: read > 1 mib", - "GiB ex: read > 1 gib", + "4 - Process search widget\n", + "Tab Toggle between searching for PID and name\n", + "Esc Close the search widget (retains the filter)\n", + "Ctrl-a Skip to the start of the search query\n", + "Ctrl-e Skip to the end of the search query\n", + "Ctrl-u Clear the current search query\n", + "Backspace Delete the character behind the cursor\n", + "Delete Delete the character at the cursor\n", + "Alt-c/F1 Toggle matching case\n", + "Alt-w/F2 Toggle matching the entire word\n", + "Alt-r/F3 Toggle using regex\n", + "Left, Alt-h Move cursor left\n", + "Right, Alt-l Move cursor right\n", + "\n", + "Search keywords:\n", + "pid ex: pid 825\n", + "cpu ex: cpu > 4.2\n", + "mem ex: mem < 4.2\n", + "read ex: read >= 1 b\n", + "write ex: write <= 1 tb\n", + "tread ex: tread = 1\n", + "twrite ex: twrite = 1\n", + "\n", + "Comparison operators:\n", + "= ex: cpu = 1\n", + "> ex: cpu > 1\n", + "< ex: cpu < 1\n", + ">= ex: cpu >= 1\n", + "<= ex: cpu <= 1\n", + "\n", + "Logical operators:\n", + "and/&&/ ex: btm and cpu > 1 and mem > 1\n", + "or/|| ex: btm or firefox\n", + "\n", + "Supported units:\n", + "B ex: read > 1 b\n", + "KB ex: read > 1 kb\n", + "MB ex: read > 1 mb\n", + "TB ex: read > 1 tb\n", + "KiB ex: read > 1 kib\n", + "MiB ex: read > 1 mib\n", + "GiB ex: read > 1 gib\n", "TiB ex: read > 1 tib", ]; pub const SORT_HELP_TEXT: [&str; 6] = [ - "5 - Sort widget", - "Down, 'j' Scroll down in list", - "Up, 'k' Scroll up in list", - "Mouse scroll Scroll through sort widget", - "Esc Close the sort widget", + "5 - Sort widget\n", + "Down, 'j' Scroll down in list\n", + "Up, 'k' Scroll up in list\n", + "Mouse scroll Scroll through sort widget\n", + "Esc Close the sort widget\n", "Enter Sort by current selected column", ]; pub const BATTERY_HELP_TEXT: [&str; 3] = [ - "6 - Battery widget", - "Left Go to previous battery", + "6 - Battery widget\n", + "Left Go to previous battery\n", "Right Go to next battery", ];