mirror of
https://github.com/ClementTsang/bottom
synced 2024-11-10 14:44:18 +00:00
Add hiding time and autohiding time.
This commit is contained in:
parent
78a05bc683
commit
e5588f1606
10 changed files with 250 additions and 77 deletions
|
@ -216,6 +216,8 @@ Note that `q` is disabled while in the search widget.
|
|||
|
||||
- Scrolling with the mouse will scroll through the currently selected list if the widget is a scrollable table.
|
||||
|
||||
- Scrolling on a graph will zoom in (scroll up) or zoom out (scroll down).
|
||||
|
||||
## Bugs and Requests
|
||||
|
||||
Spot an bug? Have an idea? Leave an issue that explains what you want in detail and I'll try to take a look.
|
||||
|
|
87
src/app.rs
87
src/app.rs
|
@ -222,27 +222,31 @@ pub struct AppConfigFields {
|
|||
pub use_basic_mode: bool,
|
||||
pub default_time_value: u64,
|
||||
pub time_interval: u64,
|
||||
pub hide_time: bool,
|
||||
pub autohide_time: bool,
|
||||
}
|
||||
|
||||
/// Network specific
|
||||
pub struct NetworkState {
|
||||
pub struct NetState {
|
||||
pub is_showing_tray: bool,
|
||||
pub is_showing_rx: bool,
|
||||
pub is_showing_tx: bool,
|
||||
pub zoom_level: f64,
|
||||
pub display_time: u64,
|
||||
pub force_update: bool,
|
||||
pub display_time_instant: Option<Instant>,
|
||||
}
|
||||
|
||||
impl Default for NetworkState {
|
||||
impl Default for NetState {
|
||||
fn default() -> Self {
|
||||
NetworkState {
|
||||
NetState {
|
||||
is_showing_tray: false,
|
||||
is_showing_rx: true,
|
||||
is_showing_tx: true,
|
||||
zoom_level: 100.0,
|
||||
display_time: constants::DEFAULT_TIME_MILLISECONDS,
|
||||
force_update: false,
|
||||
display_time_instant: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -254,6 +258,7 @@ pub struct CpuState {
|
|||
pub core_show_vec: Vec<bool>,
|
||||
pub display_time: u64,
|
||||
pub force_update: bool,
|
||||
pub display_time_instant: Option<Instant>,
|
||||
}
|
||||
|
||||
impl Default for CpuState {
|
||||
|
@ -264,6 +269,7 @@ impl Default for CpuState {
|
|||
core_show_vec: Vec::new(),
|
||||
display_time: constants::DEFAULT_TIME_MILLISECONDS,
|
||||
force_update: false,
|
||||
display_time_instant: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -276,6 +282,7 @@ pub struct MemState {
|
|||
pub zoom_level: f64,
|
||||
pub display_time: u64,
|
||||
pub force_update: bool,
|
||||
pub display_time_instant: Option<Instant>,
|
||||
}
|
||||
|
||||
impl Default for MemState {
|
||||
|
@ -287,6 +294,7 @@ impl Default for MemState {
|
|||
zoom_level: 100.0,
|
||||
display_time: constants::DEFAULT_TIME_MILLISECONDS,
|
||||
force_update: false,
|
||||
display_time_instant: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -315,7 +323,7 @@ pub struct App {
|
|||
pub is_resized: bool,
|
||||
pub cpu_state: CpuState,
|
||||
pub mem_state: MemState,
|
||||
pub net_state: NetworkState,
|
||||
pub net_state: NetState,
|
||||
}
|
||||
|
||||
impl App {
|
||||
|
@ -330,7 +338,7 @@ impl App {
|
|||
) -> App {
|
||||
let mut cpu_state = CpuState::default();
|
||||
let mut mem_state = MemState::default();
|
||||
let mut net_state = NetworkState::default();
|
||||
let mut net_state = NetState::default();
|
||||
|
||||
cpu_state.display_time = default_time_value;
|
||||
mem_state.display_time = default_time_value;
|
||||
|
@ -379,6 +387,8 @@ impl App {
|
|||
use_basic_mode,
|
||||
default_time_value,
|
||||
time_interval,
|
||||
hide_time: false,
|
||||
autohide_time: false,
|
||||
},
|
||||
is_expanded: false,
|
||||
is_resized: false,
|
||||
|
@ -1400,7 +1410,7 @@ impl App {
|
|||
WidgetPosition::Process => self.change_process_position(-1),
|
||||
WidgetPosition::Temp => self.change_temp_position(-1),
|
||||
WidgetPosition::Disk => self.change_disk_position(-1),
|
||||
WidgetPosition::CpuLegend => self.change_cpu_table_position(-1), // TODO: [PO?] Temporary, may change if we add scaling
|
||||
WidgetPosition::CpuLegend => self.change_cpu_table_position(-1),
|
||||
_ => {}
|
||||
}
|
||||
self.app_scroll_positions.scroll_direction = ScrollDirection::UP;
|
||||
|
@ -1414,7 +1424,7 @@ impl App {
|
|||
WidgetPosition::Process => self.change_process_position(1),
|
||||
WidgetPosition::Temp => self.change_temp_position(1),
|
||||
WidgetPosition::Disk => self.change_disk_position(1),
|
||||
WidgetPosition::CpuLegend => self.change_cpu_table_position(1), // TODO: [PO?] Temporary, may change if we add scaling
|
||||
WidgetPosition::CpuLegend => self.change_cpu_table_position(1),
|
||||
_ => {}
|
||||
}
|
||||
self.app_scroll_positions.scroll_direction = ScrollDirection::DOWN;
|
||||
|
@ -1507,6 +1517,15 @@ impl App {
|
|||
if new_time <= constants::STALE_MAX_MILLISECONDS {
|
||||
self.cpu_state.display_time = new_time;
|
||||
self.cpu_state.force_update = true;
|
||||
if self.app_config_fields.autohide_time {
|
||||
self.cpu_state.display_time_instant = Some(Instant::now());
|
||||
}
|
||||
} else if self.cpu_state.display_time != constants::STALE_MAX_MILLISECONDS {
|
||||
self.cpu_state.display_time = constants::STALE_MAX_MILLISECONDS;
|
||||
self.cpu_state.force_update = true;
|
||||
if self.app_config_fields.autohide_time {
|
||||
self.cpu_state.display_time_instant = Some(Instant::now());
|
||||
}
|
||||
}
|
||||
}
|
||||
WidgetPosition::Mem => {
|
||||
|
@ -1514,6 +1533,15 @@ impl App {
|
|||
if new_time <= constants::STALE_MAX_MILLISECONDS {
|
||||
self.mem_state.display_time = new_time;
|
||||
self.mem_state.force_update = true;
|
||||
if self.app_config_fields.autohide_time {
|
||||
self.mem_state.display_time_instant = Some(Instant::now());
|
||||
}
|
||||
} else if self.mem_state.display_time != constants::STALE_MAX_MILLISECONDS {
|
||||
self.mem_state.display_time = constants::STALE_MAX_MILLISECONDS;
|
||||
self.mem_state.force_update = true;
|
||||
if self.app_config_fields.autohide_time {
|
||||
self.mem_state.display_time_instant = Some(Instant::now());
|
||||
}
|
||||
}
|
||||
}
|
||||
WidgetPosition::Network => {
|
||||
|
@ -1521,6 +1549,15 @@ impl App {
|
|||
if new_time <= constants::STALE_MAX_MILLISECONDS {
|
||||
self.net_state.display_time = new_time;
|
||||
self.net_state.force_update = true;
|
||||
if self.app_config_fields.autohide_time {
|
||||
self.net_state.display_time_instant = Some(Instant::now());
|
||||
}
|
||||
} else if self.net_state.display_time != constants::STALE_MAX_MILLISECONDS {
|
||||
self.net_state.display_time = constants::STALE_MAX_MILLISECONDS;
|
||||
self.net_state.force_update = true;
|
||||
if self.app_config_fields.autohide_time {
|
||||
self.net_state.display_time_instant = Some(Instant::now());
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
|
@ -1534,6 +1571,15 @@ impl App {
|
|||
if new_time >= constants::STALE_MIN_MILLISECONDS {
|
||||
self.cpu_state.display_time = new_time;
|
||||
self.cpu_state.force_update = true;
|
||||
if self.app_config_fields.autohide_time {
|
||||
self.cpu_state.display_time_instant = Some(Instant::now());
|
||||
}
|
||||
} else if self.cpu_state.display_time != constants::STALE_MIN_MILLISECONDS {
|
||||
self.cpu_state.display_time = constants::STALE_MIN_MILLISECONDS;
|
||||
self.cpu_state.force_update = true;
|
||||
if self.app_config_fields.autohide_time {
|
||||
self.cpu_state.display_time_instant = Some(Instant::now());
|
||||
}
|
||||
}
|
||||
}
|
||||
WidgetPosition::Mem => {
|
||||
|
@ -1541,6 +1587,15 @@ impl App {
|
|||
if new_time >= constants::STALE_MIN_MILLISECONDS {
|
||||
self.mem_state.display_time = new_time;
|
||||
self.mem_state.force_update = true;
|
||||
if self.app_config_fields.autohide_time {
|
||||
self.mem_state.display_time_instant = Some(Instant::now());
|
||||
}
|
||||
} else if self.mem_state.display_time != constants::STALE_MIN_MILLISECONDS {
|
||||
self.mem_state.display_time = constants::STALE_MIN_MILLISECONDS;
|
||||
self.mem_state.force_update = true;
|
||||
if self.app_config_fields.autohide_time {
|
||||
self.mem_state.display_time_instant = Some(Instant::now());
|
||||
}
|
||||
}
|
||||
}
|
||||
WidgetPosition::Network => {
|
||||
|
@ -1548,6 +1603,15 @@ impl App {
|
|||
if new_time >= constants::STALE_MIN_MILLISECONDS {
|
||||
self.net_state.display_time = new_time;
|
||||
self.net_state.force_update = true;
|
||||
if self.app_config_fields.autohide_time {
|
||||
self.net_state.display_time_instant = Some(Instant::now());
|
||||
}
|
||||
} else if self.net_state.display_time != constants::STALE_MIN_MILLISECONDS {
|
||||
self.net_state.display_time = constants::STALE_MIN_MILLISECONDS;
|
||||
self.net_state.force_update = true;
|
||||
if self.app_config_fields.autohide_time {
|
||||
self.net_state.display_time_instant = Some(Instant::now());
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
|
@ -1559,14 +1623,23 @@ impl App {
|
|||
WidgetPosition::Cpu => {
|
||||
self.cpu_state.display_time = self.app_config_fields.default_time_value;
|
||||
self.cpu_state.force_update = true;
|
||||
if self.app_config_fields.autohide_time {
|
||||
self.cpu_state.display_time_instant = Some(Instant::now());
|
||||
}
|
||||
}
|
||||
WidgetPosition::Mem => {
|
||||
self.mem_state.display_time = self.app_config_fields.default_time_value;
|
||||
self.mem_state.force_update = true;
|
||||
if self.app_config_fields.autohide_time {
|
||||
self.mem_state.display_time_instant = Some(Instant::now());
|
||||
}
|
||||
}
|
||||
WidgetPosition::Network => {
|
||||
self.net_state.display_time = self.app_config_fields.default_time_value;
|
||||
self.net_state.force_update = true;
|
||||
if self.app_config_fields.autohide_time {
|
||||
self.net_state.display_time_instant = Some(Instant::now());
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
|
|
@ -72,44 +72,47 @@ pub struct Painter {
|
|||
impl Painter {
|
||||
/// Must be run once before drawing, but after setting colours.
|
||||
/// This is to set some remaining styles and text.
|
||||
/// This bypasses some logic checks (size > 2, for example) but this
|
||||
/// assumes that you, the programmer, are sane and do not do stupid things.
|
||||
/// RIGHT?
|
||||
pub fn initialize(&mut self) {
|
||||
self.is_mac_os = cfg!(target_os = "macos");
|
||||
|
||||
self.styled_general_help_text.push(Text::Styled(
|
||||
GENERAL_HELP_TEXT[0].into(),
|
||||
self.colours.table_header_style,
|
||||
));
|
||||
self.styled_general_help_text.extend(
|
||||
GENERAL_HELP_TEXT[1..]
|
||||
.iter()
|
||||
.map(|&text| Text::Styled(text.into(), self.colours.text_style))
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
if GENERAL_HELP_TEXT.len() > 1 {
|
||||
self.styled_general_help_text.push(Text::Styled(
|
||||
GENERAL_HELP_TEXT[0].into(),
|
||||
self.colours.table_header_style,
|
||||
));
|
||||
self.styled_general_help_text.extend(
|
||||
GENERAL_HELP_TEXT[1..]
|
||||
.iter()
|
||||
.map(|&text| Text::Styled(text.into(), self.colours.text_style))
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
}
|
||||
|
||||
self.styled_process_help_text.push(Text::Styled(
|
||||
PROCESS_HELP_TEXT[0].into(),
|
||||
self.colours.table_header_style,
|
||||
));
|
||||
self.styled_process_help_text.extend(
|
||||
PROCESS_HELP_TEXT[1..]
|
||||
.iter()
|
||||
.map(|&text| Text::Styled(text.into(), self.colours.text_style))
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
if PROCESS_HELP_TEXT.len() > 1 {
|
||||
self.styled_process_help_text.push(Text::Styled(
|
||||
PROCESS_HELP_TEXT[0].into(),
|
||||
self.colours.table_header_style,
|
||||
));
|
||||
self.styled_process_help_text.extend(
|
||||
PROCESS_HELP_TEXT[1..]
|
||||
.iter()
|
||||
.map(|&text| Text::Styled(text.into(), self.colours.text_style))
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
}
|
||||
|
||||
self.styled_search_help_text.push(Text::Styled(
|
||||
SEARCH_HELP_TEXT[0].into(),
|
||||
self.colours.table_header_style,
|
||||
));
|
||||
self.styled_search_help_text.extend(
|
||||
SEARCH_HELP_TEXT[1..]
|
||||
.iter()
|
||||
.map(|&text| Text::Styled(text.into(), self.colours.text_style))
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
if SEARCH_HELP_TEXT.len() > 1 {
|
||||
self.styled_search_help_text.push(Text::Styled(
|
||||
SEARCH_HELP_TEXT[0].into(),
|
||||
self.colours.table_header_style,
|
||||
));
|
||||
self.styled_search_help_text.extend(
|
||||
SEARCH_HELP_TEXT[1..]
|
||||
.iter()
|
||||
.map(|&text| Text::Styled(text.into(), self.colours.text_style))
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn draw_specific_table<B: Backend>(
|
||||
|
@ -260,11 +263,11 @@ impl Painter {
|
|||
0
|
||||
};
|
||||
|
||||
self.draw_cpu_graph(&mut f, &app_state, cpu_chunk[graph_index]);
|
||||
self.draw_cpu_graph(&mut f, app_state, cpu_chunk[graph_index]);
|
||||
self.draw_cpu_legend(&mut f, app_state, cpu_chunk[legend_index]);
|
||||
}
|
||||
WidgetPosition::Mem | WidgetPosition::BasicMem => {
|
||||
self.draw_memory_graph(&mut f, &app_state, rect[0]);
|
||||
self.draw_memory_graph(&mut f, app_state, rect[0]);
|
||||
}
|
||||
WidgetPosition::Disk => {
|
||||
self.draw_disk_table(&mut f, app_state, rect[0], true);
|
||||
|
@ -275,7 +278,7 @@ impl Painter {
|
|||
WidgetPosition::Network
|
||||
| WidgetPosition::BasicNet
|
||||
| WidgetPosition::NetworkLegend => {
|
||||
self.draw_network_graph(&mut f, &app_state, rect[0]);
|
||||
self.draw_network_graph(&mut f, app_state, rect[0]);
|
||||
}
|
||||
WidgetPosition::Process | WidgetPosition::ProcessSearch => {
|
||||
self.draw_process_and_search(&mut f, app_state, rect[0], true);
|
||||
|
@ -408,10 +411,10 @@ impl Painter {
|
|||
0
|
||||
};
|
||||
|
||||
self.draw_cpu_graph(&mut f, &app_state, cpu_chunk[graph_index]);
|
||||
self.draw_cpu_graph(&mut f, app_state, cpu_chunk[graph_index]);
|
||||
self.draw_cpu_legend(&mut f, app_state, cpu_chunk[legend_index]);
|
||||
self.draw_memory_graph(&mut f, &app_state, middle_chunks[0]);
|
||||
self.draw_network_graph(&mut f, &app_state, network_chunk[0]);
|
||||
self.draw_memory_graph(&mut f, app_state, middle_chunks[0]);
|
||||
self.draw_network_graph(&mut f, app_state, network_chunk[0]);
|
||||
self.draw_network_labels(&mut f, app_state, network_chunk[1]);
|
||||
self.draw_temp_table(&mut f, app_state, middle_divided_chunk_2[0], true);
|
||||
self.draw_disk_table(&mut f, app_state, middle_divided_chunk_2[1], true);
|
||||
|
|
|
@ -31,25 +31,46 @@ lazy_static! {
|
|||
}
|
||||
|
||||
pub trait CpuGraphWidget {
|
||||
fn draw_cpu_graph<B: Backend>(&self, f: &mut Frame<'_, B>, app_state: &App, draw_loc: Rect);
|
||||
fn draw_cpu_graph<B: Backend>(&self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect);
|
||||
fn draw_cpu_legend<B: Backend>(
|
||||
&self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect,
|
||||
);
|
||||
}
|
||||
|
||||
impl CpuGraphWidget for Painter {
|
||||
fn draw_cpu_graph<B: Backend>(&self, f: &mut Frame<'_, B>, app_state: &App, draw_loc: Rect) {
|
||||
fn draw_cpu_graph<B: Backend>(
|
||||
&self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect,
|
||||
) {
|
||||
let cpu_data: &[ConvertedCpuData] = &app_state.canvas_data.cpu_data;
|
||||
|
||||
let display_time_labels = [
|
||||
format!("{}s", app_state.cpu_state.display_time / 1000),
|
||||
"0s".to_string(),
|
||||
];
|
||||
let x_axis = Axis::default()
|
||||
.bounds([0.0, app_state.cpu_state.display_time as f64])
|
||||
.style(self.colours.graph_style)
|
||||
.labels_style(self.colours.graph_style)
|
||||
.labels(&display_time_labels);
|
||||
let x_axis = if app_state.app_config_fields.hide_time
|
||||
|| app_state.cpu_state.display_time_instant.is_none()
|
||||
{
|
||||
Axis::default().bounds([0.0, app_state.cpu_state.display_time as f64])
|
||||
} else if let Some(time) = app_state.cpu_state.display_time_instant {
|
||||
if std::time::Instant::now().duration_since(time).as_millis()
|
||||
< AUTOHIDE_TIMEOUT_MILLISECONDS as u128
|
||||
{
|
||||
Axis::default()
|
||||
.bounds([0.0, app_state.cpu_state.display_time as f64])
|
||||
.style(self.colours.graph_style)
|
||||
.labels_style(self.colours.graph_style)
|
||||
.labels(&display_time_labels)
|
||||
} else {
|
||||
app_state.cpu_state.display_time_instant = None;
|
||||
Axis::default().bounds([0.0, app_state.cpu_state.display_time as f64])
|
||||
}
|
||||
} else {
|
||||
Axis::default()
|
||||
.bounds([0.0, app_state.cpu_state.display_time as f64])
|
||||
.style(self.colours.graph_style)
|
||||
.labels_style(self.colours.graph_style)
|
||||
.labels(&display_time_labels)
|
||||
};
|
||||
|
||||
// Note this is offset as otherwise the 0 value is not drawn!
|
||||
let y_axis = Axis::default()
|
||||
|
|
|
@ -3,6 +3,7 @@ use std::cmp::max;
|
|||
use crate::{
|
||||
app::{App, WidgetPosition},
|
||||
canvas::Painter,
|
||||
constants::*,
|
||||
};
|
||||
|
||||
use tui::{
|
||||
|
@ -13,11 +14,15 @@ use tui::{
|
|||
};
|
||||
|
||||
pub trait MemGraphWidget {
|
||||
fn draw_memory_graph<B: Backend>(&self, f: &mut Frame<'_, B>, app_state: &App, draw_loc: Rect);
|
||||
fn draw_memory_graph<B: Backend>(
|
||||
&self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect,
|
||||
);
|
||||
}
|
||||
|
||||
impl MemGraphWidget for Painter {
|
||||
fn draw_memory_graph<B: Backend>(&self, f: &mut Frame<'_, B>, app_state: &App, draw_loc: Rect) {
|
||||
fn draw_memory_graph<B: Backend>(
|
||||
&self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect,
|
||||
) {
|
||||
let mem_data: &[(f64, f64)] = &app_state.canvas_data.mem_data;
|
||||
let swap_data: &[(f64, f64)] = &app_state.canvas_data.swap_data;
|
||||
|
||||
|
@ -25,11 +30,30 @@ impl MemGraphWidget for Painter {
|
|||
format!("{}s", app_state.mem_state.display_time / 1000),
|
||||
"0s".to_string(),
|
||||
];
|
||||
let x_axis = Axis::default()
|
||||
.bounds([0.0, app_state.mem_state.display_time as f64])
|
||||
.style(self.colours.graph_style)
|
||||
.labels_style(self.colours.graph_style)
|
||||
.labels(&display_time_labels);
|
||||
let x_axis = if app_state.app_config_fields.hide_time
|
||||
|| app_state.mem_state.display_time_instant.is_none()
|
||||
{
|
||||
Axis::default().bounds([0.0, app_state.mem_state.display_time as f64])
|
||||
} else if let Some(time) = app_state.mem_state.display_time_instant {
|
||||
if std::time::Instant::now().duration_since(time).as_millis()
|
||||
< AUTOHIDE_TIMEOUT_MILLISECONDS as u128
|
||||
{
|
||||
Axis::default()
|
||||
.bounds([0.0, app_state.mem_state.display_time as f64])
|
||||
.style(self.colours.graph_style)
|
||||
.labels_style(self.colours.graph_style)
|
||||
.labels(&display_time_labels)
|
||||
} else {
|
||||
app_state.mem_state.display_time_instant = None;
|
||||
Axis::default().bounds([0.0, app_state.mem_state.display_time as f64])
|
||||
}
|
||||
} else {
|
||||
Axis::default()
|
||||
.bounds([0.0, app_state.mem_state.display_time as f64])
|
||||
.style(self.colours.graph_style)
|
||||
.labels_style(self.colours.graph_style)
|
||||
.labels(&display_time_labels)
|
||||
};
|
||||
|
||||
// Offset as the zero value isn't drawn otherwise...
|
||||
let y_axis: Axis<'_, &str> = Axis::default()
|
||||
|
|
|
@ -23,7 +23,9 @@ lazy_static! {
|
|||
}
|
||||
|
||||
pub trait NetworkGraphWidget {
|
||||
fn draw_network_graph<B: Backend>(&self, f: &mut Frame<'_, B>, app_state: &App, draw_loc: Rect);
|
||||
fn draw_network_graph<B: Backend>(
|
||||
&self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect,
|
||||
);
|
||||
|
||||
fn draw_network_labels<B: Backend>(
|
||||
&self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect,
|
||||
|
@ -32,7 +34,7 @@ pub trait NetworkGraphWidget {
|
|||
|
||||
impl NetworkGraphWidget for Painter {
|
||||
fn draw_network_graph<B: Backend>(
|
||||
&self, f: &mut Frame<'_, B>, app_state: &App, draw_loc: Rect,
|
||||
&self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect,
|
||||
) {
|
||||
let network_data_rx: &[(f64, f64)] = &app_state.canvas_data.network_data_rx;
|
||||
let network_data_tx: &[(f64, f64)] = &app_state.canvas_data.network_data_tx;
|
||||
|
@ -41,13 +43,32 @@ impl NetworkGraphWidget for Painter {
|
|||
format!("{}s", app_state.net_state.display_time / 1000),
|
||||
"0s".to_string(),
|
||||
];
|
||||
let x_axis = Axis::default()
|
||||
.bounds([0.0, app_state.net_state.display_time as f64])
|
||||
.style(self.colours.graph_style)
|
||||
.labels_style(self.colours.graph_style)
|
||||
.labels(&display_time_labels);
|
||||
let x_axis = if app_state.app_config_fields.hide_time
|
||||
|| app_state.net_state.display_time_instant.is_none()
|
||||
{
|
||||
Axis::default().bounds([0.0, app_state.net_state.display_time as f64])
|
||||
} else if let Some(time) = app_state.net_state.display_time_instant {
|
||||
if std::time::Instant::now().duration_since(time).as_millis()
|
||||
< AUTOHIDE_TIMEOUT_MILLISECONDS as u128
|
||||
{
|
||||
Axis::default()
|
||||
.bounds([0.0, app_state.net_state.display_time as f64])
|
||||
.style(self.colours.graph_style)
|
||||
.labels_style(self.colours.graph_style)
|
||||
.labels(&display_time_labels)
|
||||
} else {
|
||||
app_state.net_state.display_time_instant = None;
|
||||
Axis::default().bounds([0.0, app_state.net_state.display_time as f64])
|
||||
}
|
||||
} else {
|
||||
Axis::default()
|
||||
.bounds([0.0, app_state.net_state.display_time as f64])
|
||||
.style(self.colours.graph_style)
|
||||
.labels_style(self.colours.graph_style)
|
||||
.labels(&display_time_labels)
|
||||
};
|
||||
|
||||
// 0 is offset.
|
||||
// 0 is offset.
|
||||
let y_axis: Axis<'_, &str> = Axis::default()
|
||||
.style(self.colours.graph_style)
|
||||
.labels_style(self.colours.graph_style)
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
// How long to store data.
|
||||
pub const STALE_MAX_MILLISECONDS: u64 = 300 * 1000; // Keep 5 minutes of data.
|
||||
pub const STALE_MAX_MILLISECONDS: u64 = 600 * 1000; // Keep 10 minutes of data.
|
||||
|
||||
// How much data is SHOWN
|
||||
pub const DEFAULT_TIME_MILLISECONDS: u64 = 60 * 1000; // Defaults to 1 min.
|
||||
pub const STALE_MIN_MILLISECONDS: u64 = 30 * 1000; // Lowest is 30 seconds
|
||||
pub const TIME_CHANGE_MILLISECONDS: u64 = 15 * 1000; // How much to increment each time
|
||||
pub const AUTOHIDE_TIMEOUT_MILLISECONDS: u64 = 5000; // 5 seconds to autohide
|
||||
|
||||
pub const TICK_RATE_IN_MILLISECONDS: u64 = 200;
|
||||
// How fast the screen refreshes
|
||||
|
@ -143,7 +144,7 @@ pub const DEFAULT_CONFIG_CONTENT: &str = r##"
|
|||
#default_time_value = 60000
|
||||
|
||||
# The time delta on each zoom in/out action (in milliseconds).
|
||||
# time_delta = 15000
|
||||
#time_delta = 15000
|
||||
|
||||
# These are all the components that support custom theming. Currently, it only
|
||||
# supports taking in a string representing a hex colour. Note that colour support
|
||||
|
|
|
@ -89,7 +89,7 @@ fn get_matches() -> clap::ArgMatches<'static> {
|
|||
(@arg DEFAULT_TIME_VALUE: -t --default_time_value +takes_value "Default time value for graphs in milliseconds; minimum is 30s, defaults to 60s.")
|
||||
(@arg TIME_DELTA: -d --time_delta +takes_value "The amount changed upon zooming in/out in milliseconds; minimum is 1s, defaults to 15s.")
|
||||
(@arg HIDE_TIME: --hide_time "Completely hide the time scaling")
|
||||
(@arg AUTOHIDE_TIME: --autohide_time "Automatically hide the time scaling in graphs after being shown for a brief moment when zoomed in/out. If time is disabled then this will have no effect.")
|
||||
(@arg AUTOHIDE_TIME: --autohide_time "Automatically hide the time scaling in graphs after being shown for a brief moment when zoomed in/out. If time is disabled via --hide_time then this will have no effect.")
|
||||
(@group DEFAULT_WIDGET =>
|
||||
(@arg CPU_WIDGET: --cpu_default "Selects the CPU widget to be selected by default.")
|
||||
(@arg MEM_WIDGET: --memory_default "Selects the memory widget to be selected by default.")
|
||||
|
@ -143,6 +143,8 @@ fn main() -> error::Result<()> {
|
|||
enable_app_case_sensitive(&matches, &config, &mut app);
|
||||
enable_app_match_whole_word(&matches, &config, &mut app);
|
||||
enable_app_use_regex(&matches, &config, &mut app);
|
||||
enable_hide_time(&matches, &config, &mut app);
|
||||
enable_autohide_time(&matches, &config, &mut app);
|
||||
|
||||
// Set up up tui and crossterm
|
||||
let mut stdout_val = stdout();
|
||||
|
|
|
@ -29,6 +29,8 @@ pub struct ConfigFlags {
|
|||
pub basic: Option<bool>,
|
||||
pub default_time_value: Option<u64>,
|
||||
pub time_delta: Option<u64>,
|
||||
pub autohide_time: Option<bool>,
|
||||
pub hide_time: Option<bool>,
|
||||
//disabled_cpu_cores: Option<Vec<u64>>, // TODO: [FEATURE] Enable disabling cores in config/flags
|
||||
}
|
||||
|
||||
|
@ -199,9 +201,9 @@ pub fn get_default_time_value_option(
|
|||
return Err(BottomError::InvalidArg(
|
||||
"Please set your default value to be at least 30 seconds.".to_string(),
|
||||
));
|
||||
} else if default_time as u128 > std::u64::MAX as u128 {
|
||||
} else if default_time as u128 > STALE_MAX_MILLISECONDS as u128 {
|
||||
return Err(BottomError::InvalidArg(
|
||||
"Please set your default value to be at most unsigned INT_MAX.".to_string(),
|
||||
"Please set your default value to be at most 10 minutes.".to_string(),
|
||||
));
|
||||
}
|
||||
|
||||
|
@ -227,9 +229,9 @@ pub fn get_time_interval_option(
|
|||
return Err(BottomError::InvalidArg(
|
||||
"Please set your time delta to be at least 1 second.".to_string(),
|
||||
));
|
||||
} else if time_interval > std::u64::MAX as u128 {
|
||||
} else if time_interval > STALE_MAX_MILLISECONDS as u128 {
|
||||
return Err(BottomError::InvalidArg(
|
||||
"Please set your time delta to be at most unsigned INT_MAX.".to_string(),
|
||||
"Please set your time delta to be at most 10 minutes.".to_string(),
|
||||
));
|
||||
}
|
||||
|
||||
|
@ -288,6 +290,30 @@ pub fn enable_app_use_regex(matches: &clap::ArgMatches<'static>, config: &Config
|
|||
}
|
||||
}
|
||||
|
||||
pub fn enable_hide_time(matches: &clap::ArgMatches<'static>, config: &Config, app: &mut App) {
|
||||
if matches.is_present("HIDE_TIME") {
|
||||
app.app_config_fields.hide_time = true;
|
||||
} else if let Some(flags) = &config.flags {
|
||||
if let Some(hide_time) = flags.hide_time {
|
||||
if hide_time {
|
||||
app.app_config_fields.hide_time = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn enable_autohide_time(matches: &clap::ArgMatches<'static>, config: &Config, app: &mut App) {
|
||||
if matches.is_present("AUTOHIDE_TIME") {
|
||||
app.app_config_fields.autohide_time = true;
|
||||
} else if let Some(flags) = &config.flags {
|
||||
if let Some(autohide_time) = flags.autohide_time {
|
||||
if autohide_time {
|
||||
app.app_config_fields.autohide_time = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_default_widget(matches: &clap::ArgMatches<'static>, config: &Config) -> WidgetPosition {
|
||||
if matches.is_present("CPU_WIDGET") {
|
||||
return WidgetPosition::Cpu;
|
||||
|
|
|
@ -42,7 +42,7 @@ fn test_large_default_time() -> Result<(), Box<dyn std::error::Error>> {
|
|||
.assert()
|
||||
.failure()
|
||||
.stderr(predicate::str::contains(
|
||||
"Please set your default value to be at most unsigned INT_MAX.",
|
||||
"Please set your default value to be at most 10 minutes.",
|
||||
));
|
||||
Ok(())
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ fn test_large_delta_time() -> Result<(), Box<dyn std::error::Error>> {
|
|||
.assert()
|
||||
.failure()
|
||||
.stderr(predicate::str::contains(
|
||||
"Please set your time delta to be at most unsigned INT_MAX.",
|
||||
"Please set your time delta to be at most 10 minutes.",
|
||||
));
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue