summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorClement Tsang <34804052+ClementTsang@users.noreply.github.com>2020-02-16 19:50:34 -0500
committerGitHub <noreply@github.com>2020-02-16 19:50:34 -0500
commit683a3d3a259814e6aa9d4ce372dd990157364959 (patch)
tree947c18705f4a3c8e190eb4158c4723f79ed8e1fb /src
parent3224adf0473aae687a0fddffe4e443b46c4c6cce (diff)
parent65634f23d4af748c158151cb2ead13e861c2bc1a (diff)
Merge pull request #9 from ClementTsang/add_graph_filtering
Add graph filtering
Diffstat (limited to 'src')
-rw-r--r--src/app.rs411
-rw-r--r--src/canvas.rs154
-rw-r--r--src/canvas/canvas_colours/colour_utils.rs3
-rw-r--r--src/main.rs48
4 files changed, 431 insertions, 185 deletions
diff --git a/src/app.rs b/src/app.rs
index b2004602..c9b8bac3 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -60,62 +60,63 @@ impl Default for AppScrollState {
}
}
-/// AppSearchState only deals with the search's current settings and state.
+/// AppSearchState deals with generic searching (I might do this in the future).
pub struct AppSearchState {
+ is_enabled: bool,
current_search_query: String,
- searching_pid: bool,
- ignore_case: bool,
current_regex: std::result::Result<regex::Regex, regex::Error>,
current_cursor_position: usize,
- match_word: bool,
- use_regex: bool,
+ pub is_invalid_or_blank_search: bool,
}
impl Default for AppSearchState {
fn default() -> Self {
AppSearchState {
+ is_enabled: false,
current_search_query: String::default(),
- searching_pid: false,
- ignore_case: true,
current_regex: BASE_REGEX.clone(),
current_cursor_position: 0,
- match_word: false,
- use_regex: false,
+ is_invalid_or_blank_search: true,
}
}
}
-impl AppSearchState {
+/// ProcessSearchState only deals with process' search's current settings and state.
+pub struct ProcessSearchState {
+ pub search_state: AppSearchState,
+ pub is_searching_with_pid: bool,
+ pub is_ignoring_case: bool,
+ pub is_searching_whole_word: bool,
+ pub is_searching_with_regex: bool,
+}
+
+impl Default for ProcessSearchState {
+ fn default() -> Self {
+ ProcessSearchState {
+ search_state: AppSearchState::default(),
+ is_searching_with_pid: false,
+ is_ignoring_case: true,
+ is_searching_whole_word: false,
+ is_searching_with_regex: false,
+ }
+ }
+}
+
+impl ProcessSearchState {
pub fn toggle_ignore_case(&mut self) {
- self.ignore_case = !self.ignore_case;
+ self.is_ignoring_case = !self.is_ignoring_case;
}
pub fn toggle_search_whole_word(&mut self) {
- self.match_word = !self.match_word;
+ self.is_searching_whole_word = !self.is_searching_whole_word;
}
pub fn toggle_search_regex(&mut self) {
- self.use_regex = !self.use_regex;
+ self.is_searching_with_regex = !self.is_searching_with_regex;
}
pub fn toggle_search_with_pid(&mut self) {
- self.searching_pid = !self.searching_pid;
- }
-
- pub fn is_ignoring_case(&self) -> bool {
- self.ignore_case
- }
-
- pub fn is_searching_whole_word(&self) -> bool {
- self.match_word
- }
-
- pub fn is_searching_with_regex(&self) -> bool {
- self.use_regex
- }
-
- pub fn is_searching_with_pid(&self) -> bool {
- self.searching_pid
+ self.is_searching_with_pid = !self.is_searching_with_pid;
}
}
@@ -156,6 +157,61 @@ pub struct AppConfigFields {
pub use_current_cpu_total: bool,
}
+/// Network specific
+pub struct NetworkState {
+ pub is_showing_tray: bool,
+ pub is_showing_rx: bool,
+ pub is_showing_tx: bool,
+ pub zoom_level: f64,
+}
+
+impl Default for NetworkState {
+ fn default() -> Self {
+ NetworkState {
+ is_showing_tray: false,
+ is_showing_rx: true,
+ is_showing_tx: true,
+ zoom_level: 100.0,
+ }
+ }
+}
+
+/// CPU specific
+pub struct CpuState {
+ pub is_showing_tray: bool,
+ pub zoom_level: f64,
+ pub core_show_vec: Vec<bool>,
+}
+
+impl Default for CpuState {
+ fn default() -> Self {
+ CpuState {
+ is_showing_tray: false,
+ zoom_level: 100.0,
+ core_show_vec: Vec::new(),
+ }
+ }
+}
+
+/// Memory specific
+pub struct MemState {
+ pub is_showing_tray: bool,
+ pub is_showing_ram: bool,
+ pub is_showing_swap: bool,
+ pub zoom_level: f64,
+}
+
+impl Default for MemState {
+ fn default() -> Self {
+ MemState {
+ is_showing_tray: false,
+ is_showing_ram: true,
+ is_showing_swap: true,
+ zoom_level: 100.0,
+ }
+ }
+}
+
pub struct App {
pub process_sorting_type: processes::ProcessSorting,
pub process_sorting_reverse: bool,
@@ -171,13 +227,15 @@ pub struct App {
last_key_press: Instant,
pub canvas_data: canvas::DisplayableData,
enable_grouping: bool,
- enable_searching: bool,
pub data_collection: DataCollection,
- pub search_state: AppSearchState,
+ pub process_search_state: ProcessSearchState,
pub delete_dialog_state: AppDeleteDialogState,
pub help_dialog_state: AppHelpDialogState,
pub app_config_fields: AppConfigFields,
pub is_expanded: bool,
+ pub cpu_state: CpuState,
+ pub mem_state: MemState,
+ pub net_state: NetworkState,
}
impl App {
@@ -201,9 +259,8 @@ impl App {
last_key_press: Instant::now(),
canvas_data: canvas::DisplayableData::default(),
enable_grouping: false,
- enable_searching: false,
data_collection: DataCollection::default(),
- search_state: AppSearchState::default(),
+ process_search_state: ProcessSearchState::default(),
delete_dialog_state: AppDeleteDialogState::default(),
help_dialog_state: AppHelpDialogState::default(),
app_config_fields: AppConfigFields {
@@ -215,6 +272,9 @@ impl App {
use_current_cpu_total,
},
is_expanded: false,
+ cpu_state: CpuState::default(),
+ mem_state: MemState::default(),
+ net_state: NetworkState::default(),
}
}
@@ -222,12 +282,12 @@ impl App {
self.reset_multi_tap_keys();
self.help_dialog_state.is_showing_help = false;
self.delete_dialog_state.is_showing_dd = false;
- if self.enable_searching {
+ if self.process_search_state.search_state.is_enabled {
self.current_widget_selected = WidgetPosition::Process;
- self.enable_searching = false;
+ self.process_search_state.search_state.is_enabled = false;
}
- self.search_state.current_search_query = String::new();
- self.search_state.searching_pid = false;
+ self.process_search_state.search_state.current_search_query = String::new();
+ self.process_search_state.is_searching_with_pid = false;
self.to_delete_process_list = None;
self.dd_err = None;
}
@@ -241,14 +301,37 @@ impl App {
self.delete_dialog_state.is_on_yes = false;
self.to_delete_process_list = None;
self.dd_err = None;
- } else if self.enable_searching {
- self.current_widget_selected = WidgetPosition::Process;
- self.enable_searching = false;
+ } else if self.is_filtering_or_searching() {
+ match self.current_widget_selected {
+ 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;
+ }
+ }
+ WidgetPosition::Cpu => {
+ self.cpu_state.is_showing_tray = false;
+ }
+ WidgetPosition::Mem => {
+ self.mem_state.is_showing_tray = false;
+ }
+ WidgetPosition::Network => {
+ self.net_state.is_showing_tray = false;
+ }
+ _ => {}
+ }
} else if self.is_expanded {
self.is_expanded = false;
}
}
+ fn is_filtering_or_searching(&self) -> bool {
+ self.cpu_state.is_showing_tray
+ || self.mem_state.is_showing_tray
+ || self.net_state.is_showing_tray
+ || self.process_search_state.search_state.is_enabled
+ }
+
fn reset_multi_tap_keys(&mut self) {
self.awaiting_second_char = false;
self.second_char = None;
@@ -273,7 +356,7 @@ impl App {
WidgetPosition::Process => self.toggle_grouping(),
WidgetPosition::Disk => {}
WidgetPosition::ProcessSearch => {
- if self.search_state.is_searching_with_pid() {
+ if self.process_search_state.is_searching_with_pid {
self.search_with_name();
} else {
self.search_with_pid();
@@ -287,21 +370,48 @@ impl App {
self.enable_grouping
}
- pub fn enable_searching(&mut self) {
+ pub fn on_space(&mut self) {
+ match self.current_widget_selected {
+ WidgetPosition::Cpu => {
+ let curr_posn = self
+ .app_scroll_positions
+ .cpu_scroll_state
+ .current_scroll_position;
+ if self.cpu_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];
+ }
+ }
+ _ => {}
+ }
+ }
+
+ pub fn on_slash(&mut self) {
if !self.is_in_dialog() {
match self.current_widget_selected {
WidgetPosition::Process | WidgetPosition::ProcessSearch => {
// Toggle on
- self.enable_searching = true;
+ self.process_search_state.search_state.is_enabled = true;
self.current_widget_selected = WidgetPosition::ProcessSearch;
}
+ WidgetPosition::Cpu => {
+ self.cpu_state.is_showing_tray = true;
+ }
+ // WidgetPosition::Mem => {
+ // self.mem_state.is_showing_tray = true;
+ // }
+ // WidgetPosition::Network => {
+ // self.net_state.is_showing_tray = true;
+ // }
_ => {}
}
}
}
pub fn is_searching(&self) -> bool {
- self.enable_searching
+ self.process_search_state.search_state.is_enabled
}
pub fn is_in_search_widget(&self) -> bool {
@@ -315,7 +425,7 @@ impl App {
pub fn search_with_pid(&mut self) {
if !self.is_in_dialog() && self.is_searching() {
if let WidgetPosition::ProcessSearch = self.current_widget_selected {
- self.search_state.searching_pid = true;
+ self.process_search_state.is_searching_with_pid = true;
}
}
}
@@ -323,19 +433,19 @@ impl App {
pub fn search_with_name(&mut self) {
if !self.is_in_dialog() && self.is_searching() {
if let WidgetPosition::ProcessSearch = self.current_widget_selected {
- self.search_state.searching_pid = false;
+ self.process_search_state.is_searching_with_pid = false;
}
}
}
pub fn get_current_search_query(&self) -> &String {
- &self.search_state.current_search_query
+ &self.process_search_state.search_state.current_search_query
}
pub fn toggle_ignore_case(&mut self) {
if !self.is_in_dialog() && self.is_searching() {
if let WidgetPosition::ProcessSearch = self.current_widget_selected {
- self.search_state.toggle_ignore_case();
+ self.process_search_state.toggle_ignore_case();
self.update_regex();
self.update_process_gui = true;
}
@@ -343,24 +453,43 @@ impl App {
}
pub fn update_regex(&mut self) {
- self.search_state.current_regex = if self.search_state.current_search_query.is_empty() {
+ self.process_search_state.search_state.current_regex = if self
+ .process_search_state
+ .search_state
+ .current_search_query
+ .is_empty()
+ {
+ self.process_search_state
+ .search_state
+ .is_invalid_or_blank_search = true;
BASE_REGEX.clone()
} else {
- let mut final_regex_string = self.search_state.current_search_query.clone();
+ let mut final_regex_string = self
+ .process_search_state
+ .search_state
+ .current_search_query
+ .clone();
- if !self.search_state.is_searching_with_regex() {
+ if !self.process_search_state.is_searching_with_regex {
final_regex_string = regex::escape(&final_regex_string);
}
- if self.search_state.is_searching_whole_word() {
+ if self.process_search_state.is_searching_whole_word {
final_regex_string = format!("^{}$", final_regex_string);
}
- if self.search_state.is_ignoring_case() {
+ if self.process_search_state.is_ignoring_case {
final_regex_string = format!("(?i){}", final_regex_string);
}
regex::Regex::new(&final_regex_string)
};
+ self.process_search_state
+ .search_state
+ .is_invalid_or_blank_search = self
+ .process_search_state
+ .search_state
+ .current_regex
+ .is_err();
self.app_scroll_positions
.process_scroll_state
.previous_scroll_position = 0;
@@ -370,7 +499,9 @@ impl App {
}
pub fn get_cursor_position(&self) -> usize {
- self.search_state.current_cursor_position
+ self.process_search_state
+ .search_state
+ .current_cursor_position
}
/// One of two functions allowed to run while in a dialog...
@@ -394,18 +525,33 @@ impl App {
self.delete_dialog_state.is_showing_dd = false;
}
} else if !self.is_in_dialog() {
- // Pop-out mode.
- self.is_expanded = true;
+ // Pop-out mode. We ignore if in process search.
+ match self.current_widget_selected {
+ WidgetPosition::ProcessSearch => {}
+ _ => self.is_expanded = true,
+ }
}
}
pub fn on_backspace(&mut self) {
if let WidgetPosition::ProcessSearch = self.current_widget_selected {
- if self.search_state.current_cursor_position > 0 {
- self.search_state.current_cursor_position -= 1;
- self.search_state
+ if self
+ .process_search_state
+ .search_state
+ .current_cursor_position
+ > 0
+ {
+ self.process_search_state
+ .search_state
+ .current_cursor_position -= 1;
+ self.process_search_state
+ .search_state
.current_search_query
- .remove(self.search_state.current_cursor_position);
+ .remove(
+ self.process_search_state
+ .search_state
+ .current_cursor_position,
+ );
self.update_regex();
self.update_process_gui = true;
@@ -414,7 +560,7 @@ impl App {
}
pub fn get_current_regex_matcher(&self) -> &std::result::Result<regex::Regex, regex::Error> {
- &self.search_state.current_regex
+ &self.process_search_state.search_state.current_regex
}
pub fn on_up_key(&mut self) {
@@ -438,8 +584,15 @@ impl App {
pub fn on_left_key(&mut self) {
if !self.is_in_dialog() {
if let WidgetPosition::ProcessSearch = self.current_widget_selected {
- if self.search_state.current_cursor_position > 0 {
- self.search_state.current_cursor_position -= 1;
+ if self
+ .process_search_state
+ .search_state
+ .current_cursor_position
+ > 0
+ {
+ self.process_search_state
+ .search_state
+ .current_cursor_position -= 1;
}
}
} else if self.delete_dialog_state.is_showing_dd && !self.delete_dialog_state.is_on_yes {
@@ -450,10 +603,19 @@ impl App {
pub fn on_right_key(&mut self) {
if !self.is_in_dialog() {
if let WidgetPosition::ProcessSearch = self.current_widget_selected {
- if self.search_state.current_cursor_position
- < self.search_state.current_search_query.len()
+ if self
+ .process_search_state
+ .search_state
+ .current_cursor_position
+ < self
+ .process_search_state
+ .search_state
+ .current_search_query
+ .len()
{
- self.search_state.current_cursor_position += 1;
+ self.process_search_state
+ .search_state
+ .current_cursor_position += 1;
}
}
} else if self.delete_dialog_state.is_showing_dd && self.delete_dialog_state.is_on_yes {
@@ -464,7 +626,9 @@ impl App {
pub fn skip_cursor_beginning(&mut self) {
if !self.is_in_dialog() {
if let WidgetPosition::ProcessSearch = self.current_widget_selected {
- self.search_state.current_cursor_position = 0;
+ self.process_search_state
+ .search_state
+ .current_cursor_position = 0;
}
}
}
@@ -472,12 +636,58 @@ impl App {
pub fn skip_cursor_end(&mut self) {
if !self.is_in_dialog() {
if let WidgetPosition::ProcessSearch = self.current_widget_selected {
- self.search_state.current_cursor_position =
- self.search_state.current_search_query.len();
+ self.process_search_state
+ .search_state
+ .current_cursor_position = self
+ .process_search_state
+ .search_state
+ .current_search_query
+ .len();
}
}
}
+ pub fn start_dd(&mut self) {
+ if self
+ .app_scroll_positions
+ .process_scroll_state
+ .current_scroll_position
+ < self.canvas_data.finalized_process_data.len() as u64
+ {
+ let current_process = if self.is_grouped() {
+ let group_pids = &self.canvas_data.finalized_process_data[self
+ .app_scroll_positions
+ .process_scroll_state
+ .current_scroll_position
+ as usize]
+ .group_pids;
+
+ let mut ret = ("".to_string(), group_pids.clone());
+
+ for pid in group_pids {
+ if let Some(process) = self.canvas_data.process_data.get(&pid) {
+ ret.0 = process.name.clone();
+ break;
+ }
+ }
+ ret
+ } else {
+ let process = self.canvas_data.finalized_process_data[self
+ .app_scroll_positions
+ .process_scroll_state
+ .current_scroll_position
+ as usize]
+ .clone();
+ (process.name.clone(), vec![process.pid])
+ };
+
+ self.to_delete_process_list = Some(current_process);
+ self.delete_dialog_state.is_showing_dd = true;
+ }
+
+ self.reset_multi_tap_keys();
+ }
+
pub fn on_char_key(&mut self, caught_char: char) {
// Forbid any char key presses when showing a dialog box...
if !self.is_in_dialog() {
@@ -491,10 +701,18 @@ impl App {
self.last_key_press = current_key_press_inst;
if let WidgetPosition::ProcessSearch = self.current_widget_selected {
- self.search_state
+ self.process_search_state
+ .search_state
.current_search_query
- .insert(self.search_state.current_cursor_position, caught_char);
- self.search_state.current_cursor_position += 1;
+ .insert(
+ self.process_search_state
+ .search_state
+ .current_cursor_position,
+ caught_char,
+ );
+ self.process_search_state
+ .search_state
+ .current_cursor_position += 1;
self.update_regex();
@@ -502,7 +720,7 @@ impl App {
} else {
match caught_char {
'/' => {
- self.enable_searching();
+ self.on_slash();
}
'd' => {
if let WidgetPosition::Process = self.current_widget_selected {
@@ -513,49 +731,7 @@ impl App {
self.awaiting_second_char = false;
self.second_char = None;
- if self
- .app_scroll_positions
- .process_scroll_state
- .current_scroll_position < self
- .canvas_data
- .finalized_process_data
- .len() as u64
- {
- let current_process = if self.is_grouped() {
- let group_pids = &self
- .canvas_data
- .finalized_process_data[self
- .app_scroll_positions
- .process_scroll_state
- .current_scroll_position as usize]
- .group_pids;
-
- let mut ret = ("".to_string(), group_pids.clone());
-
- for pid in group_pids {
- if let Some(process) =
- self.canvas_data.process_data.get(&pid)
- {
- ret.0 = process.name.clone();
- break;
- }
- }
- ret
- } else {
- let process = self.canvas_data.finalized_process_data
- [self
- .app_scroll_positions
- .process_scroll_state
- .current_scroll_position as usize]
- .clone();
- (process.name.clone(), vec![process.pid])
- };
-
- self.to_delete_process_list = Some(current_process);
- self.delete_dialog_state.is_showing_dd = true;
- }
-
- self.reset_multi_tap_keys();
+ self.start_dd();
}
}
@@ -657,6 +833,7 @@ impl App {
'L' => self.move_widget_selection_right(),
'K' => self.move_widget_selection_up(),
'J' => self.move_widget_selection_down(),
+ ' ' => self.on_space(),
_ => {}
}
diff --git a/src/canvas.rs b/src/canvas.rs
index 97139f54..65108285 100644
--- a/src/canvas.rs
+++ b/src/canvas.rs
@@ -23,9 +23,10 @@ use drawing_utils::*;
// Headers
const CPU_LEGEND_HEADER: [&str; 2] = ["CPU", "Use%"];
+const CPU_SELECT_LEGEND_HEADER: [&str; 3] = ["CPU", "Use%", "Show"];
const DISK_HEADERS: [&str; 7] = ["Disk", "Mount", "Used", "Free", "Total", "R/s", "W/s"];
const TEMP_HEADERS: [&str; 2] = ["Sensor", "Temp"];
-const MEM_HEADERS: [&str; 3] = ["Mem", "Usage", "Usage%"];
+const MEM_HEADERS: [&str; 3] = ["Mem", "Usage", "Use%"];
const NETWORK_HEADERS: [&str; 4] = ["RX", "TX", "Total RX", "Total TX"];
const FORCE_MIN_THRESHOLD: usize = 5;
@@ -40,6 +41,10 @@ lazy_static! {
.iter()
.map(|entry| max(FORCE_MIN_THRESHOLD, entry.len()))
.collect::<Vec<_>>();
+ static ref CPU_SELECT_LEGEND_HEADER_LENS: Vec<usize> = CPU_SELECT_LEGEND_HEADER
+ .iter()
+ .map(|entry| max(FORCE_MIN_THRESHOLD, entry.len()))
+ .collect::<Vec<_>>();
static ref TEMP_HEADERS_LENS: Vec<usize> = TEMP_HEADERS
.iter()
.map(|entry| max(FORCE_MIN_THRESHOLD, entry.len()))
@@ -99,6 +104,7 @@ impl Painter {
/// 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.styled_general_help_text.push(Text::Styled(
GENERAL_HELP_TEXT[0].into(),
@@ -532,22 +538,11 @@ impl Painter {
let mut dataset_vector: Vec<Dataset> = Vec::new();
let mut cpu_entries_vec: Vec<(Style, Vec<(f64, f64)>)> = Vec::new();
- for (i, cpu) in cpu_data.iter().enumerate() {
- cpu_entries_vec.push((
- self.colours.cpu_colour_styles[(i) % self.colours.cpu_colour_styles.len()],
- cpu.cpu_data
- .iter()
- .map(<(f64, f64)>::from)
- .collect::<Vec<_>>(),
- ));
- }
-
- if app_state.app_config_fields.show_average_cpu {
- if let Some(avg_cpu_entry) = cpu_data.first() {
+ for (itx, cpu) in cpu_data.iter().enumerate() {
+ if app_state.cpu_state.core_show_vec[itx] {
cpu_entries_vec.push((
- self.colours.cpu_colour_styles[0],
- avg_cpu_entry
- .cpu_data
+ self.colours.cpu_colour_styles[(itx) % self.colours.cpu_colour_styles.len()],
+ cpu.cpu_data
.iter()
.map(<(f64, f64)>::from)
.collect::<Vec<_>>(),
@@ -568,7 +563,7 @@ impl Painter {
);
}
- let title = if app_state.is_expanded {
+ let title = if app_state.is_expanded && !app_state.cpu_state.is_showing_tray {
const TITLE_BASE: &str = " CPU ── Esc to go back ";
let repeat_num = max(
0,
@@ -625,44 +620,58 @@ impl Painter {
let sliced_cpu_data = &cpu_data[start_position as usize..];
let mut stringified_cpu_data: Vec<Vec<String>> = Vec::new();
- for cpu in sliced_cpu_data {
+ for (itx, cpu) in sliced_cpu_data.iter().enumerate() {
if let Some(cpu_data) = cpu.cpu_data.last() {
- stringified_cpu_data.push(vec![
+ let mut entry = vec![
cpu.cpu_name.clone(),
format!("{:.0}%", cpu_data.usage.round()),
- ]);
+ ];
+
+ if app_state.cpu_state.is_showing_tray {
+ entry.push(
+ if app_state.cpu_state.core_show_vec[itx + start_position as usize] {
+ "[*]".to_string()
+ } else {
+ "[ ]".to_string()
+ },
+ )
+ }
+
+ stringified_cpu_data.push(entry);
}
}
- let mut cpu_row_counter: i64 = 0;
-
let cpu_rows = stringified_cpu_data
.iter()
.enumerate()
+ .filter(|(itx, _)| {
+ if app_state.cpu_state.is_showing_tray {
+ true
+ } else {
+ app_state.cpu_state.core_show_vec[*itx]
+ }
+ })
.map(|(itx, cpu_string_row)| {
Row::StyledData(
cpu_string_row.iter(),
match app_state.current_widget_selected {
app::WidgetPosition::Cpu => {
- if cpu_row_counter as u64
+ if itx as u64
== app_state
.app_scroll_positions
.cpu_scroll_state
.current_scroll_position - start_position
{
- cpu_row_counter = -1;
self.colours.currently_selected_text_style
} else {
- if cpu_row_counter >= 0 {
- cpu_row_counter += 1;
- }
- self.colours.cpu_colour_styles
- [itx % self.colours.cpu_colour_styles.len()]
+ self.colours.cpu_colour_styles[itx
+ + start_position as usize
+ % self.colours.cpu_colour_styles.len()]
}
}
_ => {
- self.colours.cpu_colour_styles
- [itx % self.colours.cpu_colour_styles.len()]
+ self.colours.cpu_colour_styles[itx
+ + start_position as usize % self.colours.cpu_colour_styles.len()]
}
},
)
@@ -670,27 +679,70 @@ impl Painter {
// Calculate widths
let width = f64::from(draw_loc.width);
- let width_ratios = vec![0.5, 0.5];
- let variable_intrinsic_results =
- get_variable_intrinsic_widths(width as u16, &width_ratios, &CPU_LEGEND_HEADER_LENS);
+ let width_ratios = if app_state.cpu_state.is_showing_tray {
+ vec![0.4, 0.3, 0.3]
+ } else {
+ vec![0.5, 0.5]
+ };
+ let variable_intrinsic_results = get_variable_intrinsic_widths(
+ width as u16,
+ &width_ratios,
+ if app_state.cpu_state.is_showing_tray {
+ &CPU_SELECT_LEGEND_HEADER_LENS
+ } else {
+ &CPU_LEGEND_HEADER_LENS
+ },
+ );
let intrinsic_widths = &(variable_intrinsic_results.0)[0..variable_intrinsic_results.1];
+ let title = if app_state.cpu_state.is_showing_tray {
+ const TITLE_BASE: &str = " Esc to go close ";
+ let repeat_num = max(
+ 0,
+ draw_loc.width as i32 - TITLE_BASE.chars().count() as i32 - 2,
+ );
+ let result_title = format!("{} Esc to go close ", "─".repeat(repeat_num as usize));
+
+ result_title
+ } else {
+ "".to_string()
+ };
+
// Draw
- Table::new(CPU_LEGEND_HEADER.iter(), cpu_rows)
- .block(Block::default().borders(Borders::ALL).border_style(
- match app_state.current_widget_selected {
+ Table::new(
+ if app_state.cpu_state.is_showing_tray {
+ CPU_SELECT_LEGEND_HEADER.to_vec()
+ } else {
+ CPU_LEGEND_HEADER.to_vec()
+ }
+ .iter(),
+ cpu_rows,
+ )
+ .block(
+ Block::default()
+ .title(&title)
+ .title_style(if app_state.is_expanded {
+ self.colours.highlighted_border_style
+ } else {
+ match app_state.current_widget_selected {
+ app::WidgetPosition::Cpu => self.colours.highlighted_border_style,
+ _ => self.colours.border_style,
+ }
+ })
+ .borders(Borders::ALL)
+ .border_style(match app_state.current_widget_selected {
app::WidgetPosition::Cpu => self.colours.highlighted_border_style,
_ => self.colours.border_style,
- },
- ))
- .header_style(self.colours.table_header_style)
- .widths(
- &(intrinsic_widths
- .iter()
- .map(|calculated_width| Constraint::Length(*calculated_width as u16))
- .collect::<Vec<_>>()),
- )
- .render(f, draw_loc);
+ }),
+ )
+ .header_style(self.colours.table_header_style)
+ .widths(
+ &(intrinsic_widths
+ .iter()
+ .map(|calculated_width| Constraint::Length(*calculated_width as u16))
+ .collect::<Vec<_>>()),
+ )
+ .render(f, draw_loc);
}
fn draw_memory_graph<B: backend::Backend>(
@@ -1144,7 +1196,7 @@ impl Painter {
)]
};
- let mut search_text = vec![if app_state.search_state.is_searching_with_pid() {
+ let mut search_text = vec![if app_state.process_search_state.is_searching_with_pid {
Text::styled(
"Search by PID (Tab for Name): ",
self.colours.table_header_style,
@@ -1164,21 +1216,21 @@ impl Painter {
let option_row = vec![
Text::styled("Match Case (Alt+C)", self.colours.table_header_style),
- if !app_state.search_state.is_ignoring_case() {
+ if !app_state.process_search_state.is_ignoring_case {
Text::styled("[*]", self.colours.table_header_style)
} else {
Text::styled("[ ]", self.colours.table_header_style)
},
Text::styled(" ", self.colours.table_header_style),
Text::styled("Match Whole Word (Alt+W)", self.colours.table_header_style),
- if app_state.search_state.is_searching_whole_word() {
+ if app_state.process_search_state.is_searching_whole_word {
Text::styled("[*]", self.colours.table_header_style)
} else {
Text::styled("[ ]", self.colours.table_header_style)
},
Text::styled(" ", self.colours.table_header_style),
Text::styled("Use Regex (Alt+R)", self.colours.table_header_style),
- if app_state.search_state.is_searching_with_regex() {
+ if app_state.process_search_state.is_searching_with_regex {
Text::styled("[*]", self.colours.table_header_style)
} else {
Text::styled("[ ]", self.colours.table_header_style)
diff --git a/src/canvas/canvas_colours/colour_utils.rs b/src/canvas/canvas_colours/colour_utils.rs
index e54c99e9..b02e0fff 100644
--- a/src/canvas/canvas_colours/colour_utils.rs
+++ b/src/canvas/canvas_colours/colour_utils.rs
@@ -37,11 +37,10 @@ pub fn gen_n_styles(num_to_gen: i32) -> Vec<Style> {
Style::default().fg(Color::LightMagenta),
Style::default().fg(Color::LightCyan),
Style::default().fg(Color::Green),
- Style::default().fg(Color::Red),
];
let mut h: f32 = 0.4; // We don't need random colours... right?
- for _i in 0..(num_to_gen - 6) {
+ for _i in 0..(num_to_gen - 5) {
h = gen_hsv(h);
let result = hsv_to_rgb(h, 0.5, 0.95);
colour_vec.push(Style::default().fg(Color::Rgb(result.0, result.1, result.2)));
diff --git a/src/main.rs b/src/main.rs
index 9a321178..5c6fd2d4 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -254,6 +254,13 @@ fn main() -> error::Result<()> {
&app.data_collection,
);
+ // Pre-fill CPU if needed
+ for itx in 0..app.canvas_data.cpu_data.len() {
+ if app.cpu_state.core_show_vec.len() <= itx {
+ app.cpu_state.core_show_vec.push(true);
+ }
+ }
+
// Processes
let (single, grouped) = convert_process_data(&app.data_collection);
app.canvas_data.process_data = single;
@@ -295,8 +302,6 @@ fn handle_key_event_or_break(
event: KeyEvent, app: &mut app::App, rtx: &std::sync::mpsc::Sender<ResetEvent>,
) -> bool {
if event.modifiers.is_empty() {
- // If only a code, and no modifiers, don't bother...
-
// Required catch for searching - otherwise you couldn't search with q.
if event.code == KeyCode::Char('q') && !app.is_in_search_widget() {
return true;
@@ -314,6 +319,7 @@ fn handle_key_event_or_break(
KeyCode::Enter => app.on_enter(),
KeyCode::Tab => app.on_tab(),
KeyCode::Backspace => app.on_backspace(),
+ KeyCode::Delete => app.start_dd(),
_ => {}
}
} else {
@@ -324,7 +330,7 @@ fn handle_key_event_or_break(
}
match event.code {
- KeyCode::Char('f') => app.enable_searching(),
+ KeyCode::Char('f') => app.on_slash(),
KeyCode::Left => app.move_widget_selection_left(),
KeyCode::Right => app.move_widget_selection_right(),
KeyCode::Up => app.move_widget_selection_up(),
@@ -355,19 +361,19 @@ fn handle_key_event_or_break(
match event.code {
KeyCode::Char('c') => {
if app.is_in_search_widget() {
- app.search_state.toggle_ignore_case();
+ app.process_search_state.toggle_ignore_case();
app.update_regex();
}
}
KeyCode::Char('w') => {
if app.is_in_search_widget() {
- app.search_state.toggle_search_whole_word();
+ app.process_search_state.toggle_search_whole_word();
app.update_regex();
}
}
KeyCode::Char('r') => {
if app.is_in_search_widget() {
- app.search_state.toggle_search_regex();
+ app.process_search_state.toggle_search_regex();
app.update_regex();
}
}
@@ -526,11 +532,11 @@ fn enable_app_case_sensitive(
matches: &clap::ArgMatches<'static>, config: &Config, app: &mut app::App,
) {
if matches.is_present("CASE_SENSITIVE") {
- app.search_state.toggle_ignore_case();
+ app.process_search_state.toggle_ignore_case();
} else if let Some(flags) = &config.flags {
if let Some(case_sensitive) = flags.case_sensitive {
if case_sensitive {
- app.search_state.toggle_ignore_case();
+ app.process_search_state.toggle_ignore_case();
}
}
}
@@ -540,11 +546,11 @@ fn enable_app_match_whole_word(
matches: &clap::ArgMatches<'static>, config: &Config, app: &mut app::App,
) {
if matches.is_present("WHOLE_WORD") {
- app.search_state.toggle_search_whole_word();
+ app.process_search_state.toggle_search_whole_word();
} else if let Some(flags) = &config.flags {
if let Some(whole_word) = flags.whole_word {
if whole_word {
- app.search_state.toggle_search_whole_word();
+ app.process_search_state.toggle_search_whole_word();
}
}
}
@@ -552,11 +558,11 @@ fn enable_app_match_whole_word(
fn enable_app_use_regex(matches: &clap::ArgMatches<'static>, config: &Config, app: &mut app::App) {
if matches.is_present("REGEX_DEFAULT") {
- app.search_state.toggle_search_regex();
+ app.process_search_state.toggle_search_regex();
} else if let Some(flags) = &config.flags {
if let Some(regex) = flags.regex {
if regex {
- app.search_state.toggle_search_regex();
+ app.process_search_state.toggle_search_regex();
}
}