summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorClement Tsang <34804052+ClementTsang@users.noreply.github.com>2020-04-01 20:31:43 -0400
committerGitHub <noreply@github.com>2020-04-01 20:31:43 -0400
commit0b1d84fdf590bf8cacc5d0f94b67f63daa9b768a (patch)
treed2ff261148f9ef21f2e860af43f795df911c5c79 /src
parentc1a19f960fc1b348dd4465fe9a4d698bed229c77 (diff)
Add modularity to widget placement and inclusion (#95)
Diffstat (limited to 'src')
-rw-r--r--src/app.rs2695
-rw-r--r--src/app/data_harvester/processes.rs13
-rw-r--r--src/app/layout_manager.rs940
-rw-r--r--src/app/process_killer.rs2
-rw-r--r--src/canvas.rs480
-rw-r--r--src/canvas/dialogs/dd_dialog.rs2
-rw-r--r--src/canvas/widgets/basic_table_arrows.rs34
-rw-r--r--src/canvas/widgets/cpu_basic.rs10
-rw-r--r--src/canvas/widgets/cpu_graph.rs464
-rw-r--r--src/canvas/widgets/disk_table.rs194
-rw-r--r--src/canvas/widgets/mem_basic.rs8
-rw-r--r--src/canvas/widgets/mem_graph.rs181
-rw-r--r--src/canvas/widgets/network_basic.rs12
-rw-r--r--src/canvas/widgets/network_graph.rs244
-rw-r--r--src/canvas/widgets/process_table.rs683
-rw-r--r--src/canvas/widgets/temp_table.rs192
-rw-r--r--src/constants.rs41
-rw-r--r--src/data_conversion.rs54
-rw-r--r--src/main.rs265
-rw-r--r--src/options.rs313
-rw-r--r--src/options/layout_manager.rs3
-rw-r--r--src/options/layout_options.rs307
22 files changed, 4751 insertions, 2386 deletions
diff --git a/src/app.rs b/src/app.rs
index 4cca1d81..ba2186a4 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -1,5 +1,4 @@
-use std::cmp::max;
-use std::time::Instant;
+use std::{cmp::max, collections::HashMap, time::Instant};
use unicode_segmentation::GraphemeCursor;
use unicode_width::{UnicodeWidthChar, UnicodeWidthStr};
@@ -8,64 +7,20 @@ use typed_builder::*;
use data_farmer::*;
use data_harvester::{processes, temperature};
+use layout_manager::*;
-use crate::{canvas, constants, utils::error::Result};
+use crate::{
+ canvas, constants,
+ utils::error::{BottomError, Result},
+};
pub mod data_farmer;
pub mod data_harvester;
+pub mod layout_manager;
mod process_killer;
const MAX_SEARCH_LENGTH: usize = 200;
-#[derive(Debug, Clone, Copy)]
-pub enum WidgetPosition {
- Cpu,
- CpuLegend,
- Mem,
- Disk,
- Temp,
- Network,
- NetworkLegend,
- Process,
- ProcessSearch,
- BasicCpu,
- BasicMem,
- BasicNet,
-}
-
-impl WidgetPosition {
- pub fn is_widget_table(self) -> bool {
- match self {
- WidgetPosition::Disk
- | WidgetPosition::Process
- | WidgetPosition::ProcessSearch
- | WidgetPosition::Temp
- | WidgetPosition::CpuLegend => true,
- _ => false,
- }
- }
-
- pub fn is_widget_graph(self) -> bool {
- match self {
- WidgetPosition::Cpu | WidgetPosition::Network | WidgetPosition::Mem => true,
- _ => false,
- }
- }
-
- pub fn get_pretty_name(self) -> String {
- use WidgetPosition::*;
- match self {
- Cpu | BasicCpu | CpuLegend => "CPU",
- Mem | BasicMem => "Memory",
- Disk => "Disks",
- Temp => "Temperature",
- Network | BasicNet | NetworkLegend => "Network",
- Process | ProcessSearch => "Processes",
- }
- .to_string()
- }
-}
-
#[derive(Debug)]
pub enum ScrollDirection {
// UP means scrolling up --- this usually DECREMENTS
@@ -74,6 +29,12 @@ pub enum ScrollDirection {
DOWN,
}
+impl Default for ScrollDirection {
+ fn default() -> Self {
+ ScrollDirection::DOWN
+ }
+}
+
#[derive(Debug)]
pub enum CursorDirection {
LEFT,
@@ -85,28 +46,52 @@ pub enum CursorDirection {
pub struct AppScrollWidgetState {
pub current_scroll_position: u64,
pub previous_scroll_position: u64,
+ pub scroll_direction: ScrollDirection,
}
-pub struct AppScrollState {
- pub scroll_direction: ScrollDirection,
- pub process_scroll_state: AppScrollWidgetState,
- pub disk_scroll_state: AppScrollWidgetState,
- pub temp_scroll_state: AppScrollWidgetState,
- pub cpu_scroll_state: AppScrollWidgetState,
+#[derive(Default)]
+pub struct AppDeleteDialogState {
+ pub is_showing_dd: bool,
+ pub is_on_yes: bool, // Defaults to "No"
}
-impl Default for AppScrollState {
+pub enum AppHelpCategory {
+ General,
+ Process,
+ Search,
+}
+
+pub struct AppHelpDialogState {
+ pub is_showing_help: bool,
+ pub current_category: AppHelpCategory,
+}
+
+impl Default for AppHelpDialogState {
fn default() -> Self {
- AppScrollState {
- scroll_direction: ScrollDirection::DOWN,
- process_scroll_state: AppScrollWidgetState::default(),
- disk_scroll_state: AppScrollWidgetState::default(),
- temp_scroll_state: AppScrollWidgetState::default(),
- cpu_scroll_state: AppScrollWidgetState::default(),
+ AppHelpDialogState {
+ is_showing_help: false,
+ current_category: AppHelpCategory::General,
}
}
}
+/// AppConfigFields is meant to cover basic fields that would normally be set
+/// by config files or launch options.
+pub struct AppConfigFields {
+ pub update_rate_in_milliseconds: u64,
+ pub temperature_type: temperature::TemperatureType,
+ pub use_dot: bool,
+ pub left_legend: bool,
+ pub show_average_cpu: bool,
+ pub use_current_cpu_total: bool,
+ pub show_disabled_data: bool,
+ pub use_basic_mode: bool,
+ pub default_time_value: u64,
+ pub time_interval: u64,
+ pub hide_time: bool,
+ pub autohide_time: bool,
+}
+
/// AppSearchState deals with generic searching (I might do this in the future).
pub struct AppSearchState {
pub is_enabled: bool,
@@ -186,138 +171,299 @@ impl ProcessSearchState {
}
}
-#[derive(Default)]
-pub struct AppDeleteDialogState {
- pub is_showing_dd: bool,
- pub is_on_yes: bool, // Defaults to "No"
+pub struct ProcWidgetState {
+ pub process_search_state: ProcessSearchState,
+ pub is_grouped: bool,
+ pub scroll_state: AppScrollWidgetState,
+ pub process_sorting_type: processes::ProcessSorting,
+ pub process_sorting_reverse: bool,
}
-pub enum AppHelpCategory {
- General,
- Process,
- Search,
-}
+impl ProcWidgetState {
+ pub fn init(
+ is_case_sensitive: bool, is_match_whole_word: bool, is_use_regex: bool, is_grouped: bool,
+ ) -> Self {
+ let mut process_search_state = ProcessSearchState::default();
+ if is_case_sensitive {
+ // By default it's off
+ process_search_state.search_toggle_ignore_case();
+ }
+ if is_match_whole_word {
+ process_search_state.search_toggle_whole_word();
+ }
+ if is_use_regex {
+ process_search_state.search_toggle_regex();
+ }
-pub struct AppHelpDialogState {
- pub is_showing_help: bool,
- pub current_category: AppHelpCategory,
-}
+ ProcWidgetState {
+ process_search_state,
+ is_grouped,
+ scroll_state: AppScrollWidgetState::default(),
+ process_sorting_type: processes::ProcessSorting::CPU,
+ process_sorting_reverse: true,
+ }
+ }
-impl Default for AppHelpDialogState {
- fn default() -> Self {
- AppHelpDialogState {
- is_showing_help: false,
- current_category: AppHelpCategory::General,
+ pub fn get_cursor_position(&self) -> usize {
+ self.process_search_state
+ .search_state
+ .grapheme_cursor
+ .cur_cursor()
+ }
+
+ pub fn get_char_cursor_position(&self) -> usize {
+ self.process_search_state.search_state.char_cursor_position
+ }
+
+ pub fn is_search_enabled(&self) -> bool {
+ self.process_search_state.search_state.is_enabled
+ }
+
+ pub fn get_current_search_query(&self) -> &String {
+ &self.process_search_state.search_state.current_search_query
+ }
+
+ pub fn update_regex(&mut self) {
+ if self
+ .process_search_state
+ .search_state
+ .current_search_query
+ .is_empty()
+ {
+ self.process_search_state.search_state.is_invalid_search = false;
+ self.process_search_state.search_state.is_blank_search = true;
+ } else {
+ let regex_string = &self.process_search_state.search_state.current_search_query;
+ let escaped_regex: String;
+ let final_regex_string = &format!(
+ "{}{}{}{}",
+ if self.process_search_state.is_searching_whole_word {
+ "^"
+ } else {
+ ""
+ },
+ if self.process_search_state.is_ignoring_case {
+ "(?i)"
+ } else {
+ ""
+ },
+ if !self.process_search_state.is_searching_with_regex {
+ escaped_regex = regex::escape(regex_string);
+ &escaped_regex
+ } else {
+ regex_string
+ },
+ if self.process_search_state.is_searching_whole_word {
+ "$"
+ } else {
+ ""
+ },
+ );
+
+ let new_regex = regex::Regex::new(final_regex_string);
+ self.process_search_state.search_state.is_blank_search = false;
+ self.process_search_state.search_state.is_invalid_search = new_regex.is_err();
+
+ self.process_search_state.search_state.current_regex = Some(new_regex);
}
+ self.scroll_state.previous_scroll_position = 0;
+ self.scroll_state.current_scroll_position = 0;
+ }
+
+ pub fn clear_search(&mut self) {
+ self.process_search_state.search_state.reset();
+ }
+
+ pub fn search_walk_forward(&mut self, start_position: usize) {
+ self.process_search_state
+ .search_state
+ .grapheme_cursor
+ .next_boundary(
+ &self.process_search_state.search_state.current_search_query[start_position..],
+ start_position,
+ )
+ .unwrap();
+ }
+
+ pub fn search_walk_back(&mut self, start_position: usize) {
+ self.process_search_state
+ .search_state
+ .grapheme_cursor
+ .prev_boundary(
+ &self.process_search_state.search_state.current_search_query[..start_position],
+ 0,
+ )
+ .unwrap();
}
}
-/// AppConfigFields is meant to cover basic fields that would normally be set
-/// by config files or launch options.
-pub struct AppConfigFields {
- pub update_rate_in_milliseconds: u64,
- pub temperature_type: temperature::TemperatureType,
- pub use_dot: bool,
- pub left_legend: bool,
- pub show_average_cpu: bool,
- pub use_current_cpu_total: bool,
- pub show_disabled_data: bool,
- pub use_basic_mode: bool,
- pub default_time_value: u64,
- pub time_interval: u64,
- pub hide_time: bool,
- pub autohide_time: bool,
+pub struct ProcState {
+ pub widget_states: HashMap<u64, ProcWidgetState>,
+ pub force_update: Option<u64>,
+ pub force_update_all: bool,
}
-/// Network specific
-pub struct NetState {
- pub is_showing_tray: bool,
- pub is_showing_rx: bool,
- pub is_showing_tx: bool,
- pub zoom_level: f64,
+impl ProcState {
+ pub fn init(widget_states: HashMap<u64, ProcWidgetState>) -> Self {
+ ProcState {
+ widget_states,
+ force_update: None,
+ force_update_all: false,
+ }
+ }
+}
+
+pub struct NetWidgetState {
pub current_display_time: u64,
- pub force_update: bool,
pub autohide_timer: Option<Instant>,
}
-impl NetState {
+impl NetWidgetState {
pub fn init(current_display_time: u64, autohide_timer: Option<Instant>) -> Self {
- NetState {
- is_showing_tray: false,
- is_showing_rx: true,
- is_showing_tx: true,
- zoom_level: 100.0,
+ NetWidgetState {
current_display_time,
- force_update: false,
autohide_timer,
}
}
}
-/// CPU specific
-pub struct CpuState {
+pub struct NetState {
+ pub force_update: Option<u64>,
+ pub widget_states: HashMap<u64, NetWidgetState>,
+}
+
+impl NetState {
+ pub fn init(widget_states: HashMap<u64, NetWidgetState>) -> Self {
+ NetState {
+ force_update: None,
+ widget_states,
+ }
+ }
+}
+
+pub struct CpuWidgetState {
+ pub current_display_time: u64,
+ pub is_legend_hidden: bool,
pub is_showing_tray: bool,
- pub zoom_level: f64,
pub core_show_vec: Vec<bool>,
- pub num_cpus_shown: u64,
- pub current_display_time: u64,
- pub force_update: bool,
+ pub num_cpus_shown: usize,
pub autohide_timer: Option<Instant>,
+ pub scroll_state: AppScrollWidgetState,
}
-impl CpuState {
+impl CpuWidgetState {
pub fn init(current_display_time: u64, autohide_timer: Option<Instant>) -> Self {
- CpuState {
+ CpuWidgetState {
+ current_display_time,
+ is_legend_hidden: false,
is_showing_tray: false,
- zoom_level: 100.0,
core_show_vec: Vec::new(),
num_cpus_shown: 0,
- current_display_time,
- force_update: false,
autohide_timer,
+ scroll_state: AppScrollWidgetState::default(),
}
}
}
-/// Memory specific
-pub struct MemState {
- pub is_showing_tray: bool,
- pub is_showing_ram: bool,
- pub is_showing_swap: bool,
- pub zoom_level: f64,
+pub struct CpuState {
+ pub force_update: Option<u64>,
+ pub widget_states: HashMap<u64, CpuWidgetState>,
+ pub num_cpus_total: usize,
+}
+
+impl CpuState {
+ pub fn init(widget_states: HashMap<u64, CpuWidgetState>) -> Self {
+ CpuState {
+ force_update: None,
+ widget_states,
+ num_cpus_total: 0,
+ }
+ }
+}
+
+pub struct MemWidgetState {
pub current_display_time: u64,
- pub force_update: bool,
pub autohide_timer: Option<Instant>,
}
-impl MemState {
+impl MemWidgetState {
pub fn init(current_display_time: u64, autohide_timer: Option<Instant>) -> Self {
- MemState {
- is_showing_tray: false,
- is_showing_ram: true,
- is_showing_swap: true,
- zoom_level: 100.0,
+ MemWidgetState {
current_display_time,
- force_update: false,
autohide_timer,
}
}
}
-#[derive(TypedBuilder)]
-pub struct App {
- #[builder(default=processes::ProcessSorting::CPU, setter(skip))]
- pub process_sorting_type: processes::ProcessSorting,
+pub struct MemState {
+ pub force_update: Option<u64>,
+ pub widget_states: HashMap<u64, MemWidgetState>,
+}
- #[builder(default = true, setter(skip))]
- pub process_sorting_reverse: bool,
+impl MemState {
+ pub fn init(widget_states: HashMap<u64, MemWidgetState>) -> Self {
+ MemState {
+ force_update: None,
+ widget_states,
+ }
+ }
+}
- #[builder(default = false, setter(skip))]
- pub force_update_processes: bool,
+pub struct TempWidgetState {
+ pub scroll_state: AppScrollWidgetState,
+}
- #[builder(default, setter(skip))]
- pub app_scroll_positions: AppScrollState,
+impl TempWidgetState {
+ pub fn init() -> Self {
+ TempWidgetState {
+ scroll_state: AppScrollWidgetState::default(),
+ }
+ }
+}
+
+pub struct TempState {
+ pub widget_states: HashMap<u64, TempWidgetState>,
+}
+impl TempState {
+ pub fn init(widget_states: HashMap<u64, TempWidgetState>) -> Self {
+ TempState { widget_states }
+ }
+}
+
+pub struct DiskWidgetState {
+ pub scroll_state: AppScrollWidgetState,
+}
+
+impl DiskWidgetState {
+ pub fn init() -> Self {
+ DiskWidgetState {
+ scroll_state: AppScrollWidgetState::default(),
+ }
+ }
+}
+
+pub struct DiskState {
+ pub widget_states: HashMap<u64, DiskWidgetState>,
+}
+
+impl DiskState {
+ pub fn init(widget_states: HashMap<u64, DiskWidgetState>) -> Self {
+ DiskState { widget_states }
+ }
+}
+
+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,
+}
+
+#[derive(TypedBuilder)]
+pub struct App {
#[builder(default = false, setter(skip))]
awaiting_second_char: bool,
@@ -339,16 +485,10 @@ pub struct App {
#[builder(default, setter(skip))]
pub canvas_data: canvas::DisplayableData,
- #[builder(default = false)]
- enable_grouping: bool,
-
#[builder(default, setter(skip))]
pub data_collection: DataCollection,
#[builder(default, setter(skip))]
- pub process_search_state: ProcessSearchState,
-
- #[builder(default, setter(skip))]
pub delete_dialog_state: AppDeleteDialogState,
#[builder(default, setter(skip))]
@@ -363,10 +503,15 @@ pub struct App {
pub cpu_state: CpuState,
pub mem_state: MemState,
pub net_state: NetState,
+ pub proc_state: ProcState,
+ pub temp_state: TempState,
+ pub disk_state: DiskState,
+
+ pub basic_table_widget_state: Option<BasicTableWidgetState>,
pub app_config_fields: AppConfigFields,
- pub current_widget_selected: WidgetPosition,
- pub previous_basic_table_selected: WidgetPosition,
+ pub widget_map: HashMap<u64, BottomWidget>,
+ pub current_widget: BottomWidget,
}
impl App {
@@ -378,9 +523,22 @@ impl App {
self.help_dialog_state.is_showing_help = false;
self.delete_dialog_state.is_showing_dd = false;
- // Close search and reset it
- self.process_search_state.search_state.reset();
- self.force_update_processes = true;
+ // Close all searches and reset it
+ self.proc_state
+ .widget_states
+ .values_mut()
+ .for_each(|state| {
+ state.process_search_state.search_state.reset();
+ });
+ self.proc_state.force_update_all = true;
+
+ // Reset all CPU filter states
+ self.cpu_state.widget_states.values_mut().for_each(|state| {
+ for show_vec_state in &mut state.core_show_vec {
+ *show_vec_state = true;
+ }
+ state.num_cpus_shown = state.core_show_vec.len();
+ });
// Clear current delete list
self.to_delete_process_list = None;
@@ -408,59 +566,136 @@ impl App {
self.to_delete_process_list = None;
self.dd_err = None;
} else if self.is_filtering_or_searching() {
- match self.current_widget_selected {
- WidgetPosition::Cpu | WidgetPosition::CpuLegend => {
- self.cpu_state.is_showing_tray = false;
- if self
- .app_scroll_positions
- .cpu_scroll_state
- .current_scroll_position
- >= self.cpu_state.num_cpus_shown
+ match self.current_widget.widget_type {
+ BottomWidgetType::Cpu => {
+ if let Some(cpu_widget_state) = self
+ .cpu_state
+ .widget_states
+ .get_mut(&self.current_widget.widget_id)
{
- let new_position = max(0, self.cpu_state.num_cpus_shown as i64 - 1) as u64;
- self.app_scroll_positions
- .cpu_scroll_state
- .current_scroll_position = new_position;
- self.app_scroll_positions
- .cpu_scroll_state
- .previous_scroll_position = 0;
+ cpu_widget_state.is_showing_tray = false;
+ if cpu_widget_state.scroll_state.current_scroll_position
+ >= cpu_widget_state.num_cpus_shown as u64
+ {
+ let new_position =
+ max(0, cpu_widget_state.num_cpus_shown as i64 - 1) as u64;
+ cpu_widget_state.scroll_state.current_scroll_position = new_position;
+ cpu_widget_state.scroll_state.previous_scroll_position = 0;
+ }
}
}
- WidgetPosition::Process | WidgetPosition::ProcessSearch => {
- if self.process_search_state.search_state.is_enabled {
- self.current_widget_selected = WidgetPosition::Process;
- self.process_search_state.search_state.is_enabled = false;
+ BottomWidgetType::CpuLegend => {
+ if let Some(cpu_widget_state) = self
+ .cpu_state
+ .widget_states
+ .get_mut(&(self.current_widget.widget_id - 1))
+ {
+ cpu_widget_state.is_showing_tray = false;
+ if cpu_widget_state.scroll_state.current_scroll_position
+ >= cpu_widget_state.num_cpus_shown as u64
+ {
+ let new_position =
+ max(0, cpu_widget_state.num_cpus_shown as i64 - 1) as u64;
+ cpu_widget_state.scroll_state.current_scroll_position = new_position;
+ cpu_widget_state.scroll_state.previous_scroll_position = 0;
+ }
}
}
- WidgetPosition::Mem => {
- self.mem_state.is_showing_tray = false;
+ BottomWidgetType::Proc => {
+ if let Some(current_proc_state) = self
+ .proc_state
+ .widget_states
+ .get_mut(&self.current_widget.widget_id)
+ {
+ if current_proc_state.is_search_enabled() {
+ current_proc_state
+ .process_search_state
+ .search_state
+ .is_enabled = false;
+ }
+ }
}
- WidgetPosition::Network => {
- self.net_state.is_showing_tray = false;
+ BottomWidgetType::ProcSearch => {
+ if let Some(current_proc_state) = self
+ .proc_state
+ .widget_states
+ .get_mut(&(self.current_widget.widget_id - 1))
+ {
+ if current_proc_state.is_search_enabled() {
+ current_proc_state
+ .process_search_state
+ .search_state
+ .is_enabled = false;
+ self.move_widget_selection_up();
+ }
+ }
}
_ => {}
}
} else if self.is_expanded {
self.is_expanded = false;
self.is_resized = true;
- if self.app_config_fields.use_basic_mode {
- self.current_widget_selected = match self.current_widget_selected {
- WidgetPosition::Cpu | WidgetPosition::CpuLegend => WidgetPosition::BasicCpu,
- WidgetPosition::Mem => WidgetPosition::BasicMem,
- WidgetPosition::Network => WidgetPosition::BasicNet,
- _ => self.current_widget_selected,
- }
- }
}
}
+ pub fn is_in_search_widget(&self) -> bool {
+ matches!(
+ self.current_widget.widget_type,
+ BottomWidgetType::ProcSearch
+ )
+ }
+
fn is_filtering_or_searching(&self) -> bool {
- match self.current_widget_selected {
- WidgetPosition::Cpu | WidgetPosition::CpuLegend => self.cpu_state.is_showing_tray,
- // WidgetPosition::Mem => self.mem_state.is_showing_tray,
- // WidgetPosition::Network => self.net_state.is_showing_tray,
- WidgetPosition::Process | WidgetPosition::ProcessSearch => {
- self.process_search_state.search_state.is_enabled
+ match self.current_widget.widget_type {
+ BottomWidgetType::Cpu => {
+ if let Some(cpu_widget_state) = self
+ .cpu_state
+ .widget_states
+ .get(&self.current_widget.widget_id)
+ {
+ cpu_widget_state.is_showing_tray
+ } else {
+ false
+ }
+ }
+ BottomWidgetType::CpuLegend => {
+ if let Some(cpu_widget_state) = self
+ .cpu_state
+ .widget_states
+ .get(&(self.current_widget.widget_id - 1))
+ {
+ cpu_widget_state.is_showing_tray
+ } else {
+ false
+ }
+ }
+ BottomWidgetType::Proc => {
+ if let Some(proc_widget_state) = self
+ .proc_state
+ .widget_states
+ .get(&self.current_widget.widget_id)
+ {
+ proc_widget_state
+ .process_search_state
+ .search_state
+ .is_enabled
+ } else {
+ false
+ }
+ }
+ BottomWidgetType::ProcSearch => {
+ if let Some(proc_widget_state) = self
+ .proc_state
+ .widget_states
+ .get(&(self.current_widget.widget_id - 1))
+ {
+ proc_widget_state
+ .process_search_state
+ .search_state
+ .is_enabled
+ } else {
+ false
+ }
}
_ => false,
}
@@ -475,208 +710,210 @@ impl App {
self.help_dialog_state.is_showing_help || self.delete_dialog_state.is_showing_dd
}
- pub fn toggle_grouping(&mut self) {
+ pub fn on_tab(&mut self) {
// Disallow usage whilst in a dialog and only in processes
- if !self.is_in_dialog() {
- if let WidgetPosition::Process = self.current_widget_selected {
- self.enable_grouping = !(self.enable_grouping);
- self.force_update_processes = true;
- }
- }
- }
- pub fn on_tab(&mut self) {
- match self.current_widget_selected {
- WidgetPosition::Process => {
- self.toggle_grouping();
- if self.is_grouped() {
- self.search_with_name();
+ let is_in_search_widget = self.is_in_search_widget();
+ if !self.is_in_dialog() {
+ if let Some(proc_widget_state) = self
+ .proc_state
+ .widget_states
+ .get_mut(&(self.current_widget.widget_id - 1))
+ {
+ if is_in_search_widget {
+ if !proc_widget_state.is_grouped {
+ if proc_widget_state.process_search_state.is_searching_with_pid {
+ self.search_with_name();
+ } else {
+ self.search_with_pid();
+ }
+ }
} else {
- self.force_update_processes = true;
- }
- }
- WidgetPosition::ProcessSearch => {
- if !self.is_grouped() {
- if self.process_search_state.is_searching_with_pid {
+ // Toggles process widget grouping state
+ proc_widget_state.is_grouped = !(proc_widget_state.is_grouped);
+ if proc_widget_state.is_grouped {
self.search_with_name();
- } else {
- self.search_with_pid();
}
}
}
- _ => {}
}
}
- pub fn is_grouped(&self) -> bool {
- self.enable_grouping
+ /// I don't like this, but removing it causes a bunch of breakage.
+ /// Use ``proc_widget_state.is_grouped`` if possible!
+ pub fn is_grouped(&self, widget_id: u64) -> bool {
+ if let Some(proc_widget_state) = self.proc_state.widget_states.get(&widget_id) {
+ proc_widget_state.is_grouped
+ } else {
+ false
+ }
}
+ /// "On space" if we don't want to treat is as a character.
pub fn on_space(&mut self) {
- match self.current_widget_selected {
- WidgetPosition::CpuLegend => {
- let curr_posn = self
- .app_scroll_positions
- .cpu_scroll_state
- .current_scroll_position;
- if self.cpu_state.is_showing_tray
+ if let BottomWidgetType::CpuLegend = self.current_widget.widget_type {
+ if let Some(cpu_widget_state) = self
+ .cpu_state
+ .widget_states
+ .get_mut(&(self.current_widget.widget_id - 1))
+ {
+ let curr_posn = cpu_widget_state.scroll_state.current_scroll_position;
+ if cpu_widget_state.is_showing_tray
&& curr_posn < self.data_collection.cpu_harvest.len() as u64
{
- self.cpu_state.core_show_vec[curr_posn as usize] =
- !self.cpu_state.core_show_vec[curr_posn as usize];
+ cpu_widget_state.core_show_vec[curr_posn as usize] =
+ !cpu_widget_state.core_show_vec[curr_posn as usize];
if !self.app_config_fields.show_disabled_data {
- if !self.cpu_state.core_show_vec[curr_posn as usize] {
- self.cpu_state.num_cpus_shown -= 1;
+ if !cpu_widget_state.core_show_vec[c