mirror of
https://github.com/ClementTsang/bottom.git
synced 2025-07-27 07:34:27 +02:00
feature: support custom widget borders (#1642)
* run a dep bump * add widget border type * feature: support custom widget borders * fmt * remove none since it looks really bad * fix bug with title for tables with no title when expanded * fix jsonschema * fix some unused stuff
This commit is contained in:
parent
1fe17ddc21
commit
0d182e4b3a
8
Cargo.lock
generated
8
Cargo.lock
generated
@ -620,9 +620,9 @@ checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "hashbrown"
|
||||||
version = "0.15.1"
|
version = "0.15.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3"
|
checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"allocator-api2",
|
"allocator-api2",
|
||||||
"equivalent",
|
"equivalent",
|
||||||
@ -1278,9 +1278,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_json"
|
name = "serde_json"
|
||||||
version = "1.0.132"
|
version = "1.0.133"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03"
|
checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itoa",
|
"itoa",
|
||||||
"memchr",
|
"memchr",
|
||||||
|
@ -81,7 +81,7 @@ crossterm = "0.28.1"
|
|||||||
ctrlc = { version = "3.4.5", features = ["termination"] }
|
ctrlc = { version = "3.4.5", features = ["termination"] }
|
||||||
dirs = "5.0.1"
|
dirs = "5.0.1"
|
||||||
# Maybe consider https://github.com/rust-lang/rustc-hash for some cases too?
|
# Maybe consider https://github.com/rust-lang/rustc-hash for some cases too?
|
||||||
hashbrown = "0.15.0"
|
hashbrown = "0.15.2"
|
||||||
humantime = "2.1.0"
|
humantime = "2.1.0"
|
||||||
indexmap = "2.6.0"
|
indexmap = "2.6.0"
|
||||||
indoc = "2.0.5"
|
indoc = "2.0.5"
|
||||||
@ -104,7 +104,7 @@ time = { version = "0.3.36", features = ["local-offset", "formatting", "macros"]
|
|||||||
|
|
||||||
# These are just used for JSON schema generation.
|
# These are just used for JSON schema generation.
|
||||||
schemars = { version = "0.8.21", optional = true }
|
schemars = { version = "0.8.21", optional = true }
|
||||||
serde_json = { version = "1.0.132", optional = true }
|
serde_json = { version = "1.0.133", optional = true }
|
||||||
strum = { version = "0.26.3", features = ["derive"], optional = true }
|
strum = { version = "0.26.3", features = ["derive"], optional = true }
|
||||||
|
|
||||||
[target.'cfg(unix)'.dependencies]
|
[target.'cfg(unix)'.dependencies]
|
||||||
|
@ -955,6 +955,15 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"WidgetBorderType": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Default",
|
||||||
|
"Rounded",
|
||||||
|
"Double",
|
||||||
|
"Thick"
|
||||||
|
]
|
||||||
|
},
|
||||||
"WidgetStyle": {
|
"WidgetStyle": {
|
||||||
"description": "General styling for generic widgets.",
|
"description": "General styling for generic widgets.",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
@ -1014,6 +1023,17 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"widget_border_type": {
|
||||||
|
"description": "Widget borders type.",
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/WidgetBorderType"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"widget_title": {
|
"widget_title": {
|
||||||
"description": "Text styling for a widget's title.",
|
"description": "Text styling for a widget's title.",
|
||||||
"anyOf": [
|
"anyOf": [
|
||||||
|
@ -18,12 +18,12 @@ use crate::{
|
|||||||
App,
|
App,
|
||||||
},
|
},
|
||||||
constants::*,
|
constants::*,
|
||||||
options::config::style::ColourPalette,
|
options::config::style::Styles,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Handles the canvas' state.
|
/// Handles the canvas' state.
|
||||||
pub struct Painter {
|
pub struct Painter {
|
||||||
pub colours: ColourPalette,
|
pub styles: Styles,
|
||||||
previous_height: u16,
|
previous_height: u16,
|
||||||
previous_width: u16,
|
previous_width: u16,
|
||||||
|
|
||||||
@ -47,7 +47,7 @@ pub enum LayoutConstraint {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Painter {
|
impl Painter {
|
||||||
pub fn init(layout: BottomLayout, styling: ColourPalette) -> anyhow::Result<Self> {
|
pub fn init(layout: BottomLayout, styling: Styles) -> anyhow::Result<Self> {
|
||||||
// Now for modularity; we have to also initialize the base layouts!
|
// Now for modularity; we have to also initialize the base layouts!
|
||||||
// We want to do this ONCE and reuse; after this we can just construct
|
// We want to do this ONCE and reuse; after this we can just construct
|
||||||
// based on the console size.
|
// based on the console size.
|
||||||
@ -131,7 +131,7 @@ impl Painter {
|
|||||||
});
|
});
|
||||||
|
|
||||||
let painter = Painter {
|
let painter = Painter {
|
||||||
colours: styling,
|
styles: styling,
|
||||||
previous_height: 0,
|
previous_height: 0,
|
||||||
previous_width: 0,
|
previous_width: 0,
|
||||||
row_constraints,
|
row_constraints,
|
||||||
@ -149,9 +149,9 @@ impl Painter {
|
|||||||
pub fn get_border_style(&self, widget_id: u64, selected_widget_id: u64) -> tui::style::Style {
|
pub fn get_border_style(&self, widget_id: u64, selected_widget_id: u64) -> tui::style::Style {
|
||||||
let is_on_widget = widget_id == selected_widget_id;
|
let is_on_widget = widget_id == selected_widget_id;
|
||||||
if is_on_widget {
|
if is_on_widget {
|
||||||
self.colours.highlighted_border_style
|
self.styles.highlighted_border_style
|
||||||
} else {
|
} else {
|
||||||
self.colours.border_style
|
self.styles.border_style
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,7 +159,7 @@ impl Painter {
|
|||||||
f.render_widget(
|
f.render_widget(
|
||||||
Paragraph::new(Span::styled(
|
Paragraph::new(Span::styled(
|
||||||
"Frozen, press 'f' to unfreeze",
|
"Frozen, press 'f' to unfreeze",
|
||||||
self.colours.selected_text_style,
|
self.styles.selected_text_style,
|
||||||
)),
|
)),
|
||||||
Layout::default()
|
Layout::default()
|
||||||
.horizontal_margin(1)
|
.horizontal_margin(1)
|
||||||
@ -333,15 +333,11 @@ impl Painter {
|
|||||||
_ => 0,
|
_ => 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
self.draw_process(f, app_state, rect[0], true, widget_id);
|
self.draw_process(f, app_state, rect[0], widget_id);
|
||||||
|
}
|
||||||
|
Battery => {
|
||||||
|
self.draw_battery(f, app_state, rect[0], app_state.current_widget.widget_id)
|
||||||
}
|
}
|
||||||
Battery => self.draw_battery(
|
|
||||||
f,
|
|
||||||
app_state,
|
|
||||||
rect[0],
|
|
||||||
true,
|
|
||||||
app_state.current_widget.widget_id,
|
|
||||||
),
|
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
} else if app_state.app_config_fields.use_basic_mode {
|
} else if app_state.app_config_fields.use_basic_mode {
|
||||||
@ -444,18 +440,14 @@ impl Painter {
|
|||||||
ProcSort => 2,
|
ProcSort => 2,
|
||||||
_ => 0,
|
_ => 0,
|
||||||
};
|
};
|
||||||
self.draw_process(f, app_state, vertical_chunks[3], false, wid);
|
self.draw_process(f, app_state, vertical_chunks[3], wid);
|
||||||
}
|
}
|
||||||
Temp => {
|
Temp => {
|
||||||
self.draw_temp_table(f, app_state, vertical_chunks[3], widget_id)
|
self.draw_temp_table(f, app_state, vertical_chunks[3], widget_id)
|
||||||
}
|
}
|
||||||
Battery => self.draw_battery(
|
Battery => {
|
||||||
f,
|
self.draw_battery(f, app_state, vertical_chunks[3], widget_id)
|
||||||
app_state,
|
}
|
||||||
vertical_chunks[3],
|
|
||||||
false,
|
|
||||||
widget_id,
|
|
||||||
),
|
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -729,8 +721,8 @@ impl Painter {
|
|||||||
Net => self.draw_network(f, app_state, *draw_loc, widget.widget_id),
|
Net => self.draw_network(f, app_state, *draw_loc, widget.widget_id),
|
||||||
Temp => self.draw_temp_table(f, app_state, *draw_loc, widget.widget_id),
|
Temp => self.draw_temp_table(f, app_state, *draw_loc, widget.widget_id),
|
||||||
Disk => self.draw_disk_table(f, app_state, *draw_loc, widget.widget_id),
|
Disk => self.draw_disk_table(f, app_state, *draw_loc, widget.widget_id),
|
||||||
Proc => self.draw_process(f, app_state, *draw_loc, true, widget.widget_id),
|
Proc => self.draw_process(f, app_state, *draw_loc, widget.widget_id),
|
||||||
Battery => self.draw_battery(f, app_state, *draw_loc, true, widget.widget_id),
|
Battery => self.draw_battery(f, app_state, *draw_loc, widget.widget_id),
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
pub mod data_table;
|
pub mod data_table;
|
||||||
pub mod time_graph;
|
pub mod time_graph;
|
||||||
mod tui_widget;
|
mod tui_widget;
|
||||||
|
|
||||||
pub mod widget_carousel;
|
pub mod widget_carousel;
|
||||||
|
|
||||||
pub use tui_widget::*;
|
pub use tui_widget::*;
|
||||||
|
@ -7,10 +7,9 @@ use concat_string::concat_string;
|
|||||||
use tui::{
|
use tui::{
|
||||||
layout::{Constraint, Direction, Layout, Rect},
|
layout::{Constraint, Direction, Layout, Rect},
|
||||||
text::{Line, Span, Text},
|
text::{Line, Span, Text},
|
||||||
widgets::{Block, Borders, Row, Table},
|
widgets::{Block, Row, Table},
|
||||||
Frame,
|
Frame,
|
||||||
};
|
};
|
||||||
use unicode_segmentation::UnicodeSegmentation;
|
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
CalculateColumnWidths, ColumnHeader, ColumnWidthBounds, DataTable, DataTableColumn, DataToCell,
|
CalculateColumnWidths, ColumnHeader, ColumnWidthBounds, DataTable, DataTableColumn, DataToCell,
|
||||||
@ -18,8 +17,8 @@ use super::{
|
|||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
app::layout_manager::BottomWidget,
|
app::layout_manager::BottomWidget,
|
||||||
canvas::Painter,
|
canvas::{drawing_utils::widget_block, Painter},
|
||||||
constants::{SIDE_BORDERS, TABLE_GAP_HEIGHT_LIMIT},
|
constants::TABLE_GAP_HEIGHT_LIMIT,
|
||||||
utils::strings::truncate_to_text,
|
utils::strings::truncate_to_text,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -68,46 +67,41 @@ where
|
|||||||
C: DataTableColumn<H>,
|
C: DataTableColumn<H>,
|
||||||
{
|
{
|
||||||
fn block<'a>(&self, draw_info: &'a DrawInfo, data_len: usize) -> Block<'a> {
|
fn block<'a>(&self, draw_info: &'a DrawInfo, data_len: usize) -> Block<'a> {
|
||||||
let border_style = match draw_info.selection_state {
|
let is_selected = match draw_info.selection_state {
|
||||||
SelectionState::NotSelected => self.styling.border_style,
|
SelectionState::NotSelected => false,
|
||||||
SelectionState::Selected | SelectionState::Expanded => {
|
SelectionState::Selected | SelectionState::Expanded => true,
|
||||||
self.styling.highlighted_border_style
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if !self.props.is_basic {
|
let border_style = if is_selected {
|
||||||
let block = Block::default()
|
self.styling.highlighted_border_style
|
||||||
.borders(Borders::ALL)
|
|
||||||
.border_style(border_style);
|
|
||||||
|
|
||||||
if let Some(title) = self.generate_title(draw_info, data_len) {
|
|
||||||
block.title(title)
|
|
||||||
} else {
|
|
||||||
block
|
|
||||||
}
|
|
||||||
} else if draw_info.is_on_widget() {
|
|
||||||
// Implies it is basic mode but selected.
|
|
||||||
Block::default()
|
|
||||||
.borders(SIDE_BORDERS)
|
|
||||||
.border_style(border_style)
|
|
||||||
} else {
|
} else {
|
||||||
Block::default().borders(Borders::NONE)
|
self.styling.border_style
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut block = widget_block(self.props.is_basic, is_selected, self.styling.border_type)
|
||||||
|
.border_style(border_style);
|
||||||
|
|
||||||
|
if let Some((left_title, right_title)) = self.generate_title(draw_info, data_len) {
|
||||||
|
if !self.props.is_basic {
|
||||||
|
block = block.title_top(left_title);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(right_title) = right_title {
|
||||||
|
block = block.title_top(right_title);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
block
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generates a title, given the available space.
|
/// Generates a title, given the available space.
|
||||||
pub fn generate_title<'a>(
|
fn generate_title(
|
||||||
&self, draw_info: &'a DrawInfo, total_items: usize,
|
&self, draw_info: &'_ DrawInfo, total_items: usize,
|
||||||
) -> Option<Line<'a>> {
|
) -> Option<(Line<'static>, Option<Line<'static>>)> {
|
||||||
self.props.title.as_ref().map(|title| {
|
self.props.title.as_ref().map(|title| {
|
||||||
let current_index = self.state.current_index.saturating_add(1);
|
let current_index = self.state.current_index.saturating_add(1);
|
||||||
let draw_loc = draw_info.loc;
|
let draw_loc = draw_info.loc;
|
||||||
let title_style = self.styling.title_style;
|
let title_style = self.styling.title_style;
|
||||||
let border_style = if draw_info.is_on_widget() {
|
|
||||||
self.styling.highlighted_border_style
|
|
||||||
} else {
|
|
||||||
self.styling.border_style
|
|
||||||
};
|
|
||||||
|
|
||||||
let title = if self.props.show_table_scroll_position {
|
let title = if self.props.show_table_scroll_position {
|
||||||
let pos = current_index.to_string();
|
let pos = current_index.to_string();
|
||||||
@ -123,19 +117,15 @@ where
|
|||||||
title.to_string()
|
title.to_string()
|
||||||
};
|
};
|
||||||
|
|
||||||
if draw_info.is_expanded() {
|
let left_title = Line::from(Span::styled(title, title_style)).left_aligned();
|
||||||
let title_base = concat_string!(title, "── Esc to go back ");
|
|
||||||
let lines = "─".repeat(usize::from(draw_loc.width).saturating_sub(
|
let right_title = if draw_info.is_expanded() {
|
||||||
UnicodeSegmentation::graphemes(title_base.as_str(), true).count() + 2,
|
Some(Line::from(" Esc to go back ").right_aligned())
|
||||||
));
|
|
||||||
let esc = concat_string!("─", lines, "─ Esc to go back ");
|
|
||||||
Line::from(vec![
|
|
||||||
Span::styled(title, title_style),
|
|
||||||
Span::styled(esc, border_style),
|
|
||||||
])
|
|
||||||
} else {
|
} else {
|
||||||
Line::from(Span::styled(title, title_style))
|
None
|
||||||
}
|
};
|
||||||
|
|
||||||
|
(left_title, right_title)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,8 +192,9 @@ where
|
|||||||
|
|
||||||
if !self.data.is_empty() || !self.first_draw {
|
if !self.data.is_empty() || !self.first_draw {
|
||||||
if self.first_draw {
|
if self.first_draw {
|
||||||
self.first_draw = false; // TODO: Doing it this way is fine, but it could be done better (e.g. showing
|
// TODO: Doing it this way is fine, but it could be done better (e.g. showing
|
||||||
// custom no results/entries message)
|
// custom no results/entries message)
|
||||||
|
self.first_draw = false;
|
||||||
if let Some(first_index) = self.first_index {
|
if let Some(first_index) = self.first_index {
|
||||||
self.set_position(first_index);
|
self.set_position(first_index);
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
use tui::style::Style;
|
use tui::{style::Style, widgets::BorderType};
|
||||||
|
|
||||||
use crate::options::config::style::ColourPalette;
|
use crate::options::config::style::Styles;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct DataTableStyling {
|
pub struct DataTableStyling {
|
||||||
pub header_style: Style,
|
pub header_style: Style,
|
||||||
pub border_style: Style,
|
pub border_style: Style,
|
||||||
|
pub border_type: BorderType,
|
||||||
pub highlighted_border_style: Style,
|
pub highlighted_border_style: Style,
|
||||||
pub text_style: Style,
|
pub text_style: Style,
|
||||||
pub highlighted_text_style: Style,
|
pub highlighted_text_style: Style,
|
||||||
@ -13,14 +14,15 @@ pub struct DataTableStyling {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl DataTableStyling {
|
impl DataTableStyling {
|
||||||
pub fn from_palette(colours: &ColourPalette) -> Self {
|
pub fn from_palette(styles: &Styles) -> Self {
|
||||||
Self {
|
Self {
|
||||||
header_style: colours.table_header_style,
|
header_style: styles.table_header_style,
|
||||||
border_style: colours.border_style,
|
border_style: styles.border_style,
|
||||||
highlighted_border_style: colours.highlighted_border_style,
|
border_type: styles.border_type,
|
||||||
text_style: colours.text_style,
|
highlighted_border_style: styles.highlighted_border_style,
|
||||||
highlighted_text_style: colours.selected_text_style,
|
text_style: styles.text_style,
|
||||||
title_style: colours.widget_title_style,
|
highlighted_text_style: styles.selected_text_style,
|
||||||
|
title_style: styles.widget_title_style,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,10 +6,11 @@ use tui::{
|
|||||||
style::Style,
|
style::Style,
|
||||||
symbols::Marker,
|
symbols::Marker,
|
||||||
text::{Line, Span},
|
text::{Line, Span},
|
||||||
widgets::{Block, Borders, GraphType},
|
widgets::{BorderType, GraphType},
|
||||||
Frame,
|
Frame,
|
||||||
};
|
};
|
||||||
use unicode_segmentation::UnicodeSegmentation;
|
|
||||||
|
use crate::canvas::drawing_utils::widget_block;
|
||||||
|
|
||||||
use super::time_chart::{
|
use super::time_chart::{
|
||||||
Axis, Dataset, LegendPosition, Point, TimeChart, DEFAULT_LEGEND_CONSTRAINTS,
|
Axis, Dataset, LegendPosition, Point, TimeChart, DEFAULT_LEGEND_CONSTRAINTS,
|
||||||
@ -42,9 +43,15 @@ pub struct TimeGraph<'a> {
|
|||||||
/// The border style.
|
/// The border style.
|
||||||
pub border_style: Style,
|
pub border_style: Style,
|
||||||
|
|
||||||
|
/// The border type.
|
||||||
|
pub border_type: BorderType,
|
||||||
|
|
||||||
/// The graph title.
|
/// The graph title.
|
||||||
pub title: Cow<'a, str>,
|
pub title: Cow<'a, str>,
|
||||||
|
|
||||||
|
/// Whether this graph is selected.
|
||||||
|
pub is_selected: bool,
|
||||||
|
|
||||||
/// Whether this graph is expanded.
|
/// Whether this graph is expanded.
|
||||||
pub is_expanded: bool,
|
pub is_expanded: bool,
|
||||||
|
|
||||||
@ -100,29 +107,6 @@ impl TimeGraph<'_> {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generates a title for the [`TimeGraph`] widget, given the available
|
|
||||||
/// space.
|
|
||||||
fn generate_title(&self, draw_loc: Rect) -> Line<'_> {
|
|
||||||
if self.is_expanded {
|
|
||||||
let title_base = concat_string!(self.title, "── Esc to go back ");
|
|
||||||
Line::from(vec![
|
|
||||||
Span::styled(self.title.as_ref(), self.title_style),
|
|
||||||
Span::styled(
|
|
||||||
concat_string!(
|
|
||||||
"─",
|
|
||||||
"─".repeat(usize::from(draw_loc.width).saturating_sub(
|
|
||||||
UnicodeSegmentation::graphemes(title_base.as_str(), true).count() + 2
|
|
||||||
)),
|
|
||||||
"─ Esc to go back "
|
|
||||||
),
|
|
||||||
self.border_style,
|
|
||||||
),
|
|
||||||
])
|
|
||||||
} else {
|
|
||||||
Line::from(Span::styled(self.title.as_ref(), self.title_style))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Draws a time graph at [`Rect`] location provided by `draw_loc`. A time
|
/// Draws a time graph at [`Rect`] location provided by `draw_loc`. A time
|
||||||
/// graph is used to display data points throughout time in the x-axis.
|
/// graph is used to display data points throughout time in the x-axis.
|
||||||
///
|
///
|
||||||
@ -139,10 +123,18 @@ impl TimeGraph<'_> {
|
|||||||
// This is some ugly manual loop unswitching. Maybe unnecessary.
|
// This is some ugly manual loop unswitching. Maybe unnecessary.
|
||||||
// TODO: Optimize this step. Cut out unneeded points.
|
// TODO: Optimize this step. Cut out unneeded points.
|
||||||
let data = graph_data.iter().map(create_dataset).collect();
|
let data = graph_data.iter().map(create_dataset).collect();
|
||||||
let block = Block::default()
|
|
||||||
.title(self.generate_title(draw_loc))
|
let block = {
|
||||||
.borders(Borders::ALL)
|
let mut b = widget_block(false, self.is_selected, self.border_type)
|
||||||
.border_style(self.border_style);
|
.border_style(self.border_style)
|
||||||
|
.title_top(Line::styled(self.title.as_ref(), self.title_style));
|
||||||
|
|
||||||
|
if self.is_expanded {
|
||||||
|
b = b.title_top(Line::styled(" Esc to go back ", self.title_style).right_aligned())
|
||||||
|
}
|
||||||
|
|
||||||
|
b
|
||||||
|
};
|
||||||
|
|
||||||
f.render_widget(
|
f.render_widget(
|
||||||
TimeChart::new(data)
|
TimeChart::new(data)
|
||||||
@ -186,10 +178,10 @@ mod test {
|
|||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
use tui::{
|
use tui::{
|
||||||
layout::Rect,
|
|
||||||
style::{Color, Style},
|
style::{Color, Style},
|
||||||
symbols::Marker,
|
symbols::Marker,
|
||||||
text::{Line, Span},
|
text::Span,
|
||||||
|
widgets::BorderType,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::TimeGraph;
|
use super::TimeGraph;
|
||||||
@ -210,6 +202,8 @@ mod test {
|
|||||||
y_labels: &Y_LABELS,
|
y_labels: &Y_LABELS,
|
||||||
graph_style: Style::default().fg(Color::Red),
|
graph_style: Style::default().fg(Color::Red),
|
||||||
border_style: Style::default().fg(Color::Blue),
|
border_style: Style::default().fg(Color::Blue),
|
||||||
|
border_type: BorderType::Plain,
|
||||||
|
is_selected: false,
|
||||||
is_expanded: false,
|
is_expanded: false,
|
||||||
title_style: Style::default().fg(Color::Cyan),
|
title_style: Style::default().fg(Color::Cyan),
|
||||||
legend_position: None,
|
legend_position: None,
|
||||||
@ -252,26 +246,4 @@ mod test {
|
|||||||
assert_eq!(y_axis.labels, actual.labels);
|
assert_eq!(y_axis.labels, actual.labels);
|
||||||
assert_eq!(y_axis.style, actual.style);
|
assert_eq!(y_axis.style, actual.style);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn time_graph_gen_title() {
|
|
||||||
let mut time_graph = create_time_graph();
|
|
||||||
let draw_loc = Rect::new(0, 0, 32, 100);
|
|
||||||
|
|
||||||
let title = time_graph.generate_title(draw_loc);
|
|
||||||
assert_eq!(
|
|
||||||
title,
|
|
||||||
Line::from(Span::styled(" Network ", Style::default().fg(Color::Cyan)))
|
|
||||||
);
|
|
||||||
|
|
||||||
time_graph.is_expanded = true;
|
|
||||||
let title = time_graph.generate_title(draw_loc);
|
|
||||||
assert_eq!(
|
|
||||||
title,
|
|
||||||
Line::from(vec![
|
|
||||||
Span::styled(" Network ", Style::default().fg(Color::Cyan)),
|
|
||||||
Span::styled("───── Esc to go back ", Style::default().fg(Color::Blue))
|
|
||||||
])
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -84,26 +84,25 @@ impl Painter {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// TODO: I can do this text effect as just a border now!
|
||||||
let left_name = left_table.get_pretty_name();
|
let left_name = left_table.get_pretty_name();
|
||||||
let right_name = right_table.get_pretty_name();
|
let right_name = right_table.get_pretty_name();
|
||||||
|
|
||||||
let num_spaces =
|
let num_spaces =
|
||||||
usize::from(draw_loc.width).saturating_sub(6 + left_name.len() + right_name.len());
|
usize::from(draw_loc.width).saturating_sub(6 + left_name.len() + right_name.len());
|
||||||
|
let carousel_text_style = if widget_id == app_state.current_widget.widget_id {
|
||||||
|
self.styles.highlighted_border_style
|
||||||
|
} else {
|
||||||
|
self.styles.text_style
|
||||||
|
};
|
||||||
|
|
||||||
let left_arrow_text = vec![
|
let left_arrow_text = vec![
|
||||||
Line::default(),
|
Line::default(),
|
||||||
Line::from(Span::styled(
|
Line::from(Span::styled(format!("◄ {left_name}"), carousel_text_style)),
|
||||||
format!("◄ {left_name}"),
|
|
||||||
self.colours.text_style,
|
|
||||||
)),
|
|
||||||
];
|
];
|
||||||
|
|
||||||
let right_arrow_text = vec![
|
let right_arrow_text = vec![
|
||||||
Line::default(),
|
Line::default(),
|
||||||
Line::from(Span::styled(
|
Line::from(Span::styled(format!("{right_name} ►"), carousel_text_style)),
|
||||||
format!("{right_name} ►"),
|
|
||||||
self.colours.text_style,
|
|
||||||
)),
|
|
||||||
];
|
];
|
||||||
|
|
||||||
let margined_draw_loc = Layout::default()
|
let margined_draw_loc = Layout::default()
|
||||||
|
@ -4,19 +4,16 @@ use std::cmp::min;
|
|||||||
use tui::{
|
use tui::{
|
||||||
layout::{Alignment, Constraint, Direction, Layout, Rect},
|
layout::{Alignment, Constraint, Direction, Layout, Rect},
|
||||||
text::{Line, Span, Text},
|
text::{Line, Span, Text},
|
||||||
widgets::{Block, Borders, Paragraph, Wrap},
|
widgets::{Block, Paragraph, Wrap},
|
||||||
Frame,
|
Frame,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
app::{App, KillSignal, MAX_PROCESS_SIGNAL},
|
app::{App, KillSignal, MAX_PROCESS_SIGNAL},
|
||||||
canvas::Painter,
|
canvas::{drawing_utils::dialog_block, Painter},
|
||||||
widgets::ProcWidgetMode,
|
widgets::ProcWidgetMode,
|
||||||
};
|
};
|
||||||
|
|
||||||
const DD_BASE: &str = " Confirm Kill Process ── Esc to close ";
|
|
||||||
const DD_ERROR_BASE: &str = " Error ── Esc to close ";
|
|
||||||
|
|
||||||
cfg_if::cfg_if! {
|
cfg_if::cfg_if! {
|
||||||
if #[cfg(target_os = "linux")] {
|
if #[cfg(target_os = "linux")] {
|
||||||
const SIGNAL_TEXT: [&str; 63] = [
|
const SIGNAL_TEXT: [&str; 63] = [
|
||||||
@ -211,12 +208,12 @@ impl Painter {
|
|||||||
if MAX_PROCESS_SIGNAL == 1 || !app_state.app_config_fields.is_advanced_kill {
|
if MAX_PROCESS_SIGNAL == 1 || !app_state.app_config_fields.is_advanced_kill {
|
||||||
let (yes_button, no_button) = match app_state.delete_dialog_state.selected_signal {
|
let (yes_button, no_button) = match app_state.delete_dialog_state.selected_signal {
|
||||||
KillSignal::Kill(_) => (
|
KillSignal::Kill(_) => (
|
||||||
Span::styled("Yes", self.colours.selected_text_style),
|
Span::styled("Yes", self.styles.selected_text_style),
|
||||||
Span::styled("No", self.colours.text_style),
|
Span::styled("No", self.styles.text_style),
|
||||||
),
|
),
|
||||||
KillSignal::Cancel => (
|
KillSignal::Cancel => (
|
||||||
Span::styled("Yes", self.colours.text_style),
|
Span::styled("Yes", self.styles.text_style),
|
||||||
Span::styled("No", self.colours.selected_text_style),
|
Span::styled("No", self.styles.selected_text_style),
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -322,11 +319,11 @@ impl Painter {
|
|||||||
let mut buttons = SIGNAL_TEXT
|
let mut buttons = SIGNAL_TEXT
|
||||||
[scroll_offset + 1..min((layout.len()) + scroll_offset, SIGNAL_TEXT.len())]
|
[scroll_offset + 1..min((layout.len()) + scroll_offset, SIGNAL_TEXT.len())]
|
||||||
.iter()
|
.iter()
|
||||||
.map(|text| Span::styled(*text, self.colours.text_style))
|
.map(|text| Span::styled(*text, self.styles.text_style))
|
||||||
.collect::<Vec<Span<'_>>>();
|
.collect::<Vec<Span<'_>>>();
|
||||||
buttons.insert(0, Span::styled(SIGNAL_TEXT[0], self.colours.text_style));
|
buttons.insert(0, Span::styled(SIGNAL_TEXT[0], self.styles.text_style));
|
||||||
buttons[selected - scroll_offset] =
|
buttons[selected - scroll_offset] =
|
||||||
Span::styled(SIGNAL_TEXT[selected], self.colours.selected_text_style);
|
Span::styled(SIGNAL_TEXT[selected], self.styles.selected_text_style);
|
||||||
|
|
||||||
app_state.delete_dialog_state.button_positions = layout
|
app_state.delete_dialog_state.button_positions = layout
|
||||||
.iter()
|
.iter()
|
||||||
@ -354,45 +351,24 @@ impl Painter {
|
|||||||
) -> bool {
|
) -> bool {
|
||||||
if let Some(dd_text) = dd_text {
|
if let Some(dd_text) = dd_text {
|
||||||
let dd_title = if app_state.dd_err.is_some() {
|
let dd_title = if app_state.dd_err.is_some() {
|
||||||
Line::from(vec![
|
Line::styled(" Error ", self.styles.widget_title_style)
|
||||||
Span::styled(" Error ", self.colours.widget_title_style),
|
|
||||||
Span::styled(
|
|
||||||
format!(
|
|
||||||
"─{}─ Esc to close ",
|
|
||||||
"─".repeat(
|
|
||||||
usize::from(draw_loc.width)
|
|
||||||
.saturating_sub(DD_ERROR_BASE.chars().count() + 2)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
self.colours.border_style,
|
|
||||||
),
|
|
||||||
])
|
|
||||||
} else {
|
} else {
|
||||||
Line::from(vec![
|
Line::styled(" Confirm Kill Process ", self.styles.widget_title_style)
|
||||||
Span::styled(" Confirm Kill Process ", self.colours.widget_title_style),
|
|
||||||
Span::styled(
|
|
||||||
format!(
|
|
||||||
"─{}─ Esc to close ",
|
|
||||||
"─".repeat(
|
|
||||||
usize::from(draw_loc.width)
|
|
||||||
.saturating_sub(DD_BASE.chars().count() + 2)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
self.colours.border_style,
|
|
||||||
),
|
|
||||||
])
|
|
||||||
};
|
};
|
||||||
|
|
||||||
f.render_widget(
|
f.render_widget(
|
||||||
Paragraph::new(dd_text)
|
Paragraph::new(dd_text)
|
||||||
.block(
|
.block(
|
||||||
Block::default()
|
dialog_block(self.styles.border_type)
|
||||||
.title(dd_title)
|
.title_top(dd_title)
|
||||||
.style(self.colours.border_style)
|
.title_top(
|
||||||
.borders(Borders::ALL)
|
Line::styled(" Esc to close ", self.styles.widget_title_style)
|
||||||
.border_style(self.colours.border_style),
|
.right_aligned(),
|
||||||
|
)
|
||||||
|
.style(self.styles.border_style)
|
||||||
|
.border_style(self.styles.border_style),
|
||||||
)
|
)
|
||||||
.style(self.colours.text_style)
|
.style(self.styles.text_style)
|
||||||
.alignment(Alignment::Center)
|
.alignment(Alignment::Center)
|
||||||
.wrap(Wrap { trim: true }),
|
.wrap(Wrap { trim: true }),
|
||||||
draw_loc,
|
draw_loc,
|
||||||
|
@ -3,19 +3,17 @@ use std::cmp::{max, min};
|
|||||||
use tui::{
|
use tui::{
|
||||||
layout::{Alignment, Rect},
|
layout::{Alignment, Rect},
|
||||||
text::{Line, Span},
|
text::{Line, Span},
|
||||||
widgets::{Block, Borders, Paragraph, Wrap},
|
widgets::{Paragraph, Wrap},
|
||||||
Frame,
|
Frame,
|
||||||
};
|
};
|
||||||
use unicode_width::UnicodeWidthStr;
|
use unicode_width::UnicodeWidthStr;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
app::App,
|
app::App,
|
||||||
canvas::Painter,
|
canvas::{drawing_utils::dialog_block, Painter},
|
||||||
constants::{self, HELP_TEXT},
|
constants::{self, HELP_TEXT},
|
||||||
};
|
};
|
||||||
|
|
||||||
const HELP_BASE: &str = " Help ── Esc to close ";
|
|
||||||
|
|
||||||
// TODO: [REFACTOR] Make generic dialog boxes to build off of instead?
|
// TODO: [REFACTOR] Make generic dialog boxes to build off of instead?
|
||||||
impl Painter {
|
impl Painter {
|
||||||
fn help_text_lines(&self) -> Vec<Line<'_>> {
|
fn help_text_lines(&self) -> Vec<Line<'_>> {
|
||||||
@ -28,12 +26,12 @@ impl Painter {
|
|||||||
if itx > 0 {
|
if itx > 0 {
|
||||||
if let Some(header) = section.next() {
|
if let Some(header) = section.next() {
|
||||||
styled_help_spans.push(Span::default());
|
styled_help_spans.push(Span::default());
|
||||||
styled_help_spans.push(Span::styled(*header, self.colours.table_header_style));
|
styled_help_spans.push(Span::styled(*header, self.styles.table_header_style));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
section.for_each(|&text| {
|
section.for_each(|&text| {
|
||||||
styled_help_spans.push(Span::styled(text, self.colours.text_style))
|
styled_help_spans.push(Span::styled(text, self.styles.text_style))
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -43,24 +41,12 @@ impl Painter {
|
|||||||
pub fn draw_help_dialog(&self, f: &mut Frame<'_>, app_state: &mut App, draw_loc: Rect) {
|
pub fn draw_help_dialog(&self, f: &mut Frame<'_>, app_state: &mut App, draw_loc: Rect) {
|
||||||
let styled_help_text = self.help_text_lines();
|
let styled_help_text = self.help_text_lines();
|
||||||
|
|
||||||
let help_title = Line::from(vec![
|
let block = dialog_block(self.styles.border_type)
|
||||||
Span::styled(" Help ", self.colours.widget_title_style),
|
.border_style(self.styles.border_style)
|
||||||
Span::styled(
|
.title_top(Line::styled(" Help ", self.styles.widget_title_style))
|
||||||
format!(
|
.title_top(
|
||||||
"─{}─ Esc to close ",
|
Line::styled(" Esc to close ", self.styles.widget_title_style).right_aligned(),
|
||||||
"─".repeat(
|
);
|
||||||
usize::from(draw_loc.width).saturating_sub(HELP_BASE.chars().count() + 2)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
self.colours.border_style,
|
|
||||||
),
|
|
||||||
]);
|
|
||||||
|
|
||||||
let block = Block::default()
|
|
||||||
.title(help_title)
|
|
||||||
.style(self.colours.border_style)
|
|
||||||
.borders(Borders::ALL)
|
|
||||||
.border_style(self.colours.border_style);
|
|
||||||
|
|
||||||
if app_state.should_get_widget_bounds() {
|
if app_state.should_get_widget_bounds() {
|
||||||
// We must also recalculate how many lines are wrapping to properly get
|
// We must also recalculate how many lines are wrapping to properly get
|
||||||
@ -116,7 +102,7 @@ impl Painter {
|
|||||||
f.render_widget(
|
f.render_widget(
|
||||||
Paragraph::new(styled_help_text.clone())
|
Paragraph::new(styled_help_text.clone())
|
||||||
.block(block)
|
.block(block)
|
||||||
.style(self.colours.text_style)
|
.style(self.styles.text_style)
|
||||||
.alignment(Alignment::Left)
|
.alignment(Alignment::Left)
|
||||||
.wrap(Wrap { trim: true })
|
.wrap(Wrap { trim: true })
|
||||||
.scroll((
|
.scroll((
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
use std::{cmp::min, time::Instant};
|
use std::{cmp::min, time::Instant};
|
||||||
|
|
||||||
use tui::layout::Rect;
|
use tui::{
|
||||||
|
layout::Rect,
|
||||||
|
widgets::{Block, BorderType, Borders},
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::SIDE_BORDERS;
|
||||||
|
|
||||||
/// Calculate how many bars are to be drawn within basic mode's components.
|
/// Calculate how many bars are to be drawn within basic mode's components.
|
||||||
pub fn calculate_basic_use_bars(use_percentage: f64, num_bars_available: usize) -> usize {
|
pub fn calculate_basic_use_bars(use_percentage: f64, num_bars_available: usize) -> usize {
|
||||||
@ -30,6 +35,30 @@ pub fn should_hide_x_label(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return a widget block.
|
||||||
|
pub fn widget_block(is_basic: bool, is_selected: bool, border_type: BorderType) -> Block<'static> {
|
||||||
|
let mut block = Block::default().border_type(border_type);
|
||||||
|
|
||||||
|
if is_basic {
|
||||||
|
if is_selected {
|
||||||
|
block = block.borders(SIDE_BORDERS);
|
||||||
|
} else {
|
||||||
|
block = block.borders(Borders::empty());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
block = block.borders(Borders::all());
|
||||||
|
}
|
||||||
|
|
||||||
|
block
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return a dialog block.
|
||||||
|
pub fn dialog_block(border_type: BorderType) -> Block<'static> {
|
||||||
|
Block::default()
|
||||||
|
.border_type(border_type)
|
||||||
|
.borders(Borders::all())
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
|
|
||||||
|
@ -1,23 +1,24 @@
|
|||||||
use tui::{
|
use tui::{
|
||||||
layout::{Constraint, Direction, Layout, Rect},
|
layout::{Constraint, Direction, Layout, Rect},
|
||||||
text::{Line, Span},
|
text::{Line, Span},
|
||||||
widgets::{Block, Borders, Cell, Paragraph, Row, Table, Tabs},
|
widgets::{Cell, Paragraph, Row, Table, Tabs},
|
||||||
Frame,
|
Frame,
|
||||||
};
|
};
|
||||||
use unicode_segmentation::UnicodeSegmentation;
|
|
||||||
use unicode_width::UnicodeWidthStr;
|
use unicode_width::UnicodeWidthStr;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
app::App,
|
app::App,
|
||||||
canvas::{drawing_utils::calculate_basic_use_bars, Painter},
|
canvas::{
|
||||||
|
drawing_utils::{calculate_basic_use_bars, widget_block},
|
||||||
|
Painter,
|
||||||
|
},
|
||||||
constants::*,
|
constants::*,
|
||||||
data_conversion::BatteryDuration,
|
data_conversion::BatteryDuration,
|
||||||
};
|
};
|
||||||
|
|
||||||
impl Painter {
|
impl Painter {
|
||||||
pub fn draw_battery(
|
pub fn draw_battery(
|
||||||
&self, f: &mut Frame<'_>, app_state: &mut App, draw_loc: Rect, draw_border: bool,
|
&self, f: &mut Frame<'_>, app_state: &mut App, draw_loc: Rect, widget_id: u64,
|
||||||
widget_id: u64,
|
|
||||||
) {
|
) {
|
||||||
let should_get_widget_bounds = app_state.should_get_widget_bounds();
|
let should_get_widget_bounds = app_state.should_get_widget_bounds();
|
||||||
if let Some(battery_widget_state) = app_state
|
if let Some(battery_widget_state) = app_state
|
||||||
@ -28,9 +29,9 @@ impl Painter {
|
|||||||
{
|
{
|
||||||
let is_on_widget = widget_id == app_state.current_widget.widget_id;
|
let is_on_widget = widget_id == app_state.current_widget.widget_id;
|
||||||
let border_style = if is_on_widget {
|
let border_style = if is_on_widget {
|
||||||
self.colours.highlighted_border_style
|
self.styles.highlighted_border_style
|
||||||
} else {
|
} else {
|
||||||
self.colours.border_style
|
self.styles.border_style
|
||||||
};
|
};
|
||||||
let table_gap = if draw_loc.height < TABLE_GAP_HEIGHT_LIMIT {
|
let table_gap = if draw_loc.height < TABLE_GAP_HEIGHT_LIMIT {
|
||||||
0
|
0
|
||||||
@ -38,35 +39,23 @@ impl Painter {
|
|||||||
app_state.app_config_fields.table_gap
|
app_state.app_config_fields.table_gap
|
||||||
};
|
};
|
||||||
|
|
||||||
let title = if app_state.is_expanded {
|
let block = {
|
||||||
const TITLE_BASE: &str = " Battery ── Esc to go back ";
|
let mut block = widget_block(
|
||||||
Line::from(vec![
|
app_state.app_config_fields.use_basic_mode,
|
||||||
Span::styled(" Battery ", self.colours.widget_title_style),
|
is_on_widget,
|
||||||
Span::styled(
|
self.styles.border_type,
|
||||||
format!(
|
)
|
||||||
"─{}─ Esc to go back ",
|
.border_style(border_style)
|
||||||
"─".repeat(usize::from(draw_loc.width).saturating_sub(
|
.title_top(Line::styled(" Battery ", self.styles.widget_title_style));
|
||||||
UnicodeSegmentation::graphemes(TITLE_BASE, true).count() + 2
|
|
||||||
))
|
|
||||||
),
|
|
||||||
border_style,
|
|
||||||
),
|
|
||||||
])
|
|
||||||
} else {
|
|
||||||
Line::from(Span::styled(" Battery ", self.colours.widget_title_style))
|
|
||||||
};
|
|
||||||
|
|
||||||
let battery_block = if draw_border {
|
if app_state.is_expanded {
|
||||||
Block::default()
|
block = block.title_top(
|
||||||
.title(title)
|
Line::styled(" Esc to go back ", self.styles.widget_title_style)
|
||||||
.borders(Borders::ALL)
|
.right_aligned(),
|
||||||
.border_style(border_style)
|
)
|
||||||
} else if is_on_widget {
|
}
|
||||||
Block::default()
|
|
||||||
.borders(SIDE_BORDERS)
|
block
|
||||||
.border_style(self.colours.highlighted_border_style)
|
|
||||||
} else {
|
|
||||||
Block::default().borders(Borders::NONE)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if app_state.converted_data.battery_data.len() > 1 {
|
if app_state.converted_data.battery_data.len() > 1 {
|
||||||
@ -95,8 +84,8 @@ impl Painter {
|
|||||||
.collect::<Vec<_>>(),
|
.collect::<Vec<_>>(),
|
||||||
)
|
)
|
||||||
.divider(tui::symbols::line::VERTICAL)
|
.divider(tui::symbols::line::VERTICAL)
|
||||||
.style(self.colours.text_style)
|
.style(self.styles.text_style)
|
||||||
.highlight_style(self.colours.selected_text_style)
|
.highlight_style(self.styles.selected_text_style)
|
||||||
.select(battery_widget_state.currently_selected_battery_index),
|
.select(battery_widget_state.currently_selected_battery_index),
|
||||||
tab_draw_loc,
|
tab_draw_loc,
|
||||||
);
|
);
|
||||||
@ -120,9 +109,11 @@ impl Painter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let is_basic = app_state.app_config_fields.use_basic_mode;
|
||||||
|
|
||||||
let margined_draw_loc = Layout::default()
|
let margined_draw_loc = Layout::default()
|
||||||
.constraints([Constraint::Percentage(100)])
|
.constraints([Constraint::Percentage(100)])
|
||||||
.horizontal_margin(u16::from(!(is_on_widget || draw_border)))
|
.horizontal_margin(u16::from(!(is_on_widget || is_basic)))
|
||||||
.direction(Direction::Horizontal)
|
.direction(Direction::Horizontal)
|
||||||
.split(draw_loc)[0];
|
.split(draw_loc)[0];
|
||||||
|
|
||||||
@ -144,15 +135,15 @@ impl Painter {
|
|||||||
|
|
||||||
let mut battery_charge_rows = Vec::with_capacity(2);
|
let mut battery_charge_rows = Vec::with_capacity(2);
|
||||||
battery_charge_rows.push(Row::new([
|
battery_charge_rows.push(Row::new([
|
||||||
Cell::from("Charge").style(self.colours.text_style)
|
Cell::from("Charge").style(self.styles.text_style)
|
||||||
]));
|
]));
|
||||||
battery_charge_rows.push(Row::new([Cell::from(bars).style(
|
battery_charge_rows.push(Row::new([Cell::from(bars).style(
|
||||||
if charge_percentage < 10.0 {
|
if charge_percentage < 10.0 {
|
||||||
self.colours.low_battery
|
self.styles.low_battery
|
||||||
} else if charge_percentage < 50.0 {
|
} else if charge_percentage < 50.0 {
|
||||||
self.colours.medium_battery
|
self.styles.medium_battery
|
||||||
} else {
|
} else {
|
||||||
self.colours.high_battery
|
self.styles.high_battery
|
||||||
},
|
},
|
||||||
)]));
|
)]));
|
||||||
|
|
||||||
@ -160,16 +151,16 @@ impl Painter {
|
|||||||
battery_rows.push(Row::new([""]).bottom_margin(table_gap + 1));
|
battery_rows.push(Row::new([""]).bottom_margin(table_gap + 1));
|
||||||
battery_rows.push(
|
battery_rows.push(
|
||||||
Row::new(["Rate", &battery_details.watt_consumption])
|
Row::new(["Rate", &battery_details.watt_consumption])
|
||||||
.style(self.colours.text_style),
|
.style(self.styles.text_style),
|
||||||
);
|
);
|
||||||
|
|
||||||
battery_rows.push(
|
battery_rows.push(
|
||||||
Row::new(["State", &battery_details.state]).style(self.colours.text_style),
|
Row::new(["State", &battery_details.state]).style(self.styles.text_style),
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut time: String; // Keep string lifetime in scope.
|
let mut time: String; // Keep string lifetime in scope.
|
||||||
{
|
{
|
||||||
let style = self.colours.text_style;
|
let style = self.styles.text_style;
|
||||||
match &battery_details.battery_duration {
|
match &battery_details.battery_duration {
|
||||||
BatteryDuration::ToEmpty(secs) => {
|
BatteryDuration::ToEmpty(secs) => {
|
||||||
time = long_time(*secs);
|
time = long_time(*secs);
|
||||||
@ -198,7 +189,7 @@ impl Painter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
battery_rows.push(
|
battery_rows.push(
|
||||||
Row::new(["Health", &battery_details.health]).style(self.colours.text_style),
|
Row::new(["Health", &battery_details.health]).style(self.styles.text_style),
|
||||||
);
|
);
|
||||||
|
|
||||||
let header = if app_state.converted_data.battery_data.len() > 1 {
|
let header = if app_state.converted_data.battery_data.len() > 1 {
|
||||||
@ -210,7 +201,7 @@ impl Painter {
|
|||||||
// Draw bar
|
// Draw bar
|
||||||
f.render_widget(
|
f.render_widget(
|
||||||
Table::new(battery_charge_rows, [Constraint::Percentage(100)])
|
Table::new(battery_charge_rows, [Constraint::Percentage(100)])
|
||||||
.block(battery_block.clone())
|
.block(block.clone())
|
||||||
.header(header.clone()),
|
.header(header.clone()),
|
||||||
margined_draw_loc,
|
margined_draw_loc,
|
||||||
);
|
);
|
||||||
@ -221,7 +212,7 @@ impl Painter {
|
|||||||
battery_rows,
|
battery_rows,
|
||||||
[Constraint::Percentage(50), Constraint::Percentage(50)],
|
[Constraint::Percentage(50), Constraint::Percentage(50)],
|
||||||
)
|
)
|
||||||
.block(battery_block)
|
.block(block)
|
||||||
.header(header),
|
.header(header),
|
||||||
margined_draw_loc,
|
margined_draw_loc,
|
||||||
);
|
);
|
||||||
@ -230,13 +221,10 @@ impl Painter {
|
|||||||
|
|
||||||
contents.push(Line::from(Span::styled(
|
contents.push(Line::from(Span::styled(
|
||||||
"No data found for this battery",
|
"No data found for this battery",
|
||||||
self.colours.text_style,
|
self.styles.text_style,
|
||||||
)));
|
)));
|
||||||
|
|
||||||
f.render_widget(
|
f.render_widget(Paragraph::new(contents).block(block), margined_draw_loc);
|
||||||
Paragraph::new(contents).block(battery_block),
|
|
||||||
margined_draw_loc,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if should_get_widget_bounds {
|
if should_get_widget_bounds {
|
||||||
@ -253,7 +241,6 @@ impl Painter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn get_hms(secs: i64) -> (i64, i64, i64) {
|
fn get_hms(secs: i64) -> (i64, i64, i64) {
|
||||||
let hours = secs / (60 * 60);
|
let hours = secs / (60 * 60);
|
||||||
let minutes = (secs / 60) - hours * 60;
|
let minutes = (secs / 60) - hours * 60;
|
||||||
@ -266,23 +253,16 @@ fn long_time(secs: i64) -> String {
|
|||||||
let (hours, minutes, seconds) = get_hms(secs);
|
let (hours, minutes, seconds) = get_hms(secs);
|
||||||
|
|
||||||
if hours > 0 {
|
if hours > 0 {
|
||||||
format!(
|
let h = if hours == 1 { "hour" } else { "hours" };
|
||||||
"{} hour{}, {} minute{}, {} second{}",
|
let m = if minutes == 1 { "minute" } else { "minutes" };
|
||||||
hours,
|
let s = if seconds == 1 { "second" } else { "seconds" };
|
||||||
if hours == 1 { "" } else { "s" },
|
|
||||||
minutes,
|
format!("{hours} {h}, {minutes} {m}, {seconds} {s}")
|
||||||
if minutes == 1 { "" } else { "s" },
|
|
||||||
seconds,
|
|
||||||
if seconds == 1 { "" } else { "s" },
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
format!(
|
let m = if minutes == 1 { "minute" } else { "minutes" };
|
||||||
"{} minute{}, {} second{}",
|
let s = if seconds == 1 { "second" } else { "seconds" };
|
||||||
minutes,
|
|
||||||
if minutes == 1 { "" } else { "s" },
|
format!("{minutes} {m}, {seconds} {s}")
|
||||||
seconds,
|
|
||||||
if seconds == 1 { "" } else { "s" },
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@ use std::cmp::min;
|
|||||||
|
|
||||||
use tui::{
|
use tui::{
|
||||||
layout::{Constraint, Direction, Layout, Rect},
|
layout::{Constraint, Direction, Layout, Rect},
|
||||||
widgets::Block,
|
|
||||||
Frame,
|
Frame,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -10,9 +9,9 @@ use crate::{
|
|||||||
app::App,
|
app::App,
|
||||||
canvas::{
|
canvas::{
|
||||||
components::pipe_gauge::{LabelLimit, PipeGauge},
|
components::pipe_gauge::{LabelLimit, PipeGauge},
|
||||||
|
drawing_utils::widget_block,
|
||||||
Painter,
|
Painter,
|
||||||
},
|
},
|
||||||
constants::*,
|
|
||||||
data_collection::cpu::CpuDataType,
|
data_collection::cpu::CpuDataType,
|
||||||
data_conversion::CpuWidgetData,
|
data_conversion::CpuWidgetData,
|
||||||
};
|
};
|
||||||
@ -38,9 +37,8 @@ impl Painter {
|
|||||||
|
|
||||||
if app_state.current_widget.widget_id == widget_id {
|
if app_state.current_widget.widget_id == widget_id {
|
||||||
f.render_widget(
|
f.render_widget(
|
||||||
Block::default()
|
widget_block(true, true, self.styles.border_type)
|
||||||
.borders(SIDE_BORDERS)
|
.border_style(self.styles.highlighted_border_style),
|
||||||
.border_style(self.colours.highlighted_border_style),
|
|
||||||
draw_loc,
|
draw_loc,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -156,10 +154,10 @@ impl Painter {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let (outer, style) = match data_type {
|
let (outer, style) = match data_type {
|
||||||
CpuDataType::Avg => ("AVG".to_string(), self.colours.avg_cpu_colour),
|
CpuDataType::Avg => ("AVG".to_string(), self.styles.avg_cpu_colour),
|
||||||
CpuDataType::Cpu(index) => (
|
CpuDataType::Cpu(index) => (
|
||||||
format!("{index:<3}",),
|
format!("{index:<3}",),
|
||||||
self.colours.cpu_colour_styles[index % self.colours.cpu_colour_styles.len()],
|
self.styles.cpu_colour_styles[index % self.styles.cpu_colour_styles.len()],
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
let inner = format!("{:>3.0}%", last_entry.round());
|
let inner = format!("{:>3.0}%", last_entry.round());
|
||||||
|
@ -136,13 +136,13 @@ impl Painter {
|
|||||||
CpuWidgetData::All => None,
|
CpuWidgetData::All => None,
|
||||||
CpuWidgetData::Entry { data, .. } => {
|
CpuWidgetData::Entry { data, .. } => {
|
||||||
let style = if show_avg_cpu && itx == AVG_POSITION {
|
let style = if show_avg_cpu && itx == AVG_POSITION {
|
||||||
self.colours.avg_cpu_colour
|
self.styles.avg_cpu_colour
|
||||||
} else if itx == ALL_POSITION {
|
} else if itx == ALL_POSITION {
|
||||||
self.colours.all_cpu_colour
|
self.styles.all_cpu_colour
|
||||||
} else {
|
} else {
|
||||||
let offset_position = itx - 1; // Because of the all position
|
let offset_position = itx - 1; // Because of the all position
|
||||||
self.colours.cpu_colour_styles[(offset_position - show_avg_offset)
|
self.styles.cpu_colour_styles[(offset_position - show_avg_offset)
|
||||||
% self.colours.cpu_colour_styles.len()]
|
% self.styles.cpu_colour_styles.len()]
|
||||||
};
|
};
|
||||||
|
|
||||||
Some(GraphData {
|
Some(GraphData {
|
||||||
@ -158,11 +158,11 @@ impl Painter {
|
|||||||
cpu_data.get(current_scroll_position)
|
cpu_data.get(current_scroll_position)
|
||||||
{
|
{
|
||||||
let style = if show_avg_cpu && current_scroll_position == AVG_POSITION {
|
let style = if show_avg_cpu && current_scroll_position == AVG_POSITION {
|
||||||
self.colours.avg_cpu_colour
|
self.styles.avg_cpu_colour
|
||||||
} else {
|
} else {
|
||||||
let offset_position = current_scroll_position - 1; // Because of the all position
|
let offset_position = current_scroll_position - 1; // Because of the all position
|
||||||
self.colours.cpu_colour_styles
|
self.styles.cpu_colour_styles
|
||||||
[(offset_position - show_avg_offset) % self.colours.cpu_colour_styles.len()]
|
[(offset_position - show_avg_offset) % self.styles.cpu_colour_styles.len()]
|
||||||
};
|
};
|
||||||
|
|
||||||
vec![GraphData {
|
vec![GraphData {
|
||||||
@ -228,11 +228,13 @@ impl Painter {
|
|||||||
hide_x_labels,
|
hide_x_labels,
|
||||||
y_bounds: Y_BOUNDS,
|
y_bounds: Y_BOUNDS,
|
||||||
y_labels: &Y_LABELS,
|
y_labels: &Y_LABELS,
|
||||||
graph_style: self.colours.graph_style,
|
graph_style: self.styles.graph_style,
|
||||||
border_style,
|
border_style,
|
||||||
|
border_type: self.styles.border_type,
|
||||||
title,
|
title,
|
||||||
|
is_selected: app_state.current_widget.widget_id == widget_id,
|
||||||
is_expanded: app_state.is_expanded,
|
is_expanded: app_state.is_expanded,
|
||||||
title_style: self.colours.widget_title_style,
|
title_style: self.styles.widget_title_style,
|
||||||
legend_position: None,
|
legend_position: None,
|
||||||
legend_constraints: None,
|
legend_constraints: None,
|
||||||
marker,
|
marker,
|
||||||
|
@ -1,13 +1,11 @@
|
|||||||
use tui::{
|
use tui::{
|
||||||
layout::{Constraint, Direction, Layout, Rect},
|
layout::{Constraint, Direction, Layout, Rect},
|
||||||
widgets::Block,
|
|
||||||
Frame,
|
Frame,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
app::App,
|
app::App,
|
||||||
canvas::{components::pipe_gauge::PipeGauge, Painter},
|
canvas::{components::pipe_gauge::PipeGauge, drawing_utils::widget_block, Painter},
|
||||||
constants::*,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
impl Painter {
|
impl Painter {
|
||||||
@ -19,9 +17,8 @@ impl Painter {
|
|||||||
|
|
||||||
if app_state.current_widget.widget_id == widget_id {
|
if app_state.current_widget.widget_id == widget_id {
|
||||||
f.render_widget(
|
f.render_widget(
|
||||||
Block::default()
|
widget_block(true, true, self.styles.border_type)
|
||||||
.borders(SIDE_BORDERS)
|
.border_style(self.styles.highlighted_border_style),
|
||||||
.border_style(self.colours.highlighted_border_style),
|
|
||||||
draw_loc,
|
draw_loc,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -50,8 +47,8 @@ impl Painter {
|
|||||||
.ratio(ram_percentage / 100.0)
|
.ratio(ram_percentage / 100.0)
|
||||||
.start_label("RAM")
|
.start_label("RAM")
|
||||||
.inner_label(memory_fraction_label)
|
.inner_label(memory_fraction_label)
|
||||||
.label_style(self.colours.ram_style)
|
.label_style(self.styles.ram_style)
|
||||||
.gauge_style(self.colours.ram_style),
|
.gauge_style(self.styles.ram_style),
|
||||||
);
|
);
|
||||||
|
|
||||||
#[cfg(not(target_os = "windows"))]
|
#[cfg(not(target_os = "windows"))]
|
||||||
@ -75,8 +72,8 @@ impl Painter {
|
|||||||
.ratio(cache_percentage / 100.0)
|
.ratio(cache_percentage / 100.0)
|
||||||
.start_label("CHE")
|
.start_label("CHE")
|
||||||
.inner_label(cache_fraction_label)
|
.inner_label(cache_fraction_label)
|
||||||
.label_style(self.colours.cache_style)
|
.label_style(self.styles.cache_style)
|
||||||
.gauge_style(self.colours.cache_style),
|
.gauge_style(self.styles.cache_style),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -100,8 +97,8 @@ impl Painter {
|
|||||||
.ratio(swap_percentage / 100.0)
|
.ratio(swap_percentage / 100.0)
|
||||||
.start_label("SWP")
|
.start_label("SWP")
|
||||||
.inner_label(swap_fraction_label)
|
.inner_label(swap_fraction_label)
|
||||||
.label_style(self.colours.swap_style)
|
.label_style(self.styles.swap_style)
|
||||||
.gauge_style(self.colours.swap_style),
|
.gauge_style(self.styles.swap_style),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,8 +121,8 @@ impl Painter {
|
|||||||
.ratio(arc_percentage / 100.0)
|
.ratio(arc_percentage / 100.0)
|
||||||
.start_label("ARC")
|
.start_label("ARC")
|
||||||
.inner_label(arc_fraction_label)
|
.inner_label(arc_fraction_label)
|
||||||
.label_style(self.colours.arc_style)
|
.label_style(self.styles.arc_style)
|
||||||
.gauge_style(self.colours.arc_style),
|
.gauge_style(self.styles.arc_style),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -133,7 +130,7 @@ impl Painter {
|
|||||||
#[cfg(feature = "gpu")]
|
#[cfg(feature = "gpu")]
|
||||||
{
|
{
|
||||||
if let Some(gpu_data) = &app_state.converted_data.gpu_data {
|
if let Some(gpu_data) = &app_state.converted_data.gpu_data {
|
||||||
let gpu_styles = &self.colours.gpu_colours;
|
let gpu_styles = &self.styles.gpu_colours;
|
||||||
let mut color_index = 0;
|
let mut color_index = 0;
|
||||||
|
|
||||||
gpu_data.iter().for_each(|gpu_data_vec| {
|
gpu_data.iter().for_each(|gpu_data_vec| {
|
||||||
|
@ -55,7 +55,7 @@ impl Painter {
|
|||||||
let mem_label = format!("RAM:{label_percent}{label_frac}");
|
let mem_label = format!("RAM:{label_percent}{label_frac}");
|
||||||
points.push(GraphData {
|
points.push(GraphData {
|
||||||
points: &app_state.converted_data.mem_data,
|
points: &app_state.converted_data.mem_data,
|
||||||
style: self.colours.ram_style,
|
style: self.styles.ram_style,
|
||||||
name: Some(mem_label.into()),
|
name: Some(mem_label.into()),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -64,7 +64,7 @@ impl Painter {
|
|||||||
let cache_label = format!("CHE:{label_percent}{label_frac}");
|
let cache_label = format!("CHE:{label_percent}{label_frac}");
|
||||||
points.push(GraphData {
|
points.push(GraphData {
|
||||||
points: &app_state.converted_data.cache_data,
|
points: &app_state.converted_data.cache_data,
|
||||||
style: self.colours.cache_style,
|
style: self.styles.cache_style,
|
||||||
name: Some(cache_label.into()),
|
name: Some(cache_label.into()),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -72,7 +72,7 @@ impl Painter {
|
|||||||
let swap_label = format!("SWP:{label_percent}{label_frac}");
|
let swap_label = format!("SWP:{label_percent}{label_frac}");
|
||||||
points.push(GraphData {
|
points.push(GraphData {
|
||||||
points: &app_state.converted_data.swap_data,
|
points: &app_state.converted_data.swap_data,
|
||||||
style: self.colours.swap_style,
|
style: self.styles.swap_style,
|
||||||
name: Some(swap_label.into()),
|
name: Some(swap_label.into()),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -81,7 +81,7 @@ impl Painter {
|
|||||||
let arc_label = format!("ARC:{label_percent}{label_frac}");
|
let arc_label = format!("ARC:{label_percent}{label_frac}");
|
||||||
points.push(GraphData {
|
points.push(GraphData {
|
||||||
points: &app_state.converted_data.arc_data,
|
points: &app_state.converted_data.arc_data,
|
||||||
style: self.colours.arc_style,
|
style: self.styles.arc_style,
|
||||||
name: Some(arc_label.into()),
|
name: Some(arc_label.into()),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -89,7 +89,7 @@ impl Painter {
|
|||||||
{
|
{
|
||||||
if let Some(gpu_data) = &app_state.converted_data.gpu_data {
|
if let Some(gpu_data) = &app_state.converted_data.gpu_data {
|
||||||
let mut color_index = 0;
|
let mut color_index = 0;
|
||||||
let gpu_styles = &self.colours.gpu_colours;
|
let gpu_styles = &self.styles.gpu_colours;
|
||||||
gpu_data.iter().for_each(|gpu| {
|
gpu_data.iter().for_each(|gpu| {
|
||||||
let gpu_label =
|
let gpu_label =
|
||||||
format!("{}:{}{}", gpu.name, gpu.mem_percent, gpu.mem_total);
|
format!("{}:{}{}", gpu.name, gpu.mem_percent, gpu.mem_total);
|
||||||
@ -128,11 +128,13 @@ impl Painter {
|
|||||||
hide_x_labels,
|
hide_x_labels,
|
||||||
y_bounds: Y_BOUNDS,
|
y_bounds: Y_BOUNDS,
|
||||||
y_labels: &Y_LABELS,
|
y_labels: &Y_LABELS,
|
||||||
graph_style: self.colours.graph_style,
|
graph_style: self.styles.graph_style,
|
||||||
border_style,
|
border_style,
|
||||||
|
border_type: self.styles.border_type,
|
||||||
title: " Memory ".into(),
|
title: " Memory ".into(),
|
||||||
|
is_selected: app_state.current_widget.widget_id == widget_id,
|
||||||
is_expanded: app_state.is_expanded,
|
is_expanded: app_state.is_expanded,
|
||||||
title_style: self.colours.widget_title_style,
|
title_style: self.styles.widget_title_style,
|
||||||
legend_position: app_state.app_config_fields.memory_legend_position,
|
legend_position: app_state.app_config_fields.memory_legend_position,
|
||||||
legend_constraints: Some((Constraint::Ratio(3, 4), Constraint::Ratio(3, 4))),
|
legend_constraints: Some((Constraint::Ratio(3, 4), Constraint::Ratio(3, 4))),
|
||||||
marker,
|
marker,
|
||||||
|
@ -5,7 +5,10 @@ use tui::{
|
|||||||
Frame,
|
Frame,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{app::App, canvas::Painter, constants::*};
|
use crate::{
|
||||||
|
app::App,
|
||||||
|
canvas::{drawing_utils::widget_block, Painter},
|
||||||
|
};
|
||||||
|
|
||||||
impl Painter {
|
impl Painter {
|
||||||
pub fn draw_basic_network(
|
pub fn draw_basic_network(
|
||||||
@ -30,9 +33,8 @@ impl Painter {
|
|||||||
|
|
||||||
if app_state.current_widget.widget_id == widget_id {
|
if app_state.current_widget.widget_id == widget_id {
|
||||||
f.render_widget(
|
f.render_widget(
|
||||||
Block::default()
|
widget_block(true, true, self.styles.border_type)
|
||||||
.borders(SIDE_BORDERS)
|
.border_style(self.styles.highlighted_border_style),
|
||||||
.border_style(self.colours.highlighted_border_style),
|
|
||||||
draw_loc,
|
draw_loc,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -43,13 +45,13 @@ impl Painter {
|
|||||||
let total_tx_label = format!("Total TX: {}", app_state.converted_data.total_tx_display);
|
let total_tx_label = format!("Total TX: {}", app_state.converted_data.total_tx_display);
|
||||||
|
|
||||||
let net_text = vec![
|
let net_text = vec![
|
||||||
Line::from(Span::styled(rx_label, self.colours.rx_style)),
|
Line::from(Span::styled(rx_label, self.styles.rx_style)),
|
||||||
Line::from(Span::styled(tx_label, self.colours.tx_style)),
|
Line::from(Span::styled(tx_label, self.styles.tx_style)),
|
||||||
];
|
];
|
||||||
|
|
||||||
let total_net_text = vec![
|
let total_net_text = vec![
|
||||||
Line::from(Span::styled(total_rx_label, self.colours.total_rx_style)),
|
Line::from(Span::styled(total_rx_label, self.styles.total_rx_style)),
|
||||||
Line::from(Span::styled(total_tx_label, self.colours.total_tx_style)),
|
Line::from(Span::styled(total_tx_label, self.styles.total_tx_style)),
|
||||||
];
|
];
|
||||||
|
|
||||||
f.render_widget(Paragraph::new(net_text).block(Block::default()), net_loc[0]);
|
f.render_widget(Paragraph::new(net_text).block(Block::default()), net_loc[0]);
|
||||||
|
@ -107,17 +107,17 @@ impl Painter {
|
|||||||
vec![
|
vec![
|
||||||
GraphData {
|
GraphData {
|
||||||
points: network_data_rx,
|
points: network_data_rx,
|
||||||
style: self.colours.rx_style,
|
style: self.styles.rx_style,
|
||||||
name: Some(format!("RX: {:7}", app_state.converted_data.rx_display).into()),
|
name: Some(format!("RX: {:7}", app_state.converted_data.rx_display).into()),
|
||||||
},
|
},
|
||||||
GraphData {
|
GraphData {
|
||||||
points: network_data_tx,
|
points: network_data_tx,
|
||||||
style: self.colours.tx_style,
|
style: self.styles.tx_style,
|
||||||
name: Some(format!("TX: {:7}", app_state.converted_data.tx_display).into()),
|
name: Some(format!("TX: {:7}", app_state.converted_data.tx_display).into()),
|
||||||
},
|
},
|
||||||
GraphData {
|
GraphData {
|
||||||
points: &[],
|
points: &[],
|
||||||
style: self.colours.total_rx_style,
|
style: self.styles.total_rx_style,
|
||||||
name: Some(
|
name: Some(
|
||||||
format!("Total RX: {:7}", app_state.converted_data.total_rx_display)
|
format!("Total RX: {:7}", app_state.converted_data.total_rx_display)
|
||||||
.into(),
|
.into(),
|
||||||
@ -125,7 +125,7 @@ impl Painter {
|
|||||||
},
|
},
|
||||||
GraphData {
|
GraphData {
|
||||||
points: &[],
|
points: &[],
|
||||||
style: self.colours.total_tx_style,
|
style: self.styles.total_tx_style,
|
||||||
name: Some(
|
name: Some(
|
||||||
format!("Total TX: {:7}", app_state.converted_data.total_tx_display)
|
format!("Total TX: {:7}", app_state.converted_data.total_tx_display)
|
||||||
.into(),
|
.into(),
|
||||||
@ -136,12 +136,12 @@ impl Painter {
|
|||||||
vec![
|
vec![
|
||||||
GraphData {
|
GraphData {
|
||||||
points: network_data_rx,
|
points: network_data_rx,
|
||||||
style: self.colours.rx_style,
|
style: self.styles.rx_style,
|
||||||
name: Some((&app_state.converted_data.rx_display).into()),
|
name: Some((&app_state.converted_data.rx_display).into()),
|
||||||
},
|
},
|
||||||
GraphData {
|
GraphData {
|
||||||
points: network_data_tx,
|
points: network_data_tx,
|
||||||
style: self.colours.tx_style,
|
style: self.styles.tx_style,
|
||||||
name: Some((&app_state.converted_data.tx_display).into()),
|
name: Some((&app_state.converted_data.tx_display).into()),
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
@ -158,11 +158,13 @@ impl Painter {
|
|||||||
hide_x_labels,
|
hide_x_labels,
|
||||||
y_bounds,
|
y_bounds,
|
||||||
y_labels: &y_labels,
|
y_labels: &y_labels,
|
||||||
graph_style: self.colours.graph_style,
|
graph_style: self.styles.graph_style,
|
||||||
border_style,
|
border_style,
|
||||||
|
border_type: self.styles.border_type,
|
||||||
title: " Network ".into(),
|
title: " Network ".into(),
|
||||||
|
is_selected: app_state.current_widget.widget_id == widget_id,
|
||||||
is_expanded: app_state.is_expanded,
|
is_expanded: app_state.is_expanded,
|
||||||
title_style: self.colours.widget_title_style,
|
title_style: self.styles.widget_title_style,
|
||||||
legend_position: app_state.app_config_fields.network_legend_position,
|
legend_position: app_state.app_config_fields.network_legend_position,
|
||||||
legend_constraints: Some(legend_constraints),
|
legend_constraints: Some(legend_constraints),
|
||||||
marker,
|
marker,
|
||||||
@ -183,10 +185,10 @@ impl Painter {
|
|||||||
|
|
||||||
// Gross but I need it to work...
|
// Gross but I need it to work...
|
||||||
let total_network = vec![Row::new([
|
let total_network = vec![Row::new([
|
||||||
Text::styled(rx_display, self.colours.rx_style),
|
Text::styled(rx_display, self.styles.rx_style),
|
||||||
Text::styled(tx_display, self.colours.tx_style),
|
Text::styled(tx_display, self.styles.tx_style),
|
||||||
Text::styled(total_rx_display, self.colours.total_rx_style),
|
Text::styled(total_rx_display, self.styles.total_rx_style),
|
||||||
Text::styled(total_tx_display, self.colours.total_tx_style),
|
Text::styled(total_tx_display, self.styles.total_tx_style),
|
||||||
])];
|
])];
|
||||||
|
|
||||||
// Draw
|
// Draw
|
||||||
@ -198,15 +200,15 @@ impl Painter {
|
|||||||
.map(Constraint::Length)
|
.map(Constraint::Length)
|
||||||
.collect::<Vec<_>>()),
|
.collect::<Vec<_>>()),
|
||||||
)
|
)
|
||||||
.header(Row::new(NETWORK_HEADERS).style(self.colours.table_header_style))
|
.header(Row::new(NETWORK_HEADERS).style(self.styles.table_header_style))
|
||||||
.block(Block::default().borders(Borders::ALL).border_style(
|
.block(Block::default().borders(Borders::ALL).border_style(
|
||||||
if app_state.current_widget.widget_id == widget_id {
|
if app_state.current_widget.widget_id == widget_id {
|
||||||
self.colours.highlighted_border_style
|
self.styles.highlighted_border_style
|
||||||
} else {
|
} else {
|
||||||
self.colours.border_style
|
self.styles.border_style
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
.style(self.colours.text_style),
|
.style(self.styles.text_style),
|
||||||
draw_loc,
|
draw_loc,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ use tui::{
|
|||||||
layout::{Alignment, Constraint, Direction, Layout, Rect},
|
layout::{Alignment, Constraint, Direction, Layout, Rect},
|
||||||
style::Style,
|
style::Style,
|
||||||
text::{Line, Span},
|
text::{Line, Span},
|
||||||
widgets::{Block, Borders, Paragraph},
|
widgets::Paragraph,
|
||||||
Frame,
|
Frame,
|
||||||
};
|
};
|
||||||
use unicode_segmentation::UnicodeSegmentation;
|
use unicode_segmentation::UnicodeSegmentation;
|
||||||
@ -11,9 +11,9 @@ use crate::{
|
|||||||
app::{App, AppSearchState},
|
app::{App, AppSearchState},
|
||||||
canvas::{
|
canvas::{
|
||||||
components::data_table::{DrawInfo, SelectionState},
|
components::data_table::{DrawInfo, SelectionState},
|
||||||
|
drawing_utils::widget_block,
|
||||||
Painter,
|
Painter,
|
||||||
},
|
},
|
||||||
constants::*,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const SORT_MENU_WIDTH: u16 = 7;
|
const SORT_MENU_WIDTH: u16 = 7;
|
||||||
@ -23,11 +23,11 @@ impl Painter {
|
|||||||
/// - `widget_id` here represents the widget ID of the process widget
|
/// - `widget_id` here represents the widget ID of the process widget
|
||||||
/// itself!
|
/// itself!
|
||||||
pub fn draw_process(
|
pub fn draw_process(
|
||||||
&self, f: &mut Frame<'_>, app_state: &mut App, draw_loc: Rect, draw_border: bool,
|
&self, f: &mut Frame<'_>, app_state: &mut App, draw_loc: Rect, widget_id: u64,
|
||||||
widget_id: u64,
|
|
||||||
) {
|
) {
|
||||||
if let Some(proc_widget_state) = app_state.states.proc_state.widget_states.get(&widget_id) {
|
if let Some(proc_widget_state) = app_state.states.proc_state.widget_states.get(&widget_id) {
|
||||||
let search_height = if draw_border { 5 } else { 3 };
|
let is_basic = app_state.app_config_fields.use_basic_mode;
|
||||||
|
let search_height = if !is_basic { 5 } else { 3 };
|
||||||
let is_sort_open = proc_widget_state.is_sort_open;
|
let is_sort_open = proc_widget_state.is_sort_open;
|
||||||
|
|
||||||
let mut proc_draw_loc = draw_loc;
|
let mut proc_draw_loc = draw_loc;
|
||||||
@ -38,13 +38,7 @@ impl Painter {
|
|||||||
.split(draw_loc);
|
.split(draw_loc);
|
||||||
proc_draw_loc = processes_chunk[0];
|
proc_draw_loc = processes_chunk[0];
|
||||||
|
|
||||||
self.draw_search_field(
|
self.draw_search_field(f, app_state, processes_chunk[1], widget_id + 1);
|
||||||
f,
|
|
||||||
app_state,
|
|
||||||
processes_chunk[1],
|
|
||||||
draw_border,
|
|
||||||
widget_id + 1,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if is_sort_open {
|
if is_sort_open {
|
||||||
@ -110,8 +104,7 @@ impl Painter {
|
|||||||
/// - `widget_id` represents the widget ID of the search box itself --- NOT
|
/// - `widget_id` represents the widget ID of the search box itself --- NOT
|
||||||
/// the process widget state that is stored.
|
/// the process widget state that is stored.
|
||||||
fn draw_search_field(
|
fn draw_search_field(
|
||||||
&self, f: &mut Frame<'_>, app_state: &mut App, draw_loc: Rect, draw_border: bool,
|
&self, f: &mut Frame<'_>, app_state: &mut App, draw_loc: Rect, widget_id: u64,
|
||||||
widget_id: u64,
|
|
||||||
) {
|
) {
|
||||||
fn build_query_span(
|
fn build_query_span(
|
||||||
search_state: &AppSearchState, available_width: usize, is_on_widget: bool,
|
search_state: &AppSearchState, available_width: usize, is_on_widget: bool,
|
||||||
@ -157,16 +150,18 @@ impl Painter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let is_basic = app_state.app_config_fields.use_basic_mode;
|
||||||
|
|
||||||
if let Some(proc_widget_state) = app_state
|
if let Some(proc_widget_state) = app_state
|
||||||
.states
|
.states
|
||||||
.proc_state
|
.proc_state
|
||||||
.widget_states
|
.widget_states
|
||||||
.get_mut(&(widget_id - 1))
|
.get_mut(&(widget_id - 1))
|
||||||
{
|
{
|
||||||
let is_on_widget = widget_id == app_state.current_widget.widget_id;
|
let is_selected = widget_id == app_state.current_widget.widget_id;
|
||||||
let num_columns = usize::from(draw_loc.width);
|
let num_columns = usize::from(draw_loc.width);
|
||||||
const SEARCH_TITLE: &str = "> ";
|
const SEARCH_TITLE: &str = "> ";
|
||||||
let offset = if draw_border { 4 } else { 2 }; // width of 3 removed for >_|
|
let offset = 4;
|
||||||
let available_width = if num_columns > (offset + 3) {
|
let available_width = if num_columns > (offset + 3) {
|
||||||
num_columns - offset
|
num_columns - offset
|
||||||
} else {
|
} else {
|
||||||
@ -182,18 +177,18 @@ impl Painter {
|
|||||||
let query_with_cursor = build_query_span(
|
let query_with_cursor = build_query_span(
|
||||||
&proc_widget_state.proc_search.search_state,
|
&proc_widget_state.proc_search.search_state,
|
||||||
available_width,
|
available_width,
|
||||||
is_on_widget,
|
is_selected,
|
||||||
self.colours.selected_text_style,
|
self.styles.selected_text_style,
|
||||||
self.colours.text_style,
|
self.styles.text_style,
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut search_text = vec![Line::from({
|
let mut search_text = vec![Line::from({
|
||||||
let mut search_vec = vec![Span::styled(
|
let mut search_vec = vec![Span::styled(
|
||||||
SEARCH_TITLE,
|
SEARCH_TITLE,
|
||||||
if is_on_widget {
|
if is_selected {
|
||||||
self.colours.table_header_style
|
self.styles.table_header_style
|
||||||
} else {
|
} else {
|
||||||
self.colours.text_style
|
self.styles.text_style
|
||||||
},
|
},
|
||||||
)];
|
)];
|
||||||
search_vec.extend(query_with_cursor);
|
search_vec.extend(query_with_cursor);
|
||||||
@ -203,21 +198,21 @@ impl Painter {
|
|||||||
|
|
||||||
// Text options shamelessly stolen from VS Code.
|
// Text options shamelessly stolen from VS Code.
|
||||||
let case_style = if !proc_widget_state.proc_search.is_ignoring_case {
|
let case_style = if !proc_widget_state.proc_search.is_ignoring_case {
|
||||||
self.colours.selected_text_style
|
self.styles.selected_text_style
|
||||||
} else {
|
} else {
|
||||||
self.colours.text_style
|
self.styles.text_style
|
||||||
};
|
};
|
||||||
|
|
||||||
let whole_word_style = if proc_widget_state.proc_search.is_searching_whole_word {
|
let whole_word_style = if proc_widget_state.proc_search.is_searching_whole_word {
|
||||||
self.colours.selected_text_style
|
self.styles.selected_text_style
|
||||||
} else {
|
} else {
|
||||||
self.colours.text_style
|
self.styles.text_style
|
||||||
};
|
};
|
||||||
|
|
||||||
let regex_style = if proc_widget_state.proc_search.is_searching_with_regex {
|
let regex_style = if proc_widget_state.proc_search.is_searching_with_regex {
|
||||||
self.colours.selected_text_style
|
self.styles.selected_text_style
|
||||||
} else {
|
} else {
|
||||||
self.colours.text_style
|
self.styles.text_style
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: [MOUSE] Mouse support for these in search
|
// TODO: [MOUSE] Mouse support for these in search
|
||||||
@ -245,54 +240,42 @@ impl Painter {
|
|||||||
} else {
|
} else {
|
||||||
""
|
""
|
||||||
},
|
},
|
||||||
self.colours.invalid_query_style,
|
self.styles.invalid_query_style,
|
||||||
)));
|
)));
|
||||||
search_text.push(option_text);
|
search_text.push(option_text);
|
||||||
|
|
||||||
let current_border_style =
|
let current_border_style =
|
||||||
if proc_widget_state.proc_search.search_state.is_invalid_search {
|
if proc_widget_state.proc_search.search_state.is_invalid_search {
|
||||||
self.colours.invalid_query_style
|
self.styles.invalid_query_style
|
||||||
} else if is_on_widget {
|
} else if is_selected {
|
||||||
self.colours.highlighted_border_style
|
self.styles.highlighted_border_style
|
||||||
} else {
|
} else {
|
||||||
self.colours.border_style
|
self.styles.border_style
|
||||||
};
|
};
|
||||||
|
|
||||||
let title = Span::styled(
|
let process_search_block = {
|
||||||
if draw_border {
|
let mut block = widget_block(is_basic, is_selected, self.styles.border_type)
|
||||||
const TITLE_BASE: &str = " Esc to close ";
|
.border_style(current_border_style);
|
||||||
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 {
|
if !is_basic {
|
||||||
Block::default()
|
block = block.title_top(
|
||||||
.title(title)
|
Line::styled(" Esc to close ", current_border_style).right_aligned(),
|
||||||
.borders(Borders::ALL)
|
)
|
||||||
.border_style(current_border_style)
|
}
|
||||||
} else if is_on_widget {
|
|
||||||
Block::default()
|
block
|
||||||
.borders(SIDE_BORDERS)
|
|
||||||
.border_style(current_border_style)
|
|
||||||
} else {
|
|
||||||
Block::default().borders(Borders::NONE)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let margined_draw_loc = Layout::default()
|
let margined_draw_loc = Layout::default()
|
||||||
.constraints([Constraint::Percentage(100)])
|
.constraints([Constraint::Percentage(100)])
|
||||||
.horizontal_margin(u16::from(!(is_on_widget || draw_border)))
|
.horizontal_margin(u16::from(is_basic && !is_selected))
|
||||||
.direction(Direction::Horizontal)
|
.direction(Direction::Horizontal)
|
||||||
.split(draw_loc)[0];
|
.split(draw_loc)[0];
|
||||||
|
|
||||||
f.render_widget(
|
f.render_widget(
|
||||||
Paragraph::new(search_text)
|
Paragraph::new(search_text)
|
||||||
.block(process_search_block)
|
.block(process_search_block)
|
||||||
.style(self.colours.text_style)
|
.style(self.styles.text_style)
|
||||||
.alignment(Alignment::Left),
|
.alignment(Alignment::Left),
|
||||||
margined_draw_loc,
|
margined_draw_loc,
|
||||||
);
|
);
|
||||||
|
@ -16,7 +16,7 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
use config::style::ColourPalette;
|
use config::style::Styles;
|
||||||
pub use config::Config;
|
pub use config::Config;
|
||||||
pub(crate) use error::{OptionError, OptionResult};
|
pub(crate) use error::{OptionError, OptionResult};
|
||||||
use hashbrown::{HashMap, HashSet};
|
use hashbrown::{HashMap, HashSet};
|
||||||
@ -144,7 +144,7 @@ fn create_config_at_path(path: &Path) -> anyhow::Result<Config> {
|
|||||||
/// - If the user does NOT pass in a path explicitly, then just show a warning,
|
/// - If the user does NOT pass in a path explicitly, then just show a warning,
|
||||||
/// but continue. This is in case they do not want to write a default config file at
|
/// but continue. This is in case they do not want to write a default config file at
|
||||||
/// the XDG locations, for example.
|
/// the XDG locations, for example.
|
||||||
pub fn get_or_create_config(config_path: Option<&Path>) -> anyhow::Result<Config> {
|
pub(crate) fn get_or_create_config(config_path: Option<&Path>) -> anyhow::Result<Config> {
|
||||||
let adjusted_config_path = get_config_path(config_path);
|
let adjusted_config_path = get_config_path(config_path);
|
||||||
|
|
||||||
match &adjusted_config_path {
|
match &adjusted_config_path {
|
||||||
@ -196,9 +196,7 @@ pub fn get_or_create_config(config_path: Option<&Path>) -> anyhow::Result<Config
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Initialize the app.
|
/// Initialize the app.
|
||||||
pub(crate) fn init_app(
|
pub(crate) fn init_app(args: BottomArgs, config: Config) -> Result<(App, BottomLayout, Styles)> {
|
||||||
args: BottomArgs, config: Config,
|
|
||||||
) -> Result<(App, BottomLayout, ColourPalette)> {
|
|
||||||
use BottomWidgetType::*;
|
use BottomWidgetType::*;
|
||||||
|
|
||||||
// Since everything takes a reference, but we want to take ownership here to
|
// Since everything takes a reference, but we want to take ownership here to
|
||||||
@ -206,7 +204,7 @@ pub(crate) fn init_app(
|
|||||||
let args = &args;
|
let args = &args;
|
||||||
let config = &config;
|
let config = &config;
|
||||||
|
|
||||||
let styling = ColourPalette::new(args, config)?;
|
let styling = Styles::new(args, config)?;
|
||||||
|
|
||||||
let (widget_layout, default_widget_id, default_widget_type_option) =
|
let (widget_layout, default_widget_id, default_widget_type_option) =
|
||||||
get_widget_layout(args, config)
|
get_widget_layout(args, config)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
//! Config options around styling.
|
//! Config options around styling.
|
||||||
|
|
||||||
mod battery;
|
mod battery;
|
||||||
|
mod borders;
|
||||||
mod cpu;
|
mod cpu;
|
||||||
mod graphs;
|
mod graphs;
|
||||||
mod memory;
|
mod memory;
|
||||||
@ -19,7 +20,7 @@ use memory::MemoryStyle;
|
|||||||
use network::NetworkStyle;
|
use network::NetworkStyle;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use tables::TableStyle;
|
use tables::TableStyle;
|
||||||
use tui::style::Style;
|
use tui::{style::Style, widgets::BorderType};
|
||||||
use utils::{opt, set_colour, set_colour_list, set_style};
|
use utils::{opt, set_colour, set_colour_list, set_style};
|
||||||
use widgets::WidgetStyle;
|
use widgets::WidgetStyle;
|
||||||
|
|
||||||
@ -92,45 +93,47 @@ pub(crate) struct StyleConfig {
|
|||||||
pub(crate) widgets: Option<WidgetStyle>,
|
pub(crate) widgets: Option<WidgetStyle>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The actual internal representation of the configured colours,
|
/// The actual internal representation of the configured styles.
|
||||||
/// as a "palette".
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ColourPalette {
|
pub struct Styles {
|
||||||
pub ram_style: Style,
|
pub(crate) ram_style: Style,
|
||||||
#[cfg(not(target_os = "windows"))]
|
#[cfg(not(target_os = "windows"))]
|
||||||
pub cache_style: Style,
|
pub(crate) cache_style: Style,
|
||||||
pub swap_style: Style,
|
pub(crate) swap_style: Style,
|
||||||
pub arc_style: Style,
|
#[cfg(feature = "zfs")]
|
||||||
pub gpu_colours: Vec<Style>,
|
pub(crate) arc_style: Style,
|
||||||
pub rx_style: Style,
|
#[cfg(feature = "gpu")]
|
||||||
pub tx_style: Style,
|
pub(crate) gpu_colours: Vec<Style>,
|
||||||
pub total_rx_style: Style,
|
pub(crate) rx_style: Style,
|
||||||
pub total_tx_style: Style,
|
pub(crate) tx_style: Style,
|
||||||
pub all_cpu_colour: Style,
|
pub(crate) total_rx_style: Style,
|
||||||
pub avg_cpu_colour: Style,
|
pub(crate) total_tx_style: Style,
|
||||||
pub cpu_colour_styles: Vec<Style>,
|
pub(crate) all_cpu_colour: Style,
|
||||||
pub border_style: Style,
|
pub(crate) avg_cpu_colour: Style,
|
||||||
pub highlighted_border_style: Style,
|
pub(crate) cpu_colour_styles: Vec<Style>,
|
||||||
pub text_style: Style,
|
pub(crate) border_style: Style,
|
||||||
pub selected_text_style: Style,
|
pub(crate) highlighted_border_style: Style,
|
||||||
pub table_header_style: Style,
|
pub(crate) text_style: Style,
|
||||||
pub widget_title_style: Style,
|
pub(crate) selected_text_style: Style,
|
||||||
pub graph_style: Style,
|
pub(crate) table_header_style: Style,
|
||||||
pub graph_legend_style: Style,
|
pub(crate) widget_title_style: Style,
|
||||||
pub high_battery: Style,
|
pub(crate) graph_style: Style,
|
||||||
pub medium_battery: Style,
|
pub(crate) graph_legend_style: Style,
|
||||||
pub low_battery: Style,
|
pub(crate) high_battery: Style,
|
||||||
pub invalid_query_style: Style,
|
pub(crate) medium_battery: Style,
|
||||||
pub disabled_text_style: Style,
|
pub(crate) low_battery: Style,
|
||||||
|
pub(crate) invalid_query_style: Style,
|
||||||
|
pub(crate) disabled_text_style: Style,
|
||||||
|
pub(crate) border_type: BorderType,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for ColourPalette {
|
impl Default for Styles {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::default_palette()
|
Self::default_style()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ColourPalette {
|
impl Styles {
|
||||||
pub fn new(args: &BottomArgs, config: &Config) -> anyhow::Result<Self> {
|
pub fn new(args: &BottomArgs, config: &Config) -> anyhow::Result<Self> {
|
||||||
let mut palette = match &args.style.theme {
|
let mut palette = match &args.style.theme {
|
||||||
Some(theme) => Self::from_theme(theme)?,
|
Some(theme) => Self::from_theme(theme)?,
|
||||||
@ -141,8 +144,8 @@ impl ColourPalette {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Apply theme from config on top.
|
// Apply theme from config on top.
|
||||||
if let Some(style) = &config.styles {
|
if let Some(config_style) = &config.styles {
|
||||||
palette.set_colours_from_palette(style)?;
|
palette.set_styles_from_config(config_style)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(palette)
|
Ok(palette)
|
||||||
@ -151,7 +154,7 @@ impl ColourPalette {
|
|||||||
fn from_theme(theme: &str) -> anyhow::Result<Self> {
|
fn from_theme(theme: &str) -> anyhow::Result<Self> {
|
||||||
let lower_case = theme.to_lowercase();
|
let lower_case = theme.to_lowercase();
|
||||||
match lower_case.as_str() {
|
match lower_case.as_str() {
|
||||||
"default" => Ok(Self::default_palette()),
|
"default" => Ok(Self::default_style()),
|
||||||
"default-light" => Ok(Self::default_light_mode()),
|
"default-light" => Ok(Self::default_light_mode()),
|
||||||
"gruvbox" => Ok(Self::gruvbox_palette()),
|
"gruvbox" => Ok(Self::gruvbox_palette()),
|
||||||
"gruvbox-light" => Ok(Self::gruvbox_light_palette()),
|
"gruvbox-light" => Ok(Self::gruvbox_light_palette()),
|
||||||
@ -164,7 +167,7 @@ impl ColourPalette {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_colours_from_palette(&mut self, config: &StyleConfig) -> OptionResult<()> {
|
fn set_styles_from_config(&mut self, config: &StyleConfig) -> OptionResult<()> {
|
||||||
// CPU
|
// CPU
|
||||||
set_colour!(self.avg_cpu_colour, config.cpu, avg_entry_color);
|
set_colour!(self.avg_cpu_colour, config.cpu, avg_entry_color);
|
||||||
set_colour!(self.all_cpu_colour, config.cpu, all_entry_color);
|
set_colour!(self.all_cpu_colour, config.cpu, all_entry_color);
|
||||||
@ -215,6 +218,12 @@ impl ColourPalette {
|
|||||||
selected_border_color
|
selected_border_color
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if let Some(widgets) = &config.widgets {
|
||||||
|
if let Some(widget_borders) = widgets.widget_border_type {
|
||||||
|
self.border_type = widget_borders.into();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -224,20 +233,14 @@ mod test {
|
|||||||
|
|
||||||
use tui::style::{Color, Style};
|
use tui::style::{Color, Style};
|
||||||
|
|
||||||
use super::ColourPalette;
|
use super::Styles;
|
||||||
use crate::options::config::style::utils::str_to_colour;
|
use crate::options::config::style::utils::str_to_colour;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn default_selected_colour_works() {
|
fn default_selected_colour_works() {
|
||||||
let mut colours = ColourPalette::default();
|
let mut colours = Styles::default();
|
||||||
let original_selected_text_colour = ColourPalette::default_palette()
|
let original_selected_text_colour = Styles::default_style().selected_text_style.fg.unwrap();
|
||||||
.selected_text_style
|
let original_selected_bg_colour = Styles::default_style().selected_text_style.bg.unwrap();
|
||||||
.fg
|
|
||||||
.unwrap();
|
|
||||||
let original_selected_bg_colour = ColourPalette::default_palette()
|
|
||||||
.selected_text_style
|
|
||||||
.bg
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
colours.selected_text_style,
|
colours.selected_text_style,
|
||||||
@ -259,11 +262,11 @@ mod test {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn built_in_colour_schemes_work() {
|
fn built_in_colour_schemes_work() {
|
||||||
ColourPalette::from_theme("default").unwrap();
|
Styles::from_theme("default").unwrap();
|
||||||
ColourPalette::from_theme("default-light").unwrap();
|
Styles::from_theme("default-light").unwrap();
|
||||||
ColourPalette::from_theme("gruvbox").unwrap();
|
Styles::from_theme("gruvbox").unwrap();
|
||||||
ColourPalette::from_theme("gruvbox-light").unwrap();
|
Styles::from_theme("gruvbox-light").unwrap();
|
||||||
ColourPalette::from_theme("nord").unwrap();
|
Styles::from_theme("nord").unwrap();
|
||||||
ColourPalette::from_theme("nord-light").unwrap();
|
Styles::from_theme("nord-light").unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
42
src/options/config/style/borders.rs
Normal file
42
src/options/config/style/borders.rs
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use tui::widgets::BorderType;
|
||||||
|
|
||||||
|
#[derive(Default, Clone, Copy, Debug, Serialize)]
|
||||||
|
#[cfg_attr(feature = "generate_schema", derive(schemars::JsonSchema))]
|
||||||
|
#[cfg_attr(test, derive(PartialEq, Eq))]
|
||||||
|
pub(crate) enum WidgetBorderType {
|
||||||
|
#[default]
|
||||||
|
Default,
|
||||||
|
Rounded,
|
||||||
|
Double,
|
||||||
|
Thick,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de> Deserialize<'de> for WidgetBorderType {
|
||||||
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
|
where
|
||||||
|
D: serde::Deserializer<'de>,
|
||||||
|
{
|
||||||
|
let value = String::deserialize(deserializer)?.to_lowercase();
|
||||||
|
match value.as_str() {
|
||||||
|
"default" => Ok(WidgetBorderType::Default),
|
||||||
|
"rounded" => Ok(WidgetBorderType::Rounded),
|
||||||
|
"double" => Ok(WidgetBorderType::Double),
|
||||||
|
"thick" => Ok(WidgetBorderType::Thick),
|
||||||
|
_ => Err(serde::de::Error::custom(
|
||||||
|
"doesn't match any widget border type",
|
||||||
|
)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<WidgetBorderType> for BorderType {
|
||||||
|
fn from(value: WidgetBorderType) -> Self {
|
||||||
|
match value {
|
||||||
|
WidgetBorderType::Default => BorderType::Plain,
|
||||||
|
WidgetBorderType::Rounded => BorderType::Rounded,
|
||||||
|
WidgetBorderType::Double => BorderType::Double,
|
||||||
|
WidgetBorderType::Thick => BorderType::Thick,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,10 +1,13 @@
|
|||||||
use tui::style::{Color, Modifier, Style};
|
use tui::{
|
||||||
|
style::{Color, Modifier, Style},
|
||||||
|
widgets::BorderType,
|
||||||
|
};
|
||||||
|
|
||||||
use super::color;
|
use super::color;
|
||||||
use crate::options::config::style::ColourPalette;
|
use crate::options::config::style::Styles;
|
||||||
|
|
||||||
impl ColourPalette {
|
impl Styles {
|
||||||
pub(crate) fn default_palette() -> Self {
|
pub(crate) fn default_style() -> Self {
|
||||||
const FIRST_COLOUR: Color = Color::LightMagenta;
|
const FIRST_COLOUR: Color = Color::LightMagenta;
|
||||||
const SECOND_COLOUR: Color = Color::LightYellow;
|
const SECOND_COLOUR: Color = Color::LightYellow;
|
||||||
const THIRD_COLOUR: Color = Color::LightCyan;
|
const THIRD_COLOUR: Color = Color::LightCyan;
|
||||||
@ -22,7 +25,9 @@ impl ColourPalette {
|
|||||||
#[cfg(not(target_os = "windows"))]
|
#[cfg(not(target_os = "windows"))]
|
||||||
cache_style: color!(FIFTH_COLOUR),
|
cache_style: color!(FIFTH_COLOUR),
|
||||||
swap_style: color!(SECOND_COLOUR),
|
swap_style: color!(SECOND_COLOUR),
|
||||||
|
#[cfg(feature = "zfs")]
|
||||||
arc_style: color!(THIRD_COLOUR),
|
arc_style: color!(THIRD_COLOUR),
|
||||||
|
#[cfg(feature = "gpu")]
|
||||||
gpu_colours: vec![
|
gpu_colours: vec![
|
||||||
color!(FOURTH_COLOUR),
|
color!(FOURTH_COLOUR),
|
||||||
color!(Color::LightBlue),
|
color!(Color::LightBlue),
|
||||||
@ -61,6 +66,7 @@ impl ColourPalette {
|
|||||||
low_battery: color!(Color::Red),
|
low_battery: color!(Color::Red),
|
||||||
invalid_query_style: color!(Color::Red),
|
invalid_query_style: color!(Color::Red),
|
||||||
disabled_text_style: color!(Color::DarkGray),
|
disabled_text_style: color!(Color::DarkGray),
|
||||||
|
border_type: BorderType::Plain,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,7 +76,9 @@ impl ColourPalette {
|
|||||||
#[cfg(not(target_os = "windows"))]
|
#[cfg(not(target_os = "windows"))]
|
||||||
cache_style: color!(Color::LightRed),
|
cache_style: color!(Color::LightRed),
|
||||||
swap_style: color!(Color::Red),
|
swap_style: color!(Color::Red),
|
||||||
|
#[cfg(feature = "zfs")]
|
||||||
arc_style: color!(Color::LightBlue),
|
arc_style: color!(Color::LightBlue),
|
||||||
|
#[cfg(feature = "gpu")]
|
||||||
gpu_colours: vec![
|
gpu_colours: vec![
|
||||||
color!(Color::LightGreen),
|
color!(Color::LightGreen),
|
||||||
color!(Color::LightCyan),
|
color!(Color::LightCyan),
|
||||||
@ -101,7 +109,7 @@ impl ColourPalette {
|
|||||||
graph_style: color!(Color::Black),
|
graph_style: color!(Color::Black),
|
||||||
graph_legend_style: color!(Color::Black),
|
graph_legend_style: color!(Color::Black),
|
||||||
disabled_text_style: color!(Color::Gray),
|
disabled_text_style: color!(Color::Gray),
|
||||||
..Self::default_palette()
|
..Self::default_style()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,21 @@
|
|||||||
use tui::style::{Color, Modifier};
|
use tui::{
|
||||||
|
style::{Color, Modifier},
|
||||||
|
widgets::BorderType,
|
||||||
|
};
|
||||||
|
|
||||||
use super::{color, hex};
|
use super::{color, hex};
|
||||||
use crate::options::config::style::{utils::convert_hex_to_color, ColourPalette};
|
use crate::options::config::style::{utils::convert_hex_to_color, Styles};
|
||||||
|
|
||||||
impl ColourPalette {
|
impl Styles {
|
||||||
pub(crate) fn gruvbox_palette() -> Self {
|
pub(crate) fn gruvbox_palette() -> Self {
|
||||||
Self {
|
Self {
|
||||||
ram_style: hex!("#8ec07c"),
|
ram_style: hex!("#8ec07c"),
|
||||||
#[cfg(not(target_os = "windows"))]
|
#[cfg(not(target_os = "windows"))]
|
||||||
cache_style: hex!("#b16286"),
|
cache_style: hex!("#b16286"),
|
||||||
swap_style: hex!("#fabd2f"),
|
swap_style: hex!("#fabd2f"),
|
||||||
|
#[cfg(feature = "zfs")]
|
||||||
arc_style: hex!("#689d6a"),
|
arc_style: hex!("#689d6a"),
|
||||||
|
#[cfg(feature = "gpu")]
|
||||||
gpu_colours: vec![
|
gpu_colours: vec![
|
||||||
hex!("#d79921"),
|
hex!("#d79921"),
|
||||||
hex!("#458588"),
|
hex!("#458588"),
|
||||||
@ -61,6 +66,7 @@ impl ColourPalette {
|
|||||||
low_battery: hex!("#fb4934"),
|
low_battery: hex!("#fb4934"),
|
||||||
invalid_query_style: color!(Color::Red),
|
invalid_query_style: color!(Color::Red),
|
||||||
disabled_text_style: hex!("#665c54"),
|
disabled_text_style: hex!("#665c54"),
|
||||||
|
border_type: BorderType::Plain,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,7 +76,9 @@ impl ColourPalette {
|
|||||||
#[cfg(not(target_os = "windows"))]
|
#[cfg(not(target_os = "windows"))]
|
||||||
cache_style: hex!("#d79921"),
|
cache_style: hex!("#d79921"),
|
||||||
swap_style: hex!("#cc241d"),
|
swap_style: hex!("#cc241d"),
|
||||||
|
#[cfg(feature = "zfs")]
|
||||||
arc_style: hex!("#689d6a"),
|
arc_style: hex!("#689d6a"),
|
||||||
|
#[cfg(feature = "gpu")]
|
||||||
gpu_colours: vec![
|
gpu_colours: vec![
|
||||||
hex!("#9d0006"),
|
hex!("#9d0006"),
|
||||||
hex!("#98971a"),
|
hex!("#98971a"),
|
||||||
@ -121,6 +129,7 @@ impl ColourPalette {
|
|||||||
low_battery: hex!("#cc241d"),
|
low_battery: hex!("#cc241d"),
|
||||||
invalid_query_style: color!(Color::Red),
|
invalid_query_style: color!(Color::Red),
|
||||||
disabled_text_style: hex!("#d5c4a1"),
|
disabled_text_style: hex!("#d5c4a1"),
|
||||||
|
border_type: BorderType::Plain,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,21 @@
|
|||||||
use tui::style::{Color, Modifier};
|
use tui::{
|
||||||
|
style::{Color, Modifier},
|
||||||
|
widgets::BorderType,
|
||||||
|
};
|
||||||
|
|
||||||
use super::{color, hex};
|
use super::{color, hex};
|
||||||
use crate::options::config::style::{utils::convert_hex_to_color, ColourPalette};
|
use crate::options::config::style::{utils::convert_hex_to_color, Styles};
|
||||||
|
|
||||||
impl ColourPalette {
|
impl Styles {
|
||||||
pub(crate) fn nord_palette() -> Self {
|
pub(crate) fn nord_palette() -> Self {
|
||||||
Self {
|
Self {
|
||||||
ram_style: hex!("#88c0d0"),
|
ram_style: hex!("#88c0d0"),
|
||||||
#[cfg(not(target_os = "windows"))]
|
#[cfg(not(target_os = "windows"))]
|
||||||
cache_style: hex!("#d8dee9"),
|
cache_style: hex!("#d8dee9"),
|
||||||
swap_style: hex!("#d08770"),
|
swap_style: hex!("#d08770"),
|
||||||
|
#[cfg(feature = "zfs")]
|
||||||
arc_style: hex!("#5e81ac"),
|
arc_style: hex!("#5e81ac"),
|
||||||
|
#[cfg(feature = "gpu")]
|
||||||
gpu_colours: vec![
|
gpu_colours: vec![
|
||||||
hex!("#8fbcbb"),
|
hex!("#8fbcbb"),
|
||||||
hex!("#81a1c1"),
|
hex!("#81a1c1"),
|
||||||
@ -49,6 +54,7 @@ impl ColourPalette {
|
|||||||
low_battery: hex!("#bf616a"),
|
low_battery: hex!("#bf616a"),
|
||||||
invalid_query_style: color!(Color::Red),
|
invalid_query_style: color!(Color::Red),
|
||||||
disabled_text_style: hex!("#4c566a"),
|
disabled_text_style: hex!("#4c566a"),
|
||||||
|
border_type: BorderType::Plain,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,7 +64,9 @@ impl ColourPalette {
|
|||||||
#[cfg(not(target_os = "windows"))]
|
#[cfg(not(target_os = "windows"))]
|
||||||
cache_style: hex!("#4c566a"),
|
cache_style: hex!("#4c566a"),
|
||||||
swap_style: hex!("#d08770"),
|
swap_style: hex!("#d08770"),
|
||||||
|
#[cfg(feature = "zfs")]
|
||||||
arc_style: hex!("#5e81ac"),
|
arc_style: hex!("#5e81ac"),
|
||||||
|
#[cfg(feature = "gpu")]
|
||||||
gpu_colours: vec![
|
gpu_colours: vec![
|
||||||
hex!("#8fbcbb"),
|
hex!("#8fbcbb"),
|
||||||
hex!("#88c0d0"),
|
hex!("#88c0d0"),
|
||||||
@ -97,6 +105,7 @@ impl ColourPalette {
|
|||||||
low_battery: hex!("#bf616a"),
|
low_battery: hex!("#bf616a"),
|
||||||
invalid_query_style: color!(Color::Red),
|
invalid_query_style: color!(Color::Red),
|
||||||
disabled_text_style: hex!("#d8dee9"),
|
disabled_text_style: hex!("#d8dee9"),
|
||||||
|
border_type: BorderType::Plain,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use super::{ColorStr, TextStyleConfig};
|
use super::{borders::WidgetBorderType, ColorStr, TextStyleConfig};
|
||||||
|
|
||||||
/// General styling for generic widgets.
|
/// General styling for generic widgets.
|
||||||
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
||||||
@ -26,4 +26,7 @@ pub(crate) struct WidgetStyle {
|
|||||||
|
|
||||||
/// Text styling for text when representing something that is disabled.
|
/// Text styling for text when representing something that is disabled.
|
||||||
pub(crate) disabled_text: Option<TextStyleConfig>,
|
pub(crate) disabled_text: Option<TextStyleConfig>,
|
||||||
|
|
||||||
|
/// Widget borders type.
|
||||||
|
pub(crate) widget_border_type: Option<WidgetBorderType>,
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ use crate::{
|
|||||||
},
|
},
|
||||||
data_collection::cpu::CpuDataType,
|
data_collection::cpu::CpuDataType,
|
||||||
data_conversion::CpuWidgetData,
|
data_conversion::CpuWidgetData,
|
||||||
options::config::{cpu::CpuDefault, style::ColourPalette},
|
options::config::{cpu::CpuDefault, style::Styles},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub enum CpuWidgetColumn {
|
pub enum CpuWidgetColumn {
|
||||||
@ -106,15 +106,14 @@ impl DataToCell<CpuWidgetColumn> for CpuWidgetTableData {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn style_row<'a>(&self, row: Row<'a>, painter: &Painter) -> Row<'a> {
|
fn style_row<'a>(&self, row: Row<'a>, painter: &Painter) -> Row<'a> {
|
||||||
let style = match self {
|
let style = match self {
|
||||||
CpuWidgetTableData::All => painter.colours.all_cpu_colour,
|
CpuWidgetTableData::All => painter.styles.all_cpu_colour,
|
||||||
CpuWidgetTableData::Entry {
|
CpuWidgetTableData::Entry {
|
||||||
data_type,
|
data_type,
|
||||||
last_entry: _,
|
last_entry: _,
|
||||||
} => match data_type {
|
} => match data_type {
|
||||||
CpuDataType::Avg => painter.colours.avg_cpu_colour,
|
CpuDataType::Avg => painter.styles.avg_cpu_colour,
|
||||||
CpuDataType::Cpu(index) => {
|
CpuDataType::Cpu(index) => {
|
||||||
painter.colours.cpu_colour_styles
|
painter.styles.cpu_colour_styles[index % painter.styles.cpu_colour_styles.len()]
|
||||||
[index % painter.colours.cpu_colour_styles.len()]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -142,7 +141,7 @@ pub struct CpuWidgetState {
|
|||||||
impl CpuWidgetState {
|
impl CpuWidgetState {
|
||||||
pub(crate) fn new(
|
pub(crate) fn new(
|
||||||
config: &AppConfigFields, default_selection: CpuDefault, current_display_time: u64,
|
config: &AppConfigFields, default_selection: CpuDefault, current_display_time: u64,
|
||||||
autohide_timer: Option<Instant>, colours: &ColourPalette,
|
autohide_timer: Option<Instant>, colours: &Styles,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
const COLUMNS: [Column<CpuWidgetColumn>; 2] = [
|
const COLUMNS: [Column<CpuWidgetColumn>; 2] = [
|
||||||
Column::soft(CpuWidgetColumn::Cpu, Some(0.5)),
|
Column::soft(CpuWidgetColumn::Cpu, Some(0.5)),
|
||||||
|
@ -8,7 +8,7 @@ use crate::{
|
|||||||
ColumnHeader, DataTableColumn, DataTableProps, DataTableStyling, DataToCell, SortColumn,
|
ColumnHeader, DataTableColumn, DataTableProps, DataTableStyling, DataToCell, SortColumn,
|
||||||
SortDataTable, SortDataTableProps, SortOrder, SortsRow,
|
SortDataTable, SortDataTableProps, SortOrder, SortsRow,
|
||||||
},
|
},
|
||||||
options::config::style::ColourPalette,
|
options::config::style::Styles,
|
||||||
utils::{data_prefixes::get_decimal_bytes, general::sort_partial_fn},
|
utils::{data_prefixes::get_decimal_bytes, general::sort_partial_fn},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -275,9 +275,7 @@ const fn default_disk_columns() -> [SortColumn<DiskColumn>; 8] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl DiskTableWidget {
|
impl DiskTableWidget {
|
||||||
pub fn new(
|
pub fn new(config: &AppConfigFields, palette: &Styles, columns: Option<&[DiskColumn]>) -> Self {
|
||||||
config: &AppConfigFields, palette: &ColourPalette, columns: Option<&[DiskColumn]>,
|
|
||||||
) -> Self {
|
|
||||||
let props = SortDataTableProps {
|
let props = SortDataTableProps {
|
||||||
inner: DataTableProps {
|
inner: DataTableProps {
|
||||||
title: Some(" Disks ".into()),
|
title: Some(" Disks ".into()),
|
||||||
|
@ -23,7 +23,7 @@ use crate::{
|
|||||||
DataTableStyling, SortColumn, SortDataTable, SortDataTableProps, SortOrder, SortsRow,
|
DataTableStyling, SortColumn, SortDataTable, SortDataTableProps, SortOrder, SortsRow,
|
||||||
},
|
},
|
||||||
data_collection::processes::{Pid, ProcessHarvest},
|
data_collection::processes::{Pid, ProcessHarvest},
|
||||||
options::config::style::ColourPalette,
|
options::config::style::Styles,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// ProcessSearchState only deals with process' search's current settings and
|
/// ProcessSearchState only deals with process' search's current settings and
|
||||||
@ -160,7 +160,7 @@ pub struct ProcWidgetState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ProcWidgetState {
|
impl ProcWidgetState {
|
||||||
fn new_sort_table(config: &AppConfigFields, palette: &ColourPalette) -> SortTable {
|
fn new_sort_table(config: &AppConfigFields, palette: &Styles) -> SortTable {
|
||||||
const COLUMNS: [Column<SortTableColumn>; 1] = [Column::hard(SortTableColumn, 7)];
|
const COLUMNS: [Column<SortTableColumn>; 1] = [Column::hard(SortTableColumn, 7)];
|
||||||
|
|
||||||
let props = DataTableProps {
|
let props = DataTableProps {
|
||||||
@ -177,7 +177,7 @@ impl ProcWidgetState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn new_process_table(
|
fn new_process_table(
|
||||||
config: &AppConfigFields, colours: &ColourPalette, columns: Vec<SortColumn<ProcColumn>>,
|
config: &AppConfigFields, colours: &Styles, columns: Vec<SortColumn<ProcColumn>>,
|
||||||
default_index: usize, default_order: SortOrder,
|
default_index: usize, default_order: SortOrder,
|
||||||
) -> ProcessTable {
|
) -> ProcessTable {
|
||||||
let inner_props = DataTableProps {
|
let inner_props = DataTableProps {
|
||||||
@ -200,7 +200,7 @@ impl ProcWidgetState {
|
|||||||
|
|
||||||
pub fn new(
|
pub fn new(
|
||||||
config: &AppConfigFields, mode: ProcWidgetMode, table_config: ProcTableConfig,
|
config: &AppConfigFields, mode: ProcWidgetMode, table_config: ProcTableConfig,
|
||||||
colours: &ColourPalette, config_columns: &Option<IndexSet<ProcWidgetColumn>>,
|
colours: &Styles, config_columns: &Option<IndexSet<ProcWidgetColumn>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let process_search_state = {
|
let process_search_state = {
|
||||||
let mut pss = ProcessSearchState::default();
|
let mut pss = ProcessSearchState::default();
|
||||||
@ -1130,7 +1130,7 @@ mod test {
|
|||||||
|
|
||||||
fn init_state(table_config: ProcTableConfig, columns: &[ProcWidgetColumn]) -> ProcWidgetState {
|
fn init_state(table_config: ProcTableConfig, columns: &[ProcWidgetColumn]) -> ProcWidgetState {
|
||||||
let config = AppConfigFields::default();
|
let config = AppConfigFields::default();
|
||||||
let styling = ColourPalette::default();
|
let styling = Styles::default();
|
||||||
let columns = Some(columns.iter().cloned().collect());
|
let columns = Some(columns.iter().cloned().collect());
|
||||||
|
|
||||||
ProcWidgetState::new(
|
ProcWidgetState::new(
|
||||||
|
@ -340,7 +340,7 @@ impl DataToCell<ProcColumn> for ProcWidgetData {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn style_row<'a>(&self, row: Row<'a>, painter: &Painter) -> Row<'a> {
|
fn style_row<'a>(&self, row: Row<'a>, painter: &Painter) -> Row<'a> {
|
||||||
if self.disabled {
|
if self.disabled {
|
||||||
row.style(painter.colours.disabled_text_style)
|
row.style(painter.styles.disabled_text_style)
|
||||||
} else {
|
} else {
|
||||||
row
|
row
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ use crate::{
|
|||||||
SortDataTable, SortDataTableProps, SortOrder, SortsRow,
|
SortDataTable, SortDataTableProps, SortOrder, SortsRow,
|
||||||
},
|
},
|
||||||
data_collection::temperature::TemperatureType,
|
data_collection::temperature::TemperatureType,
|
||||||
options::config::style::ColourPalette,
|
options::config::style::Styles,
|
||||||
utils::general::sort_partial_fn,
|
utils::general::sort_partial_fn,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -100,7 +100,7 @@ pub struct TempWidgetState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl TempWidgetState {
|
impl TempWidgetState {
|
||||||
pub(crate) fn new(config: &AppConfigFields, palette: &ColourPalette) -> Self {
|
pub(crate) fn new(config: &AppConfigFields, palette: &Styles) -> Self {
|
||||||
let columns = [
|
let columns = [
|
||||||
SortColumn::soft(TempWidgetColumn::Sensor, Some(0.8)),
|
SortColumn::soft(TempWidgetColumn::Sensor, Some(0.8)),
|
||||||
SortColumn::soft(TempWidgetColumn::Temp, None).default_descending(),
|
SortColumn::soft(TempWidgetColumn::Temp, None).default_descending(),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user