From de86ceb482595f38461d074321d2b5bc12e63f9c Mon Sep 17 00:00:00 2001 From: ClementTsang Date: Sun, 23 May 2021 18:51:35 -0400 Subject: [PATCH] refactor: Remove and refactor code refactor: Create a prototype time graph element Move some state content over refactor: rename folder refactor: More renaming and pruning of old unused code. Create a prototype time graph element scrollable table Temporarily add dead code allows Minor refactorings refactor: Move current widgets to the new element system squash this - WIP of re-refactor Revert "squash this - WIP of re-refactor" This reverts commit a3ce25732663863b1ba2ef8a764c57572406014f. Revert "refactor: Move current widgets to the new element system" This reverts commit c7218472c2ce6d1bebf5550aaf53c171d3cd7c3e. WIP re-refactor Revert "refactor: Create a prototype time graph element" This reverts commit bd95ca8b73623c9df1dab03e0c51b31cb9b99c4d. --- src/app.rs | 226 +----------- .../mod.rs} | 0 src/app/filter.rs | 14 + src/app/widget_states/battery_state.rs | 25 ++ src/app/widget_states/cpu_state.rs | 47 +++ src/app/widget_states/disk_state.rs | 35 ++ src/app/widget_states/graph_state.rs | 1 + src/app/widget_states/mem_state.rs | 37 ++ src/app/widget_states/mod.rs | 125 +++++++ src/app/widget_states/net_state.rs | 52 +++ .../process_state.rs} | 338 +----------------- src/app/widget_states/table_state.rs | 1 + src/app/widget_states/temp_state.rs | 35 ++ src/bin/main.rs | 1 - src/canvas.rs | 15 +- src/canvas/dialogs/dd_dialog.rs | 16 +- src/canvas/dialogs/help_dialog.rs | 6 +- src/canvas/screens.rs | 3 - src/canvas/screens/config_screen.rs | 33 -- src/canvas/widgets/basic_table_arrows.rs | 6 +- src/canvas/widgets/battery_display.rs | 6 +- src/canvas/widgets/cpu_basic.rs | 6 +- src/canvas/widgets/cpu_graph.rs | 14 +- src/canvas/widgets/disk_table.rs | 8 +- src/canvas/widgets/mem_basic.rs | 6 +- src/canvas/widgets/mem_graph.rs | 6 +- src/canvas/widgets/network_basic.rs | 6 +- src/canvas/widgets/network_graph.rs | 14 +- src/canvas/widgets/process_table.rs | 18 +- src/canvas/widgets/temp_table.rs | 8 +- src/data_conversion.rs | 4 +- src/lib.rs | 14 +- src/options.rs | 80 +---- 33 files changed, 468 insertions(+), 738 deletions(-) rename src/app/{data_harvester.rs => data_harvester/mod.rs} (100%) create mode 100644 src/app/filter.rs create mode 100644 src/app/widget_states/battery_state.rs create mode 100644 src/app/widget_states/cpu_state.rs create mode 100644 src/app/widget_states/disk_state.rs create mode 100644 src/app/widget_states/graph_state.rs create mode 100644 src/app/widget_states/mem_state.rs create mode 100644 src/app/widget_states/mod.rs create mode 100644 src/app/widget_states/net_state.rs rename src/app/{states.rs => widget_states/process_state.rs} (69%) create mode 100644 src/app/widget_states/table_state.rs create mode 100644 src/app/widget_states/temp_state.rs delete mode 100644 src/canvas/screens.rs delete mode 100644 src/canvas/screens/config_screen.rs diff --git a/src/app.rs b/src/app.rs index 822d4a1de..0ecb15e4b 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,8 +1,14 @@ +pub mod data_farmer; +pub mod data_harvester; +pub mod filter; +pub mod layout_manager; +mod process_killer; +pub mod query; +pub mod widget_states; + use std::{ cmp::{max, min}, collections::HashMap, - // io::Write, - path::PathBuf, time::Instant, }; @@ -13,26 +19,17 @@ use typed_builder::*; use data_farmer::*; use data_harvester::{processes, temperature}; +pub use filter::*; use layout_manager::*; -pub use states::*; +pub use widget_states::*; use crate::{ canvas, constants, - options::Config, - options::ConfigFlags, - options::WidgetIdEnabled, units::data_units::DataUnit, utils::error::{BottomError, Result}, Pid, }; -pub mod data_farmer; -pub mod data_harvester; -pub mod layout_manager; -mod process_killer; -pub mod query; -pub mod states; - const MAX_SEARCH_LENGTH: usize = 200; #[derive(Debug, Clone)] @@ -68,23 +65,8 @@ pub struct AppConfigFields { pub network_use_binary_prefix: bool, } -/// For filtering out information -#[derive(Debug, Clone)] -pub struct DataFilters { - pub disk_filter: Option, - pub mount_filter: Option, - pub temp_filter: Option, - pub net_filter: Option, -} - -#[derive(Debug, Clone)] -pub struct Filter { - pub is_list_ignored: bool, - pub list: Vec, -} - #[derive(TypedBuilder)] -pub struct App { +pub struct AppState { #[builder(default = false, setter(skip))] awaiting_second_char: bool, @@ -127,12 +109,6 @@ pub struct App { #[builder(default = false, setter(skip))] pub basic_mode_use_percent: bool, - #[builder(default = false, setter(skip))] - pub is_config_open: bool, - - #[builder(default = false, setter(skip))] - pub did_config_fail_to_save: bool, - #[cfg(target_family = "unix")] #[builder(default, setter(skip))] pub user_table: processes::UserTable, @@ -150,8 +126,6 @@ pub struct App { pub current_widget: BottomWidget, pub used_widgets: UsedWidgets, pub filters: DataFilters, - pub config: Config, - pub config_path: Option, } #[cfg(target_os = "windows")] @@ -161,7 +135,7 @@ const MAX_SIGNAL: usize = 64; #[cfg(target_os = "macos")] const MAX_SIGNAL: usize = 31; -impl App { +impl AppState { pub fn reset(&mut self) { // Reset multi self.reset_multi_tap_keys(); @@ -218,8 +192,6 @@ impl App { } self.is_force_redraw = true; - } else if self.is_config_open { - self.close_config_screen(); } else { match self.current_widget.widget_type { BottomWidgetType::Proc => { @@ -297,7 +269,7 @@ impl App { } fn ignore_normal_keybinds(&self) -> bool { - self.is_config_open || self.is_in_dialog() + self.is_in_dialog() } pub fn on_tab(&mut self) { @@ -507,7 +479,6 @@ impl App { pub fn toggle_ignore_case(&mut self) { let is_in_search_widget = self.is_in_search_widget(); - let mut is_case_sensitive: Option = None; if let Some(proc_widget_state) = self .proc_state .widget_states @@ -519,50 +490,12 @@ impl App { .search_toggle_ignore_case(); proc_widget_state.update_query(); self.proc_state.force_update = Some(self.current_widget.widget_id - 1); - - // Remember, it's the opposite (ignoring case is case "in"sensitive) - is_case_sensitive = Some(!proc_widget_state.process_search_state.is_ignoring_case); - } - } - - // Also toggle it in the config file if we actually changed it. - if let Some(is_ignoring_case) = is_case_sensitive { - if let Some(flags) = &mut self.config.flags { - if let Some(map) = &mut flags.search_case_enabled_widgets_map { - // Just update the map. - let mapping = map.entry(self.current_widget.widget_id - 1).or_default(); - *mapping = is_ignoring_case; - - flags.search_case_enabled_widgets = - Some(WidgetIdEnabled::create_from_hashmap(&map)); - } else { - // Map doesn't exist yet... initialize ourselves. - let mut map = HashMap::default(); - map.insert(self.current_widget.widget_id - 1, is_ignoring_case); - flags.search_case_enabled_widgets = - Some(WidgetIdEnabled::create_from_hashmap(&map)); - flags.search_case_enabled_widgets_map = Some(map); - } - } else { - // Must initialize it ourselves... - let mut map = HashMap::default(); - map.insert(self.current_widget.widget_id - 1, is_ignoring_case); - - self.config.flags = Some( - ConfigFlags::builder() - .search_case_enabled_widgets(WidgetIdEnabled::create_from_hashmap(&map)) - .search_case_enabled_widgets_map(map) - .build(), - ); } - - // self.did_config_fail_to_save = self.update_config_file().is_err(); } } pub fn toggle_search_whole_word(&mut self) { let is_in_search_widget = self.is_in_search_widget(); - let mut is_searching_whole_word: Option = None; if let Some(proc_widget_state) = self .proc_state .widget_states @@ -574,55 +507,12 @@ impl App { .search_toggle_whole_word(); proc_widget_state.update_query(); self.proc_state.force_update = Some(self.current_widget.widget_id - 1); - - is_searching_whole_word = Some( - proc_widget_state - .process_search_state - .is_searching_whole_word, - ); - } - } - - // Also toggle it in the config file if we actually changed it. - if let Some(is_searching_whole_word) = is_searching_whole_word { - if let Some(flags) = &mut self.config.flags { - if let Some(map) = &mut flags.search_whole_word_enabled_widgets_map { - // Just update the map. - let mapping = map.entry(self.current_widget.widget_id - 1).or_default(); - *mapping = is_searching_whole_word; - - flags.search_whole_word_enabled_widgets = - Some(WidgetIdEnabled::create_from_hashmap(&map)); - } else { - // Map doesn't exist yet... initialize ourselves. - let mut map = HashMap::default(); - map.insert(self.current_widget.widget_id - 1, is_searching_whole_word); - flags.search_whole_word_enabled_widgets = - Some(WidgetIdEnabled::create_from_hashmap(&map)); - flags.search_whole_word_enabled_widgets_map = Some(map); - } - } else { - // Must initialize it ourselves... - let mut map = HashMap::default(); - map.insert(self.current_widget.widget_id - 1, is_searching_whole_word); - - self.config.flags = Some( - ConfigFlags::builder() - .search_whole_word_enabled_widgets(WidgetIdEnabled::create_from_hashmap( - &map, - )) - .search_whole_word_enabled_widgets_map(map) - .build(), - ); } - - // self.did_config_fail_to_save = self.update_config_file().is_err(); } } pub fn toggle_search_regex(&mut self) { let is_in_search_widget = self.is_in_search_widget(); - let mut is_searching_with_regex: Option = None; if let Some(proc_widget_state) = self .proc_state .widget_states @@ -632,48 +522,8 @@ impl App { proc_widget_state.process_search_state.search_toggle_regex(); proc_widget_state.update_query(); self.proc_state.force_update = Some(self.current_widget.widget_id - 1); - - is_searching_with_regex = Some( - proc_widget_state - .process_search_state - .is_searching_with_regex, - ); } } - - // Also toggle it in the config file if we actually changed it. - if let Some(is_searching_whole_word) = is_searching_with_regex { - if let Some(flags) = &mut self.config.flags { - if let Some(map) = &mut flags.search_regex_enabled_widgets_map { - // Just update the map. - let mapping = map.entry(self.current_widget.widget_id - 1).or_default(); - *mapping = is_searching_whole_word; - - flags.search_regex_enabled_widgets = - Some(WidgetIdEnabled::create_from_hashmap(&map)); - } else { - // Map doesn't exist yet... initialize ourselves. - let mut map = HashMap::default(); - map.insert(self.current_widget.widget_id - 1, is_searching_whole_word); - flags.search_regex_enabled_widgets = - Some(WidgetIdEnabled::create_from_hashmap(&map)); - flags.search_regex_enabled_widgets_map = Some(map); - } - } else { - // Must initialize it ourselves... - let mut map = HashMap::default(); - map.insert(self.current_widget.widget_id - 1, is_searching_whole_word); - - self.config.flags = Some( - ConfigFlags::builder() - .search_regex_enabled_widgets(WidgetIdEnabled::create_from_hashmap(&map)) - .search_regex_enabled_widgets_map(map) - .build(), - ); - } - - // self.did_config_fail_to_save = self.update_config_file().is_err(); - } } pub fn toggle_tree_mode(&mut self) { @@ -910,8 +760,7 @@ impl App { } pub fn on_up_key(&mut self) { - if self.is_config_open { - } else if !self.is_in_dialog() { + if !self.is_in_dialog() { self.decrement_position_count(); } else if self.help_dialog_state.is_showing_help { self.help_scroll_up(); @@ -932,8 +781,7 @@ impl App { } pub fn on_down_key(&mut self) { - if self.is_config_open { - } else if !self.is_in_dialog() { + if !self.is_in_dialog() { self.increment_position_count(); } else if self.help_dialog_state.is_showing_help { self.help_scroll_down(); @@ -954,8 +802,7 @@ impl App { } pub fn on_left_key(&mut self) { - if self.is_config_open { - } else if !self.is_in_dialog() { + if !self.is_in_dialog() { match self.current_widget.widget_type { BottomWidgetType::ProcSearch => { let is_in_search_widget = self.is_in_search_widget(); @@ -1026,8 +873,7 @@ impl App { } pub fn on_right_key(&mut self) { - if self.is_config_open { - } else if !self.is_in_dialog() { + if !self.is_in_dialog() { match self.current_widget.widget_type { BottomWidgetType::ProcSearch => { let is_in_search_widget = self.is_in_search_widget(); @@ -1163,7 +1009,6 @@ impl App { } } } - } else if self.is_config_open { } } @@ -1210,7 +1055,6 @@ impl App { } } } - } else if self.is_config_open { } } @@ -1464,7 +1308,6 @@ impl App { 'G' => self.skip_to_last(), _ => {} } - } else if self.is_config_open { } } @@ -1647,39 +1490,6 @@ impl App { pub fn on_space(&mut self) {} - pub fn open_config_screen(&mut self) { - self.is_config_open = true; - self.is_force_redraw = true; - } - - pub fn close_config_screen(&mut self) { - self.is_config_open = false; - self.is_force_redraw = true; - } - - /// TODO: Disabled. - /// Call this whenever the config value is updated! - // fn update_config_file(&mut self) -> anyhow::Result<()> { - // if self.app_config_fields.no_write { - // // debug!("No write enabled. Config will not be written."); - // // Don't write! - // // FIXME: [CONFIG] This should be made VERY clear to the user... make a thing saying "it will not write due to no_write option" - // Ok(()) - // } else if let Some(config_path) = &self.config_path { - // // Update - // // debug!("Updating config file - writing to: {:?}", config_path); - // std::fs::File::create(config_path)? - // .write_all(self.config.get_config_as_bytes()?.as_ref())?; - // Ok(()) - // } else { - // // FIXME: [CONFIG] Put an actual error message? - // Err(anyhow::anyhow!( - // "Config path was missing, please try restarting bottom..." - // )) - // } - // Ok(()) - // } - pub fn kill_highlighted_process(&mut self) -> Result<()> { if let BottomWidgetType::Proc = self.current_widget.widget_type { if let Some(current_selected_processes) = &self.to_delete_process_list { @@ -2238,7 +2048,6 @@ impl App { _ => {} } self.reset_multi_tap_keys(); - } else if self.is_config_open { } else if self.help_dialog_state.is_showing_help { self.help_dialog_state.scroll_state.current_scroll_index = 0; } else if self.delete_dialog_state.is_showing_dd { @@ -2317,7 +2126,6 @@ impl App { _ => {} } self.reset_multi_tap_keys(); - } else if self.is_config_open { } else if self.help_dialog_state.is_showing_help { self.help_dialog_state.scroll_state.current_scroll_index = self .help_dialog_state diff --git a/src/app/data_harvester.rs b/src/app/data_harvester/mod.rs similarity index 100% rename from src/app/data_harvester.rs rename to src/app/data_harvester/mod.rs diff --git a/src/app/filter.rs b/src/app/filter.rs new file mode 100644 index 000000000..2674f74d7 --- /dev/null +++ b/src/app/filter.rs @@ -0,0 +1,14 @@ +#[derive(Debug, Clone)] +pub struct Filter { + pub is_list_ignored: bool, + pub list: Vec, +} + +/// For filtering out information +#[derive(Debug, Clone)] +pub struct DataFilters { + pub disk_filter: Option, + pub mount_filter: Option, + pub temp_filter: Option, + pub net_filter: Option, +} diff --git a/src/app/widget_states/battery_state.rs b/src/app/widget_states/battery_state.rs new file mode 100644 index 000000000..62f27d93a --- /dev/null +++ b/src/app/widget_states/battery_state.rs @@ -0,0 +1,25 @@ +use std::collections::HashMap; + +#[derive(Default)] +pub struct BatteryWidgetState { + pub currently_selected_battery_index: usize, + pub tab_click_locs: Option>, +} + +pub struct BatteryState { + pub widget_states: HashMap, +} + +impl BatteryState { + pub fn init(widget_states: HashMap) -> Self { + BatteryState { widget_states } + } + + pub fn get_mut_widget_state(&mut self, widget_id: u64) -> Option<&mut BatteryWidgetState> { + self.widget_states.get_mut(&widget_id) + } + + pub fn get_widget_state(&self, widget_id: u64) -> Option<&BatteryWidgetState> { + self.widget_states.get(&widget_id) + } +} diff --git a/src/app/widget_states/cpu_state.rs b/src/app/widget_states/cpu_state.rs new file mode 100644 index 000000000..c155cf84c --- /dev/null +++ b/src/app/widget_states/cpu_state.rs @@ -0,0 +1,47 @@ +use std::{collections::HashMap, time::Instant}; + +use super::{AppScrollWidgetState, CanvasTableWidthState}; + +pub struct CpuWidgetState { + pub current_display_time: u64, + pub is_legend_hidden: bool, + pub autohide_timer: Option, + pub scroll_state: AppScrollWidgetState, + pub is_multi_graph_mode: bool, + pub table_width_state: CanvasTableWidthState, +} + +impl CpuWidgetState { + pub fn init(current_display_time: u64, autohide_timer: Option) -> Self { + CpuWidgetState { + current_display_time, + is_legend_hidden: false, + autohide_timer, + scroll_state: AppScrollWidgetState::default(), + is_multi_graph_mode: false, + table_width_state: CanvasTableWidthState::default(), + } + } +} + +pub struct CpuState { + pub force_update: Option, + pub widget_states: HashMap, +} + +impl CpuState { + pub fn init(widget_states: HashMap) -> Self { + CpuState { + force_update: None, + widget_states, + } + } + + pub fn get_mut_widget_state(&mut self, widget_id: u64) -> Option<&mut CpuWidgetState> { + self.widget_states.get_mut(&widget_id) + } + + pub fn get_widget_state(&self, widget_id: u64) -> Option<&CpuWidgetState> { + self.widget_states.get(&widget_id) + } +} diff --git a/src/app/widget_states/disk_state.rs b/src/app/widget_states/disk_state.rs new file mode 100644 index 000000000..8528668c1 --- /dev/null +++ b/src/app/widget_states/disk_state.rs @@ -0,0 +1,35 @@ +use std::collections::HashMap; + +use super::{AppScrollWidgetState, CanvasTableWidthState}; + +pub struct DiskWidgetState { + pub scroll_state: AppScrollWidgetState, + pub table_width_state: CanvasTableWidthState, +} + +impl DiskWidgetState { + pub fn init() -> Self { + DiskWidgetState { + scroll_state: AppScrollWidgetState::default(), + table_width_state: CanvasTableWidthState::default(), + } + } +} + +pub struct DiskState { + pub widget_states: HashMap, +} + +impl DiskState { + pub fn init(widget_states: HashMap) -> Self { + DiskState { widget_states } + } + + pub fn get_mut_widget_state(&mut self, widget_id: u64) -> Option<&mut DiskWidgetState> { + self.widget_states.get_mut(&widget_id) + } + + pub fn get_widget_state(&self, widget_id: u64) -> Option<&DiskWidgetState> { + self.widget_states.get(&widget_id) + } +} diff --git a/src/app/widget_states/graph_state.rs b/src/app/widget_states/graph_state.rs new file mode 100644 index 000000000..6f3b55d48 --- /dev/null +++ b/src/app/widget_states/graph_state.rs @@ -0,0 +1 @@ +//! States for a graph widget. diff --git a/src/app/widget_states/mem_state.rs b/src/app/widget_states/mem_state.rs new file mode 100644 index 000000000..1e6ce5f75 --- /dev/null +++ b/src/app/widget_states/mem_state.rs @@ -0,0 +1,37 @@ +use std::{collections::HashMap, time::Instant}; + +pub struct MemWidgetState { + pub current_display_time: u64, + pub autohide_timer: Option, +} + +impl MemWidgetState { + pub fn init(current_display_time: u64, autohide_timer: Option) -> Self { + MemWidgetState { + current_display_time, + autohide_timer, + } + } +} + +pub struct MemState { + pub force_update: Option, + pub widget_states: HashMap, +} + +impl MemState { + pub fn init(widget_states: HashMap) -> Self { + MemState { + force_update: None, + widget_states, + } + } + + pub fn get_mut_widget_state(&mut self, widget_id: u64) -> Option<&mut MemWidgetState> { + self.widget_states.get_mut(&widget_id) + } + + pub fn get_widget_state(&self, widget_id: u64) -> Option<&MemWidgetState> { + self.widget_states.get(&widget_id) + } +} diff --git a/src/app/widget_states/mod.rs b/src/app/widget_states/mod.rs new file mode 100644 index 000000000..dc6c02e74 --- /dev/null +++ b/src/app/widget_states/mod.rs @@ -0,0 +1,125 @@ +use std::time::Instant; + +use tui::widgets::TableState; + +use crate::{app::layout_manager::BottomWidgetType, constants}; + +pub mod process_state; +pub use process_state::*; + +pub mod net_state; +pub use net_state::*; + +pub mod mem_state; +pub use mem_state::*; + +pub mod cpu_state; +pub use cpu_state::*; + +pub mod disk_state; +pub use disk_state::*; + +pub mod battery_state; +pub use battery_state::*; + +pub mod temp_state; +pub use temp_state::*; + +#[derive(Debug)] +pub enum ScrollDirection { + // UP means scrolling up --- this usually DECREMENTS + Up, + // DOWN means scrolling down --- this usually INCREMENTS + Down, +} + +impl Default for ScrollDirection { + fn default() -> Self { + ScrollDirection::Down + } +} + +#[derive(Debug)] +pub enum CursorDirection { + Left, + Right, +} + +/// AppScrollWidgetState deals with fields for a scrollable app's current state. +#[derive(Default)] +pub struct AppScrollWidgetState { + pub current_scroll_position: usize, + pub previous_scroll_position: usize, + pub scroll_direction: ScrollDirection, + pub table_state: TableState, +} + +#[derive(PartialEq)] +pub enum KillSignal { + Cancel, + Kill(usize), +} + +impl Default for KillSignal { + #[cfg(target_family = "unix")] + fn default() -> Self { + KillSignal::Kill(15) + } + #[cfg(target_os = "windows")] + fn default() -> Self { + KillSignal::Kill(1) + } +} + +#[derive(Default)] +pub struct AppDeleteDialogState { + pub is_showing_dd: bool, + pub selected_signal: KillSignal, + /// tl x, tl y, br x, br y, index/signal + pub button_positions: Vec<(u16, u16, u16, u16, usize)>, + pub keyboard_signal_select: usize, + pub last_number_press: Option, + pub scroll_pos: usize, +} + +pub struct AppHelpDialogState { + pub is_showing_help: bool, + pub scroll_state: ParagraphScrollState, + pub index_shortcuts: Vec, +} + +impl Default for AppHelpDialogState { + fn default() -> Self { + AppHelpDialogState { + is_showing_help: false, + scroll_state: ParagraphScrollState::default(), + index_shortcuts: vec![0; constants::HELP_TEXT.len()], + } + } +} + +/// Meant for canvas operations involving table column widths. +#[derive(Default)] +pub struct CanvasTableWidthState { + pub desired_column_widths: Vec, + pub calculated_column_widths: Vec, +} + +pub struct BasicTableWidgetState { + // Since this is intended (currently) to only be used for ONE widget, that's + // how it's going to be written. If we want to allow for multiple of these, + // then we can expand outwards with a normal BasicTableState and a hashmap + pub currently_displayed_widget_type: BottomWidgetType, + pub currently_displayed_widget_id: u64, + pub widget_id: i64, + pub left_tlc: Option<(u16, u16)>, + pub left_brc: Option<(u16, u16)>, + pub right_tlc: Option<(u16, u16)>, + pub right_brc: Option<(u16, u16)>, +} + +#[derive(Default)] +pub struct ParagraphScrollState { + pub current_scroll_index: u16, + pub max_scroll_index: u16, +} diff --git a/src/app/widget_states/net_state.rs b/src/app/widget_states/net_state.rs new file mode 100644 index 000000000..85c1281e0 --- /dev/null +++ b/src/app/widget_states/net_state.rs @@ -0,0 +1,52 @@ +use std::{collections::HashMap, time::Instant}; + +pub struct NetWidgetState { + pub current_display_time: u64, + pub autohide_timer: Option, + // pub draw_max_range_cache: f64, + // pub draw_labels_cache: Vec, + // pub draw_time_start_cache: f64, + // TODO: Re-enable these when we move net details state-side! + // pub unit_type: DataUnitTypes, + // pub scale_type: AxisScaling, +} + +impl NetWidgetState { + pub fn init( + current_display_time: u64, + autohide_timer: Option, + // unit_type: DataUnitTypes, + // scale_type: AxisScaling, + ) -> Self { + NetWidgetState { + current_display_time, + autohide_timer, + // draw_max_range_cache: 0.0, + // draw_labels_cache: vec![], + // draw_time_start_cache: 0.0, + // unit_type, + // scale_type, + } + } +} +pub struct NetState { + pub force_update: Option, + pub widget_states: HashMap, +} + +impl NetState { + pub fn init(widget_states: HashMap) -> Self { + NetState { + force_update: None, + widget_states, + } + } + + pub fn get_mut_widget_state(&mut self, widget_id: u64) -> Option<&mut NetWidgetState> { + self.widget_states.get_mut(&widget_id) + } + + pub fn get_widget_state(&self, widget_id: u64) -> Option<&NetWidgetState> { + self.widget_states.get(&widget_id) + } +} diff --git a/src/app/states.rs b/src/app/widget_states/process_state.rs similarity index 69% rename from src/app/states.rs rename to src/app/widget_states/process_state.rs index 28d1323b5..b10d5aded 100644 --- a/src/app/states.rs +++ b/src/app/widget_states/process_state.rs @@ -1,88 +1,16 @@ -use std::{collections::HashMap, time::Instant}; +use std::collections::HashMap; use unicode_segmentation::GraphemeCursor; use tui::widgets::TableState; use crate::{ - app::{layout_manager::BottomWidgetType, query::*}, - constants, + app::query::*, data_harvester::processes::{self, ProcessSorting}, }; use ProcessSorting::*; -#[derive(Debug)] -pub enum ScrollDirection { - // UP means scrolling up --- this usually DECREMENTS - Up, - // DOWN means scrolling down --- this usually INCREMENTS - Down, -} - -impl Default for ScrollDirection { - fn default() -> Self { - ScrollDirection::Down - } -} - -#[derive(Debug)] -pub enum CursorDirection { - Left, - Right, -} - -/// AppScrollWidgetState deals with fields for a scrollable app's current state. -#[derive(Default)] -pub struct AppScrollWidgetState { - pub current_scroll_position: usize, - pub previous_scroll_position: usize, - pub scroll_direction: ScrollDirection, - pub table_state: TableState, -} - -#[derive(PartialEq)] -pub enum KillSignal { - Cancel, - Kill(usize), -} - -impl Default for KillSignal { - #[cfg(target_family = "unix")] - fn default() -> Self { - KillSignal::Kill(15) - } - #[cfg(target_os = "windows")] - fn default() -> Self { - KillSignal::Kill(1) - } -} - -#[derive(Default)] -pub struct AppDeleteDialogState { - pub is_showing_dd: bool, - pub selected_signal: KillSignal, - /// tl x, tl y, br x, br y, index/signal - pub button_positions: Vec<(u16, u16, u16, u16, usize)>, - pub keyboard_signal_select: usize, - pub last_number_press: Option, - pub scroll_pos: usize, -} - -pub struct AppHelpDialogState { - pub is_showing_help: bool, - pub scroll_state: ParagraphScrollState, - pub index_shortcuts: Vec, -} - -impl Default for AppHelpDialogState { - fn default() -> Self { - AppHelpDialogState { - is_showing_help: false, - scroll_state: ParagraphScrollState::default(), - index_shortcuts: vec![0; constants::HELP_TEXT.len()], - } - } -} +use super::{AppScrollWidgetState, CanvasTableWidthState, CursorDirection, ScrollDirection}; /// AppSearchState deals with generic searching (I might do this in the future). pub struct AppSearchState { @@ -131,13 +59,6 @@ impl AppSearchState { } } -/// Meant for canvas operations involving table column widths. -#[derive(Default)] -pub struct CanvasTableWidthState { - pub desired_column_widths: Vec, - pub calculated_column_widths: Vec, -} - /// ProcessSearchState only deals with process' search's current settings and state. pub struct ProcessSearchState { pub search_state: AppSearchState, @@ -685,256 +606,3 @@ impl ProcState { self.widget_states.get(&widget_id) } } - -pub struct NetWidgetState { - pub current_display_time: u64, - pub autohide_timer: Option, - // pub draw_max_range_cache: f64, - // pub draw_labels_cache: Vec, - // pub draw_time_start_cache: f64, - // TODO: Re-enable these when we move net details state-side! - // pub unit_type: DataUnitTypes, - // pub scale_type: AxisScaling, -} - -impl NetWidgetState { - pub fn init( - current_display_time: u64, - autohide_timer: Option, - // unit_type: DataUnitTypes, - // scale_type: AxisScaling, - ) -> Self { - NetWidgetState { - current_display_time, - autohide_timer, - // draw_max_range_cache: 0.0, - // draw_labels_cache: vec![], - // draw_time_start_cache: 0.0, - // unit_type, - // scale_type, - } - } -} - -pub struct NetState { - pub force_update: Option, - pub widget_states: HashMap, -} - -impl NetState { - pub fn init(widget_states: HashMap) -> Self { - NetState { - force_update: None, - widget_states, - } - } - - pub fn get_mut_widget_state(&mut self, widget_id: u64) -> Option<&mut NetWidgetState> { - self.widget_states.get_mut(&widget_id) - } - - pub fn get_widget_state(&self, widget_id: u64) -> Option<&NetWidgetState> { - self.widget_states.get(&widget_id) - } -} - -pub struct CpuWidgetState { - pub current_display_time: u64, - pub is_legend_hidden: bool, - pub autohide_timer: Option, - pub scroll_state: AppScrollWidgetState, - pub is_multi_graph_mode: bool, - pub table_width_state: CanvasTableWidthState, -} - -impl CpuWidgetState { - pub fn init(current_display_time: u64, autohide_timer: Option) -> Self { - CpuWidgetState { - current_display_time, - is_legend_hidden: false, - autohide_timer, - scroll_state: AppScrollWidgetState::default(), - is_multi_graph_mode: false, - table_width_state: CanvasTableWidthState::default(), - } - } -} - -pub struct CpuState { - pub force_update: Option, - pub widget_states: HashMap, -} - -impl CpuState { - pub fn init(widget_states: HashMap) -> Self { - CpuState { - force_update: None, - widget_states, - } - } - - pub fn get_mut_widget_state(&mut self, widget_id: u64) -> Option<&mut CpuWidgetState> { - self.widget_states.get_mut(&widget_id) - } - - pub fn get_widget_state(&self, widget_id: u64) -> Option<&CpuWidgetState> { - self.widget_states.get(&widget_id) - } -} - -pub struct MemWidgetState { - pub current_display_time: u64, - pub autohide_timer: Option, -} - -impl MemWidgetState { - pub fn init(current_display_time: u64, autohide_timer: Option) -> Self { - MemWidgetState { - current_display_time, - autohide_timer, - } - } -} -pub struct MemState { - pub force_update: Option, - pub widget_states: HashMap, -} - -impl MemState { - pub fn init(widget_states: HashMap) -> Self { - MemState { - force_update: None, - widget_states, - } - } - - pub fn get_mut_widget_state(&mut self, widget_id: u64) -> Option<&mut MemWidgetState> { - self.widget_states.get_mut(&widget_id) - } - - pub fn get_widget_state(&self, widget_id: u64) -> Option<&MemWidgetState> { - self.widget_states.get(&widget_id) - } -} - -pub struct TempWidgetState { - pub scroll_state: AppScrollWidgetState, - pub table_width_state: CanvasTableWidthState, -} - -impl TempWidgetState { - pub fn init() -> Self { - TempWidgetState { - scroll_state: AppScrollWidgetState::default(), - table_width_state: CanvasTableWidthState::default(), - } - } -} - -pub struct TempState { - pub widget_states: HashMap, -} - -impl TempState { - pub fn init(widget_states: HashMap) -> Self { - TempState { widget_states } - } - - pub fn get_mut_widget_state(&mut self, widget_id: u64) -> Option<&mut TempWidgetState> { - self.widget_states.get_mut(&widget_id) - } - - pub fn get_widget_state(&self, widget_id: u64) -> Option<&TempWidgetState> { - self.widget_states.get(&widget_id) - } -} - -pub struct DiskWidgetState { - pub scroll_state: AppScrollWidgetState, - pub table_width_state: CanvasTableWidthState, -} - -impl DiskWidgetState { - pub fn init() -> Self { - DiskWidgetState { - scroll_state: AppScrollWidgetState::default(), - table_width_state: CanvasTableWidthState::default(), - } - } -} - -pub struct DiskState { - pub widget_states: HashMap, -} - -impl DiskState { - pub fn init(widget_states: HashMap) -> Self { - DiskState { widget_states } - } - - pub fn get_mut_widget_state(&mut self, widget_id: u64) -> Option<&mut DiskWidgetState> { - self.widget_states.get_mut(&widget_id) - } - - pub fn get_widget_state(&self, widget_id: u64) -> Option<&DiskWidgetState> { - self.widget_states.get(&widget_id) - } -} -pub struct BasicTableWidgetState { - // Since this is intended (currently) to only be used for ONE widget, that's - // how it's going to be written. If we want to allow for multiple of these, - // then we can expand outwards with a normal BasicTableState and a hashmap - pub currently_displayed_widget_type: BottomWidgetType, - pub currently_displayed_widget_id: u64, - pub widget_id: i64, - pub left_tlc: Option<(u16, u16)>, - pub left_brc: Option<(u16, u16)>, - pub right_tlc: Option<(u16, u16)>, - pub right_brc: Option<(u16, u16)>, -} - -#[derive(Default)] -pub struct BatteryWidgetState { - pub currently_selected_battery_index: usize, - pub tab_click_locs: Option>, -} - -pub struct BatteryState { - pub widget_states: HashMap, -} - -impl BatteryState { - pub fn init(widget_states: HashMap) -> Self { - BatteryState { widget_states } - } - - pub fn get_mut_widget_state(&mut self, widget_id: u64) -> Option<&mut BatteryWidgetState> { - self.widget_states.get_mut(&widget_id) - } - - pub fn get_widget_state(&self, widget_id: u64) -> Option<&BatteryWidgetState> { - self.widget_states.get(&widget_id) - } -} - -#[derive(Default)] -pub struct ParagraphScrollState { - pub current_scroll_index: u16, - pub max_scroll_index: u16, -} - -#[derive(Default)] -pub struct ConfigState { - pub current_category_index: usize, - pub category_list: Vec, -} - -#[derive(Default)] -pub struct ConfigCategory { - pub category_name: &'static str, - pub options_list: Vec, -} - -pub struct ConfigOption { - pub set_function: Box anyhow::Result<()>>, -} diff --git a/src/app/widget_states/table_state.rs b/src/app/widget_states/table_state.rs new file mode 100644 index 000000000..2e57e8f13 --- /dev/null +++ b/src/app/widget_states/table_state.rs @@ -0,0 +1 @@ +//! States for a table widget. diff --git a/src/app/widget_states/temp_state.rs b/src/app/widget_states/temp_state.rs new file mode 100644 index 000000000..e8bd73f44 --- /dev/null +++ b/src/app/widget_states/temp_state.rs @@ -0,0 +1,35 @@ +use std::collections::HashMap; + +use super::{AppScrollWidgetState, CanvasTableWidthState}; + +pub struct TempWidgetState { + pub scroll_state: AppScrollWidgetState, + pub table_width_state: CanvasTableWidthState, +} + +impl TempWidgetState { + pub fn init() -> Self { + TempWidgetState { + scroll_state: AppScrollWidgetState::default(), + table_width_state: CanvasTableWidthState::default(), + } + } +} + +pub struct TempState { + pub widget_states: HashMap, +} + +impl TempState { + pub fn init(widget_states: HashMap) -> Self { + TempState { widget_states } + } + + pub fn get_mut_widget_state(&mut self, widget_id: u64) -> Option<&mut TempWidgetState> { + self.widget_states.get_mut(&widget_id) + } + + pub fn get_widget_state(&self, widget_id: u64) -> Option<&TempWidgetState> { + self.widget_states.get(&widget_id) + } +} diff --git a/src/bin/main.rs b/src/bin/main.rs index 02828ed78..48a757a03 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -50,7 +50,6 @@ fn main() -> Result<()> { &widget_layout, default_widget_id, &default_widget_type_option, - config_path, )?; // Create painter and set colours. diff --git a/src/canvas.rs b/src/canvas.rs index 79118e3bd..d96b78d95 100644 --- a/src/canvas.rs +++ b/src/canvas.rs @@ -13,14 +13,13 @@ use tui::{ use canvas_colours::*; use dialogs::*; -use screens::*; use widgets::*; use crate::{ app::{ self, layout_manager::{BottomColRow, BottomLayout, BottomWidgetType}, - App, + AppState, }, constants::*, data_conversion::{ConvertedBatteryData, ConvertedCpuData, ConvertedProcessData}, @@ -33,7 +32,6 @@ use crate::{ mod canvas_colours; mod dialogs; mod drawing_utils; -mod screens; mod widgets; /// Point is of time, data @@ -299,7 +297,7 @@ impl Painter { } pub fn draw_data( - &mut self, terminal: &mut Terminal, app_state: &mut app::App, + &mut self, terminal: &mut Terminal, app_state: &mut app::AppState, ) -> error::Result<()> { use BottomWidgetType::*; @@ -521,13 +519,6 @@ impl Painter { ), _ => {} } - } else if app_state.is_config_open { - let rect = Layout::default() - .margin(0) - .constraints([Constraint::Percentage(100)]) - .split(f.size())[0]; - - self.draw_config_screen(&mut f, app_state, rect) } else if app_state.app_config_fields.use_basic_mode { // Basic mode. This basically removes all graphs but otherwise // the same info. @@ -715,7 +706,7 @@ impl Painter { } fn draw_widgets_with_constraints( - &self, f: &mut Frame<'_, B>, app_state: &mut App, widgets: &BottomColRow, + &self, f: &mut Frame<'_, B>, app_state: &mut AppState, widgets: &BottomColRow, widget_draw_locs: &[Rect], ) { use BottomWidgetType::*; diff --git a/src/canvas/dialogs/dd_dialog.rs b/src/canvas/dialogs/dd_dialog.rs index ac9c6910c..8a187e8fd 100644 --- a/src/canvas/dialogs/dd_dialog.rs +++ b/src/canvas/dialogs/dd_dialog.rs @@ -9,7 +9,7 @@ use tui::{ }; use crate::{ - app::{App, KillSignal}, + app::{AppState, KillSignal}, canvas::Painter, }; @@ -17,19 +17,20 @@ const DD_BASE: &str = " Confirm Kill Process ── Esc to close "; const DD_ERROR_BASE: &str = " Error ── Esc to close "; pub trait KillDialog { - fn get_dd_spans(&self, app_state: &App) -> Option>; + fn get_dd_spans(&self, app_state: &AppState) -> Option>; fn draw_dd_confirm_buttons( - &self, f: &mut Frame<'_, B>, button_draw_loc: &Rect, app_state: &mut App, + &self, f: &mut Frame<'_, B>, button_draw_loc: &Rect, app_state: &mut AppState, ); fn draw_dd_dialog( - &self, f: &mut Frame<'_, B>, dd_text: Option>, app_state: &mut App, draw_loc: Rect, + &self, f: &mut Frame<'_, B>, dd_text: Option>, app_state: &mut AppState, + draw_loc: Rect, ) -> bool; } impl KillDialog for Painter { - fn get_dd_spans(&self, app_state: &App) -> Option> { + fn get_dd_spans(&self, app_state: &AppState) -> Option> { if let Some(dd_err) = &app_state.dd_err { return Some(Text::from(vec![ Spans::default(), @@ -68,7 +69,7 @@ impl KillDialog for Painter { } fn draw_dd_confirm_buttons( - &self, f: &mut Frame<'_, B>, button_draw_loc: &Rect, app_state: &mut App, + &self, f: &mut Frame<'_, B>, button_draw_loc: &Rect, app_state: &mut AppState, ) { if cfg!(target_os = "windows") || !app_state.app_config_fields.is_advanced_kill { let (yes_button, no_button) = match app_state.delete_dialog_state.selected_signal { @@ -318,7 +319,8 @@ impl KillDialog for Painter { } fn draw_dd_dialog( - &self, f: &mut Frame<'_, B>, dd_text: Option>, app_state: &mut App, draw_loc: Rect, + &self, f: &mut Frame<'_, B>, dd_text: Option>, app_state: &mut AppState, + draw_loc: Rect, ) -> bool { if let Some(dd_text) = dd_text { let dd_title = if app_state.dd_err.is_some() { diff --git a/src/canvas/dialogs/help_dialog.rs b/src/canvas/dialogs/help_dialog.rs index 2e6dd7d86..54b470007 100644 --- a/src/canvas/dialogs/help_dialog.rs +++ b/src/canvas/dialogs/help_dialog.rs @@ -1,6 +1,6 @@ use unicode_width::UnicodeWidthStr; -use crate::{app::App, canvas::Painter, constants}; +use crate::{app::AppState, canvas::Painter, constants}; use tui::{ backend::Backend, layout::{Alignment, Rect}, @@ -14,14 +14,14 @@ const HELP_BASE: &str = " Help ── Esc to close "; pub trait HelpDialog { fn draw_help_dialog( - &self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect, + &self, f: &mut Frame<'_, B>, app_state: &mut AppState, draw_loc: Rect, ); } // TODO: [REFACTOR] Make generic dialog boxes to build off of instead? impl HelpDialog for Painter { fn draw_help_dialog( - &self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect, + &self, f: &mut Frame<'_, B>, app_state: &mut AppState, draw_loc: Rect, ) { let help_title = Spans::from(vec![ Span::styled(" Help ", self.colours.widget_title_style), diff --git a/src/canvas/screens.rs b/src/canvas/screens.rs deleted file mode 100644 index e17aa573a..000000000 --- a/src/canvas/screens.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub mod config_screen; - -pub use config_screen::*; diff --git a/src/canvas/screens/config_screen.rs b/src/canvas/screens/config_screen.rs deleted file mode 100644 index b51a0b734..000000000 --- a/src/canvas/screens/config_screen.rs +++ /dev/null @@ -1,33 +0,0 @@ -#![allow(unused_variables)] //FIXME: Remove this -#![allow(unused_imports)] //FIXME: Remove this -use crate::{app::App, canvas::Painter, constants}; -use tui::{ - backend::Backend, - layout::Constraint, - layout::Direction, - layout::Layout, - layout::{Alignment, Rect}, - terminal::Frame, - text::Span, - widgets::{Block, Borders, Paragraph}, -}; - -pub trait ConfigScreen { - fn draw_config_screen( - &self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect, - ); -} - -impl ConfigScreen for Painter { - fn draw_config_screen( - &self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect, - ) { - let config_block = Block::default() - .title(Span::styled(" Config ", self.colours.widget_title_style)) - .style(self.colours.border_style) - .borders(Borders::ALL) - .border_style(self.colours.border_style); - - f.render_widget(config_block, draw_loc); - } -} diff --git a/src/canvas/widgets/basic_table_arrows.rs b/src/canvas/widgets/basic_table_arrows.rs index 6ab511241..82c232453 100644 --- a/src/canvas/widgets/basic_table_arrows.rs +++ b/src/canvas/widgets/basic_table_arrows.rs @@ -1,5 +1,5 @@ use crate::{ - app::{layout_manager::BottomWidgetType, App}, + app::{layout_manager::BottomWidgetType, AppState}, canvas::Painter, }; @@ -14,13 +14,13 @@ use tui::{ pub trait BasicTableArrows { fn draw_basic_table_arrows( - &self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect, widget_id: u64, + &self, f: &mut Frame<'_, B>, app_state: &mut AppState, draw_loc: Rect, widget_id: u64, ); } impl BasicTableArrows for Painter { fn draw_basic_table_arrows( - &self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect, widget_id: u64, + &self, f: &mut Frame<'_, B>, app_state: &mut AppState, draw_loc: Rect, widget_id: u64, ) { if let Some(current_table) = app_state.widget_map.get(&widget_id) { let current_table = if let BottomWidgetType::ProcSort = current_table.widget_type { diff --git a/src/canvas/widgets/battery_display.rs b/src/canvas/widgets/battery_display.rs index 52b769df4..34d9783cc 100644 --- a/src/canvas/widgets/battery_display.rs +++ b/src/canvas/widgets/battery_display.rs @@ -1,5 +1,5 @@ use crate::{ - app::App, + app::AppState, canvas::{drawing_utils::calculate_basic_use_bars, Painter}, constants::*, }; @@ -15,14 +15,14 @@ use unicode_segmentation::UnicodeSegmentation; pub trait BatteryDisplayWidget { fn draw_battery_display( - &self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect, draw_border: bool, + &self, f: &mut Frame<'_, B>, app_state: &mut AppState, draw_loc: Rect, draw_border: bool, widget_id: u64, ); } impl BatteryDisplayWidget for Painter { fn draw_battery_display( - &self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect, draw_border: bool, + &self, f: &mut Frame<'_, B>, app_state: &mut AppState, draw_loc: Rect, draw_border: bool, widget_id: u64, ) { let should_get_widget_bounds = app_state.should_get_widget_bounds(); diff --git a/src/canvas/widgets/cpu_basic.rs b/src/canvas/widgets/cpu_basic.rs index 5beb3f738..84f12f07a 100644 --- a/src/canvas/widgets/cpu_basic.rs +++ b/src/canvas/widgets/cpu_basic.rs @@ -1,7 +1,7 @@ use std::cmp::min; use crate::{ - app::App, + app::AppState, canvas::{drawing_utils::*, Painter}, constants::*, data_conversion::ConvertedCpuData, @@ -17,13 +17,13 @@ use tui::{ pub trait CpuBasicWidget { fn draw_basic_cpu( - &self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect, widget_id: u64, + &self, f: &mut Frame<'_, B>, app_state: &mut AppState, draw_loc: Rect, widget_id: u64, ); } impl CpuBasicWidget for Painter { fn draw_basic_cpu( - &self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect, widget_id: u64, + &self, f: &mut Frame<'_, B>, app_state: &mut AppState, draw_loc: Rect, widget_id: u64, ) { // Skip the first element, it's the "all" element if app_state.canvas_data.cpu_data.len() > 1 { diff --git a/src/canvas/widgets/cpu_graph.rs b/src/canvas/widgets/cpu_graph.rs index ff6838f2b..8e07ec28d 100644 --- a/src/canvas/widgets/cpu_graph.rs +++ b/src/canvas/widgets/cpu_graph.rs @@ -2,7 +2,7 @@ use once_cell::sync::Lazy; use unicode_segmentation::UnicodeSegmentation; use crate::{ - app::{layout_manager::WidgetDirection, App}, + app::{layout_manager::WidgetDirection, AppState}, canvas::{ drawing_utils::{get_column_widths, get_start_position, interpolate_points}, Painter, @@ -34,19 +34,19 @@ static CPU_LEGEND_HEADER_LENS: Lazy> = Lazy::new(|| { pub trait CpuGraphWidget { fn draw_cpu( - &self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect, widget_id: u64, + &self, f: &mut Frame<'_, B>, app_state: &mut AppState, draw_loc: Rect, widget_id: u64, ); fn draw_cpu_graph( - &self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect, widget_id: u64, + &self, f: &mut Frame<'_, B>, app_state: &mut AppState, draw_loc: Rect, widget_id: u64, ); fn draw_cpu_legend( - &self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect, widget_id: u64, + &self, f: &mut Frame<'_, B>, app_state: &mut AppState, draw_loc: Rect, widget_id: u64, ); } impl CpuGraphWidget for Painter { fn draw_cpu( - &self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect, widget_id: u64, + &self, f: &mut Frame<'_, B>, app_state: &mut AppState, draw_loc: Rect, widget_id: u64, ) { if draw_loc.width as f64 * 0.15 <= 6.0 { // Skip drawing legend @@ -132,7 +132,7 @@ impl CpuGraphWidget for Painter { } fn draw_cpu_graph( - &self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect, widget_id: u64, + &self, f: &mut Frame<'_, B>, app_state: &mut AppState, draw_loc: Rect, widget_id: u64, ) { if let Some(cpu_widget_state) = app_state.cpu_state.widget_states.get_mut(&widget_id) { let cpu_data: &mut [ConvertedCpuData] = &mut app_state.canvas_data.cpu_data; @@ -382,7 +382,7 @@ impl CpuGraphWidget for Painter { } fn draw_cpu_legend( - &self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect, widget_id: u64, + &self, f: &mut Frame<'_, B>, app_state: &mut AppState, draw_loc: Rect, widget_id: u64, ) { let recalculate_column_widths = app_state.should_get_widget_bounds(); if let Some(cpu_widget_state) = app_state.cpu_state.widget_states.get_mut(&(widget_id - 1)) diff --git a/src/canvas/widgets/disk_table.rs b/src/canvas/widgets/disk_table.rs index 7d493f17c..6a79c5b69 100644 --- a/src/canvas/widgets/disk_table.rs +++ b/src/canvas/widgets/disk_table.rs @@ -29,15 +29,15 @@ static DISK_HEADERS_LENS: Lazy> = Lazy::new(|| { pub trait DiskTableWidget { fn draw_disk_table( - &self, f: &mut Frame<'_, B>, app_state: &mut app::App, draw_loc: Rect, draw_border: bool, - widget_id: u64, + &self, f: &mut Frame<'_, B>, app_state: &mut app::AppState, draw_loc: Rect, + draw_border: bool, widget_id: u64, ); } impl DiskTableWidget for Painter { fn draw_disk_table( - &self, f: &mut Frame<'_, B>, app_state: &mut app::App, draw_loc: Rect, draw_border: bool, - widget_id: u64, + &self, f: &mut Frame<'_, B>, app_state: &mut app::AppState, draw_loc: Rect, + draw_border: bool, widget_id: u64, ) { let recalculate_column_widths = app_state.should_get_widget_bounds(); if let Some(disk_widget_state) = app_state.disk_state.widget_states.get_mut(&widget_id) { diff --git a/src/canvas/widgets/mem_basic.rs b/src/canvas/widgets/mem_basic.rs index 3bb40ad78..afb3da537 100644 --- a/src/canvas/widgets/mem_basic.rs +++ b/src/canvas/widgets/mem_basic.rs @@ -1,5 +1,5 @@ use crate::{ - app::App, + app::AppState, canvas::{drawing_utils::*, Painter}, constants::*, }; @@ -15,13 +15,13 @@ use tui::{ pub trait MemBasicWidget { fn draw_basic_memory( - &self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect, widget_id: u64, + &self, f: &mut Frame<'_, B>, app_state: &mut AppState, draw_loc: Rect, widget_id: u64, ); } impl MemBasicWidget for Painter { fn draw_basic_memory( - &self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect, widget_id: u64, + &self, f: &mut Frame<'_, B>, app_state: &mut AppState, draw_loc: Rect, widget_id: u64, ) { let mem_data: &[(f64, f64)] = &app_state.canvas_data.mem_data; let swap_data: &[(f64, f64)] = &app_state.canvas_data.swap_data; diff --git a/src/canvas/widgets/mem_graph.rs b/src/canvas/widgets/mem_graph.rs index 6b5bc5ab7..cd0d06721 100644 --- a/src/canvas/widgets/mem_graph.rs +++ b/src/canvas/widgets/mem_graph.rs @@ -1,5 +1,5 @@ use crate::{ - app::App, + app::AppState, canvas::{drawing_utils::interpolate_points, Painter}, constants::*, }; @@ -17,13 +17,13 @@ use unicode_segmentation::UnicodeSegmentation; pub trait MemGraphWidget { fn draw_memory_graph( - &self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect, widget_id: u64, + &self, f: &mut Frame<'_, B>, app_state: &mut AppState, draw_loc: Rect, widget_id: u64, ); } impl MemGraphWidget for Painter { fn draw_memory_graph( - &self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect, widget_id: u64, + &self, f: &mut Frame<'_, B>, app_state: &mut AppState, draw_loc: Rect, widget_id: u64, ) { if let Some(mem_widget_state) = app_state.mem_state.widget_states.get_mut(&widget_id) { let mem_data: &mut [(f64, f64)] = &mut app_state.canvas_data.mem_data; diff --git a/src/canvas/widgets/network_basic.rs b/src/canvas/widgets/network_basic.rs index 7f0e393eb..42ebd73b5 100644 --- a/src/canvas/widgets/network_basic.rs +++ b/src/canvas/widgets/network_basic.rs @@ -1,4 +1,4 @@ -use crate::{app::App, canvas::Painter, constants::*}; +use crate::{app::AppState, canvas::Painter, constants::*}; use tui::{ backend::Backend, @@ -10,13 +10,13 @@ use tui::{ pub trait NetworkBasicWidget { fn draw_basic_network( - &self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect, widget_id: u64, + &self, f: &mut Frame<'_, B>, app_state: &mut AppState, draw_loc: Rect, widget_id: u64, ); } impl NetworkBasicWidget for Painter { fn draw_basic_network( - &self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect, widget_id: u64, + &self, f: &mut Frame<'_, B>, app_state: &mut AppState, draw_loc: Rect, widget_id: u64, ) { let divided_loc = Layout::default() .direction(Direction::Horizontal) diff --git a/src/canvas/widgets/network_graph.rs b/src/canvas/widgets/network_graph.rs index 745092242..be33264aa 100644 --- a/src/canvas/widgets/network_graph.rs +++ b/src/canvas/widgets/network_graph.rs @@ -3,7 +3,7 @@ use std::cmp::max; use unicode_segmentation::UnicodeSegmentation; use crate::{ - app::{App, AxisScaling}, + app::{AppState, AxisScaling}, canvas::{ drawing_utils::{get_column_widths, interpolate_points}, Painter, @@ -34,22 +34,22 @@ static NETWORK_HEADERS_LENS: Lazy> = Lazy::new(|| { pub trait NetworkGraphWidget { fn draw_network( - &self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect, widget_id: u64, + &self, f: &mut Frame<'_, B>, app_state: &mut AppState, draw_loc: Rect, widget_id: u64, ); fn draw_network_graph( - &self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect, widget_id: u64, + &self, f: &mut Frame<'_, B>, app_state: &mut AppState, draw_loc: Rect, widget_id: u64, hide_legend: bool, ); fn draw_network_labels( - &self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect, widget_id: u64, + &self, f: &mut Frame<'_, B>, app_state: &mut AppState, draw_loc: Rect, widget_id: u64, ); } impl NetworkGraphWidget for Painter { fn draw_network( - &self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect, widget_id: u64, + &self, f: &mut Frame<'_, B>, app_state: &mut AppState, draw_loc: Rect, widget_id: u64, ) { if app_state.app_config_fields.use_old_network_legend { let network_chunk = Layout::default() @@ -80,7 +80,7 @@ impl NetworkGraphWidget for Painter { } fn draw_network_graph( - &self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect, widget_id: u64, + &self, f: &mut Frame<'_, B>, app_state: &mut AppState, draw_loc: Rect, widget_id: u64, hide_legend: bool, ) { /// Point is of time, data @@ -702,7 +702,7 @@ impl NetworkGraphWidget for Painter { } fn draw_network_labels( - &self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect, widget_id: u64, + &self, f: &mut Frame<'_, B>, app_state: &mut AppState, draw_loc: Rect, widget_id: u64, ) { let table_gap = if draw_loc.height < TABLE_GAP_HEIGHT_LIMIT { 0 diff --git a/src/canvas/widgets/process_table.rs b/src/canvas/widgets/process_table.rs index 2abab933e..190a216e0 100644 --- a/src/canvas/widgets/process_table.rs +++ b/src/canvas/widgets/process_table.rs @@ -1,5 +1,5 @@ use crate::{ - app::App, + app::AppState, canvas::{ drawing_utils::{get_column_widths, get_search_start_position, get_start_position}, Painter, @@ -103,7 +103,7 @@ pub trait ProcessTableWidget { /// Draws and handles all process-related drawing. Use this. /// - `widget_id` here represents the widget ID of the process widget itself! fn draw_process_features( - &self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect, draw_border: bool, + &self, f: &mut Frame<'_, B>, app_state: &mut AppState, draw_loc: Rect, draw_border: bool, widget_id: u64, ); @@ -112,7 +112,7 @@ pub trait ProcessTableWidget { /// /// This should not be directly called. fn draw_processes_table( - &self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect, draw_border: bool, + &self, f: &mut Frame<'_, B>, app_state: &mut AppState, draw_loc: Rect, draw_border: bool, widget_id: u64, ); @@ -122,7 +122,7 @@ pub trait ProcessTableWidget { /// /// This should not be directly called. fn draw_search_field( - &self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect, draw_border: bool, + &self, f: &mut Frame<'_, B>, app_state: &mut AppState, draw_loc: Rect, draw_border: bool, widget_id: u64, ); @@ -132,14 +132,14 @@ pub trait ProcessTableWidget { /// /// This should not be directly called. fn draw_process_sort( - &self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect, draw_border: bool, + &self, f: &mut Frame<'_, B>, app_state: &mut AppState, draw_loc: Rect, draw_border: bool, widget_id: u64, ); } impl ProcessTableWidget for Painter { fn draw_process_features( - &self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect, draw_border: bool, + &self, f: &mut Frame<'_, B>, app_state: &mut AppState, draw_loc: Rect, draw_border: bool, widget_id: u64, ) { if let Some(process_widget_state) = app_state.proc_state.widget_states.get(&widget_id) { @@ -185,7 +185,7 @@ impl ProcessTableWidget for Painter { } fn draw_processes_table( - &self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect, draw_border: bool, + &self, f: &mut Frame<'_, B>, app_state: &mut AppState, draw_loc: Rect, draw_border: bool, widget_id: u64, ) { let should_get_widget_bounds = app_state.should_get_widget_bounds(); @@ -567,7 +567,7 @@ impl ProcessTableWidget for Painter { } fn draw_search_field( - &self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect, draw_border: bool, + &self, f: &mut Frame<'_, B>, app_state: &mut AppState, draw_loc: Rect, draw_border: bool, widget_id: u64, ) { fn build_query<'a>( @@ -786,7 +786,7 @@ impl ProcessTableWidget for Painter { } fn draw_process_sort( - &self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect, draw_border: bool, + &self, f: &mut Frame<'_, B>, app_state: &mut AppState, draw_loc: Rect, draw_border: bool, widget_id: u64, ) { let is_on_widget = widget_id == app_state.current_widget.widget_id; diff --git a/src/canvas/widgets/temp_table.rs b/src/canvas/widgets/temp_table.rs index 5347fb9d6..eaa9ea2a1 100644 --- a/src/canvas/widgets/temp_table.rs +++ b/src/canvas/widgets/temp_table.rs @@ -29,15 +29,15 @@ static TEMP_HEADERS_LENS: Lazy> = Lazy::new(|| { pub trait TempTableWidget { fn draw_temp_table( - &self, f: &mut Frame<'_, B>, app_state: &mut app::App, draw_loc: Rect, draw_border: bool, - widget_id: u64, + &self, f: &mut Frame<'_, B>, app_state: &mut app::AppState, draw_loc: Rect, + draw_border: bool, widget_id: u64, ); } impl TempTableWidget for Painter { fn draw_temp_table( - &self, f: &mut Frame<'_, B>, app_state: &mut app::App, draw_loc: Rect, draw_border: bool, - widget_id: u64, + &self, f: &mut Frame<'_, B>, app_state: &mut app::AppState, draw_loc: Rect, + draw_border: bool, widget_id: u64, ) { let recalculate_column_widths = app_state.should_get_widget_bounds(); if let Some(temp_widget_state) = app_state.temp_state.widget_states.get_mut(&widget_id) { diff --git a/src/data_conversion.rs b/src/data_conversion.rs index 1efc6db43..a9e434880 100644 --- a/src/data_conversion.rs +++ b/src/data_conversion.rs @@ -2,7 +2,7 @@ //! can actually handle. use crate::{app::AxisScaling, units::data_units::DataUnit, Pid}; use crate::{ - app::{data_farmer, data_harvester, App, ProcWidgetState}, + app::{data_farmer, data_harvester, AppState, ProcWidgetState}, utils::{self, gen_util::*}, }; use data_harvester::processes::ProcessSorting; @@ -83,7 +83,7 @@ pub struct ConvertedCpuData { pub legend_value: String, } -pub fn convert_temp_row(app: &App) -> Vec> { +pub fn convert_temp_row(app: &AppState) -> Vec> { let current_data = &app.data_collection; let temp_type = &app.app_config_fields.temperature_type; diff --git a/src/lib.rs b/src/lib.rs index 835af242a..c0e59ce7c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -29,7 +29,7 @@ use crossterm::{ use app::{ data_harvester::{self, processes::ProcessSorting}, layout_manager::{UsedWidgets, WidgetDirection}, - App, + AppState, }; use constants::*; use data_conversion::*; @@ -71,7 +71,7 @@ pub enum ThreadControlEvent { UpdateUpdateTime(u64), } -pub fn handle_mouse_event(event: MouseEvent, app: &mut App) { +pub fn handle_mouse_event(event: MouseEvent, app: &mut AppState) { match event { MouseEvent::ScrollUp(_x, _y, _modifiers) => app.handle_scroll_up(), MouseEvent::ScrollDown(_x, _y, _modifiers) => app.handle_scroll_down(), @@ -92,7 +92,7 @@ pub fn handle_mouse_event(event: MouseEvent, app: &mut App) { } pub fn handle_key_event_or_break( - event: KeyEvent, app: &mut App, reset_sender: &std::sync::mpsc::Sender, + event: KeyEvent, app: &mut AppState, reset_sender: &std::sync::mpsc::Sender, ) -> bool { // debug!("KeyEvent: {:?}", event); @@ -240,7 +240,7 @@ pub fn create_or_get_config(config_path: &Option) -> error::Result>, - app: &mut App, painter: &mut canvas::Painter, + app: &mut AppState, painter: &mut canvas::Painter, ) -> error::Result<()> { if let Err(err) = painter.draw_data(terminal, app) { cleanup_terminal(terminal)?; @@ -300,7 +300,7 @@ pub fn panic_hook(panic_info: &PanicInfo<'_>) { .unwrap(); } -pub fn handle_force_redraws(app: &mut App) { +pub fn handle_force_redraws(app: &mut AppState) { // Currently we use an Option... because we might want to future-proof this // if we eventually get widget-specific redrawing! if app.proc_state.force_update_all { @@ -343,7 +343,7 @@ pub fn handle_force_redraws(app: &mut App) { } #[allow(clippy::needless_collect)] -pub fn update_all_process_lists(app: &mut App) { +pub fn update_all_process_lists(app: &mut AppState) { // According to clippy, I can avoid a collect... but if I follow it, // I end up conflicting with the borrow checker since app is used within the closure... hm. if !app.is_frozen { @@ -360,7 +360,7 @@ pub fn update_all_process_lists(app: &mut App) { } } -fn update_final_process_list(app: &mut App, widget_id: u64) { +fn update_final_process_list(app: &mut AppState, widget_id: u64) { let process_states = app .proc_state .widget_states diff --git a/src/options.rs b/src/options.rs index facd42fef..51b060ab6 100644 --- a/src/options.rs +++ b/src/options.rs @@ -1,9 +1,7 @@ use regex::Regex; use serde::{Deserialize, Serialize}; use std::{ - borrow::Cow, collections::{HashMap, HashSet}, - path::PathBuf, str::FromStr, time::Instant, }; @@ -16,8 +14,6 @@ use crate::{ utils::error::{self, BottomError}, }; -use typed_builder::*; - use layout_options::*; pub mod layout_options; @@ -35,136 +31,75 @@ pub struct Config { pub net_filter: Option, } -impl Config { - pub fn get_config_as_bytes(&self) -> anyhow::Result> { - let mut config_string: Vec> = Vec::default(); - - // Top level - config_string.push(CONFIG_TOP_HEAD.into()); - config_string.push(toml::to_string_pretty(self)?.into()); - - Ok(config_string.concat().as_bytes().to_vec()) - } -} - -#[derive(Clone, Debug, Default, Deserialize, Serialize, TypedBuilder)] +#[derive(Clone, Debug, Default, Deserialize, Serialize)] pub struct ConfigFlags { - #[builder(default, setter(strip_option))] pub hide_avg_cpu: Option, - #[builder(default, setter(strip_option))] pub dot_marker: Option, - #[builder(default, setter(strip_option))] pub temperature_type: Option, - #[builder(default, setter(strip_option))] pub rate: Option, - #[builder(default, setter(strip_option))] pub left_legend: Option, - #[builder(default, setter(strip_option))] pub current_usage: Option, - #[builder(default, setter(strip_option))] pub group_processes: Option, - #[builder(default, setter(strip_option))] pub case_sensitive: Option, - #[builder(default, setter(strip_option))] pub whole_word: Option, - #[builder(default, setter(strip_option))] pub regex: Option, - #[builder(default, setter(strip_option))] pub basic: Option, - #[builder(default, setter(strip_option))] pub default_time_value: Option, - #[builder(default, setter(strip_option))] pub time_delta: Option, - #[builder(default, setter(strip_option))] pub autohide_time: Option, - #[builder(default, setter(strip_option))] pub hide_time: Option, - #[builder(default, setter(strip_option))] pub default_widget_type: Option, - #[builder(default, setter(strip_option))] pub default_widget_count: Option, - #[builder(default, setter(strip_option))] pub use_old_network_legend: Option, - #[builder(default, setter(strip_option))] pub hide_table_gap: Option, - #[builder(default, setter(strip_option))] pub battery: Option, - #[builder(default, setter(strip_option))] pub disable_click: Option, - #[builder(default, setter(strip_option))] pub no_write: Option, // For built-in colour palettes. - #[builder(default, setter(strip_option))] pub color: Option, - // This is a huge hack to enable hashmap functionality WITHOUT being able to serializing the field. - // Basically, keep a hashmap in the struct, and convert to a vector every time. - #[builder(default, setter(strip_option))] - #[serde(skip)] - pub search_case_enabled_widgets_map: Option>, - - #[builder(default, setter(strip_option))] pub search_case_enabled_widgets: Option>, - #[builder(default, setter(strip_option))] - #[serde(skip)] - pub search_whole_word_enabled_widgets_map: Option>, - - #[builder(default, setter(strip_option))] pub search_whole_word_enabled_widgets: Option>, - #[builder(default, setter(strip_option))] - #[serde(skip)] - pub search_regex_enabled_widgets_map: Option>, - - #[builder(default, setter(strip_option))] pub search_regex_enabled_widgets: Option>, - // End hack - #[builder(default, setter(strip_option))] pub mem_as_value: Option, - #[builder(default, setter(strip_option))] pub tree: Option, - #[builder(default, setter(strip_option))] show_table_scroll_position: Option, - #[builder(default, setter(strip_option))] pub process_command: Option, - #[builder(default, setter(strip_option))] pub disable_advanced_kill: Option, - #[builder(default, setter(strip_option))] pub network_use_bytes: Option, - #[builder(default, setter(strip_option))] pub network_use_log: Option, - #[builder(default, setter(strip_option))] pub network_use_binary_prefix: Option, } @@ -246,8 +181,7 @@ pub struct IgnoreList { pub fn build_app( matches: &clap::ArgMatches<'static>, config: &mut Config, widget_layout: &BottomLayout, default_widget_id: u64, default_widget_type_option: &Option, - config_path: Option, -) -> Result { +) -> Result { use BottomWidgetType::*; let autohide_time = get_autohide_time(&matches, &config); let default_time_value = get_default_time_value(&matches, &config) @@ -462,13 +396,11 @@ pub fn build_app( if let Some(flags) = &mut config.flags { if flags.case_sensitive.is_none() && !matches.is_present("case_sensitive") { if let Some(search_case_enabled_widgets) = &flags.search_case_enabled_widgets { - let mapping = HashMap::new(); for widget in search_case_enabled_widgets { if let Some(proc_widget) = proc_state_map.get_mut(&widget.id) { proc_widget.process_search_state.is_ignoring_case = !widget.enabled; } } - flags.search_case_enabled_widgets_map = Some(mapping); } } @@ -476,30 +408,26 @@ pub fn build_app( if let Some(search_whole_word_enabled_widgets) = &flags.search_whole_word_enabled_widgets { - let mapping = HashMap::new(); for widget in search_whole_word_enabled_widgets { if let Some(proc_widget) = proc_state_map.get_mut(&widget.id) { proc_widget.process_search_state.is_searching_whole_word = widget.enabled; } } - flags.search_whole_word_enabled_widgets_map = Some(mapping); } } if flags.regex.is_none() && !matches.is_present("regex") { if let Some(search_regex_enabled_widgets) = &flags.search_regex_enabled_widgets { - let mapping = HashMap::new(); for widget in search_regex_enabled_widgets { if let Some(proc_widget) = proc_state_map.get_mut(&widget.id) { proc_widget.process_search_state.is_searching_with_regex = widget.enabled; } } - flags.search_regex_enabled_widgets_map = Some(mapping); } } } - Ok(App::builder() + Ok(AppState::builder() .app_config_fields(app_config_fields) .cpu_state(CpuState::init(cpu_state_map)) .mem_state(MemState::init(mem_state_map)) @@ -518,8 +446,6 @@ pub fn build_app( temp_filter, net_filter, }) - .config(config.clone()) - .config_path(config_path) .build()) }