refactor: tui-rs 0.11.0 refactor (#253)
Refactors tui-rs usage to the new 0.11.0 release. This release also fixes the highlighting bug from #249, and now, expanding a widget no longer overrides the widget title colour. This commit also introduces #255, but that seems to be easy to bandaid so hopefully it will get fixed soon?
This commit is contained in:
parent
6db76029e2
commit
750d8f3cb7
|
@ -19,8 +19,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
- [#223](https://github.com/ClementTsang/bottom/pull/223): Add tree mode for processes.
|
||||
|
||||
- [](): Add in-app configuration.
|
||||
|
||||
### Changes
|
||||
|
||||
- [#213](https://github.com/ClementTsang/bottom/pull/213), [#214](https://github.com/ClementTsang/bottom/pull/214): Updated help descriptions, added auto-complete generation.
|
||||
|
@ -33,6 +31,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
- [#224](https://github.com/ClementTsang/bottom/pull/224): Implements sorting by count. It previously did absolutely nothing.
|
||||
|
||||
- [#253](https://github.com/ClementTsang/bottom/pull/253): Fix highlighted entries being stuck in another colour when the widget is not selected.
|
||||
|
||||
- [#253](https://github.com/ClementTsang/bottom/pull/253): Expanding a widget no longer overrides the widget title colour.
|
||||
|
||||
## [0.4.7] - 2020-08-26
|
||||
|
||||
### Bug Fixes
|
||||
|
|
|
@ -1363,15 +1363,13 @@ checksum = "a7f741b240f1a48843f9b8e0444fb55fb2a4ff67293b50a9179dfd5ea67f8d41"
|
|||
|
||||
[[package]]
|
||||
name = "tui"
|
||||
version = "0.9.5"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9533d39bef0ae8f510e8a99d78702e68d1bbf0b98a78ec9740509d287010ae1e"
|
||||
checksum = "36626dee5ede9fd34015e9fb4fd7eedf3f3d05bdf1436aaef15b7d0a24233778"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cassowary",
|
||||
"crossterm",
|
||||
"either",
|
||||
"itertools",
|
||||
"unicode-segmentation",
|
||||
"unicode-width",
|
||||
]
|
||||
|
|
|
@ -42,7 +42,8 @@ serde = {version = "1.0", features = ["derive"] }
|
|||
sysinfo = "0.15.1"
|
||||
thiserror = "1.0.20"
|
||||
toml = "0.5.6"
|
||||
tui = {version = "0.9.5", features = ["crossterm"], default-features = false }
|
||||
tui = {version = "0.11.0", features = ["crossterm"], default-features = false }
|
||||
# tui = {version = "0.11.0", features = ["crossterm"], default-features = false, path="../tui-rs" }
|
||||
typed-builder = "0.7.0"
|
||||
unicode-segmentation = "1.6.0"
|
||||
unicode-width = "0.1"
|
||||
|
|
|
@ -1276,6 +1276,7 @@ impl App {
|
|||
}
|
||||
|
||||
/// Call this whenever the config value is updated!
|
||||
#[allow(dead_code)] //FIXME: Remove this
|
||||
fn update_config_file(&mut self) -> anyhow::Result<()> {
|
||||
if self.app_config_fields.no_write {
|
||||
// Don't write!
|
||||
|
|
|
@ -5,7 +5,7 @@ use std::collections::HashMap;
|
|||
use tui::{
|
||||
backend::Backend,
|
||||
layout::{Constraint, Direction, Layout, Rect},
|
||||
widgets::Text,
|
||||
text::{Span, Spans},
|
||||
Frame, Terminal,
|
||||
};
|
||||
|
||||
|
@ -63,7 +63,7 @@ pub struct Painter {
|
|||
pub colours: CanvasColours,
|
||||
height: u16,
|
||||
width: u16,
|
||||
styled_help_text: Vec<Text<'static>>,
|
||||
styled_help_text: Vec<Spans<'static>>,
|
||||
is_mac_os: bool,
|
||||
row_constraints: Vec<Constraint>,
|
||||
col_constraints: Vec<Vec<Constraint>>,
|
||||
|
@ -289,28 +289,27 @@ impl Painter {
|
|||
styled_help_spans.extend(
|
||||
section
|
||||
.iter()
|
||||
.map(|&text| Text::styled(text, self.colours.text_style))
|
||||
.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(Text::raw("\n\n"));
|
||||
styled_help_spans.push(Span::raw(""));
|
||||
styled_help_spans
|
||||
.push(Text::styled(section[0], self.colours.table_header_style));
|
||||
.push(Span::styled(section[0], self.colours.table_header_style));
|
||||
styled_help_spans.extend(
|
||||
section[1..]
|
||||
.iter()
|
||||
.map(|&text| Text::styled(text, self.colours.text_style))
|
||||
.map(|&text| Span::styled(text, self.colours.text_style))
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// self.styled_help_text = styled_help_spans.into_iter().map(Spans::from).collect();
|
||||
self.styled_help_text = styled_help_spans;
|
||||
self.styled_help_text = styled_help_spans.into_iter().map(Spans::from).collect();
|
||||
}
|
||||
|
||||
// FIXME: [CONFIG] write this, should call painter init and any changed colour functions...
|
||||
|
|
|
@ -2,7 +2,8 @@ use tui::{
|
|||
backend::Backend,
|
||||
layout::{Alignment, Constraint, Direction, Layout, Rect},
|
||||
terminal::Frame,
|
||||
widgets::{Block, Borders, Paragraph, Text},
|
||||
text::{Span, Spans, Text},
|
||||
widgets::{Block, Borders, Paragraph, Wrap},
|
||||
};
|
||||
|
||||
use crate::{app::App, canvas::Painter};
|
||||
|
@ -11,46 +12,46 @@ 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<Vec<Text<'_>>>;
|
||||
fn get_dd_spans(&self, app_state: &App) -> Option<Text<'_>>;
|
||||
|
||||
fn draw_dd_dialog<B: Backend>(
|
||||
&self, f: &mut Frame<'_, B>, dd_text: Option<Vec<Text<'_>>>, app_state: &mut App,
|
||||
draw_loc: Rect,
|
||||
&self, f: &mut Frame<'_, B>, dd_text: Option<Text<'_>>, app_state: &mut App, draw_loc: Rect,
|
||||
) -> bool;
|
||||
}
|
||||
|
||||
impl KillDialog for Painter {
|
||||
fn get_dd_spans(&self, app_state: &App) -> Option<Vec<Text<'_>>> {
|
||||
fn get_dd_spans(&self, app_state: &App) -> Option<Text<'_>> {
|
||||
if let Some(dd_err) = &app_state.dd_err {
|
||||
return Some(vec![
|
||||
Text::raw("\n"),
|
||||
Text::raw(format!("Failed to kill process.\n{}\n", dd_err)),
|
||||
Text::raw("Please press ENTER or ESC to close this dialog."),
|
||||
]);
|
||||
return Some(Text::from(vec![
|
||||
Spans::default(),
|
||||
Spans::from("Failed to kill process."),
|
||||
Spans::from(dd_err.clone()),
|
||||
Spans::from("Please press ENTER or ESC to close this dialog."),
|
||||
]));
|
||||
} 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(vec![
|
||||
Text::raw("\n"),
|
||||
return Some(Text::from(vec![
|
||||
Spans::from(""),
|
||||
if app_state.is_grouped(app_state.current_widget.widget_id) {
|
||||
if to_kill_processes.1.len() != 1 {
|
||||
Text::raw(format!(
|
||||
Spans::from(format!(
|
||||
"Kill {} processes with the name \"{}\"? Press ENTER to confirm.",
|
||||
to_kill_processes.1.len(),
|
||||
to_kill_processes.0
|
||||
))
|
||||
} else {
|
||||
Text::raw(format!(
|
||||
Spans::from(format!(
|
||||
"Kill 1 process with the name \"{}\"? Press ENTER to confirm.",
|
||||
to_kill_processes.0
|
||||
))
|
||||
}
|
||||
} else {
|
||||
Text::raw(format!(
|
||||
Spans::from(format!(
|
||||
"Kill process \"{}\" with PID {}? Press ENTER to confirm.",
|
||||
to_kill_processes.0, first_pid
|
||||
))
|
||||
},
|
||||
]);
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -58,63 +59,44 @@ impl KillDialog for Painter {
|
|||
}
|
||||
|
||||
fn draw_dd_dialog<B: Backend>(
|
||||
&self, f: &mut Frame<'_, B>, dd_text: Option<Vec<Text<'_>>>, app_state: &mut App,
|
||||
draw_loc: Rect,
|
||||
&self, f: &mut Frame<'_, B>, dd_text: Option<Text<'_>>, app_state: &mut 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() {
|
||||
format!(
|
||||
" Error ─{}─ Esc to close ",
|
||||
"─".repeat(
|
||||
usize::from(draw_loc.width)
|
||||
.saturating_sub(DD_ERROR_BASE.chars().count() + 2)
|
||||
)
|
||||
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,
|
||||
)
|
||||
} else {
|
||||
format!(
|
||||
" Confirm Kill Process ─{}─ Esc to close ",
|
||||
"─".repeat(
|
||||
usize::from(draw_loc.width).saturating_sub(DD_BASE.chars().count() + 2)
|
||||
)
|
||||
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,
|
||||
)
|
||||
};
|
||||
|
||||
f.render_widget(
|
||||
Paragraph::new(dd_text.iter())
|
||||
Paragraph::new(dd_text)
|
||||
.block(
|
||||
Block::default()
|
||||
.title(&dd_title)
|
||||
.title_style(self.colours.border_style)
|
||||
.title(dd_title)
|
||||
.style(self.colours.border_style)
|
||||
.borders(Borders::ALL)
|
||||
.border_style(self.colours.border_style),
|
||||
)
|
||||
.style(self.colours.text_style)
|
||||
.alignment(Alignment::Center)
|
||||
.wrap(true),
|
||||
.wrap(Wrap { trim: true }),
|
||||
draw_loc,
|
||||
);
|
||||
|
||||
|
@ -135,13 +117,13 @@ impl KillDialog for Painter {
|
|||
if let Some(button_draw_loc) = split_draw_loc.get(1) {
|
||||
let (yes_button, no_button) = if app_state.delete_dialog_state.is_on_yes {
|
||||
(
|
||||
Text::styled("Yes", self.colours.currently_selected_text_style),
|
||||
Text::raw("No"),
|
||||
Span::styled("Yes", self.colours.currently_selected_text_style),
|
||||
Span::raw("No"),
|
||||
)
|
||||
} else {
|
||||
(
|
||||
Text::raw("Yes"),
|
||||
Text::styled("No", self.colours.currently_selected_text_style),
|
||||
Span::raw("Yes"),
|
||||
Span::styled("No", self.colours.currently_selected_text_style),
|
||||
)
|
||||
};
|
||||
|
||||
|
@ -158,13 +140,13 @@ impl KillDialog for Painter {
|
|||
.split(*button_draw_loc);
|
||||
|
||||
f.render_widget(
|
||||
Paragraph::new([yes_button].iter())
|
||||
Paragraph::new(yes_button)
|
||||
.block(Block::default())
|
||||
.alignment(Alignment::Right),
|
||||
button_layout[0],
|
||||
);
|
||||
f.render_widget(
|
||||
Paragraph::new([no_button].iter())
|
||||
Paragraph::new(no_button)
|
||||
.block(Block::default())
|
||||
.alignment(Alignment::Left),
|
||||
button_layout[2],
|
||||
|
|
|
@ -5,7 +5,8 @@ use tui::{
|
|||
backend::Backend,
|
||||
layout::{Alignment, Rect},
|
||||
terminal::Frame,
|
||||
widgets::{Block, Borders, Paragraph},
|
||||
text::Span,
|
||||
widgets::{Block, Borders, Paragraph, Wrap},
|
||||
};
|
||||
|
||||
const HELP_BASE: &str = " Help ── Esc to close ";
|
||||
|
@ -21,19 +22,14 @@ impl HelpDialog for Painter {
|
|||
fn draw_help_dialog<B: Backend>(
|
||||
&self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect,
|
||||
) {
|
||||
// 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))
|
||||
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,
|
||||
);
|
||||
|
||||
if app_state.should_get_widget_bounds() {
|
||||
|
@ -99,24 +95,24 @@ impl HelpDialog for Painter {
|
|||
}
|
||||
|
||||
f.render_widget(
|
||||
Paragraph::new(self.styled_help_text.iter())
|
||||
Paragraph::new(self.styled_help_text.clone())
|
||||
.block(
|
||||
Block::default()
|
||||
.title(&help_title)
|
||||
.title_style(self.colours.border_style)
|
||||
.title(help_title)
|
||||
.style(self.colours.border_style)
|
||||
.borders(Borders::ALL)
|
||||
.border_style(self.colours.border_style),
|
||||
)
|
||||
.style(self.colours.text_style)
|
||||
.alignment(Alignment::Left)
|
||||
.wrap(true)
|
||||
.scroll(
|
||||
.wrap(Wrap { trim: true })
|
||||
.scroll((
|
||||
app_state
|
||||
.help_dialog_state
|
||||
.scroll_state
|
||||
.current_scroll_index,
|
||||
),
|
||||
0,
|
||||
)),
|
||||
draw_loc,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#![allow(unused_variables)] //FIXME: Remove this
|
||||
#![allow(unused_imports)] //FIXME: Remove this
|
||||
use crate::{app::App, canvas::Painter, constants};
|
||||
use tui::{
|
||||
backend::Backend,
|
||||
|
@ -6,6 +8,7 @@ use tui::{
|
|||
layout::Layout,
|
||||
layout::{Alignment, Rect},
|
||||
terminal::Frame,
|
||||
text::Span,
|
||||
widgets::{Block, Borders, Paragraph},
|
||||
};
|
||||
|
||||
|
@ -20,8 +23,7 @@ impl ConfigScreen for Painter {
|
|||
&self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect,
|
||||
) {
|
||||
let config_block = Block::default()
|
||||
.title(&" Config ")
|
||||
.title_style(self.colours.border_style)
|
||||
.title(" Config ") // FIXME: [Config] missing title styling
|
||||
.style(self.colours.border_style)
|
||||
.borders(Borders::ALL)
|
||||
.border_style(self.colours.border_style);
|
||||
|
|
|
@ -7,7 +7,9 @@ use tui::{
|
|||
backend::Backend,
|
||||
layout::{Alignment, Constraint, Direction, Layout, Rect},
|
||||
terminal::Frame,
|
||||
widgets::{Block, Paragraph, Text},
|
||||
text::Span,
|
||||
text::Spans,
|
||||
widgets::{Block, Paragraph},
|
||||
};
|
||||
|
||||
pub trait BasicTableArrows {
|
||||
|
@ -97,13 +99,19 @@ impl BasicTableArrows for Painter {
|
|||
usize::from(draw_loc.width).saturating_sub(6 + left_name.len() + right_name.len());
|
||||
|
||||
let left_arrow_text = vec![
|
||||
Text::raw("\n"),
|
||||
Text::styled(format!("◄ {}", left_name), self.colours.text_style),
|
||||
Spans::default(),
|
||||
Spans::from(Span::styled(
|
||||
format!("◄ {}", left_name),
|
||||
self.colours.text_style,
|
||||
)),
|
||||
];
|
||||
|
||||
let right_arrow_text = vec![
|
||||
Text::raw("\n"),
|
||||
Text::styled(format!("{} ►", right_name), self.colours.text_style),
|
||||
Spans::default(),
|
||||
Spans::from(Span::styled(
|
||||
format!("{} ►", right_name),
|
||||
self.colours.text_style,
|
||||
)),
|
||||
];
|
||||
|
||||
let margined_draw_loc = Layout::default()
|
||||
|
@ -120,11 +128,11 @@ impl BasicTableArrows for Painter {
|
|||
.split(draw_loc);
|
||||
|
||||
f.render_widget(
|
||||
Paragraph::new(left_arrow_text.iter()).block(Block::default()),
|
||||
Paragraph::new(left_arrow_text).block(Block::default()),
|
||||
margined_draw_loc[0],
|
||||
);
|
||||
f.render_widget(
|
||||
Paragraph::new(right_arrow_text.iter())
|
||||
Paragraph::new(right_arrow_text)
|
||||
.block(Block::default())
|
||||
.alignment(Alignment::Right),
|
||||
margined_draw_loc[2],
|
||||
|
|
|
@ -8,8 +8,10 @@ use tui::{
|
|||
backend::Backend,
|
||||
layout::{Constraint, Direction, Layout, Rect},
|
||||
terminal::Frame,
|
||||
widgets::{Block, Borders, Paragraph, Row, Table, Tabs, Text},
|
||||
text::{Span, Spans},
|
||||
widgets::{Block, Borders, Paragraph, Row, Table, Tabs},
|
||||
};
|
||||
use unicode_segmentation::UnicodeSegmentation;
|
||||
|
||||
pub trait BatteryDisplayWidget {
|
||||
fn draw_battery_display<B: Backend>(
|
||||
|
@ -28,53 +30,38 @@ impl BatteryDisplayWidget for Painter {
|
|||
app_state.battery_state.widget_states.get_mut(&widget_id)
|
||||
{
|
||||
let is_on_widget = widget_id == app_state.current_widget.widget_id;
|
||||
let border_and_title_style = if is_on_widget {
|
||||
let border_style = if is_on_widget {
|
||||
self.colours.highlighted_border_style
|
||||
} else {
|
||||
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 ";
|
||||
|
||||
format!(
|
||||
" Battery ─{}─ Esc to go back ",
|
||||
"─".repeat(
|
||||
usize::from(draw_loc.width).saturating_sub(TITLE_BASE.chars().count() + 2)
|
||||
)
|
||||
)
|
||||
Spans::from(vec![
|
||||
Span::styled(" Battery ".to_string(), self.colours.widget_title_style),
|
||||
Span::styled(
|
||||
format!(
|
||||
"─{}─ Esc to go back ",
|
||||
"─".repeat(usize::from(draw_loc.width).saturating_sub(
|
||||
UnicodeSegmentation::graphemes(TITLE_BASE, true).count() + 2
|
||||
))
|
||||
),
|
||||
border_style,
|
||||
),
|
||||
])
|
||||
} else {
|
||||
" Battery ".to_string()
|
||||
};
|
||||
|
||||
let title_style = if app_state.is_expanded {
|
||||
border_and_title_style
|
||||
} else {
|
||||
self.colours.widget_title_style
|
||||
Spans::from(Span::styled(
|
||||
" Battery ".to_string(),
|
||||
self.colours.widget_title_style,
|
||||
))
|
||||
};
|
||||
|
||||
let battery_block = if draw_border {
|
||||
Block::default()
|
||||
.title(&title)
|
||||
.title_style(title_style)
|
||||
.title(title)
|
||||
.borders(Borders::ALL)
|
||||
.border_style(border_and_title_style)
|
||||
.border_style(border_style)
|
||||
} else if is_on_widget {
|
||||
Block::default()
|
||||
.borders(*SIDE_BORDERS)
|
||||
|
@ -83,38 +70,12 @@ 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::<Vec<_>>(),
|
||||
// // )
|
||||
// Tabs::default()
|
||||
// .titles(
|
||||
// app_state
|
||||
// .canvas_data
|
||||
// .battery_data
|
||||
// .iter()
|
||||
// .map(|battery| &battery.battery_name)
|
||||
// .collect::<Vec<_>>()
|
||||
// .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,
|
||||
// );
|
||||
|
||||
let margined_draw_loc = Layout::default()
|
||||
.constraints([Constraint::Percentage(100)].as_ref())
|
||||
.horizontal_margin(if is_on_widget || draw_border { 0 } else { 1 })
|
||||
.direction(Direction::Horizontal)
|
||||
.split(draw_loc)[0];
|
||||
let battery_names = app_state
|
||||
.canvas_data
|
||||
.battery_data
|
||||
.iter()
|
||||
.map(|battery| &battery.battery_name)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let tab_draw_loc = Layout::default()
|
||||
.constraints(
|
||||
|
@ -128,6 +89,27 @@ impl BatteryDisplayWidget for Painter {
|
|||
.direction(Direction::Vertical)
|
||||
.split(draw_loc)[1];
|
||||
|
||||
f.render_widget(
|
||||
Tabs::new(
|
||||
battery_names
|
||||
.iter()
|
||||
.map(|name| Spans::from((*name).clone()))
|
||||
.collect::<Vec<_>>(),
|
||||
)
|
||||
.block(Block::default())
|
||||
.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),
|
||||
tab_draw_loc,
|
||||
);
|
||||
|
||||
let margined_draw_loc = Layout::default()
|
||||
.constraints([Constraint::Percentage(100)].as_ref())
|
||||
.horizontal_margin(if is_on_widget || draw_border { 0 } else { 1 })
|
||||
.direction(Direction::Horizontal)
|
||||
.split(draw_loc)[0];
|
||||
|
||||
if let Some(battery_details) = app_state
|
||||
.canvas_data
|
||||
.battery_data
|
||||
|
@ -189,45 +171,15 @@ impl BatteryDisplayWidget for Painter {
|
|||
);
|
||||
} else {
|
||||
f.render_widget(
|
||||
Paragraph::new(
|
||||
[Text::styled(
|
||||
"No data found for this battery",
|
||||
self.colours.text_style,
|
||||
)]
|
||||
.iter(),
|
||||
)
|
||||
Paragraph::new(Span::styled(
|
||||
"No data found for this battery",
|
||||
self.colours.text_style,
|
||||
))
|
||||
.block(battery_block),
|
||||
margined_draw_loc,
|
||||
);
|
||||
}
|
||||
|
||||
let battery_names = app_state
|
||||
.canvas_data
|
||||
.battery_data
|
||||
.iter()
|
||||
.map(|battery| &battery.battery_name)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
// 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::<Vec<_>>(),
|
||||
// )
|
||||
Tabs::default()
|
||||
.titles(battery_names.as_ref())
|
||||
.block(Block::default())
|
||||
.divider(tui::symbols::line::VERTICAL)
|
||||
.style(self.colours.text_style)
|
||||
.highlight_style(self.colours.currently_selected_text_style) //FIXME: [HIGHLIGHT] THIS IS BROKEN ON TUI's SIDE, override this with your own style...
|
||||
.select(battery_widget_state.currently_selected_battery_index),
|
||||
tab_draw_loc,
|
||||
);
|
||||
|
||||
if should_get_widget_bounds {
|
||||
// Tab wizardry
|
||||
if !battery_names.is_empty() {
|
||||
|
|
|
@ -11,7 +11,8 @@ use tui::{
|
|||
backend::Backend,
|
||||
layout::{Constraint, Direction, Layout, Rect},
|
||||
terminal::Frame,
|
||||
widgets::{Block, Paragraph, Text},
|
||||
text::{Span, Spans},
|
||||
widgets::{Block, Paragraph},
|
||||
};
|
||||
|
||||
pub trait CpuBasicWidget {
|
||||
|
@ -76,7 +77,7 @@ impl CpuBasicWidget for Painter {
|
|||
|
||||
let num_bars = calculate_basic_use_bars(use_percentage, bar_length);
|
||||
format!(
|
||||
"{:3}[{}{}{:3.0}%]\n",
|
||||
"{:3}[{}{}{:3.0}%]",
|
||||
if app_state.app_config_fields.show_average_cpu {
|
||||
if cpu_index == 0 {
|
||||
"AVG".to_string()
|
||||
|
@ -108,16 +109,11 @@ 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
|
||||
// [cpu_index % self.colours.cpu_colour_styles.len()],
|
||||
// })
|
||||
Text::styled(
|
||||
&cpu_bars[cpu_index],
|
||||
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()],
|
||||
)
|
||||
})
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
|
@ -130,7 +126,7 @@ impl CpuBasicWidget for Painter {
|
|||
.split(*chunk)[0];
|
||||
|
||||
f.render_widget(
|
||||
Paragraph::new(cpu_column.iter()).block(Block::default()),
|
||||
Paragraph::new(cpu_column).block(Block::default()),
|
||||
margined_loc,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use lazy_static::lazy_static;
|
||||
use std::borrow::Cow;
|
||||
use unicode_segmentation::UnicodeSegmentation;
|
||||
|
||||
use crate::{
|
||||
app::{layout_manager::WidgetDirection, App},
|
||||
|
@ -16,6 +17,8 @@ use tui::{
|
|||
layout::{Constraint, Direction, Layout, Rect},
|
||||
symbols::Marker,
|
||||
terminal::Frame,
|
||||
text::Span,
|
||||
text::Spans,
|
||||
widgets::{Axis, Block, Borders, Chart, Dataset, Row, Table},
|
||||
};
|
||||
|
||||
|
@ -135,17 +138,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![
|
||||
// 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 = 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 = [
|
||||
format!("{}s", cpu_widget_state.current_display_time / 1000),
|
||||
"0s".to_string(),
|
||||
let y_axis_labels = vec![
|
||||
Span::styled("0%", self.colours.graph_style),
|
||||
Span::styled("100%", self.colours.graph_style),
|
||||
];
|
||||
|
||||
let x_axis = if app_state.app_config_fields.hide_time
|
||||
|
@ -160,8 +163,7 @@ 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_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])
|
||||
|
@ -172,15 +174,13 @@ 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_style(self.colours.graph_style)
|
||||
.labels(display_time_labels)
|
||||
};
|
||||
|
||||
let y_axis = Axis::default()
|
||||
.style(self.colours.graph_style)
|
||||
.bounds([0.0, 100.5])
|
||||
.labels_style(self.colours.graph_style)
|
||||
.labels(&["0%", "100%"]);
|
||||
.labels(y_axis_labels);
|
||||
|
||||
let use_dot = app_state.app_config_fields.use_dot;
|
||||
let show_avg_cpu = app_state.app_config_fields.show_average_cpu;
|
||||
|
@ -228,32 +228,36 @@ impl CpuGraphWidget for Painter {
|
|||
vec![]
|
||||
};
|
||||
|
||||
let border_style = if app_state.current_widget.widget_id == widget_id {
|
||||
let is_on_widget = widget_id == app_state.current_widget.widget_id;
|
||||
let border_style = if is_on_widget {
|
||||
self.colours.highlighted_border_style
|
||||
} else {
|
||||
self.colours.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
|
||||
let title = if app_state.is_expanded {
|
||||
const TITLE_BASE: &str = " CPU ── Esc to go back ";
|
||||
Spans::from(vec![
|
||||
Span::styled(" CPU ", self.colours.widget_title_style),
|
||||
Span::styled(
|
||||
format!(
|
||||
"─{}─ Esc to go back ",
|
||||
"─".repeat(usize::from(draw_loc.width).saturating_sub(
|
||||
UnicodeSegmentation::graphemes(TITLE_BASE, true).count() + 2
|
||||
))
|
||||
),
|
||||
border_style,
|
||||
),
|
||||
])
|
||||
} else {
|
||||
self.colours.widget_title_style
|
||||
Spans::from(Span::styled(" CPU ", self.colours.widget_title_style))
|
||||
};
|
||||
|
||||
f.render_widget(
|
||||
// Chart::new(dataset_vector)
|
||||
Chart::default()
|
||||
.datasets(&dataset_vector)
|
||||
Chart::new(dataset_vector)
|
||||
.block(
|
||||
Block::default()
|
||||
.title(title)
|
||||
.title_style(title_style)
|
||||
.borders(Borders::ALL)
|
||||
.border_style(border_style),
|
||||
)
|
||||
|
|
|
@ -3,6 +3,8 @@ use tui::{
|
|||
backend::Backend,
|
||||
layout::{Constraint, Direction, Layout, Rect},
|
||||
terminal::Frame,
|
||||
text::Span,
|
||||
text::Spans,
|
||||
widgets::{Block, Borders, Row, Table},
|
||||
};
|
||||
|
||||
|
@ -139,19 +141,13 @@ impl DiskTableWidget for Painter {
|
|||
let first_n = graphemes
|
||||
[..(*calculated_col_width as usize - 1)]
|
||||
.concat();
|
||||
Cow::Owned(format!("{}…", first_n))
|
||||
} else {
|
||||
Cow::Borrowed(entry)
|
||||
return Cow::Owned(format!("{}…", first_n));
|
||||
}
|
||||
} else {
|
||||
Cow::Borrowed(entry)
|
||||
}
|
||||
} else {
|
||||
Cow::Borrowed(entry)
|
||||
}
|
||||
} else {
|
||||
Cow::Borrowed(entry)
|
||||
}
|
||||
|
||||
Cow::Borrowed(entry)
|
||||
},
|
||||
);
|
||||
|
||||
|
@ -159,7 +155,7 @@ impl DiskTableWidget for Painter {
|
|||
});
|
||||
|
||||
// TODO: This seems to be bugged? The selected text style gets "stuck"? I think this gets fixed with tui 0.10?
|
||||
let (border_and_title_style, highlight_style) = if is_on_widget {
|
||||
let (border_style, highlight_style) = if is_on_widget {
|
||||
(
|
||||
self.colours.highlighted_border_style,
|
||||
self.colours.currently_selected_text_style,
|
||||
|
@ -168,50 +164,29 @@ 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 ";
|
||||
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 {
|
||||
String::new()
|
||||
Spans::from(vec![
|
||||
Span::styled(" Disk ", self.colours.widget_title_style),
|
||||
Span::styled(
|
||||
format!(
|
||||
"─{}─ Esc to go back, ",
|
||||
"─".repeat(usize::from(draw_loc.width).saturating_sub(
|
||||
UnicodeSegmentation::graphemes(TITLE_BASE, true).count() + 2
|
||||
))
|
||||
),
|
||||
border_style,
|
||||
),
|
||||
])
|
||||
} else {
|
||||
" Disk ".to_string()
|
||||
};
|
||||
|
||||
let title_style = if app_state.is_expanded {
|
||||
border_and_title_style
|
||||
} else {
|
||||
self.colours.widget_title_style
|
||||
Spans::from(Span::styled(" Disk ", self.colours.widget_title_style))
|
||||
};
|
||||
|
||||
let disk_block = if draw_border {
|
||||
Block::default()
|
||||
.title(&title)
|
||||
.title_style(title_style)
|
||||
.title(title)
|
||||
.borders(Borders::ALL)
|
||||
.border_style(border_and_title_style)
|
||||
.border_style(border_style)
|
||||
} else if is_on_widget {
|
||||
Block::default()
|
||||
.borders(*SIDE_BORDERS)
|
||||
|
|
|
@ -8,7 +8,9 @@ use tui::{
|
|||
backend::Backend,
|
||||
layout::{Constraint, Layout, Rect},
|
||||
terminal::Frame,
|
||||
widgets::{Block, Paragraph, Text},
|
||||
text::Span,
|
||||
text::Spans,
|
||||
widgets::{Block, Paragraph},
|
||||
};
|
||||
|
||||
pub trait MemBasicWidget {
|
||||
|
@ -106,13 +108,13 @@ impl MemBasicWidget for Painter {
|
|||
)
|
||||
};
|
||||
|
||||
let mem_text = [
|
||||
Text::styled(mem_label, self.colours.ram_style),
|
||||
Text::styled(swap_label, self.colours.swap_style),
|
||||
let mem_text = vec![
|
||||
Spans::from(Span::styled(mem_label, self.colours.ram_style)),
|
||||
Spans::from(Span::styled(swap_label, self.colours.swap_style)),
|
||||
];
|
||||
|
||||
f.render_widget(
|
||||
Paragraph::new(mem_text.iter()).block(Block::default()),
|
||||
Paragraph::new(mem_text).block(Block::default()),
|
||||
margined_loc[0],
|
||||
);
|
||||
|
||||
|
|
|
@ -5,8 +5,11 @@ use tui::{
|
|||
layout::{Constraint, Rect},
|
||||
symbols::Marker,
|
||||
terminal::Frame,
|
||||
text::Span,
|
||||
text::Spans,
|
||||
widgets::{Axis, Block, Borders, Chart, Dataset},
|
||||
};
|
||||
use unicode_segmentation::UnicodeSegmentation;
|
||||
|
||||
pub trait MemGraphWidget {
|
||||
fn draw_memory_graph<B: Backend>(
|
||||
|
@ -22,10 +25,18 @@ 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 = [
|
||||
format!("{}s", mem_widget_state.current_display_time / 1000),
|
||||
"0s".to_string(),
|
||||
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 y_axis_label = vec![
|
||||
Span::styled("0%", self.colours.graph_style),
|
||||
Span::styled("100%", self.colours.graph_style),
|
||||
];
|
||||
|
||||
let x_axis = if app_state.app_config_fields.hide_time
|
||||
|| (app_state.app_config_fields.autohide_time
|
||||
&& mem_widget_state.autohide_timer.is_none())
|
||||
|
@ -38,8 +49,7 @@ 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_style(self.colours.graph_style)
|
||||
.labels(display_time_labels)
|
||||
} else {
|
||||
mem_widget_state.autohide_timer = None;
|
||||
Axis::default().bounds([-(mem_widget_state.current_display_time as f64), 0.0])
|
||||
|
@ -50,15 +60,13 @@ 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_style(self.colours.graph_style)
|
||||
.labels(display_time_labels)
|
||||
};
|
||||
|
||||
let y_axis = Axis::default()
|
||||
.style(self.colours.graph_style)
|
||||
.bounds([0.0, 100.5])
|
||||
.labels(&["0%", "100%"])
|
||||
.labels_style(self.colours.graph_style);
|
||||
.labels(y_axis_label);
|
||||
|
||||
let mut mem_canvas_vec: Vec<Dataset<'_>> = vec![];
|
||||
let mem_label = format!(
|
||||
|
@ -96,31 +104,39 @@ impl MemGraphWidget for Painter {
|
|||
.graph_type(tui::widgets::GraphType::Line),
|
||||
);
|
||||
|
||||
let title = if app_state.is_expanded {
|
||||
const TITLE_BASE: &str = " Memory ── Esc to go back ";
|
||||
format!(
|
||||
" Memory ─{}─ Esc to go back ",
|
||||
"─".repeat(
|
||||
usize::from(draw_loc.width).saturating_sub(TITLE_BASE.chars().count() + 2)
|
||||
)
|
||||
)
|
||||
} else {
|
||||
" Memory ".to_string()
|
||||
};
|
||||
let title_style = if app_state.is_expanded {
|
||||
let is_on_widget = widget_id == app_state.current_widget.widget_id;
|
||||
let border_style = if is_on_widget {
|
||||
self.colours.highlighted_border_style
|
||||
} else {
|
||||
self.colours.widget_title_style
|
||||
self.colours.border_style
|
||||
};
|
||||
|
||||
let title = if app_state.is_expanded {
|
||||
const TITLE_BASE: &str = " Memory ── Esc to go back ";
|
||||
Spans::from(vec![
|
||||
Span::styled(" Memory ", self.colours.widget_title_style),
|
||||
Span::styled(
|
||||
format!(
|
||||
"─{}─ Esc to go back ",
|
||||
"─".repeat(usize::from(draw_loc.width).saturating_sub(
|
||||
UnicodeSegmentation::graphemes(TITLE_BASE, true).count() + 2
|
||||
))
|
||||
),
|
||||
border_style,
|
||||
),
|
||||
])
|
||||
} else {
|
||||
Spans::from(Span::styled(
|
||||
" Memory ".to_string(),
|
||||
self.colours.widget_title_style,
|
||||
))
|
||||
};
|
||||
|
||||
f.render_widget(
|
||||
// Chart::new(mem_canvas_vec)
|
||||
Chart::default()
|
||||
.datasets(&mem_canvas_vec)
|
||||
Chart::new(mem_canvas_vec)
|
||||
.block(
|
||||
Block::default()
|
||||
.title(&title)
|
||||
.title_style(title_style)
|
||||
.title(title)
|
||||
.borders(Borders::ALL)
|
||||
.border_style(if app_state.current_widget.widget_id == widget_id {
|
||||
self.colours.highlighted_border_style
|
||||
|
|
|
@ -4,7 +4,8 @@ use tui::{
|
|||
backend::Backend,
|
||||
layout::{Constraint, Direction, Layout, Rect},
|
||||
terminal::Frame,
|
||||
widgets::{Block, Paragraph, Text},
|
||||
text::{Span, Spans, },
|
||||
widgets::{Block, Paragraph},
|
||||
};
|
||||
|
||||
pub trait NetworkBasicWidget {
|
||||
|
@ -43,28 +44,25 @@ impl NetworkBasicWidget for Painter {
|
|||
);
|
||||
}
|
||||
|
||||
let rx_label = format!("RX: {}\n", &app_state.canvas_data.rx_display);
|
||||
let rx_label = format!("RX: {}", &app_state.canvas_data.rx_display);
|
||||
let tx_label = format!("TX: {}", &app_state.canvas_data.tx_display);
|
||||
let total_rx_label = format!("Total RX: {}\n", &app_state.canvas_data.total_rx_display);
|
||||
let total_rx_label = format!("Total RX: {}", &app_state.canvas_data.total_rx_display);
|
||||
let total_tx_label = format!("Total TX: {}", &app_state.canvas_data.total_tx_display);
|
||||
|
||||
let net_text = [
|
||||
Text::styled(rx_label, self.colours.rx_style),
|
||||
Text::styled(tx_label, self.colours.tx_style),
|
||||
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 total_net_text = [
|
||||
Text::styled(total_rx_label, self.colours.total_rx_style),
|
||||
Text::styled(total_tx_label, self.colours.total_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)),
|
||||
];
|
||||
|
||||
f.render_widget(
|
||||
Paragraph::new(net_text.iter()).block(Block::default()),
|
||||
net_loc[0],
|
||||
);
|
||||
f.render_widget(Paragraph::new(net_text).block(Block::default()), net_loc[0]);
|
||||
|
||||
f.render_widget(
|
||||
Paragraph::new(total_net_text.iter()).block(Block::default()),
|
||||
Paragraph::new(total_net_text).block(Block::default()),
|
||||
total_loc[0],
|
||||
);
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use lazy_static::lazy_static;
|
||||
use std::cmp::max;
|
||||
use unicode_segmentation::UnicodeSegmentation;
|
||||
|
||||
use crate::{
|
||||
app::App,
|
||||
|
@ -13,6 +14,8 @@ use tui::{
|
|||
layout::{Constraint, Direction, Layout, Rect},
|
||||
symbols::Marker,
|
||||
terminal::Frame,
|
||||
text::Span,
|
||||
text::Spans,
|
||||
widgets::{Axis, Block, Borders, Chart, Dataset, Row, Table},
|
||||
};
|
||||
|
||||
|
@ -179,9 +182,12 @@ impl NetworkGraphWidget for Painter {
|
|||
-(network_widget_state.current_display_time as f64),
|
||||
0.0,
|
||||
);
|
||||
let display_time_labels = [
|
||||
format!("{}s", network_widget_state.current_display_time / 1000),
|
||||
"0s".to_string(),
|
||||
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 x_axis = if app_state.app_config_fields.hide_time
|
||||
|| (app_state.app_config_fields.autohide_time
|
||||
|
@ -195,8 +201,7 @@ 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_style(self.colours.graph_style)
|
||||
.labels(display_time_labels)
|
||||
} else {
|
||||
network_widget_state.autohide_timer = None;
|
||||
Axis::default()
|
||||
|
@ -208,32 +213,41 @@ 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_style(self.colours.graph_style)
|
||||
.labels(display_time_labels)
|
||||
};
|
||||
|
||||
let y_axis_labels = labels;
|
||||
let y_axis_labels = labels
|
||||
.iter()
|
||||
.map(|label| Span::styled(label, self.colours.graph_style))
|
||||
.collect::<Vec<_>>();
|
||||
let y_axis = Axis::default()
|
||||
.style(self.colours.graph_style)
|
||||
.bounds([0.0, max_range])
|
||||
.labels(&y_axis_labels)
|
||||
.labels_style(self.colours.graph_style);
|
||||
.labels(y_axis_labels);
|
||||
|
||||
let is_on_widget = widget_id == app_state.current_widget.widget_id;
|
||||
let border_style = if is_on_widget {
|
||||
self.colours.highlighted_border_style
|
||||
} else {
|
||||
self.colours.border_style
|
||||
};
|
||||
|
||||
let title = if app_state.is_expanded {
|
||||
const TITLE_BASE: &str = " Network ── Esc to go back ";
|
||||
format!(
|
||||
" Network ─{}─ Esc to go back ",
|
||||
"─".repeat(
|
||||
usize::from(draw_loc.width).saturating_sub(TITLE_BASE.chars().count() + 2)
|
||||
)
|
||||
)
|
||||
Spans::from(vec![
|
||||
Span::styled(" Network ", self.colours.widget_title_style),
|
||||
Span::styled(
|
||||
format!(
|
||||
"─{}─ Esc to go back ",
|
||||
"─".repeat(usize::from(draw_loc.width).saturating_sub(
|
||||
UnicodeSegmentation::graphemes(TITLE_BASE, true).count() + 2
|
||||
))
|
||||
),
|
||||
border_style,
|
||||
),
|
||||
])
|
||||
} else {
|
||||
" Network ".to_string()
|
||||
};
|
||||
let title_style = if app_state.is_expanded {
|
||||
self.colours.highlighted_border_style
|
||||
} else {
|
||||
self.colours.widget_title_style
|
||||
Spans::from(Span::styled(" Network ", self.colours.widget_title_style))
|
||||
};
|
||||
|
||||
let legend_constraints = if hide_legend {
|
||||
|
@ -321,13 +335,10 @@ impl NetworkGraphWidget for Painter {
|
|||
};
|
||||
|
||||
f.render_widget(
|
||||
// Chart::new(dataset)
|
||||
Chart::default()
|
||||
.datasets(&dataset)
|
||||
Chart::new(dataset)
|
||||
.block(
|
||||
Block::default()
|
||||
.title(&title)
|
||||
.title_style(title_style)
|
||||
.title(title)
|
||||
.borders(Borders::ALL)
|
||||
.border_style(if app_state.current_widget.widget_id == widget_id {
|
||||
self.colours.highlighted_border_style
|
||||
|
|
|
@ -11,7 +11,8 @@ use tui::{
|
|||
backend::Backend,
|
||||
layout::{Alignment, Constraint, Direction, Layout, Rect},
|
||||
terminal::Frame,
|
||||
widgets::{Block, Borders, Paragraph, Row, Table, Text},
|
||||
text::{Span, Spans},
|
||||
widgets::{Block, Borders, Paragraph, Row, Table},
|
||||
};
|
||||
|
||||
use std::borrow::Cow;
|
||||
|
@ -122,7 +123,7 @@ impl ProcessTableWidget for Painter {
|
|||
.direction(Direction::Horizontal)
|
||||
.split(draw_loc)[0];
|
||||
|
||||
let (border_and_title_style, highlight_style) = if is_on_widget {
|
||||
let (border_style, highlight_style) = if is_on_widget {
|
||||
(
|
||||
self.colours.highlighted_border_style,
|
||||
self.colours.currently_selected_text_style,
|
||||
|
@ -131,41 +132,35 @@ impl ProcessTableWidget for Painter {
|
|||
(self.colours.border_style, self.colours.text_style)
|
||||
};
|
||||
|
||||
let title = if draw_border {
|
||||
if app_state.is_expanded
|
||||
&& !proc_widget_state
|
||||
.process_search_state
|
||||
.search_state
|
||||
.is_enabled
|
||||
&& !proc_widget_state.is_sort_open
|
||||
{
|
||||
const TITLE_BASE: &str = " Processes ── Esc to go back ";
|
||||
format!(
|
||||
" Processes ─{}─ Esc to go back ",
|
||||
"─".repeat(
|
||||
usize::from(draw_loc.width)
|
||||
.saturating_sub(TITLE_BASE.chars().count() + 2)
|
||||
)
|
||||
)
|
||||
} else {
|
||||
" Processes ".to_string()
|
||||
}
|
||||
let title = if app_state.is_expanded
|
||||
&& !proc_widget_state
|
||||
.process_search_state
|
||||
.search_state
|
||||
.is_enabled
|
||||
&& !proc_widget_state.is_sort_open
|
||||
{
|
||||
const TITLE_BASE: &str = " Processes ── Esc to go back ";
|
||||
Spans::from(vec![
|
||||
Span::styled(" Processes ", self.colours.widget_title_style),
|
||||
Span::styled(
|
||||
format!(
|
||||
"─{}─ Esc to go back ",
|
||||
"─".repeat(usize::from(draw_loc.width).saturating_sub(
|
||||
UnicodeSegmentation::graphemes(TITLE_BASE, true).count() + 2
|
||||
))
|
||||
),
|
||||
border_style,
|
||||
),
|
||||
])
|
||||
} else {
|
||||
String::default()
|
||||
};
|
||||
|
||||
let title_style = if app_state.is_expanded {
|
||||
border_and_title_style
|
||||
} else {
|
||||
self.colours.widget_title_style
|
||||
Spans::from(Span::styled(" Processes ", self.colours.widget_title_style))
|
||||
};
|
||||
|
||||
let process_block = if draw_border {
|
||||
Block::default()
|
||||
.title(&title)
|
||||
.title_style(title_style)
|
||||
.title(title)
|
||||
.borders(Borders::ALL)
|
||||
.border_style(border_and_title_style)
|
||||
.border_style(border_style)
|
||||
} else if is_on_widget {
|
||||
Block::default()
|
||||
.borders(*SIDE_BORDERS)
|
||||
|
@ -459,7 +454,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<Text<'a>> {
|
||||
) -> Vec<Span<'a>> {
|
||||
let mut current_grapheme_posn = 0;
|
||||
|
||||
if is_on_widget {
|
||||
|
@ -471,9 +466,9 @@ impl ProcessTableWidget for Painter {
|
|||
None
|
||||
} else {
|
||||
let styled = if grapheme.0 == cursor_position {
|
||||
Text::styled(grapheme.1, currently_selected_text_style)
|
||||
Span::styled(grapheme.1, currently_selected_text_style)
|
||||
} else {
|
||||
Text::styled(grapheme.1, text_style)
|
||||
Span::styled(grapheme.1, text_style)
|
||||
};
|
||||
Some(styled)
|
||||
}
|
||||
|
@ -481,7 +476,7 @@ impl ProcessTableWidget for Painter {
|
|||
.collect::<Vec<_>>();
|
||||
|
||||
if cursor_position >= query.len() {
|
||||
res.push(Text::styled(" ", currently_selected_text_style))
|
||||
res.push(Span::styled(" ", currently_selected_text_style))
|
||||
}
|
||||
|
||||
res
|
||||
|
@ -495,7 +490,7 @@ impl ProcessTableWidget for Painter {
|
|||
if current_grapheme_posn <= start_position {
|
||||
None
|
||||
} else {
|
||||
let styled = Text::styled(grapheme.1, text_style);
|
||||
let styled = Span::styled(grapheme.1, text_style);
|
||||
Some(styled)
|
||||
}
|
||||
})
|
||||
|
@ -543,8 +538,8 @@ impl ProcessTableWidget for Painter {
|
|||
self.colours.text_style,
|
||||
);
|
||||
|
||||
let mut search_text = {
|
||||
let mut search_vec = vec![Text::styled(
|
||||
let mut search_text = vec![Spans::from({
|
||||
let mut search_vec = vec![Span::styled(
|
||||
search_title,
|
||||
if is_on_widget {
|
||||
self.colours.table_header_style
|
||||
|
@ -554,7 +549,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 {
|
||||
|
@ -583,26 +578,24 @@ impl ProcessTableWidget for Painter {
|
|||
|
||||
// FIXME: [MOUSE] Mouse support for these in search
|
||||
// FIXME: [MOVEMENT] Movement support for these in search
|
||||
let option_text = vec![
|
||||
Text::raw("\n"),
|
||||
Text::styled(
|
||||
let option_text = Spans::from(vec![
|
||||
Span::styled(
|
||||
format!("Case({})", if self.is_mac_os { "F1" } else { "Alt+C" }),
|
||||
case_style,
|
||||
),
|
||||
Text::raw(" "),
|
||||
Text::styled(
|
||||
Span::raw(" "),
|
||||
Span::styled(
|
||||
format!("Whole({})", if self.is_mac_os { "F2" } else { "Alt+W" }),
|
||||
whole_word_style,
|
||||
),
|
||||
Text::raw(" "),
|
||||
Text::styled(
|
||||
Span::raw(" "),
|
||||
Span::styled(
|
||||
format!("Regex({})", if self.is_mac_os { "F3" } else { "Alt+R" }),
|
||||
regex_style,
|
||||
),
|
||||
];
|
||||
]);
|
||||
|
||||
search_text.push(Text::raw("\n"));
|
||||
search_text.push(Text::styled(
|
||||
search_text.push(Spans::from(Span::styled(
|
||||
if let Some(err) = &proc_widget_state
|
||||
.process_search_state
|
||||
.search_state
|
||||
|
@ -613,8 +606,8 @@ impl ProcessTableWidget for Painter {
|
|||
""
|
||||
},
|
||||
self.colours.invalid_query_style,
|
||||
));
|
||||
search_text.extend(option_text);
|
||||
)));
|
||||
search_text.push(option_text);
|
||||
|
||||
let current_border_style = if proc_widget_state
|
||||
.process_search_state
|
||||
|
@ -628,20 +621,21 @@ impl ProcessTableWidget for Painter {
|
|||
self.colours.border_style
|
||||
};
|
||||
|
||||
let title = if draw_border {
|
||||
const TITLE_BASE: &str = " Esc to close ";
|
||||
|
||||
let repeat_num =
|
||||
usize::from(draw_loc.width).saturating_sub(TITLE_BASE.chars().count() + 2);
|
||||
format!("{} Esc to close ", "─".repeat(repeat_num))
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
let title = Span::styled(
|
||||
if draw_border {
|
||||
const TITLE_BASE: &str = " Esc to close ";
|
||||
let repeat_num =
|
||||
usize::from(draw_loc.width).saturating_sub(TITLE_BASE.chars().count() + 2);
|
||||
format!("{} Esc to close ", "─".repeat(repeat_num))
|
||||
} else {
|
||||
String::new()
|
||||
},
|
||||
current_border_style,
|
||||
);
|
||||
|
||||
let process_search_block = if draw_border {
|
||||
Block::default()
|
||||
.title(&title)
|
||||
.title_style(current_border_style)
|
||||
.title(title)
|
||||
.borders(Borders::ALL)
|
||||
.border_style(current_border_style)
|
||||
} else if is_on_widget {
|
||||
|
@ -659,7 +653,7 @@ impl ProcessTableWidget for Painter {
|
|||
.split(draw_loc)[0];
|
||||
|
||||
f.render_widget(
|
||||
Paragraph::new(search_text.iter())
|
||||
Paragraph::new(search_text)
|
||||
.block(process_search_block)
|
||||
.style(self.colours.text_style)
|
||||
.alignment(Alignment::Left),
|
||||
|
|
|
@ -3,6 +3,8 @@ use tui::{
|
|||
backend::Backend,
|
||||
layout::{Constraint, Direction, Layout, Rect},
|
||||
terminal::Frame,
|
||||
text::Span,
|
||||
text::Spans,
|
||||
widgets::{Block, Borders, Row, Table},
|
||||
};
|
||||
|
||||
|
@ -141,7 +143,7 @@ impl TempTableWidget for Painter {
|
|||
Row::Data(truncated_data)
|
||||
});
|
||||
|
||||
let (border_and_title_style, highlight_style) = if is_on_widget {
|
||||
let (border_style, highlight_style) = if is_on_widget {
|
||||
(
|
||||
self.colours.highlighted_border_style,
|
||||
self.colours.currently_selected_text_style,
|
||||
|
@ -152,29 +154,30 @@ impl TempTableWidget for Painter {
|
|||
|
||||
let title = if app_state.is_expanded {
|
||||
const TITLE_BASE: &str = " Temperatures ── Esc to go back ";
|
||||
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 {
|
||||
String::new()
|
||||
Spans::from(vec![
|
||||
Span::styled(" Temperatures ", self.colours.widget_title_style),
|
||||
Span::styled(
|
||||
format!(
|
||||
"─{}─ Esc to go back ",
|
||||
"─".repeat(usize::from(draw_loc.width).saturating_sub(
|
||||
UnicodeSegmentation::graphemes(TITLE_BASE, true).count() + 2
|
||||
))
|
||||
),
|
||||
border_style,
|
||||
),
|
||||
])
|
||||
} else {
|
||||
" Temperatures ".to_string()
|
||||
};
|
||||
let title_style = if app_state.is_expanded {
|
||||
border_and_title_style
|
||||
} else {
|
||||
self.colours.widget_title_style
|
||||
Spans::from(Span::styled(
|
||||
" Temperatures ",
|
||||
self.colours.widget_title_style,
|
||||
))
|
||||
};
|
||||
|
||||
let temp_block = if draw_border {
|
||||
Block::default()
|
||||
.title(&title)
|
||||
.title_style(title_style)
|
||||
.title(title)
|
||||
.borders(Borders::ALL)
|
||||
.border_style(border_and_title_style)
|
||||
.border_style(border_style)
|
||||
} else if is_on_widget {
|
||||
Block::default()
|
||||
.borders(*SIDE_BORDERS)
|
||||
|
|
198
src/constants.rs
198
src/constants.rs
|
@ -40,45 +40,45 @@ lazy_static! {
|
|||
// FIXME: [HELP] I wanna update this before release... it's missing mouse too.
|
||||
// Help text
|
||||
pub const HELP_CONTENTS_TEXT: [&str; 8] = [
|
||||
"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\n",
|
||||
"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",
|
||||
"6 - Battery widget",
|
||||
"7 - Basic memory widget",
|
||||
];
|
||||
|
||||
pub const GENERAL_HELP_TEXT: [&str; 29] = [
|
||||
"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 Toggle expanding the currently selected widget\n",
|
||||
"+ Zoom in on chart (decrease time range)\n",
|
||||
"- Zoom out on chart (increase time range)\n",
|
||||
"= Reset zoom\n",
|
||||
"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 Toggle expanding the currently selected widget",
|
||||
"+ Zoom in on chart (decrease time range)",
|
||||
"- Zoom out on chart (increase time range)",
|
||||
"= Reset zoom",
|
||||
"Mouse scroll Scroll through the tables or zoom in/out of charts by scrolling up/down",
|
||||
];
|
||||
|
||||
|
@ -90,87 +90,87 @@ pub const CPU_HELP_TEXT: [&str; 2] = [
|
|||
// TODO [Help]: Search in help?
|
||||
// TODO [Help]: Move to using tables for easier formatting?
|
||||
pub const PROCESS_HELP_TEXT: [&str; 13] = [
|
||||
"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 command or just the process name\n",
|
||||
"s, F6 Open process sort widget\n",
|
||||
"I Invert current sort\n",
|
||||
"% Toggle between values and percentages for memory usage\n",
|
||||
"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 command or just the process name",
|
||||
"s, F6 Open process sort widget",
|
||||
"I Invert current sort",
|
||||
"% Toggle between values and percentages for memory usage",
|
||||
"t, F5 Toggle tree mode",
|
||||
];
|
||||
|
||||
pub const SEARCH_HELP_TEXT: [&str; 46] = [
|
||||
"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",
|
||||
"Supported search types:\n",
|
||||
"<by name/cmd> ex: btm\n",
|
||||
"pid ex: pid 825\n",
|
||||
"cpu, cpu% ex: cpu > 4.2\n",
|
||||
"mem, mem% ex: mem < 4.2\n",
|
||||
"memb ex: memb < 100 kb\n",
|
||||
"read, r/s ex: read >= 1 b\n",
|
||||
"write, w/s ex: write <= 1 tb\n",
|
||||
"tread, t.read ex: tread = 1\n",
|
||||
"twrite, t.write ex: twrite = 1\n",
|
||||
"state ex: state = running\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, &&, <Space> 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",
|
||||
"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",
|
||||
"",
|
||||
"Supported search types:",
|
||||
"<by name/cmd> ex: btm",
|
||||
"pid ex: pid 825",
|
||||
"cpu, cpu% ex: cpu > 4.2",
|
||||
"mem, mem% ex: mem < 4.2",
|
||||
"memb ex: memb < 100 kb",
|
||||
"read, r/s ex: read >= 1 b",
|
||||
"write, w/s ex: write <= 1 tb",
|
||||
"tread, t.read ex: tread = 1",
|
||||
"twrite, t.write ex: twrite = 1",
|
||||
"state ex: state = running",
|
||||
"",
|
||||
"Comparison operators:",
|
||||
"= ex: cpu = 1",
|
||||
"> ex: cpu > 1",
|
||||
"< ex: cpu < 1",
|
||||
">= ex: cpu >= 1",
|
||||
"<= ex: cpu <= 1",
|
||||
"",
|
||||
"Logical operators:",
|
||||
"and, &&, <Space> 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",
|
||||
"TiB ex: read > 1 tib",
|
||||
];
|
||||
|
||||
pub const SORT_HELP_TEXT: [&str; 6] = [
|
||||
"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",
|
||||
"Down, 'j' Scroll down in list",
|
||||
"Up, 'k' Scroll up in list",
|
||||
"Mouse scroll Scroll through sort widget",
|
||||
"Esc Close the sort widget",
|
||||
"Enter Sort by current selected column",
|
||||
];
|
||||
|
||||
pub const BATTERY_HELP_TEXT: [&str; 3] = [
|
||||
"6 - Battery widget\n",
|
||||
"Left Go to previous battery\n",
|
||||
"6 - Battery widget",
|
||||
"Left Go to previous battery",
|
||||
"Right Go to next battery",
|
||||
];
|
||||
|
||||
pub const BASIC_MEM_HELP_TEXT: [&str; 2] = [
|
||||
"7 - Basic memory widget\n",
|
||||
"7 - Basic memory widget",
|
||||
"% Toggle between values and percentages for memory usage",
|
||||
];
|
||||
|
||||
|
|
Loading…
Reference in New Issue