mirror of
https://github.com/ClementTsang/bottom
synced 2024-11-22 12:13:06 +00:00
deps: Update dependencies, drop MSRV
Update dependencies to most recent versions if applicable. Refactor to deal with breaking changes. Drop MSRV due to dependency issues, just support stable and later.
This commit is contained in:
parent
17552c50cf
commit
d0cc6078df
22 changed files with 408 additions and 376 deletions
14
.travis.yml
14
.travis.yml
|
@ -1,7 +1,5 @@
|
|||
language: rust
|
||||
rust:
|
||||
# MSRV; though I only want to test if it builds.
|
||||
- 1.40.0
|
||||
- stable
|
||||
- beta
|
||||
os:
|
||||
|
@ -13,8 +11,6 @@ jobs:
|
|||
exclude:
|
||||
- if: tag IS present
|
||||
rust: beta
|
||||
- if: tag IS present
|
||||
rust: 1.40.0
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
|
@ -34,15 +30,9 @@ before_script:
|
|||
- rustup target add $TARGET
|
||||
- rustup component add clippy
|
||||
script:
|
||||
- |
|
||||
if [[ $TRAVIS_RUST_VERSION != "1.40.0" ]]; then
|
||||
cargo clippy -- -D clippy::all
|
||||
fi
|
||||
- cargo clippy -- -D clippy::all
|
||||
- cargo build --verbose --target $TARGET
|
||||
- |
|
||||
if [[ $TRAVIS_RUST_VERSION != "1.40.0" ]]; then
|
||||
cargo test --verbose --target $TARGET;
|
||||
fi
|
||||
- cargo test --verbose --target $TARGET
|
||||
- cargo install --path . --target $TARGET --locked --force
|
||||
|
||||
before_cache:
|
||||
|
|
|
@ -13,6 +13,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
- [179](https://github.com/ClementTsang/bottom/pull/179): Show full command/process path as an option.
|
||||
|
||||
### Changes
|
||||
|
||||
- Changed to just support stable (and newer) Rust, due to library incompatibilities.
|
||||
|
||||
## [0.4.5] - 2020-07-08
|
||||
|
||||
- No changes here, just an uptick for Crates.io using the wrong Cargo.lock.
|
||||
|
|
|
@ -36,7 +36,7 @@ For reports/suggestions that don't fit the definition of a feature or bug, try t
|
|||
If you want to help contribute by submitting a PR, by all means, I'm open! In regards to the development process:
|
||||
|
||||
- I develop primarily using _stable_ Rust. That is, whatever is the most up-to-date stable version you can get via running
|
||||
`rustup update stable`. However, as of writing, I do support a MSRV of 1.40.0.
|
||||
`rustup update stable`.
|
||||
|
||||
- Note that `cargo test` will fail on anything lower than 1.43.0 due to it using a then-introduced env variable.
|
||||
|
||||
|
|
39
Cargo.lock
generated
39
Cargo.lock
generated
|
@ -135,6 +135,7 @@ dependencies = [
|
|||
"assert_cmd",
|
||||
"backtrace",
|
||||
"battery",
|
||||
"cargo-husky",
|
||||
"chrono",
|
||||
"clap",
|
||||
"crossterm",
|
||||
|
@ -157,6 +158,12 @@ dependencies = [
|
|||
"winapi 0.3.8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cargo-husky"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b02b629252fe8ef6460461409564e2c21d0c8e77e0944f3d189ff06c4e932ad"
|
||||
|
||||
[[package]]
|
||||
name = "cassowary"
|
||||
version = "0.3.0"
|
||||
|
@ -177,9 +184,9 @@ checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
|||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
version = "0.4.11"
|
||||
version = "0.4.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "80094f509cf8b5ae86a4966a39b3ff66cd7e2a3e594accec3743ff3fabeab5b2"
|
||||
checksum = "c74d84029116787153e02106bf53e66828452a4b325cc8652b788b5967c0a0b6"
|
||||
dependencies = [
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
|
@ -188,9 +195,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "2.33.1"
|
||||
version = "2.33.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bdfa80d47f954d53a35a64987ca1422f495b8d6483c0fe9f7117b36c2a792129"
|
||||
checksum = "10040cdf04294b565d9e0319955430099ec3813a64c952b86a41200ad714ae48"
|
||||
dependencies = [
|
||||
"ansi_term",
|
||||
"atty",
|
||||
|
@ -348,21 +355,19 @@ checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
|
|||
|
||||
[[package]]
|
||||
name = "dirs"
|
||||
version = "2.0.2"
|
||||
version = "3.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13aea89a5c93364a98e9b37b2fa237effbb694d5cfe01c5b70941f7eb087d5e3"
|
||||
checksum = "142995ed02755914747cc6ca76fc7e4583cd18578746716d0508ea6ed558b9ff"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"dirs-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs-sys"
|
||||
version = "0.3.4"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "afa0b23de8fd801745c471deffa6e12d248f962c9fd4b4c33787b055599bde7b"
|
||||
checksum = "8e93d7f5705de3e49895a2b5e0b8855a1c27f080192ae9c32a6432d50741a57a"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"redox_users",
|
||||
"winapi 0.3.8",
|
||||
|
@ -1273,9 +1278,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "sysinfo"
|
||||
version = "0.14.2"
|
||||
version = "0.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70bbf8e10fc10b83e71bc19f4374ce17209d45c7c4c99b5067ac554aba3bfd08"
|
||||
checksum = "f597c00e6548b9ddd54c11b8e8534fc11223f28509d57e021f01797b50ca5ca1"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"doc-comment",
|
||||
|
@ -1340,24 +1345,22 @@ checksum = "a7f741b240f1a48843f9b8e0444fb55fb2a4ff67293b50a9179dfd5ea67f8d41"
|
|||
|
||||
[[package]]
|
||||
name = "tui"
|
||||
version = "0.9.5"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9533d39bef0ae8f510e8a99d78702e68d1bbf0b98a78ec9740509d287010ae1e"
|
||||
checksum = "a977b0bb2e2033a6fef950f218f13622c3c34e59754b704ce3492dedab1dfe95"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cassowary",
|
||||
"crossterm",
|
||||
"either",
|
||||
"itertools",
|
||||
"unicode-segmentation",
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typed-builder"
|
||||
version = "0.6.0"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85fc4459191c621a53ef6c6ca5642e6e0e5ccc61f3e5b8ad6b6ab5317f0200fb"
|
||||
checksum = "d942c3f63d40f62b3fece2ab34a5bfc0d427ef148010fa732f5d56da0ac6d6ec"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
13
Cargo.toml
13
Cargo.toml
|
@ -23,22 +23,22 @@ codegen-units = 1
|
|||
[dependencies]
|
||||
battery = "0.7.5"
|
||||
crossterm = "0.17"
|
||||
chrono = "0.4.11"
|
||||
clap = "2.33.1"
|
||||
dirs = "2.0.2"
|
||||
chrono = "0.4.13"
|
||||
clap = "2.33.2"
|
||||
dirs = "3.0.1"
|
||||
futures = "0.3.5"
|
||||
heim = "0.0.10"
|
||||
itertools = "0.9.0"
|
||||
regex = "1.3"
|
||||
sysinfo = "0.14.2"
|
||||
sysinfo = "0.15.0"
|
||||
toml = "0.5.6"
|
||||
typed-builder = "0.6.0"
|
||||
typed-builder = "0.7.0"
|
||||
lazy_static = "1.4.0"
|
||||
backtrace = "0.3"
|
||||
serde = {version = "1.0", features = ["derive"] }
|
||||
unicode-segmentation = "1.6.0"
|
||||
unicode-width = "0.1.7"
|
||||
tui = {version = "0.9", features = ["crossterm"], default-features = false }
|
||||
tui = {version = "0.10.0", features = ["crossterm"], default-features = false }
|
||||
|
||||
# For debugging only...
|
||||
fern = "0.6.0"
|
||||
|
@ -50,6 +50,7 @@ winapi = "0.3.8"
|
|||
[dev-dependencies]
|
||||
assert_cmd = "1.0"
|
||||
predicates = "1"
|
||||
cargo-husky = "1"
|
||||
|
||||
[package.metadata.deb]
|
||||
section = "utils"
|
||||
|
|
|
@ -13,7 +13,7 @@ A cross-platform graphical process/system monitor with a customizable interface
|
|||
## Table of Contents
|
||||
|
||||
- [Installation](#installation)
|
||||
- [Manual](#manual)
|
||||
- [Manually](#manually)
|
||||
- [Cargo](#cargo)
|
||||
- [AUR](#aur)
|
||||
- [Debian (and Debian-based)](#debian)
|
||||
|
@ -59,9 +59,9 @@ Note that bottom is:
|
|||
|
||||
As such, support beyond that is not guaranteed.
|
||||
|
||||
### Manual
|
||||
### [Manually]
|
||||
|
||||
There are a few ways to go about doing this. Note that the MSRV is 1.40.0. For example:
|
||||
There are a few ways to go about doing this manually. If you do so, please build using the current stable release of Rust. For example:
|
||||
|
||||
```bash
|
||||
# If required, update Rust on the stable channel
|
||||
|
@ -84,6 +84,9 @@ cargo install --path .
|
|||
### Cargo
|
||||
|
||||
```bash
|
||||
# If required, update Rust on the stable channel
|
||||
rustup update stable
|
||||
|
||||
cargo install bottom
|
||||
|
||||
# OR, --locked may be required due to how cargo install works
|
||||
|
|
|
@ -4,7 +4,7 @@ use std::collections::HashMap;
|
|||
use tui::{
|
||||
backend::Backend,
|
||||
layout::{Constraint, Direction, Layout, Rect},
|
||||
widgets::Text,
|
||||
text::{Span, Spans},
|
||||
Frame, Terminal,
|
||||
};
|
||||
|
||||
|
@ -55,7 +55,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>>,
|
||||
|
@ -139,14 +139,14 @@ impl Painter {
|
|||
colours: CanvasColours::default(),
|
||||
height: 0,
|
||||
width: 0,
|
||||
styled_help_text: Vec::new(),
|
||||
styled_help_text: Vec::default(),
|
||||
is_mac_os: false,
|
||||
row_constraints,
|
||||
col_constraints,
|
||||
col_row_constraints,
|
||||
layout_constraints,
|
||||
widget_layout,
|
||||
derived_widget_draw_locs: Vec::new(),
|
||||
derived_widget_draw_locs: Vec::default(),
|
||||
table_height_offset: 4 + table_gap,
|
||||
}
|
||||
}
|
||||
|
@ -155,34 +155,35 @@ impl Painter {
|
|||
/// This is to set some remaining styles and text.
|
||||
pub fn complete_painter_init(&mut self) {
|
||||
self.is_mac_os = cfg!(target_os = "macos");
|
||||
let mut styled_help_spans = Vec::new();
|
||||
|
||||
// Init help text:
|
||||
(*HELP_TEXT).iter().enumerate().for_each(|(itx, section)| {
|
||||
if itx == 0 {
|
||||
self.styled_help_text.extend(
|
||||
styled_help_spans.extend(
|
||||
section
|
||||
.iter()
|
||||
.map(|&text| Text::Styled(text.into(), 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 {
|
||||
self.styled_help_text.push(Text::Raw("\n\n".into()));
|
||||
self.styled_help_text.push(Text::Styled(
|
||||
section[0].into(),
|
||||
self.colours.table_header_style,
|
||||
));
|
||||
self.styled_help_text.extend(
|
||||
styled_help_spans.push(Span::from("\n\n"));
|
||||
styled_help_spans
|
||||
.push(Span::styled(section[0], self.colours.table_header_style));
|
||||
styled_help_spans.extend(
|
||||
section[1..]
|
||||
.iter()
|
||||
.map(|&text| Text::Styled(text.into(), 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();
|
||||
}
|
||||
|
||||
pub fn draw_data<B: Backend>(
|
||||
|
|
|
@ -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)?.modifier(Modifier::BOLD);
|
||||
self.table_header_style = get_style_from_config(colour)?.add_modifier(Modifier::BOLD);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,8 @@ use tui::{
|
|||
backend::Backend,
|
||||
layout::{Alignment, Rect},
|
||||
terminal::Frame,
|
||||
widgets::{Block, Borders, Paragraph, Text},
|
||||
text::{Span, Spans, Text},
|
||||
widgets::{Block, Borders, Paragraph, Wrap},
|
||||
};
|
||||
|
||||
use crate::{app::App, canvas::Painter};
|
||||
|
@ -24,60 +25,67 @@ impl KillDialog for Painter {
|
|||
) -> bool {
|
||||
if let Some(to_kill_processes) = app_state.get_to_delete_processes() {
|
||||
if let Some(first_pid) = to_kill_processes.1.first() {
|
||||
let dd_text = vec![
|
||||
if app_state.is_grouped(app_state.current_widget.widget_id) {
|
||||
if to_kill_processes.1.len() != 1 {
|
||||
Text::raw(format!(
|
||||
"\nKill {} processes with the name \"{}\"?",
|
||||
to_kill_processes.1.len(),
|
||||
to_kill_processes.0
|
||||
))
|
||||
let dd_text = 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!(
|
||||
"\nKill {} processes with the name \"{}\"?",
|
||||
to_kill_processes.1.len(),
|
||||
to_kill_processes.0
|
||||
))
|
||||
} else {
|
||||
Span::from(format!(
|
||||
"\nKill 1 process with the name \"{}\"?",
|
||||
to_kill_processes.0
|
||||
))
|
||||
}
|
||||
} else {
|
||||
Text::raw(format!(
|
||||
"\nKill 1 process with the name \"{}\"?",
|
||||
to_kill_processes.0
|
||||
Span::from(format!(
|
||||
"\nKill process \"{}\" with PID {}?",
|
||||
to_kill_processes.0, first_pid
|
||||
))
|
||||
}
|
||||
} else {
|
||||
Text::raw(format!(
|
||||
"\nKill 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)
|
||||
},
|
||||
];
|
||||
},
|
||||
]),
|
||||
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)
|
||||
},
|
||||
]),
|
||||
]);
|
||||
|
||||
let dd_title = format!(
|
||||
" Confirm Kill Process ─{}─ Esc to close ",
|
||||
"─".repeat(
|
||||
usize::from(draw_loc.width).saturating_sub(DD_BASE.chars().count() + 2)
|
||||
)
|
||||
let dd_title = 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,
|
||||
);
|
||||
|
||||
|
@ -92,31 +100,33 @@ impl KillDialog for Painter {
|
|||
}
|
||||
|
||||
fn draw_dd_error_dialog<B: Backend>(&self, f: &mut Frame<'_, B>, dd_err: &str, draw_loc: Rect) {
|
||||
let dd_text = [Text::raw(format!(
|
||||
let dd_text = Span::from(format!(
|
||||
"\nFailure to properly kill the process - {}",
|
||||
dd_err
|
||||
))];
|
||||
));
|
||||
|
||||
let error_title = format!(
|
||||
" Error ─{}─ Esc to close ",
|
||||
"─".repeat(
|
||||
usize::from(draw_loc.width).saturating_sub(DD_ERROR_BASE.chars().count() + 2)
|
||||
)
|
||||
let error_title = 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,
|
||||
);
|
||||
|
||||
f.render_widget(
|
||||
Paragraph::new(dd_text.iter())
|
||||
Paragraph::new(dd_text)
|
||||
.block(
|
||||
Block::default()
|
||||
.title(&error_title)
|
||||
.title_style(self.colours.border_style)
|
||||
.title(error_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,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -4,7 +4,8 @@ use tui::{
|
|||
backend::Backend,
|
||||
layout::{Alignment, Rect},
|
||||
terminal::Frame,
|
||||
widgets::{Block, Borders, Paragraph},
|
||||
text::Span,
|
||||
widgets::{Block, Borders, Paragraph, Wrap},
|
||||
};
|
||||
|
||||
use crate::{app::App, canvas::Painter, constants};
|
||||
|
@ -21,9 +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 = 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.is_force_redraw {
|
||||
|
@ -89,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,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -10,7 +10,8 @@ use tui::{
|
|||
backend::Backend,
|
||||
layout::{Constraint, Layout, Rect},
|
||||
terminal::Frame,
|
||||
widgets::{Block, Paragraph, Text},
|
||||
text::{Span, Spans},
|
||||
widgets::{Block, Paragraph},
|
||||
};
|
||||
|
||||
pub trait BasicTableArrows {
|
||||
|
@ -58,9 +59,12 @@ impl BasicTableArrows for Painter {
|
|||
usize::from(draw_loc.width).saturating_sub(6 + left_name.len() + right_name.len());
|
||||
|
||||
let arrow_text = vec![
|
||||
Text::Styled(format!("\n◄ {}", left_name).into(), self.colours.text_style),
|
||||
Text::Raw(" ".repeat(num_spaces).into()),
|
||||
Text::Styled(format!("{} ►", right_name).into(), self.colours.text_style),
|
||||
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),
|
||||
]),
|
||||
];
|
||||
|
||||
let margined_draw_loc = Layout::default()
|
||||
|
@ -69,7 +73,7 @@ impl BasicTableArrows for Painter {
|
|||
.split(draw_loc);
|
||||
|
||||
f.render_widget(
|
||||
Paragraph::new(arrow_text.iter()).block(Block::default()),
|
||||
Paragraph::new(arrow_text).block(Block::default()),
|
||||
margined_draw_loc[0],
|
||||
);
|
||||
}
|
||||
|
|
|
@ -8,7 +8,8 @@ use tui::{
|
|||
backend::Backend,
|
||||
layout::{Constraint, Rect},
|
||||
terminal::Frame,
|
||||
widgets::{Block, Borders, Paragraph, Row, Table, Tabs, Text},
|
||||
text::{Span, Spans},
|
||||
widgets::{Block, Borders, Paragraph, Row, Table, Tabs},
|
||||
};
|
||||
|
||||
pub trait BatteryDisplayWidget {
|
||||
|
@ -27,32 +28,31 @@ 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 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)
|
||||
)
|
||||
)
|
||||
} else {
|
||||
" Battery ".to_string()
|
||||
};
|
||||
|
||||
let border_and_title_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 battery_block = if draw_border {
|
||||
Block::default()
|
||||
.title(&title)
|
||||
.title_style(if app_state.is_expanded {
|
||||
border_and_title_style
|
||||
} else {
|
||||
self.colours.widget_title_style
|
||||
})
|
||||
.title(title)
|
||||
.borders(Borders::ALL)
|
||||
.border_style(border_and_title_style)
|
||||
} else if is_on_widget {
|
||||
|
@ -63,6 +63,23 @@ 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<_>>(),
|
||||
)
|
||||
.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,
|
||||
);
|
||||
|
||||
if let Some(battery_details) = app_state
|
||||
.canvas_data
|
||||
.battery_data
|
||||
|
@ -117,44 +134,21 @@ impl BatteryDisplayWidget for Painter {
|
|||
// Draw
|
||||
f.render_widget(
|
||||
Table::new([""].iter(), battery_rows)
|
||||
.block(battery_block)
|
||||
.block(battery_block.clone())
|
||||
.header_style(self.colours.table_header_style)
|
||||
.widths([Constraint::Percentage(50), Constraint::Percentage(50)].as_ref()),
|
||||
draw_loc,
|
||||
);
|
||||
} else {
|
||||
f.render_widget(
|
||||
Paragraph::new(
|
||||
[Text::Styled(
|
||||
"No data found for this battery".into(),
|
||||
self.colours.text_style,
|
||||
)]
|
||||
.iter(),
|
||||
)
|
||||
Paragraph::new(Spans::from(Span::styled(
|
||||
"No data found for this battery",
|
||||
self.colours.text_style,
|
||||
)))
|
||||
.block(battery_block),
|
||||
draw_loc,
|
||||
);
|
||||
}
|
||||
// if app_state.canvas_data.battery_data.len() > 1 {
|
||||
f.render_widget(
|
||||
Tabs::default()
|
||||
.block(battery_block)
|
||||
.titles(
|
||||
(app_state
|
||||
.canvas_data
|
||||
.battery_data
|
||||
.iter()
|
||||
.map(|battery| &battery.battery_name))
|
||||
.collect::<Vec<_>>()
|
||||
.as_ref(),
|
||||
)
|
||||
.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,
|
||||
);
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,10 +77,10 @@ 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()
|
||||
" AVG".to_string()
|
||||
} else {
|
||||
(cpu_index - 1).to_string()
|
||||
}
|
||||
|
@ -106,13 +107,13 @@ impl CpuBasicWidget for Painter {
|
|||
);
|
||||
row_counter -= how_many_cpus;
|
||||
let end_index = min(start_index + how_many_cpus, num_cpus);
|
||||
let cpu_column: Vec<Text<'_>> = (start_index..end_index)
|
||||
let cpu_column = (start_index..end_index)
|
||||
.map(|cpu_index| {
|
||||
Text::Styled(
|
||||
(&cpu_bars[cpu_index]).into(),
|
||||
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<_>>();
|
||||
|
||||
|
@ -125,7 +126,7 @@ impl CpuBasicWidget for Painter {
|
|||
.split(*chunk);
|
||||
|
||||
f.render_widget(
|
||||
Paragraph::new(cpu_column.iter()).block(Block::default()),
|
||||
Paragraph::new(cpu_column).block(Block::default()),
|
||||
margined_loc[0],
|
||||
);
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ use tui::{
|
|||
layout::{Constraint, Direction, Layout, Rect},
|
||||
symbols::Marker,
|
||||
terminal::Frame,
|
||||
text::Span,
|
||||
widgets::{Axis, Block, Borders, Chart, Dataset, Row, Table},
|
||||
};
|
||||
|
||||
|
@ -103,9 +104,12 @@ 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 = [
|
||||
format!("{}s", cpu_widget_state.current_display_time / 1000),
|
||||
"0s".to_string(),
|
||||
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 x_axis = if app_state.app_config_fields.hide_time
|
||||
|
@ -120,8 +124,7 @@ impl CpuGraphWidget for Painter {
|
|||
Axis::default()
|
||||
.bounds([-(cpu_widget_state.current_display_time as f64), 0.0])
|
||||
.style(self.colours.graph_style)
|
||||
.labels_style(self.colours.graph_style)
|
||||
.labels(&display_time_labels)
|
||||
.labels(display_time_labels)
|
||||
} else {
|
||||
cpu_widget_state.autohide_timer = None;
|
||||
Axis::default().bounds([-(cpu_widget_state.current_display_time as f64), 0.0])
|
||||
|
@ -132,16 +135,17 @@ impl CpuGraphWidget for Painter {
|
|||
Axis::default()
|
||||
.bounds([-(cpu_widget_state.current_display_time as f64), 0.0])
|
||||
.style(self.colours.graph_style)
|
||||
.labels_style(self.colours.graph_style)
|
||||
.labels(&display_time_labels)
|
||||
.labels(display_time_labels)
|
||||
};
|
||||
|
||||
// Note this is offset as otherwise the 0 value is not drawn!
|
||||
let y_axis = Axis::default()
|
||||
.style(self.colours.graph_style)
|
||||
.labels_style(self.colours.graph_style)
|
||||
.bounds([-0.5, 100.5])
|
||||
.labels(&["0%", "100%"]);
|
||||
.labels(vec![
|
||||
Span::styled("0%", self.colours.graph_style),
|
||||
Span::styled("100%", self.colours.graph_style),
|
||||
]);
|
||||
|
||||
let use_dot = app_state.app_config_fields.use_dot;
|
||||
let show_avg_cpu = app_state.app_config_fields.show_average_cpu;
|
||||
|
@ -189,30 +193,28 @@ impl CpuGraphWidget for Painter {
|
|||
vec![]
|
||||
};
|
||||
|
||||
let title = " CPU ".to_string();
|
||||
|
||||
let border_style = if app_state.current_widget.widget_id == widget_id {
|
||||
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)
|
||||
};
|
||||
|
||||
f.render_widget(
|
||||
Chart::default()
|
||||
Chart::new(dataset_vector)
|
||||
.block(
|
||||
Block::default()
|
||||
.title(&title)
|
||||
.title_style(if app_state.is_expanded {
|
||||
border_style
|
||||
} else {
|
||||
self.colours.widget_title_style
|
||||
})
|
||||
.title(title)
|
||||
.borders(Borders::ALL)
|
||||
.border_style(border_style),
|
||||
)
|
||||
.x_axis(x_axis)
|
||||
.y_axis(y_axis)
|
||||
.datasets(&dataset_vector),
|
||||
.y_axis(y_axis),
|
||||
draw_loc,
|
||||
);
|
||||
}
|
||||
|
@ -296,7 +298,6 @@ impl CpuGraphWidget for Painter {
|
|||
Table::new(CPU_LEGEND_HEADER.iter(), cpu_rows)
|
||||
.block(
|
||||
Block::default()
|
||||
.title_style(border_and_title_style)
|
||||
.borders(Borders::ALL)
|
||||
.border_style(border_and_title_style),
|
||||
)
|
||||
|
|
|
@ -4,6 +4,7 @@ use tui::{
|
|||
backend::Backend,
|
||||
layout::{Constraint, Direction, Layout, Rect},
|
||||
terminal::Frame,
|
||||
text::Span,
|
||||
widgets::{Block, Borders, Row, Table},
|
||||
};
|
||||
|
||||
|
@ -67,20 +68,6 @@ impl DiskTableWidget for Painter {
|
|||
get_variable_intrinsic_widths(width as u16, &width_ratios, &DISK_HEADERS_LENS);
|
||||
let intrinsic_widths = &variable_intrinsic_results.0[0..variable_intrinsic_results.1];
|
||||
|
||||
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()
|
||||
} else {
|
||||
" Disk ".to_string()
|
||||
};
|
||||
|
||||
let (border_and_title_style, highlight_style) = if is_on_widget {
|
||||
(
|
||||
self.colours.highlighted_border_style,
|
||||
|
@ -90,14 +77,27 @@ 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 disk_block = if draw_border {
|
||||
Block::default()
|
||||
.title(&title)
|
||||
.title_style(if app_state.is_expanded {
|
||||
border_and_title_style
|
||||
} else {
|
||||
self.colours.widget_title_style
|
||||
})
|
||||
.title(title)
|
||||
.borders(Borders::ALL)
|
||||
.border_style(border_and_title_style)
|
||||
} else if is_on_widget {
|
||||
|
|
|
@ -8,7 +8,8 @@ use tui::{
|
|||
backend::Backend,
|
||||
layout::{Constraint, Layout, Rect},
|
||||
terminal::Frame,
|
||||
widgets::{Block, Paragraph, Text},
|
||||
text::{Span, Spans},
|
||||
widgets::{Block, Paragraph},
|
||||
};
|
||||
|
||||
pub trait MemBasicWidget {
|
||||
|
@ -65,13 +66,13 @@ impl MemBasicWidget for Painter {
|
|||
swap_use_percentage.round(),
|
||||
);
|
||||
|
||||
let mem_text: Vec<Text<'_>> = vec![
|
||||
Text::Styled(mem_label.into(), self.colours.ram_style),
|
||||
Text::Styled(swap_label.into(), 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,6 +5,7 @@ use tui::{
|
|||
layout::{Constraint, Rect},
|
||||
symbols::Marker,
|
||||
terminal::Frame,
|
||||
text::Span,
|
||||
widgets::{Axis, Block, Borders, Chart, Dataset},
|
||||
};
|
||||
|
||||
|
@ -22,9 +23,12 @@ 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 x_axis = if app_state.app_config_fields.hide_time
|
||||
|| (app_state.app_config_fields.autohide_time
|
||||
|
@ -38,8 +42,7 @@ impl MemGraphWidget for Painter {
|
|||
Axis::default()
|
||||
.bounds([-(mem_widget_state.current_display_time as f64), 0.0])
|
||||
.style(self.colours.graph_style)
|
||||
.labels_style(self.colours.graph_style)
|
||||
.labels(&display_time_labels)
|
||||
.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,16 +53,17 @@ impl MemGraphWidget for Painter {
|
|||
Axis::default()
|
||||
.bounds([-(mem_widget_state.current_display_time as f64), 0.0])
|
||||
.style(self.colours.graph_style)
|
||||
.labels_style(self.colours.graph_style)
|
||||
.labels(&display_time_labels)
|
||||
.labels(display_time_labels)
|
||||
};
|
||||
|
||||
// Offset as the zero value isn't drawn otherwise...
|
||||
let y_axis: Axis<'_, &str> = Axis::default()
|
||||
let y_axis = Axis::default()
|
||||
.style(self.colours.graph_style)
|
||||
.labels_style(self.colours.graph_style)
|
||||
.bounds([-0.5, 100.5])
|
||||
.labels(&["0%", "100%"]);
|
||||
.labels(vec![
|
||||
Span::styled("0%", self.colours.graph_style),
|
||||
Span::styled("100%", self.colours.graph_style),
|
||||
]);
|
||||
|
||||
let mut mem_canvas_vec: Vec<Dataset<'_>> = vec![];
|
||||
|
||||
|
@ -91,26 +95,25 @@ impl MemGraphWidget for Painter {
|
|||
|
||||
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)
|
||||
)
|
||||
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,
|
||||
)
|
||||
} else {
|
||||
" Memory ".to_string()
|
||||
Span::styled(" Memory ".to_string(), self.colours.widget_title_style)
|
||||
};
|
||||
|
||||
f.render_widget(
|
||||
Chart::default()
|
||||
Chart::new(mem_canvas_vec)
|
||||
.block(
|
||||
Block::default()
|
||||
.title(&title)
|
||||
.title_style(if app_state.is_expanded {
|
||||
self.colours.highlighted_border_style
|
||||
} else {
|
||||
self.colours.widget_title_style
|
||||
})
|
||||
.title(title)
|
||||
.borders(Borders::ALL)
|
||||
.border_style(if app_state.current_widget.widget_id == widget_id {
|
||||
self.colours.highlighted_border_style
|
||||
|
@ -120,7 +123,6 @@ impl MemGraphWidget for Painter {
|
|||
)
|
||||
.x_axis(x_axis)
|
||||
.y_axis(y_axis)
|
||||
.datasets(&mem_canvas_vec)
|
||||
.hidden_legend_constraints((Constraint::Ratio(3, 4), Constraint::Ratio(3, 4))),
|
||||
draw_loc,
|
||||
);
|
||||
|
|
|
@ -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 {
|
||||
|
@ -49,22 +50,19 @@ impl NetworkBasicWidget for Painter {
|
|||
let total_tx_label = format!("Total TX: {}", &app_state.canvas_data.total_tx_display);
|
||||
|
||||
let net_text = vec![
|
||||
Text::Styled(rx_label.into(), self.colours.rx_style),
|
||||
Text::Styled(tx_label.into(), self.colours.tx_style),
|
||||
Spans::from(Span::styled(rx_label, self.colours.rx_style)),
|
||||
Spans::from(Span::styled(tx_label, self.colours.tx_style)),
|
||||
];
|
||||
|
||||
let total_net_text = vec![
|
||||
Text::Styled(total_rx_label.into(), self.colours.total_rx_style),
|
||||
Text::Styled(total_tx_label.into(), self.colours.total_tx_style),
|
||||
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],
|
||||
);
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ use tui::{
|
|||
layout::{Constraint, Direction, Layout, Rect},
|
||||
symbols::Marker,
|
||||
terminal::Frame,
|
||||
text::Span,
|
||||
widgets::{Axis, Block, Borders, Chart, Dataset, Row, Table},
|
||||
};
|
||||
|
||||
|
@ -71,9 +72,12 @@ 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 = [
|
||||
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
|
||||
|
@ -87,8 +91,7 @@ impl NetworkGraphWidget for Painter {
|
|||
Axis::default()
|
||||
.bounds([-(network_widget_state.current_display_time as f64), 0.0])
|
||||
.style(self.colours.graph_style)
|
||||
.labels_style(self.colours.graph_style)
|
||||
.labels(&display_time_labels)
|
||||
.labels(display_time_labels)
|
||||
} else {
|
||||
network_widget_state.autohide_timer = None;
|
||||
Axis::default()
|
||||
|
@ -100,27 +103,35 @@ impl NetworkGraphWidget for Painter {
|
|||
Axis::default()
|
||||
.bounds([-(network_widget_state.current_display_time as f64), 0.0])
|
||||
.style(self.colours.graph_style)
|
||||
.labels_style(self.colours.graph_style)
|
||||
.labels(&display_time_labels)
|
||||
.labels(display_time_labels)
|
||||
};
|
||||
|
||||
// 0 is offset.
|
||||
let y_axis: Axis<'_, &str> = Axis::default()
|
||||
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 = Axis::default()
|
||||
.style(self.colours.graph_style)
|
||||
.labels_style(self.colours.graph_style)
|
||||
.bounds([-0.5, 30_f64])
|
||||
.labels(&["0B", "1KiB", "1MiB", "1GiB"]);
|
||||
.labels(y_axis_labels);
|
||||
|
||||
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)
|
||||
)
|
||||
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,
|
||||
)
|
||||
} else {
|
||||
" Network ".to_string()
|
||||
Span::styled(" Network ".to_string(), self.colours.widget_title_style)
|
||||
};
|
||||
|
||||
let legend_constraints = if hide_legend {
|
||||
|
@ -209,15 +220,10 @@ impl NetworkGraphWidget for Painter {
|
|||
};
|
||||
|
||||
f.render_widget(
|
||||
Chart::default()
|
||||
Chart::new(dataset)
|
||||
.block(
|
||||
Block::default()
|
||||
.title(&title)
|
||||
.title_style(if app_state.is_expanded {
|
||||
self.colours.highlighted_border_style
|
||||
} else {
|
||||
self.colours.widget_title_style
|
||||
})
|
||||
.title(title)
|
||||
.borders(Borders::ALL)
|
||||
.border_style(if app_state.current_widget.widget_id == widget_id {
|
||||
self.colours.highlighted_border_style
|
||||
|
@ -227,7 +233,6 @@ impl NetworkGraphWidget for Painter {
|
|||
)
|
||||
.x_axis(x_axis)
|
||||
.y_axis(y_axis)
|
||||
.datasets(&dataset)
|
||||
.hidden_legend_constraints(legend_constraints),
|
||||
draw_loc,
|
||||
);
|
||||
|
|
|
@ -13,7 +13,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, Wrap},
|
||||
};
|
||||
|
||||
use unicode_segmentation::{GraphemeIndices, UnicodeSegmentation};
|
||||
|
@ -202,12 +203,12 @@ impl ProcessTableWidget for Painter {
|
|||
// TODO: This is a ugly work-around for now.
|
||||
let width_ratios = if proc_widget_state.is_grouped {
|
||||
if proc_widget_state.is_using_full_path {
|
||||
vec![0.1, 0.7, 0.05, 0.05, 0.025, 0.025, 0.025, 0.025]
|
||||
vec![0.05, 0.7, 0.05, 0.05, 0.0375, 0.0375, 0.0375, 0.0375]
|
||||
} else {
|
||||
vec![0.1, 0.2, 0.1, 0.1, 0.1, 0.1, 0.15, 0.15]
|
||||
}
|
||||
} else if proc_widget_state.is_using_full_path {
|
||||
vec![0.1, 0.7, 0.05, 0.05, 0.02, 0.02, 0.02, 0.02, 0.02]
|
||||
vec![0.05, 0.7, 0.05, 0.05, 0.03, 0.03, 0.03, 0.03]
|
||||
} else {
|
||||
vec![0.1, 0.2, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1]
|
||||
};
|
||||
|
@ -219,28 +220,6 @@ impl ProcessTableWidget for Painter {
|
|||
let intrinsic_widths =
|
||||
&(variable_intrinsic_results.0)[0..variable_intrinsic_results.1];
|
||||
|
||||
let title = if draw_border {
|
||||
if app_state.is_expanded
|
||||
&& !proc_widget_state
|
||||
.process_search_state
|
||||
.search_state
|
||||
.is_enabled
|
||||
{
|
||||
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()
|
||||
}
|
||||
} else {
|
||||
String::default()
|
||||
};
|
||||
|
||||
let (border_and_title_style, highlight_style) = if is_on_widget {
|
||||
(
|
||||
self.colours.highlighted_border_style,
|
||||
|
@ -250,14 +229,34 @@ 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
|
||||
{
|
||||
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,
|
||||
)
|
||||
} else {
|
||||
Span::styled(" Processes ".to_string(), self.colours.widget_title_style)
|
||||
}
|
||||
} else {
|
||||
Span::from(String::default())
|
||||
};
|
||||
|
||||
let process_block = if draw_border {
|
||||
Block::default()
|
||||
.title(&title)
|
||||
.title_style(if app_state.is_expanded {
|
||||
border_and_title_style
|
||||
} else {
|
||||
self.colours.widget_title_style
|
||||
})
|
||||
.title(title)
|
||||
.borders(Borders::ALL)
|
||||
.border_style(border_and_title_style)
|
||||
} else if is_on_widget {
|
||||
|
@ -304,7 +303,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 {
|
||||
|
@ -316,9 +315,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)
|
||||
}
|
||||
|
@ -326,20 +325,21 @@ 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
|
||||
} else {
|
||||
// This is easier - we just need to get a range of graphemes, rather than
|
||||
// dealing with possibly inserting a cursor (as none is shown!)
|
||||
|
||||
grapheme_indices
|
||||
.filter_map(|grapheme| {
|
||||
current_grapheme_posn += UnicodeWidthStr::width(grapheme.1);
|
||||
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)
|
||||
}
|
||||
})
|
||||
|
@ -372,17 +372,10 @@ impl ProcessTableWidget for Painter {
|
|||
app_state.is_force_redraw,
|
||||
);
|
||||
|
||||
let mut search_text = vec![Text::styled(
|
||||
search_title,
|
||||
if is_on_widget {
|
||||
self.colours.table_header_style
|
||||
} else {
|
||||
self.colours.text_style
|
||||
},
|
||||
)];
|
||||
let query = proc_widget_state.get_current_search_query().as_str();
|
||||
let grapheme_indices = UnicodeSegmentation::grapheme_indices(query, true);
|
||||
let query_with_cursor: Vec<Text<'_>> = build_query(
|
||||
|
||||
let query_with_cursor = build_query(
|
||||
is_on_widget,
|
||||
grapheme_indices,
|
||||
start_position,
|
||||
|
@ -392,6 +385,19 @@ impl ProcessTableWidget for Painter {
|
|||
self.colours.text_style,
|
||||
);
|
||||
|
||||
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
|
||||
} else {
|
||||
self.colours.text_style
|
||||
},
|
||||
)];
|
||||
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 {
|
||||
self.colours.currently_selected_text_style
|
||||
|
@ -417,41 +423,36 @@ impl ProcessTableWidget for Painter {
|
|||
self.colours.text_style
|
||||
};
|
||||
|
||||
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::from(" "),
|
||||
Span::styled(
|
||||
format!("Whole({})", if self.is_mac_os { "F2" } else { "Alt+W" }),
|
||||
whole_word_style,
|
||||
),
|
||||
Text::raw(" "),
|
||||
Text::styled(
|
||||
Span::from(" "),
|
||||
Span::styled(
|
||||
format!("Regex({})", if self.is_mac_os { "F3" } else { "Alt+R" }),
|
||||
regex_style,
|
||||
),
|
||||
];
|
||||
]);
|
||||
|
||||
search_text.extend(query_with_cursor);
|
||||
search_text.push(Text::styled(
|
||||
format!(
|
||||
"\n{}",
|
||||
if let Some(err) = &proc_widget_state
|
||||
.process_search_state
|
||||
.search_state
|
||||
.error_message
|
||||
{
|
||||
err.as_str()
|
||||
} else {
|
||||
""
|
||||
}
|
||||
),
|
||||
search_text.push(Spans::from(Span::styled(
|
||||
if let Some(err) = &proc_widget_state
|
||||
.process_search_state
|
||||
.search_state
|
||||
.error_message
|
||||
{
|
||||
err.as_str()
|
||||
} else {
|
||||
""
|
||||
},
|
||||
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
|
||||
|
@ -470,15 +471,17 @@ impl ProcessTableWidget for Painter {
|
|||
|
||||
let repeat_num =
|
||||
usize::from(draw_loc.width).saturating_sub(TITLE_BASE.chars().count() + 2);
|
||||
format!("{} Esc to close ", "─".repeat(repeat_num))
|
||||
Span::styled(
|
||||
format!("{} Esc to close ", "─".repeat(repeat_num)),
|
||||
current_border_style,
|
||||
)
|
||||
} else {
|
||||
String::new()
|
||||
Span::from(String::new())
|
||||
};
|
||||
|
||||
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 {
|
||||
|
@ -496,11 +499,11 @@ impl ProcessTableWidget for Painter {
|
|||
.split(draw_loc);
|
||||
|
||||
f.render_widget(
|
||||
Paragraph::new(search_text.iter())
|
||||
Paragraph::new(search_text)
|
||||
.block(process_search_block)
|
||||
.style(self.colours.text_style)
|
||||
.alignment(Alignment::Left)
|
||||
.wrap(false),
|
||||
.wrap(Wrap { trim: false }),
|
||||
margined_draw_loc[0],
|
||||
);
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ use tui::{
|
|||
backend::Backend,
|
||||
layout::{Constraint, Direction, Layout, Rect},
|
||||
terminal::Frame,
|
||||
text::Span,
|
||||
widgets::{Block, Borders, Row, Table},
|
||||
};
|
||||
|
||||
|
@ -67,20 +68,6 @@ impl TempTableWidget for Painter {
|
|||
get_variable_intrinsic_widths(width as u16, &width_ratios, &TEMP_HEADERS_LENS);
|
||||
let intrinsic_widths = &(variable_intrinsic_results.0)[0..variable_intrinsic_results.1];
|
||||
|
||||
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()
|
||||
} else {
|
||||
" Temperatures ".to_string()
|
||||
};
|
||||
|
||||
let (border_and_title_style, highlight_style) = if is_on_widget {
|
||||
(
|
||||
self.colours.highlighted_border_style,
|
||||
|
@ -90,14 +77,30 @@ impl TempTableWidget for Painter {
|
|||
(self.colours.border_style, self.colours.text_style)
|
||||
};
|
||||
|
||||
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,
|
||||
)
|
||||
} else if app_state.app_config_fields.use_basic_mode {
|
||||
Span::from(String::new())
|
||||
} else {
|
||||
Span::styled(
|
||||
" Temperatures ".to_string(),
|
||||
self.colours.widget_title_style,
|
||||
)
|
||||
};
|
||||
|
||||
let temp_block = if draw_border {
|
||||
Block::default()
|
||||
.title(&title)
|
||||
.title_style(if app_state.is_expanded {
|
||||
border_and_title_style
|
||||
} else {
|
||||
self.colours.widget_title_style
|
||||
})
|
||||
.title(title)
|
||||
.borders(Borders::ALL)
|
||||
.border_style(border_and_title_style)
|
||||
} else if is_on_widget {
|
||||
|
|
|
@ -365,6 +365,8 @@ fn create_config(flag_config_location: Option<&str>) -> error::Result<Config> {
|
|||
}
|
||||
} else if let Some(home_path) = dirs::home_dir() {
|
||||
let mut path = home_path;
|
||||
// TODO: This should not be done like this IMO... it should be based on the defaults set by dirs rather than home_dir
|
||||
// This WILL cause breaking changes on macOS though, warning!
|
||||
path.push(DEFAULT_UNIX_CONFIG_FILE_PATH);
|
||||
path.into_os_string()
|
||||
} else {
|
||||
|
|
Loading…
Reference in a new issue