2020-04-02 00:31:43 +00:00
|
|
|
use std::{cmp::max, collections::HashMap, time::Instant};
|
2019-12-16 07:21:44 +00:00
|
|
|
|
2020-02-29 03:24:24 +00:00
|
|
|
use unicode_segmentation::GraphemeCursor;
|
|
|
|
use unicode_width::{UnicodeWidthChar, UnicodeWidthStr};
|
|
|
|
|
2020-03-13 05:07:24 +00:00
|
|
|
use typed_builder::*;
|
|
|
|
|
2020-01-29 02:24:52 +00:00
|
|
|
use data_farmer::*;
|
2020-02-29 03:24:24 +00:00
|
|
|
use data_harvester::{processes, temperature};
|
2020-04-02 00:31:43 +00:00
|
|
|
use layout_manager::*;
|
2020-01-25 21:36:14 +00:00
|
|
|
|
2020-04-02 00:31:43 +00:00
|
|
|
use crate::{
|
|
|
|
canvas, constants,
|
|
|
|
utils::error::{BottomError, Result},
|
|
|
|
};
|
2019-09-16 23:05:44 +00:00
|
|
|
|
2020-02-29 03:24:24 +00:00
|
|
|
pub mod data_farmer;
|
2020-02-29 03:27:35 +00:00
|
|
|
pub mod data_harvester;
|
2020-04-02 00:31:43 +00:00
|
|
|
pub mod layout_manager;
|
2020-02-29 03:24:24 +00:00
|
|
|
mod process_killer;
|
2020-02-27 21:02:53 +00:00
|
|
|
|
|
|
|
const MAX_SEARCH_LENGTH: usize = 200;
|
|
|
|
|
2020-01-11 05:42:03 +00:00
|
|
|
#[derive(Debug)]
|
2019-09-16 20:18:42 +00:00
|
|
|
pub enum ScrollDirection {
|
2020-02-29 22:05:01 +00:00
|
|
|
// UP means scrolling up --- this usually DECREMENTS
|
|
|
|
UP,
|
|
|
|
// DOWN means scrolling down --- this usually INCREMENTS
|
|
|
|
DOWN,
|
2019-09-16 20:18:42 +00:00
|
|
|
}
|
|
|
|
|
2020-04-02 00:31:43 +00:00
|
|
|
impl Default for ScrollDirection {
|
|
|
|
fn default() -> Self {
|
|
|
|
ScrollDirection::DOWN
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-27 22:15:09 +00:00
|
|
|
#[derive(Debug)]
|
2020-02-28 04:39:05 +00:00
|
|
|
pub enum CursorDirection {
|
2020-02-29 22:05:01 +00:00
|
|
|
LEFT,
|
|
|
|
RIGHT,
|
2020-02-27 22:15:09 +00:00
|
|
|
}
|
|
|
|
|
2020-01-25 21:36:14 +00:00
|
|
|
/// AppScrollWidgetState deals with fields for a scrollable app's current state.
|
2020-02-12 02:16:43 +00:00
|
|
|
#[derive(Default)]
|
2020-01-25 21:36:14 +00:00
|
|
|
pub struct AppScrollWidgetState {
|
2020-02-29 22:05:01 +00:00
|
|
|
pub current_scroll_position: u64,
|
|
|
|
pub previous_scroll_position: u64,
|
2020-04-02 00:31:43 +00:00
|
|
|
pub scroll_direction: ScrollDirection,
|
2020-02-12 02:16:43 +00:00
|
|
|
}
|
|
|
|
|
2020-04-02 00:31:43 +00:00
|
|
|
#[derive(Default)]
|
|
|
|
pub struct AppDeleteDialogState {
|
|
|
|
pub is_showing_dd: bool,
|
|
|
|
pub is_on_yes: bool, // Defaults to "No"
|
|
|
|
}
|
|
|
|
|
|
|
|
pub enum AppHelpCategory {
|
|
|
|
General,
|
|
|
|
Process,
|
|
|
|
Search,
|
2020-02-12 02:16:43 +00:00
|
|
|
}
|
|
|
|
|
2020-04-02 00:31:43 +00:00
|
|
|
pub struct AppHelpDialogState {
|
|
|
|
pub is_showing_help: bool,
|
|
|
|
pub current_category: AppHelpCategory,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Default for AppHelpDialogState {
|
2020-02-29 22:05:01 +00:00
|
|
|
fn default() -> Self {
|
2020-04-02 00:31:43 +00:00
|
|
|
AppHelpDialogState {
|
|
|
|
is_showing_help: false,
|
|
|
|
current_category: AppHelpCategory::General,
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
|
|
|
}
|
2020-01-25 21:36:14 +00:00
|
|
|
}
|
|
|
|
|
2020-04-02 00:31:43 +00:00
|
|
|
/// 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,
|
2020-04-18 23:50:31 +00:00
|
|
|
pub use_old_network_legend: bool,
|
2020-04-19 21:45:32 +00:00
|
|
|
pub table_gap: u16
|
2020-04-02 00:31:43 +00:00
|
|
|
}
|
|
|
|
|
2020-02-16 20:25:52 +00:00
|
|
|
/// AppSearchState deals with generic searching (I might do this in the future).
|
2020-02-16 01:25:32 +00:00
|
|
|
pub struct AppSearchState {
|
2020-02-29 22:05:01 +00:00
|
|
|
pub is_enabled: bool,
|
2020-03-13 05:07:24 +00:00
|
|
|
pub current_search_query: String,
|
|
|
|
pub current_regex: Option<std::result::Result<regex::Regex, regex::Error>>,
|
2020-02-29 22:05:01 +00:00
|
|
|
pub is_blank_search: bool,
|
|
|
|
pub is_invalid_search: bool,
|
|
|
|
pub grapheme_cursor: GraphemeCursor,
|
|
|
|
pub cursor_direction: CursorDirection,
|
|
|
|
pub cursor_bar: usize,
|
|
|
|
/// This represents the position in terms of CHARACTERS, not graphemes
|
|
|
|
pub char_cursor_position: usize,
|
2020-02-16 01:25:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Default for AppSearchState {
|
2020-02-29 22:05:01 +00:00
|
|
|
fn default() -> Self {
|
|
|
|
AppSearchState {
|
|
|
|
is_enabled: false,
|
|
|
|
current_search_query: String::default(),
|
|
|
|
current_regex: None,
|
|
|
|
is_invalid_search: false,
|
|
|
|
is_blank_search: true,
|
|
|
|
grapheme_cursor: GraphemeCursor::new(0, 0, true),
|
|
|
|
cursor_direction: CursorDirection::RIGHT,
|
|
|
|
cursor_bar: 0,
|
|
|
|
char_cursor_position: 0,
|
|
|
|
}
|
|
|
|
}
|
2020-02-16 01:25:32 +00:00
|
|
|
}
|
|
|
|
|
2020-02-17 22:42:51 +00:00
|
|
|
impl AppSearchState {
|
2020-02-29 22:05:01 +00:00
|
|
|
/// Returns a reset but still enabled app search state
|
2020-03-13 05:07:24 +00:00
|
|
|
pub fn reset(&mut self) {
|
|
|
|
*self = AppSearchState {
|
|
|
|
is_enabled: self.is_enabled,
|
|
|
|
..AppSearchState::default()
|
|
|
|
}
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn is_invalid_or_blank_search(&self) -> bool {
|
|
|
|
self.is_blank_search || self.is_invalid_search
|
|
|
|
}
|
2020-02-17 22:42:51 +00:00
|
|
|
}
|
|
|
|
|
2020-02-16 01:25:32 +00:00
|
|
|
/// ProcessSearchState only deals with process' search's current settings and state.
|
|
|
|
pub struct ProcessSearchState {
|
2020-02-29 22:05:01 +00:00
|
|
|
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,
|
2020-02-03 04:15:24 +00:00
|
|
|
}
|
|
|
|
|
2020-02-16 01:16:05 +00:00
|
|
|
impl Default for ProcessSearchState {
|
2020-02-29 22:05:01 +00:00
|
|
|
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,
|
|
|
|
}
|
|
|
|
}
|
2020-02-03 04:15:24 +00:00
|
|
|
}
|
|
|
|
|
2020-02-16 01:16:05 +00:00
|
|
|
impl ProcessSearchState {
|
2020-02-29 22:05:01 +00:00
|
|
|
pub fn search_toggle_ignore_case(&mut self) {
|
|
|
|
self.is_ignoring_case = !self.is_ignoring_case;
|
|
|
|
}
|
2020-02-03 04:15:24 +00:00
|
|
|
|
2020-02-29 22:05:01 +00:00
|
|
|
pub fn search_toggle_whole_word(&mut self) {
|
|
|
|
self.is_searching_whole_word = !self.is_searching_whole_word;
|
|
|
|
}
|
2020-02-03 04:15:24 +00:00
|
|
|
|
2020-02-29 22:05:01 +00:00
|
|
|
pub fn search_toggle_regex(&mut self) {
|
|
|
|
self.is_searching_with_regex = !self.is_searching_with_regex;
|
|
|
|
}
|
2020-02-03 04:15:24 +00:00
|
|
|
}
|
2020-01-25 21:36:14 +00:00
|
|
|
|
2020-04-02 00:31:43 +00:00
|
|
|
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,
|
2020-02-09 22:11:57 +00:00
|
|
|
}
|
|
|
|
|
2020-04-02 00:31:43 +00:00
|
|
|
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();
|
|
|
|
}
|
2020-02-10 00:16:30 +00:00
|
|
|
|
2020-04-02 00:31:43 +00:00
|
|
|
ProcWidgetState {
|
|
|
|
process_search_state,
|
|
|
|
is_grouped,
|
|
|
|
scroll_state: AppScrollWidgetState::default(),
|
|
|
|
process_sorting_type: processes::ProcessSorting::CPU,
|
|
|
|
process_sorting_reverse: true,
|
|
|
|
}
|
|
|
|
}
|
2020-02-10 00:16:30 +00:00
|
|
|
|
2020-04-02 00:31:43 +00:00
|
|
|
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);
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
2020-04-02 00:31:43 +00:00
|
|
|
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();
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
2020-02-09 22:11:57 +00:00
|
|
|
}
|
|
|
|
|
2020-04-02 00:31:43 +00:00
|
|
|
pub struct ProcState {
|
|
|
|
pub widget_states: HashMap<u64, ProcWidgetState>,
|
|
|
|
pub force_update: Option<u64>,
|
|
|
|
pub force_update_all: bool,
|
2020-02-12 02:16:43 +00:00
|
|
|
}
|
|
|
|
|
2020-04-02 00:31:43 +00:00
|
|
|
impl ProcState {
|
|
|
|
pub fn init(widget_states: HashMap<u64, ProcWidgetState>) -> Self {
|
|
|
|
ProcState {
|
|
|
|
widget_states,
|
|
|
|
force_update: None,
|
|
|
|
force_update_all: false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct NetWidgetState {
|
2020-03-13 05:07:24 +00:00
|
|
|
pub current_display_time: u64,
|
|
|
|
pub autohide_timer: Option<Instant>,
|
2020-02-16 20:25:52 +00:00
|
|
|
}
|
|
|
|
|
2020-04-02 00:31:43 +00:00
|
|
|
impl NetWidgetState {
|
2020-03-13 05:07:24 +00:00
|
|
|
pub fn init(current_display_time: u64, autohide_timer: Option<Instant>) -> Self {
|
2020-04-02 00:31:43 +00:00
|
|
|
NetWidgetState {
|
2020-03-13 05:07:24 +00:00
|
|
|
current_display_time,
|
|
|
|
autohide_timer,
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
|
|
|
}
|
2020-02-16 20:25:52 +00:00
|
|
|
}
|
|
|
|
|
2020-04-02 00:31:43 +00:00
|
|
|
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,
|
2020-02-29 22:05:01 +00:00
|
|
|
pub is_showing_tray: bool,
|
|
|
|
pub core_show_vec: Vec<bool>,
|
2020-04-02 00:31:43 +00:00
|
|
|
pub num_cpus_shown: usize,
|
2020-03-13 05:07:24 +00:00
|
|
|
pub autohide_timer: Option<Instant>,
|
2020-04-02 00:31:43 +00:00
|
|
|
pub scroll_state: AppScrollWidgetState,
|
2020-02-16 20:25:52 +00:00
|
|
|
}
|
|
|
|
|
2020-04-02 00:31:43 +00:00
|
|
|
impl CpuWidgetState {
|
2020-03-13 05:07:24 +00:00
|
|
|
pub fn init(current_display_time: u64, autohide_timer: Option<Instant>) -> Self {
|
2020-04-02 00:31:43 +00:00
|
|
|
CpuWidgetState {
|
|
|
|
current_display_time,
|
|
|
|
is_legend_hidden: false,
|
2020-02-29 22:05:01 +00:00
|
|
|
is_showing_tray: false,
|
|
|
|
core_show_vec: Vec::new(),
|
2020-03-11 01:36:13 +00:00
|
|
|
num_cpus_shown: 0,
|
2020-03-13 05:07:24 +00:00
|
|
|
autohide_timer,
|
2020-04-02 00:31:43 +00:00
|
|
|
scroll_state: AppScrollWidgetState::default(),
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
|
|
|
}
|
2020-02-16 20:25:52 +00:00
|
|
|
}
|
|
|
|
|
2020-04-02 00:31:43 +00:00
|
|
|
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 {
|
2020-03-13 05:07:24 +00:00
|
|
|
pub current_display_time: u64,
|
|
|
|
pub autohide_timer: Option<Instant>,
|
2020-02-16 20:25:52 +00:00
|
|
|
}
|
|
|
|
|
2020-04-02 00:31:43 +00:00
|
|
|
impl MemWidgetState {
|
2020-03-13 05:07:24 +00:00
|
|
|
pub fn init(current_display_time: u64, autohide_timer: Option<Instant>) -> Self {
|
2020-04-02 00:31:43 +00:00
|
|
|
MemWidgetState {
|
2020-03-13 05:07:24 +00:00
|
|
|
current_display_time,
|
|
|
|
autohide_timer,
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
|
|
|
}
|
2020-02-16 20:25:52 +00:00
|
|
|
}
|
|
|
|
|
2020-04-02 00:31:43 +00:00
|
|
|
pub struct MemState {
|
|
|
|
pub force_update: Option<u64>,
|
|
|
|
pub widget_states: HashMap<u64, MemWidgetState>,
|
|
|
|
}
|
2020-03-13 05:07:24 +00:00
|
|
|
|
2020-04-02 00:31:43 +00:00
|
|
|
impl MemState {
|
|
|
|
pub fn init(widget_states: HashMap<u64, MemWidgetState>) -> Self {
|
|
|
|
MemState {
|
|
|
|
force_update: None,
|
|
|
|
widget_states,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-03-13 05:07:24 +00:00
|
|
|
|
2020-04-02 00:31:43 +00:00
|
|
|
pub struct TempWidgetState {
|
|
|
|
pub scroll_state: AppScrollWidgetState,
|
|
|
|
}
|
2020-03-13 05:07:24 +00:00
|
|
|
|
2020-04-02 00:31:43 +00:00
|
|
|
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,
|
|
|
|
}
|
|
|
|
|
2020-04-17 00:06:50 +00:00
|
|
|
#[derive(Default)]
|
|
|
|
pub struct BatteryWidgetState {
|
|
|
|
pub currently_selected_battery_index: usize,
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct BatteryState {
|
|
|
|
pub widget_states: HashMap<u64, BatteryWidgetState>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl BatteryState {
|
|
|
|
pub fn init(widget_states: HashMap<u64, BatteryWidgetState>) -> Self {
|
|
|
|
BatteryState { widget_states }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-02 00:31:43 +00:00
|
|
|
#[derive(TypedBuilder)]
|
|
|
|
pub struct App {
|
2020-03-13 05:07:24 +00:00
|
|
|
#[builder(default = false, setter(skip))]
|
2020-02-29 22:05:01 +00:00
|
|
|
awaiting_second_char: bool,
|
2020-03-13 05:07:24 +00:00
|
|
|
|
|
|
|
#[builder(default, setter(skip))]
|
2020-02-29 22:05:01 +00:00
|
|
|
second_char: Option<char>,
|
2020-03-13 05:07:24 +00:00
|
|
|
|
|
|
|
#[builder(default, setter(skip))]
|
2020-02-29 22:05:01 +00:00
|
|
|
pub dd_err: Option<String>,
|
2020-03-13 05:07:24 +00:00
|
|
|
|
|
|
|
#[builder(default, setter(skip))]
|
2020-02-29 22:05:01 +00:00
|
|
|
to_delete_process_list: Option<(String, Vec<u32>)>,
|
2020-03-13 05:07:24 +00:00
|
|
|
|
|
|
|
#[builder(default = false, setter(skip))]
|
2020-02-29 22:05:01 +00:00
|
|
|
pub is_frozen: bool,
|
2020-03-13 05:07:24 +00:00
|
|
|
|
|
|
|
#[builder(default = Instant::now(), setter(skip))]
|
2020-02-29 22:05:01 +00:00
|
|
|
last_key_press: Instant,
|
2020-03-13 05:07:24 +00:00
|
|
|
|
|
|
|
#[builder(default, setter(skip))]
|
2020-02-29 22:05:01 +00:00
|
|
|
pub canvas_data: canvas::DisplayableData,
|
2020-03-13 05:07:24 +00:00
|
|
|
|
|
|
|
#[builder(default, setter(skip))]
|
2020-02-29 22:05:01 +00:00
|
|
|
pub data_collection: DataCollection,
|
2020-03-13 05:07:24 +00:00
|
|
|
|
|
|
|
#[builder(default, setter(skip))]
|
2020-02-29 22:05:01 +00:00
|
|
|
pub delete_dialog_state: AppDeleteDialogState,
|
2020-03-13 05:07:24 +00:00
|
|
|
|
|
|
|
#[builder(default, setter(skip))]
|
2020-02-29 22:05:01 +00:00
|
|
|
pub help_dialog_state: AppHelpDialogState,
|
2020-03-13 05:07:24 +00:00
|
|
|
|
|
|
|
#[builder(default = false, setter(skip))]
|
2020-02-29 22:05:01 +00:00
|
|
|
pub is_expanded: bool,
|
2020-03-13 05:07:24 +00:00
|
|
|
|
|
|
|
#[builder(default = false, setter(skip))]
|
2020-02-29 22:05:01 +00:00
|
|
|
pub is_resized: bool,
|
2020-03-13 05:07:24 +00:00
|
|
|
|
2020-02-29 22:05:01 +00:00
|
|
|
pub cpu_state: CpuState,
|
|
|
|
pub mem_state: MemState,
|
2020-03-09 04:52:29 +00:00
|
|
|
pub net_state: NetState,
|
2020-04-02 00:31:43 +00:00
|
|
|
pub proc_state: ProcState,
|
|
|
|
pub temp_state: TempState,
|
|
|
|
pub disk_state: DiskState,
|
2020-04-17 00:06:50 +00:00
|
|
|
pub battery_state: BatteryState,
|
2020-04-02 00:31:43 +00:00
|
|
|
|
|
|
|
pub basic_table_widget_state: Option<BasicTableWidgetState>,
|
2020-03-13 05:07:24 +00:00
|
|
|
|
|
|
|
pub app_config_fields: AppConfigFields,
|
2020-04-02 00:31:43 +00:00
|
|
|
pub widget_map: HashMap<u64, BottomWidget>,
|
|
|
|
pub current_widget: BottomWidget,
|
2020-04-04 22:29:32 +00:00
|
|
|
pub used_widgets: UsedWidgets,
|
2019-09-08 23:56:23 +00:00
|
|
|
}
|
|
|
|
|
2019-09-14 20:46:14 +00:00
|
|
|
impl App {
|
2020-02-29 22:05:01 +00:00
|
|
|
pub fn reset(&mut self) {
|
2020-03-13 05:07:24 +00:00
|
|
|
// Reset multi
|
2020-02-29 22:05:01 +00:00
|
|
|
self.reset_multi_tap_keys();
|
2020-03-13 05:07:24 +00:00
|
|
|
|
|
|
|
// Reset dialog state
|
2020-02-29 22:05:01 +00:00
|
|
|
self.help_dialog_state.is_showing_help = false;
|
|
|
|
self.delete_dialog_state.is_showing_dd = false;
|
2020-03-13 05:07:24 +00:00
|
|
|
|
2020-04-02 00:31:43 +00:00
|
|
|
// 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();
|
|
|
|
});
|
2020-03-13 05:07:24 +00:00
|
|
|
|
|
|
|
// Clear current delete list
|
2020-02-29 22:05:01 +00:00
|
|
|
self.to_delete_process_list = None;
|
|
|
|
self.dd_err = None;
|
2020-03-13 05:07:24 +00:00
|
|
|
|
|
|
|
// Unfreeze.
|
|
|
|
self.is_frozen = false;
|
|
|
|
|
|
|
|
// Reset zoom
|
|
|
|
self.reset_cpu_zoom();
|
|
|
|
self.reset_mem_zoom();
|
|
|
|
self.reset_net_zoom();
|
|
|
|
|
|
|
|
// Reset data
|
|
|
|
self.data_collection.reset();
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn on_esc(&mut self) {
|
|
|
|
self.reset_multi_tap_keys();
|
|
|
|
if self.is_in_dialog() {
|
|
|
|
self.help_dialog_state.is_showing_help = false;
|
|
|
|
self.help_dialog_state.current_category = AppHelpCategory::General;
|
|
|
|
self.delete_dialog_state.is_showing_dd = false;
|
|
|
|
self.delete_dialog_state.is_on_yes = false;
|
|
|
|
self.to_delete_process_list = None;
|
|
|
|
self.dd_err = None;
|
|
|
|
} else if self.is_filtering_or_searching() {
|
2020-04-02 00:31:43 +00:00
|
|
|
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)
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
2020-04-07 03:04:04 +00:00
|
|
|
self.is_resized = true;
|
2020-04-02 00:31:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
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;
|
|
|
|
}
|
2020-04-07 03:04:04 +00:00
|
|
|
self.is_resized = true;
|
2020-04-02 00:31:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
BottomWidgetType::Proc => {
|
|
|
|
if let Some(current_proc_state) = self
|
|
|
|
.proc_state
|
|
|
|
.widget_states
|
|
|
|
.get_mut(&self.current_widget.widget_id)
|
2020-03-11 01:36:13 +00:00
|
|
|
{
|
2020-04-02 00:31:43 +00:00
|
|
|
if current_proc_state.is_search_enabled() {
|
|
|
|
current_proc_state
|
|
|
|
.process_search_state
|
|
|
|
.search_state
|
|
|
|
.is_enabled = false;
|
|
|
|
}
|
2020-04-07 03:04:04 +00:00
|
|
|
self.is_resized = true;
|
2020-03-11 01:36:13 +00:00
|
|
|
}
|
2020-03-04 23:16:19 +00:00
|
|
|
}
|
2020-04-02 00:31:43 +00:00
|
|
|
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();
|
|
|
|
}
|
2020-04-07 03:04:04 +00:00
|
|
|
self.is_resized = true;
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
|
|
|
}
|
2020-04-02 00:31:43 +00:00
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
} else if self.is_expanded {
|
|
|
|
self.is_expanded = false;
|
|
|
|
self.is_resized = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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.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
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
2020-04-02 00:31:43 +00:00
|
|
|
}
|
|
|
|
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
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
|
|
|
}
|
2020-04-02 00:31:43 +00:00
|
|
|
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
|
2020-03-08 20:17:28 +00:00
|
|
|
}
|
|
|
|
}
|
2020-04-02 00:31:43 +00:00
|
|
|
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
|
|
|
|
}
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
|
|
|
_ => false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn reset_multi_tap_keys(&mut self) {
|
|
|
|
self.awaiting_second_char = false;
|
|
|
|
self.second_char = None;
|
|
|
|
}
|
|
|
|
|
|
|
|
fn is_in_dialog(&self) -> bool {
|
|
|
|
self.help_dialog_state.is_showing_help || self.delete_dialog_state.is_showing_dd
|
|
|
|
}
|
|
|
|
|
2020-04-02 00:31:43 +00:00
|
|
|
pub fn on_tab(&mut self) {
|
2020-02-29 22:05:01 +00:00
|
|
|
// Disallow usage whilst in a dialog and only in processes
|
|
|
|
|
2020-04-02 00:31:43 +00:00
|
|
|
let is_in_search_widget = self.is_in_search_widget();
|
|
|
|
if !self.is_in_dialog() {
|
2020-04-08 02:38:22 +00:00
|
|
|
if is_in_search_widget {
|
|
|
|
if let Some(proc_widget_state) = self
|
|
|
|
.proc_state
|
|
|
|
.widget_states
|
|
|
|
.get_mut(&(self.current_widget.widget_id - 1))
|
|
|
|
{
|
2020-04-02 00:31:43 +00:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
}
|
2020-04-08 02:38:22 +00:00
|
|
|
}
|
|
|
|
} else if let Some(proc_widget_state) = self
|
|
|
|
.proc_state
|
|
|
|
.widget_states
|
|
|
|
.get_mut(&self.current_widget.widget_id)
|
|
|
|
{
|
|
|
|
// 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();
|
2020-04-11 00:18:26 +00:00
|
|
|
} else {
|
|
|
|
self.proc_state.force_update = Some(self.current_widget.widget_id);
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-02 00:31:43 +00:00
|
|
|
/// 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
|
|
|
|
}
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
|
|
|
|
2020-04-02 00:31:43 +00:00
|
|
|
/// "On space" if we don't want to treat is as a character.
|
2020-02-29 22:05:01 +00:00
|
|
|
pub fn on_space(&mut self) {
|
2020-04-02 00:31:43 +00:00
|
|
|
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
|
2020-02-29 22:05:01 +00:00
|
|
|
&& curr_posn < self.data_collection.cpu_harvest.len() as u64
|
|
|
|
{
|
2020-04-02 00:31:43 +00:00
|
|
|
cpu_widget_state.core_show_vec[curr_posn as usize] =
|
|
|
|
!cpu_widget_state.core_show_vec[curr_posn as usize];
|
2020-03-11 01:36:13 +00:00
|
|
|
|
|
|
|
if !self.app_config_fields.show_disabled_data {
|
2020-04-02 00:31:43 +00:00
|
|
|
if !cpu_widget_state.core_show_vec[curr_posn as usize] {
|
|
|
|
cpu_widget_state.num_cpus_shown -= 1;
|
2020-03-11 01:36:13 +00:00
|
|
|
} else {
|
2020-04-02 00:31:43 +00:00
|
|
|
cpu_widget_state.num_cpus_shown += 1;
|
2020-03-11 01:36:13 +00:00
|
|
|
}
|
|
|
|
}
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn on_slash(&mut self) {
|
|
|
|
if !self.is_in_dialog() {
|
2020-04-02 00:31:43 +00:00
|
|
|
match self.current_widget.widget_type {
|
|
|
|
BottomWidgetType::Proc => {
|
2020-02-29 22:05:01 +00:00
|
|
|
// Toggle on
|
2020-04-02 00:31:43 +00:00
|
|
|
if let Some(proc_widget_state) = self
|
|
|
|
.proc_state
|
|
|
|
.widget_states
|
|
|
|
.get_mut(&self.current_widget.widget_id)
|
|
|
|
{
|
|
|
|
proc_widget_state
|
|
|
|
.process_search_state
|
|
|
|
.search_state
|
|
|
|
.is_enabled = true;
|
|
|
|
if proc_widget_state.is_grouped {
|
|
|
|
self.search_with_name();
|
|
|
|
}
|
|
|
|
self.move_widget_selection_down();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
BottomWidgetType::Cpu => {
|
|
|
|
if let Some(cpu_widget_state) = self
|
|
|
|
.cpu_state
|
|
|
|
.widget_states
|
|
|
|
.get_mut(&self.current_widget.widget_id)
|
|
|
|
{
|
|
|
|
cpu_widget_state.is_showing_tray = true;
|
|
|
|
if self.app_config_fields.left_legend {
|
|
|
|
self.move_widget_selection_left();
|
|
|
|
} else {
|
|
|
|
self.move_widget_selection_right();
|
|
|
|
}
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
|
|
|
}
|
2020-04-02 00:31:43 +00:00
|
|
|
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 = true;
|
|
|
|
if self.app_config_fields.left_legend {
|
|
|
|
self.move_widget_selection_left();
|
|
|
|
} else {
|
|
|
|
self.move_widget_selection_right();
|
|
|
|
}
|
|
|
|
}
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn search_with_pid(&mut self) {
|
2020-04-02 00:31:43 +00:00
|
|
|
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 proc_widget_state
|
|
|
|
.process_search_state
|
|
|
|
.search_state
|
|
|
|
.is_enabled
|
|
|
|
{
|
|
|
|
proc_widget_state.process_search_state.is_searching_with_pid = true;
|
|
|
|
self.proc_state.force_update = Some(self.current_widget.widget_id - 1);
|
|
|
|
}
|
|
|
|
}
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn search_with_name(&mut self) {
|
2020-04-02 00:31:43 +00:00
|
|
|
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 proc_widget_state
|
|
|
|
.process_search_state
|
|
|
|
.search_state
|
|
|
|
.is_enabled
|
|
|
|
{
|
|
|
|
proc_widget_state.process_search_state.is_searching_with_pid = false;
|
|
|
|
self.proc_state.force_update = Some(self.current_widget.widget_id - 1);
|
|
|
|
}
|
|
|
|
}
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn toggle_ignore_case(&mut self) {
|
2020-04-02 00:31:43 +00:00
|
|
|
let is_in_search_widget = self.is_in_search_widget();
|
|
|
|
if let Some(proc_widget_state) = self
|
|
|
|
.proc_state
|
|
|
|
.widget_states
|
|
|
|
.get_mut(&(self.current_widget.widget_id - 1))
|
|
|
|
{
|
|
|
|
if is_in_search_widget && proc_widget_state.is_search_enabled() {
|
|
|
|
proc_widget_state
|
|
|
|
.process_search_state
|
|
|
|
.search_toggle_ignore_case();
|
|
|
|
proc_widget_state.update_regex();
|
|
|
|
self.proc_state.force_update = Some(self.current_widget.widget_id - 1);
|
|
|
|
}
|
|
|
|
}
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn toggle_search_whole_word(&mut self) {
|
2020-04-02 00:31:43 +00:00
|
|
|
let is_in_search_widget = self.is_in_search_widget();
|
|
|
|
if let Some(proc_widget_state) = self
|
|
|
|
.proc_state
|
|
|
|
.widget_states
|
|
|
|
.get_mut(&(self.current_widget.widget_id - 1))
|
|
|
|
{
|
|
|
|
if is_in_search_widget && proc_widget_state.is_search_enabled() {
|
|
|
|
proc_widget_state
|
|
|
|
.process_search_state
|
|
|
|
.search_toggle_whole_word();
|
|
|
|
proc_widget_state.update_regex();
|
|
|
|
self.proc_state.force_update = Some(self.current_widget.widget_id - 1);
|
|
|
|
}
|
|
|
|
}
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn toggle_search_regex(&mut self) {
|
2020-04-02 00:31:43 +00:00
|
|
|
let is_in_search_widget = self.is_in_search_widget();
|
|
|
|
if let Some(proc_widget_state) = self
|
|
|
|
.proc_state
|
|
|
|
.widget_states
|
|
|
|
.get_mut(&(self.current_widget.widget_id - 1))
|
2020-02-29 22:05:01 +00:00
|
|
|
{
|
2020-04-02 00:31:43 +00:00
|
|
|
if is_in_search_widget && proc_widget_state.is_search_enabled() {
|
|
|
|
proc_widget_state.process_search_state.search_toggle_regex();
|
|
|
|
proc_widget_state.update_regex();
|
|
|
|
self.proc_state.force_update = Some(self.current_widget.widget_id - 1);
|
|
|
|
}
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// One of two functions allowed to run while in a dialog...
|
|
|
|
pub fn on_enter(&mut self) {
|
|
|
|
if self.delete_dialog_state.is_showing_dd {
|
|
|
|
if self.delete_dialog_state.is_on_yes {
|
|
|
|
// If within dd...
|
|
|
|
if self.dd_err.is_none() {
|
|
|
|
// Also ensure that we didn't just fail a dd...
|
|
|
|
let dd_result = self.kill_highlighted_process();
|
|
|
|
self.delete_dialog_state.is_on_yes = false;
|
|
|
|
|
|
|
|
// Check if there was an issue... if so, inform the user.
|
|
|
|
if let Err(dd_err) = dd_result {
|
|
|
|
self.dd_err = Some(dd_err.to_string());
|
|
|
|
} else {
|
|
|
|
self.delete_dialog_state.is_showing_dd = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
self.delete_dialog_state.is_showing_dd = false;
|
|
|
|
}
|
2020-04-02 00:31:43 +00:00
|
|
|
} else if !self.is_in_dialog() && !self.app_config_fields.use_basic_mode {
|
2020-02-29 22:05:01 +00:00
|
|
|
// Pop-out mode. We ignore if in process search.
|
|
|
|
|
2020-04-02 00:31:43 +00:00
|
|
|
match self.current_widget.widget_type {
|
|
|
|
BottomWidgetType::ProcSearch => {}
|
2020-02-29 22:05:01 +00:00
|
|
|
_ => {
|
|
|
|
self.is_expanded = true;
|
|
|
|
self.is_resized = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn on_delete(&mut self) {
|
2020-04-02 00:31:43 +00:00
|
|
|
if let BottomWidgetType::ProcSearch = self.current_widget.widget_type {
|
|
|
|
let is_in_search_widget = self.is_in_search_widget();
|
|
|
|
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
|
|
|
|
.process_search_state
|
|
|
|
.search_state
|
|
|
|
.is_enabled
|
|
|
|
&& proc_widget_state.get_cursor_position()
|
|
|
|
< proc_widget_state
|
|
|
|
.process_search_state
|
|
|
|
.search_state
|
|
|
|
.current_search_query
|
|
|
|
.len()
|
|
|
|
{
|
|
|
|
proc_widget_state
|
2020-02-29 22:07:47 +00:00
|
|
|
.process_search_state
|
|
|
|
.search_state
|
|
|
|
.current_search_query
|
2020-04-02 00:31:43 +00:00
|
|
|
.remove(proc_widget_state.get_cursor_position());
|
2020-02-29 22:05:01 +00:00
|
|
|
|
2020-04-02 00:31:43 +00:00
|
|
|
proc_widget_state
|
|
|
|
.process_search_state
|
2020-02-29 22:05:01 +00:00
|
|
|
.search_state
|
2020-04-02 00:31:43 +00:00
|
|
|
.grapheme_cursor = GraphemeCursor::new(
|
|
|
|
proc_widget_state.get_cursor_position(),
|
|
|
|
proc_widget_state
|
|
|
|
.process_search_state
|
|
|
|
.search_state
|
|
|
|
.current_search_query
|
|
|
|
.len(),
|
|
|
|
true,
|
|
|
|
);
|
|
|
|
|
|
|
|
proc_widget_state.update_regex();
|
|
|
|
self.proc_state.force_update = Some(self.current_widget.widget_id - 1);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
self.start_dd()
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn on_backspace(&mut self) {
|
2020-04-02 00:31:43 +00:00
|
|
|
if let BottomWidgetType::ProcSearch = self.current_widget.widget_type {
|
|
|
|
let is_in_search_widget = self.is_in_search_widget();
|
|
|
|
if let Some(proc_widget_state) = self
|
|
|
|
.proc_state
|
|
|
|
.widget_states
|
|
|
|
.get_mut(&(self.current_widget.widget_id - 1))
|
|
|
|
{
|
|
|
|
if is_in_search_widget
|
|
|
|
&& proc_widget_state
|
|
|
|
.process_search_state
|
|
|
|
.search_state
|
|
|
|
.is_enabled
|
|
|
|
&& proc_widget_state.get_cursor_position() > 0
|
|
|
|
{
|
|
|
|
proc_widget_state.search_walk_back(proc_widget_state.get_cursor_position());
|
2020-02-29 22:05:01 +00:00
|
|
|
|
2020-04-02 00:31:43 +00:00
|
|
|
let removed_char = proc_widget_state
|
|
|
|
.process_search_state
|
2020-02-29 22:05:01 +00:00
|
|
|
.search_state
|
|
|
|
.current_search_query
|
2020-04-02 00:31:43 +00:00
|
|
|
.remove(proc_widget_state.get_cursor_position());
|
|
|
|
|
|
|
|
proc_widget_state
|
|
|
|
.process_search_state
|
|
|
|
.search_state
|
|
|
|
.grapheme_cursor = GraphemeCursor::new(
|
|
|
|
proc_widget_state.get_cursor_position(),
|
|
|
|
proc_widget_state
|
|
|
|
.process_search_state
|
|
|
|
.search_state
|
|
|
|
.current_search_query
|
|
|
|
.len(),
|
|
|
|
true,
|
|
|
|
);
|
2020-02-29 22:05:01 +00:00
|
|
|
|
2020-04-02 00:31:43 +00:00
|
|
|
proc_widget_state
|
|
|
|
.process_search_state
|
|
|
|
.search_state
|
|
|
|
.char_cursor_position -= UnicodeWidthChar::width(removed_char).unwrap_or(0);
|
|
|
|
proc_widget_state
|
|
|
|
.process_search_state
|
|
|
|
.search_state
|
|
|
|
.cursor_direction = CursorDirection::LEFT;
|
2020-02-29 22:05:01 +00:00
|
|
|
|
2020-04-02 00:31:43 +00:00
|
|
|
proc_widget_state.update_regex();
|
|
|
|
self.proc_state.force_update = Some(self.current_widget.widget_id - 1);
|
|
|
|
}
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_current_regex_matcher(
|
2020-04-02 00:31:43 +00:00
|
|
|
&self, widget_id: u64,
|
2020-02-29 22:05:01 +00:00
|
|
|
) -> &Option<std::result::Result<regex::Regex, regex::Error>> {
|
2020-04-02 00:31:43 +00:00
|
|
|
match self.proc_state.widget_states.get(&widget_id) {
|
|
|
|
Some(proc_widget_state) => {
|
|
|
|
&proc_widget_state
|
|
|
|
.process_search_state
|
|
|
|
.search_state
|
|
|
|
.current_regex
|
|
|
|
}
|
|
|
|
None => &None,
|
|
|
|
}
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn on_up_key(&mut self) {
|
|
|
|
if !self.is_in_dialog() {
|
2020-04-02 00:31:43 +00:00
|
|
|
self.decrement_position_count();
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn on_down_key(&mut self) {
|
|
|
|
if !self.is_in_dialog() {
|
2020-04-02 00:31:43 +00:00
|
|
|
self.increment_position_count();
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn on_left_key(&mut self) {
|
|
|
|
if !self.is_in_dialog() {
|
2020-04-17 00:06:50 +00:00
|
|
|
match self.current_widget.widget_type {
|
|
|
|
BottomWidgetType::ProcSearch => {
|
|
|
|
let is_in_search_widget = self.is_in_search_widget();
|
|
|
|
if let Some(proc_widget_state) = self
|
|
|
|
.proc_state
|
|
|
|
.widget_states
|
|
|
|
.get_mut(&(self.current_widget.widget_id - 1))
|
|
|
|
{
|
|
|
|
if is_in_search_widget {
|
|
|
|
let prev_cursor = proc_widget_state.get_cursor_position();
|
2020-04-02 00:31:43 +00:00
|
|
|
proc_widget_state
|
2020-04-17 00:06:50 +00:00
|
|
|
.search_walk_back(proc_widget_state.get_cursor_position());
|
|
|
|
if proc_widget_state.get_cursor_position() < prev_cursor {
|
|
|
|
let str_slice = &proc_widget_state
|
|
|
|
.process_search_state
|
|
|
|
.search_state
|
|
|
|
.current_search_query
|
|
|
|
[proc_widget_state.get_cursor_position()..prev_cursor];
|
|
|
|
proc_widget_state
|
|
|
|
.process_search_state
|
|
|
|
.search_state
|
|
|
|
.char_cursor_position -= UnicodeWidthStr::width(str_slice);
|
|
|
|
proc_widget_state
|
|
|
|
.process_search_state
|
|
|
|
.search_state
|
|
|
|
.cursor_direction = CursorDirection::LEFT;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
BottomWidgetType::Battery => {
|
|
|
|
if !self.canvas_data.battery_data.is_empty() {
|
|
|
|
if let Some(battery_widget_state) = self
|
|
|
|
.battery_state
|
|
|
|
.widget_states
|
|
|
|
.get_mut(&self.current_widget.widget_id)
|
|
|
|
{
|
|
|
|
if battery_widget_state.currently_selected_battery_index > 0 {
|
|
|
|
battery_widget_state.currently_selected_battery_index -= 1;
|
|
|
|
}
|
2020-04-02 00:31:43 +00:00
|
|
|
}
|
|
|
|
}
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
2020-04-17 00:06:50 +00:00
|
|
|
_ => {}
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
|
|
|
} else if self.delete_dialog_state.is_showing_dd && !self.delete_dialog_state.is_on_yes {
|
|
|
|
self.delete_dialog_state.is_on_yes = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn on_right_key(&mut self) {
|
|
|
|
if !self.is_in_dialog() {
|
2020-04-17 00:06:50 +00:00
|
|
|
match self.current_widget.widget_type {
|
|
|
|
BottomWidgetType::ProcSearch => {
|
|
|
|
let is_in_search_widget = self.is_in_search_widget();
|
|
|
|
if let Some(proc_widget_state) = self
|
|
|
|
.proc_state
|
|
|
|
.widget_states
|
|
|
|
.get_mut(&(self.current_widget.widget_id - 1))
|
|
|
|
{
|
|
|
|
if is_in_search_widget {
|
|
|
|
let prev_cursor = proc_widget_state.get_cursor_position();
|
2020-04-02 00:31:43 +00:00
|
|
|
proc_widget_state
|
2020-04-17 00:06:50 +00:00
|
|
|
.search_walk_forward(proc_widget_state.get_cursor_position());
|
|
|
|
if proc_widget_state.get_cursor_position() > prev_cursor {
|
|
|
|
let str_slice = &proc_widget_state
|
|
|
|
.process_search_state
|
|
|
|
.search_state
|
|
|
|
.current_search_query
|
|
|
|
[prev_cursor..proc_widget_state.get_cursor_position()];
|
|
|
|
proc_widget_state
|
|
|
|
.process_search_state
|
|
|
|
.search_state
|
|
|
|
.char_cursor_position += UnicodeWidthStr::width(str_slice);
|
|
|
|
proc_widget_state
|
|
|
|
.process_search_state
|
|
|
|
.search_state
|
|
|
|
.cursor_direction = CursorDirection::RIGHT;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
BottomWidgetType::Battery => {
|
|
|
|
if !self.canvas_data.battery_data.is_empty() {
|
|
|
|
let battery_count = self.canvas_data.battery_data.len();
|
|
|
|
if let Some(battery_widget_state) = self
|
|
|
|
.battery_state
|
|
|
|
.widget_states
|
|
|
|
.get_mut(&self.current_widget.widget_id)
|
|
|
|
{
|
|
|
|
if battery_widget_state.currently_selected_battery_index
|
|
|
|
< battery_count - 1
|
|
|
|
{
|
|
|
|
battery_widget_state.currently_selected_battery_index += 1;
|
|
|
|
}
|
2020-04-02 00:31:43 +00:00
|
|
|
}
|
|
|
|
}
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
2020-04-17 00:06:50 +00:00
|
|
|
_ => {}
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
|
|
|
} else if self.delete_dialog_state.is_showing_dd && self.delete_dialog_state.is_on_yes {
|
|
|
|
self.delete_dialog_state.is_on_yes = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn skip_cursor_beginning(&mut self) {
|
|
|
|
if !self.is_in_dialog() {
|
2020-04-02 00:31:43 +00:00
|
|
|
if let BottomWidgetType::ProcSearch = self.current_widget.widget_type {
|
|
|
|
let is_in_search_widget = self.is_in_search_widget();
|
|
|
|
if let Some(proc_widget_state) = self
|
|
|
|
.proc_state
|
|
|
|
.widget_states
|
|
|
|
.get_mut(&(self.current_widget.widget_id - 1))
|
|
|
|
{
|
|
|
|
if is_in_search_widget {
|
|
|
|
proc_widget_state
|
|
|
|
.process_search_state
|
|
|
|
.search_state
|
|
|
|
.grapheme_cursor = GraphemeCursor::new(
|
|
|
|
0,
|
|
|
|
proc_widget_state
|
|
|
|
.process_search_state
|
|
|
|
.search_state
|
|
|
|
.current_search_query
|
|
|
|
.len(),
|
|
|
|
true,
|
|
|
|
);
|
|
|
|
proc_widget_state
|
|
|
|
.process_search_state
|
|
|
|
.search_state
|
|
|
|
.char_cursor_position = 0;
|
|
|
|
proc_widget_state
|
|
|
|
.process_search_state
|
|
|
|
.search_state
|
|
|
|
.cursor_direction = CursorDirection::LEFT;
|
|
|
|
}
|
|
|
|
}
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn skip_cursor_end(&mut self) {
|
|
|
|
if !self.is_in_dialog() {
|
2020-04-02 00:31:43 +00:00
|
|
|
if let BottomWidgetType::ProcSearch = self.current_widget.widget_type {
|
|
|
|
let is_in_search_widget = self.is_in_search_widget();
|
|
|
|
if let Some(proc_widget_state) = self
|
|
|
|
.proc_state
|
|
|
|
.widget_states
|
|
|
|
.get_mut(&(self.current_widget.widget_id - 1))
|
|
|
|
{
|
|
|
|
if is_in_search_widget {
|
|
|
|
proc_widget_state
|
|
|
|
.process_search_state
|
2020-02-29 22:05:01 +00:00
|
|
|
.search_state
|
2020-04-02 00:31:43 +00:00
|
|
|
.grapheme_cursor = GraphemeCursor::new(
|
|
|
|
proc_widget_state
|
|
|
|
.process_search_state
|
|
|
|
.search_state
|
|
|
|
.current_search_query
|
|
|
|
.len(),
|
|
|
|
proc_widget_state
|
|
|
|
.process_search_state
|
|
|
|
.search_state
|
|
|
|
.current_search_query
|
|
|
|
.len(),
|
|
|
|
true,
|
|
|
|
);
|
|
|
|
proc_widget_state
|
|
|
|
.process_search_state
|
|
|
|
.search_state
|
|
|
|
.char_cursor_position = UnicodeWidthStr::width(
|
|
|
|
proc_widget_state
|
|
|
|
.process_search_state
|
|
|
|
.search_state
|
|
|
|
.current_search_query
|
|
|
|
.as_str(),
|
|
|
|
);
|
|
|
|
proc_widget_state
|
|
|
|
.process_search_state
|
|
|
|
.search_state
|
|
|
|
.cursor_direction = CursorDirection::RIGHT;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn clear_search(&mut self) {
|
|
|
|
if let BottomWidgetType::ProcSearch = self.current_widget.widget_type {
|
|
|
|
if let Some(proc_widget_state) = self
|
|
|
|
.proc_state
|
|
|
|
.widget_states
|
|
|
|
.get_mut(&(self.current_widget.widget_id - 1))
|
|
|
|
{
|
|
|
|
proc_widget_state.clear_search();
|
|
|
|
self.proc_state.force_update = Some(self.current_widget.widget_id - 1);
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn start_dd(&mut self) {
|
2020-04-02 00:31:43 +00:00
|
|
|
if let Some(proc_widget_state) = self
|
|
|
|
.proc_state
|
|
|
|
.widget_states
|
|
|
|
.get(&self.current_widget.widget_id)
|
2020-02-29 22:05:01 +00:00
|
|
|
{
|
2020-04-02 00:31:43 +00:00
|
|
|
if let Some(corresponding_filtered_process_list) = self
|
|
|
|
.canvas_data
|
|
|
|
.finalized_process_data_map
|
|
|
|
.get(&self.current_widget.widget_id)
|
|
|
|
{
|
|
|
|
if proc_widget_state.scroll_state.current_scroll_position
|
2020-04-12 23:26:32 +00:00
|
|
|
< corresponding_filtered_process_list.len() as u64
|
2020-04-02 00:31:43 +00:00
|
|
|
{
|
|
|
|
let current_process = if self.is_grouped(self.current_widget.widget_id) {
|
|
|
|
let group_pids = &corresponding_filtered_process_list
|
|
|
|
[proc_widget_state.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 = corresponding_filtered_process_list
|
|
|
|
[proc_widget_state.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;
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
|
|
|
|
2020-04-02 00:31:43 +00:00
|
|
|
self.reset_multi_tap_keys();
|
|
|
|
}
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn on_char_key(&mut self, caught_char: char) {
|
|
|
|
// Skip control code chars
|
|
|
|
if caught_char.is_control() {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Forbid any char key presses when showing a dialog box...
|
|
|
|
if !self.is_in_dialog() {
|
|
|
|
let current_key_press_inst = Instant::now();
|
|
|
|
if current_key_press_inst
|
|
|
|
.duration_since(self.last_key_press)
|
2020-02-29 22:07:47 +00:00
|
|
|
.as_millis()
|
2020-03-09 01:56:30 +00:00
|
|
|
> constants::MAX_KEY_TIMEOUT_IN_MILLISECONDS as u128
|
2020-02-29 22:05:01 +00:00
|
|
|
{
|
|
|
|
self.reset_multi_tap_keys();
|
|
|
|
}
|
|
|
|
self.last_key_press = current_key_press_inst;
|
|
|
|
|
2020-04-02 00:31:43 +00:00
|
|
|
if let BottomWidgetType::ProcSearch = self.current_widget.widget_type {
|
|
|
|
let is_in_search_widget = self.is_in_search_widget();
|
|
|
|
if let Some(proc_widget_state) = self
|
|
|
|
.proc_state
|
|
|
|
.widget_states
|
|
|
|
.get_mut(&(self.current_widget.widget_id - 1))
|
2020-02-29 22:05:01 +00:00
|
|
|
{
|
2020-04-02 00:31:43 +00:00
|
|
|
if is_in_search_widget
|
|
|
|
&& proc_widget_state.is_search_enabled()
|
|
|
|
&& UnicodeWidthStr::width(
|
|
|
|
proc_widget_state
|
|
|
|
.process_search_state
|
|
|
|
.search_state
|
|
|
|
.current_search_query
|
|
|
|
.as_str(),
|
|
|
|
) <= MAX_SEARCH_LENGTH
|
|
|
|
{
|
|
|
|
proc_widget_state
|
|
|
|
.process_search_state
|
2020-02-29 22:05:01 +00:00
|
|
|
.search_state
|
|
|
|
.current_search_query
|
2020-04-02 00:31:43 +00:00
|
|
|
.insert(proc_widget_state.get_cursor_position(), caught_char);
|
2020-02-29 22:05:01 +00:00
|
|
|
|
2020-04-02 00:31:43 +00:00
|
|
|
proc_widget_state
|
|
|
|
.process_search_state
|
|
|
|
.search_state
|
|
|
|
.grapheme_cursor = GraphemeCursor::new(
|
|
|
|
proc_widget_state.get_cursor_position(),
|
|
|
|
proc_widget_state
|
|
|
|
.process_search_state
|
|
|
|
.search_state
|
|
|
|
.current_search_query
|
|
|
|
.len(),
|
|
|
|
true,
|
|
|
|
);
|
|
|
|
proc_widget_state
|
|
|
|
.search_walk_forward(proc_widget_state.get_cursor_position());
|
|
|
|
|
|
|
|
proc_widget_state
|
|
|
|
.process_search_state
|
|
|
|
.search_state
|
|
|
|
.char_cursor_position +=
|
|
|
|
UnicodeWidthChar::width(caught_char).unwrap_or(0);
|
2020-02-29 22:05:01 +00:00
|
|
|
|
2020-04-02 00:31:43 +00:00
|
|
|
proc_widget_state.update_regex();
|
|
|
|
self.proc_state.force_update = Some(self.current_widget.widget_id - 1);
|
|
|
|
proc_widget_state
|
|
|
|
.process_search_state
|
|
|
|
.search_state
|
|
|
|
.cursor_direction = CursorDirection::RIGHT;
|
|
|
|
|
|
|
|
return;
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
2020-04-02 00:31:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
self.handle_char(caught_char);
|
|
|
|
} else if self.help_dialog_state.is_showing_help {
|
|
|
|
match caught_char {
|
|
|
|
'1' => self.help_dialog_state.current_category = AppHelpCategory::General,
|
|
|
|
'2' => self.help_dialog_state.current_category = AppHelpCategory::Process,
|
|
|
|
'3' => self.help_dialog_state.current_category = AppHelpCategory::Search,
|
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-02-29 22:05:01 +00:00
|
|
|
|
2020-04-02 00:31:43 +00:00
|
|
|
fn handle_char(&mut self, caught_char: char) {
|
|
|
|
match caught_char {
|
|
|
|
'/' => {
|
|
|
|
self.on_slash();
|
|
|
|
}
|
|
|
|
'd' => {
|
|
|
|
if let BottomWidgetType::Proc = self.current_widget.widget_type {
|
|
|
|
let mut is_first_d = true;
|
|
|
|
if let Some(second_char) = self.second_char {
|
|
|
|
if self.awaiting_second_char && second_char == 'd' {
|
|
|
|
is_first_d = false;
|
|
|
|
self.awaiting_second_char = false;
|
|
|
|
self.second_char = None;
|
|
|
|
|
|
|
|
self.start_dd();
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-02 00:31:43 +00:00
|
|
|
if is_first_d {
|
|
|
|
self.awaiting_second_char = true;
|
|
|
|
self.second_char = Some('d');
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
2020-04-02 00:31:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
'g' => {
|
|
|
|
let mut is_first_g = true;
|
|
|
|
if let Some(second_char) = self.second_char {
|
|
|
|
if self.awaiting_second_char && second_char == 'g' {
|
|
|
|
is_first_g = false;
|
|
|
|
self.awaiting_second_char = false;
|
|
|
|
self.second_char = None;
|
|
|
|
self.skip_to_first();
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
2020-04-02 00:31:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if is_first_g {
|
|
|
|
self.awaiting_second_char = true;
|
|
|
|
self.second_char = Some('g');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
'G' => self.skip_to_last(),
|
|
|
|
'k' => self.decrement_position_count(),
|
|
|
|
'j' => self.increment_position_count(),
|
|
|
|
'f' => {
|
|
|
|
self.is_frozen = !self.is_frozen;
|
|
|
|
if self.is_frozen {
|
|
|
|
self.data_collection.set_frozen_time();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
'c' => {
|
|
|
|
if let BottomWidgetType::Proc = self.current_widget.widget_type {
|
|
|
|
if let Some(proc_widget_state) = self
|
|
|
|
.proc_state
|
|
|
|
.widget_states
|
|
|
|
.get_mut(&self.current_widget.widget_id)
|
|
|
|
{
|
|
|
|
match proc_widget_state.process_sorting_type {
|
2020-02-29 22:05:01 +00:00
|
|
|
processes::ProcessSorting::CPU => {
|
2020-04-02 00:31:43 +00:00
|
|
|
proc_widget_state.process_sorting_reverse =
|
|
|
|
!proc_widget_state.process_sorting_reverse
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
|
|
|
_ => {
|
2020-04-02 00:31:43 +00:00
|
|
|
proc_widget_state.process_sorting_type =
|
|
|
|
processes::ProcessSorting::CPU;
|
|
|
|
proc_widget_state.process_sorting_reverse = true;
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
|
|
|
}
|
2020-04-02 00:31:43 +00:00
|
|
|
self.proc_state.force_update = Some(self.current_widget.widget_id);
|
|
|
|
|
|
|
|
self.skip_to_first();
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
2020-04-02 00:31:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
'm' => {
|
|
|
|
if let BottomWidgetType::Proc = self.current_widget.widget_type {
|
|
|
|
if let Some(proc_widget_state) = self
|
|
|
|
.proc_state
|
|
|
|
.widget_states
|
|
|
|
.get_mut(&self.current_widget.widget_id)
|
|
|
|
{
|
|
|
|
match proc_widget_state.process_sorting_type {
|
2020-02-29 22:05:01 +00:00
|
|
|
processes::ProcessSorting::MEM => {
|
2020-04-02 00:31:43 +00:00
|
|
|
proc_widget_state.process_sorting_reverse =
|
|
|
|
!proc_widget_state.process_sorting_reverse
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
|
|
|
_ => {
|
2020-04-02 00:31:43 +00:00
|
|
|
proc_widget_state.process_sorting_type =
|
|
|
|
processes::ProcessSorting::MEM;
|
|
|
|
proc_widget_state.process_sorting_reverse = true;
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
|
|
|
}
|
2020-04-02 00:31:43 +00:00
|
|
|
self.proc_state.force_update = Some(self.current_widget.widget_id);
|
|
|
|
self.skip_to_first();
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
2020-04-02 00:31:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
'p' => {
|
|
|
|
if let BottomWidgetType::Proc = self.current_widget.widget_type {
|
|
|
|
if let Some(proc_widget_state) = self
|
|
|
|
.proc_state
|
|
|
|
.widget_states
|
|
|
|
.get_mut(&self.current_widget.widget_id)
|
|
|
|
{
|
|
|
|
// Skip if grouped
|
|
|
|
if !proc_widget_state.is_grouped {
|
|
|
|
match proc_widget_state.process_sorting_type {
|
2020-02-29 22:05:01 +00:00
|
|
|
processes::ProcessSorting::PID => {
|
2020-04-02 00:31:43 +00:00
|
|
|
proc_widget_state.process_sorting_reverse =
|
|
|
|
!proc_widget_state.process_sorting_reverse
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
|
|
|
_ => {
|
2020-04-02 00:31:43 +00:00
|
|
|
proc_widget_state.process_sorting_type =
|
|
|
|
processes::ProcessSorting::PID;
|
|
|
|
proc_widget_state.process_sorting_reverse = false;
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
|
|
|
}
|
2020-04-02 00:31:43 +00:00
|
|
|
self.proc_state.force_update = Some(self.current_widget.widget_id);
|
|
|
|
self.skip_to_first();
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
|
|
|
}
|
2020-04-02 00:31:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
'n' => {
|
|
|
|
if let BottomWidgetType::Proc = self.current_widget.widget_type {
|
|
|
|
if let Some(proc_widget_state) = self
|
|
|
|
.proc_state
|
|
|
|
.widget_states
|
|
|
|
.get_mut(&self.current_widget.widget_id)
|
|
|
|
{
|
|
|
|
match proc_widget_state.process_sorting_type {
|
2020-02-29 22:05:01 +00:00
|
|
|
processes::ProcessSorting::NAME => {
|
2020-04-02 00:31:43 +00:00
|
|
|
proc_widget_state.process_sorting_reverse =
|
|
|
|
!proc_widget_state.process_sorting_reverse
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
|
|
|
_ => {
|
2020-04-02 00:31:43 +00:00
|
|
|
proc_widget_state.process_sorting_type =
|
|
|
|
processes::ProcessSorting::NAME;
|
|
|
|
proc_widget_state.process_sorting_reverse = false;
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
|
|
|
}
|
2020-04-02 00:31:43 +00:00
|
|
|
self.proc_state.force_update = Some(self.current_widget.widget_id);
|
|
|
|
self.skip_to_first();
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-04-02 00:31:43 +00:00
|
|
|
'?' => {
|
|
|
|
self.help_dialog_state.is_showing_help = true;
|
|
|
|
}
|
|
|
|
'H' => self.move_widget_selection_left(),
|
|
|
|
'L' => self.move_widget_selection_right(),
|
|
|
|
'K' => self.move_widget_selection_up(),
|
|
|
|
'J' => self.move_widget_selection_down(),
|
|
|
|
' ' => self.on_space(),
|
|
|
|
'+' => self.zoom_in(),
|
|
|
|
'-' => self.zoom_out(),
|
|
|
|
'=' => self.reset_zoom(),
|
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
|
|
|
|
if let Some(second_char) = self.second_char {
|
|
|
|
if self.awaiting_second_char && caught_char != second_char {
|
|
|
|
self.awaiting_second_char = false;
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn kill_highlighted_process(&mut self) -> Result<()> {
|
2020-04-02 00:31:43 +00:00
|
|
|
if let BottomWidgetType::Proc = self.current_widget.widget_type {
|
2020-02-29 22:05:01 +00:00
|
|
|
if let Some(current_selected_processes) = &self.to_delete_process_list {
|
|
|
|
for pid in ¤t_selected_processes.1 {
|
|
|
|
process_killer::kill_process_given_pid(*pid)?;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
self.to_delete_process_list = None;
|
2020-04-02 00:31:43 +00:00
|
|
|
Ok(())
|
|
|
|
} else {
|
|
|
|
Err(BottomError::GenericError(
|
|
|
|
"Cannot kill processes if the current widget is not the Process widget!"
|
|
|
|
.to_string(),
|
|
|
|
))
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_to_delete_processes(&self) -> Option<(String, Vec<u32>)> {
|
|
|
|
self.to_delete_process_list.clone()
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn move_widget_selection_left(&mut self) {
|
|
|
|
if !self.is_in_dialog() && !self.is_expanded {
|
2020-04-02 00:31:43 +00:00
|
|
|
if let Some(current_widget) = self.widget_map.get(&self.current_widget.widget_id) {
|
|
|
|
if let Some(new_widget_id) = current_widget.left_neighbour {
|
|
|
|
if let Some(new_widget) = self.widget_map.get(&new_widget_id) {
|
|
|
|
match new_widget.widget_type {
|
|
|
|
BottomWidgetType::Temp
|
|
|
|
| BottomWidgetType::Proc
|
|
|
|
| BottomWidgetType::ProcSearch
|
|
|
|
| BottomWidgetType::Disk
|
|
|
|
if self.basic_table_widget_state.is_some() =>
|
|
|
|
{
|
|
|
|
if let Some(basic_table_widget_state) =
|
|
|
|
&mut self.basic_table_widget_state
|
|
|
|
{
|
|
|
|
basic_table_widget_state.currently_displayed_widget_id =
|
|
|
|
new_widget_id;
|
|
|
|
basic_table_widget_state.currently_displayed_widget_type =
|
|
|
|
new_widget.widget_type.clone();
|
|
|
|
}
|
|
|
|
self.current_widget = new_widget.clone();
|
|
|
|
}
|
|
|
|
BottomWidgetType::CpuLegend => {
|
|
|
|
if let Some(cpu_widget_state) =
|
|
|
|
self.cpu_state.widget_states.get(&(new_widget_id - 1))
|
|
|
|
{
|
|
|
|
if cpu_widget_state.is_legend_hidden {
|
|
|
|
if let Some(next_new_widget_id) = new_widget.left_neighbour
|
|
|
|
{
|
|
|
|
if let Some(next_new_widget) =
|
|
|
|
self.widget_map.get(&next_new_widget_id)
|
|
|
|
{
|
|
|
|
self.current_widget = next_new_widget.clone();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
self.current_widget = new_widget.clone();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
BottomWidgetType::ProcSearch => {
|
|
|
|
if let Some(proc_widget_state) =
|
|
|
|
self.proc_state.widget_states.get(&(new_widget_id - 1))
|
|
|
|
{
|
|
|
|
if proc_widget_state.is_search_enabled() {
|
|
|
|
self.current_widget = new_widget.clone();
|
|
|
|
} else if let Some(next_new_widget_id) = new_widget.up_neighbour
|
|
|
|
{
|
|
|
|
if let Some(next_new_widget) =
|
|
|
|
self.widget_map.get(&next_new_widget_id)
|
|
|
|
{
|
|
|
|
self.current_widget = next_new_widget.clone();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_ => self.current_widget = new_widget.clone(),
|
|
|
|
}
|
2020-03-08 20:17:28 +00:00
|
|
|
}
|
2020-04-02 00:31:43 +00:00
|
|
|
}
|
2020-03-02 04:53:49 +00:00
|
|
|
}
|
2020-03-08 20:17:28 +00:00
|
|
|
} else if self.is_expanded {
|
2020-04-06 04:40:55 +00:00
|
|
|
self.handle_left_expanded_cpu_movement();
|
|
|
|
}
|
|
|
|
|
|
|
|
self.reset_multi_tap_keys();
|
|
|
|
}
|
|
|
|
|
|
|
|
fn handle_left_expanded_cpu_movement(&mut self) {
|
|
|
|
if self.app_config_fields.left_legend {
|
|
|
|
if let BottomWidgetType::Cpu = self.current_widget.widget_type {
|
|
|
|
if let Some(current_widget) = self.widget_map.get(&self.current_widget.widget_id) {
|
|
|
|
if let Some(cpu_widget_state) = self
|
|
|
|
.cpu_state
|
|
|
|
.widget_states
|
|
|
|
.get(&self.current_widget.widget_id)
|
2020-04-02 00:31:43 +00:00
|
|
|
{
|
2020-04-06 04:40:55 +00:00
|
|
|
if !cpu_widget_state.is_legend_hidden {
|
|
|
|
if let Some(new_widget_id) = current_widget.left_neighbour {
|
|
|
|
if let Some(new_widget) = self.widget_map.get(&new_widget_id) {
|
|
|
|
self.current_widget = new_widget.clone();
|
2020-04-02 00:31:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-03-08 20:17:28 +00:00
|
|
|
}
|
2020-04-06 04:40:55 +00:00
|
|
|
}
|
|
|
|
} else if let BottomWidgetType::CpuLegend = self.current_widget.widget_type {
|
|
|
|
if let Some(current_widget) = self.widget_map.get(&self.current_widget.widget_id) {
|
|
|
|
if let Some(new_widget_id) = current_widget.left_neighbour {
|
|
|
|
if let Some(new_widget) = self.widget_map.get(&new_widget_id) {
|
|
|
|
self.current_widget = new_widget.clone();
|
2020-04-02 00:31:43 +00:00
|
|
|
}
|
2020-03-08 20:17:28 +00:00
|
|
|
}
|
|
|
|
}
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn move_widget_selection_right(&mut self) {
|
|
|
|
if !self.is_in_dialog() && !self.is_expanded {
|
2020-04-02 00:31:43 +00:00
|
|
|
if let Some(current_widget) = self.widget_map.get(&self.current_widget.widget_id) {
|
|
|
|
if let Some(new_widget_id) = current_widget.right_neighbour {
|
|
|
|
if let Some(new_widget) = self.widget_map.get(&new_widget_id) {
|
|
|
|
match new_widget.widget_type {
|
|
|
|
BottomWidgetType::Temp
|
|
|
|
| BottomWidgetType::Proc
|
|
|
|
| BottomWidgetType::ProcSearch
|
|
|
|
| BottomWidgetType::Disk
|
|
|
|
if self.basic_table_widget_state.is_some() =>
|
|
|
|
{
|
|
|
|
if let Some(basic_table_widget_state) =
|
|
|
|
&mut self.basic_table_widget_state
|
|
|
|
{
|
|
|
|
basic_table_widget_state.currently_displayed_widget_id =
|
|
|
|
new_widget_id;
|
|
|
|
basic_table_widget_state.currently_displayed_widget_type =
|
|
|
|
new_widget.widget_type.clone();
|
|
|
|
}
|
|
|
|
self.current_widget = new_widget.clone();
|
|
|
|
}
|
|
|
|
BottomWidgetType::CpuLegend => {
|
|
|
|
if let Some(cpu_widget_state) =
|
|
|
|
self.cpu_state.widget_states.get(&(new_widget_id - 1))
|
|
|
|
{
|
|
|
|
if cpu_widget_state.is_legend_hidden {
|
|
|
|
if let Some(next_new_widget_id) = new_widget.right_neighbour
|
|
|
|
{
|
|
|
|
if let Some(next_new_widget) =
|
|
|
|
self.widget_map.get(&next_new_widget_id)
|
|
|
|
{
|
|
|
|
self.current_widget = next_new_widget.clone();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
self.current_widget = new_widget.clone();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
BottomWidgetType::ProcSearch => {
|
|
|
|
if let Some(proc_widget_state) =
|
|
|
|
self.proc_state.widget_states.get(&(new_widget_id - 1))
|
|
|
|
{
|
|
|
|
if proc_widget_state.is_search_enabled() {
|
|
|
|
self.current_widget = new_widget.clone();
|
|
|
|
} else if let Some(next_new_widget_id) = new_widget.up_neighbour
|
|
|
|
{
|
|
|
|
if let Some(next_new_widget) =
|
|
|
|
self.widget_map.get(&next_new_widget_id)
|
|
|
|
{
|
|
|
|
self.current_widget = next_new_widget.clone();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
_ => {
|
|
|
|
self.current_widget = new_widget.clone();
|
|
|
|
}
|
|
|
|
}
|
2020-03-08 20:17:28 +00:00
|
|
|
}
|
2020-04-02 00:31:43 +00:00
|
|
|
}
|
2020-03-02 04:53:49 +00:00
|
|
|
}
|
2020-03-08 20:17:28 +00:00
|
|
|
} else if self.is_expanded {
|
2020-04-06 04:40:55 +00:00
|
|
|
self.handle_right_expanded_cpu_movement();
|
|
|
|
}
|
|
|
|
|
|
|
|
self.reset_multi_tap_keys();
|
|
|
|
}
|
|
|
|
|
|
|
|
fn handle_right_expanded_cpu_movement(&mut self) {
|
|
|
|
if self.app_config_fields.left_legend {
|
|
|
|
if let BottomWidgetType::CpuLegend = self.current_widget.widget_type {
|
|
|
|
if let Some(current_widget) = self.widget_map.get(&self.current_widget.widget_id) {
|
|
|
|
if let Some(new_widget_id) = current_widget.right_neighbour {
|
|
|
|
if let Some(new_widget) = self.widget_map.get(&new_widget_id) {
|
|
|
|
self.current_widget = new_widget.clone();
|
2020-04-02 00:31:43 +00:00
|
|
|
}
|
|
|
|
}
|
2020-03-08 20:17:28 +00:00
|
|
|
}
|
2020-04-06 04:40:55 +00:00
|
|
|
}
|
|
|
|
} else if let BottomWidgetType::Cpu = self.current_widget.widget_type {
|
|
|
|
if let Some(current_widget) = self.widget_map.get(&self.current_widget.widget_id) {
|
|
|
|
if let Some(cpu_widget_state) = self
|
|
|
|
.cpu_state
|
|
|
|
.widget_states
|
|
|
|
.get(&self.current_widget.widget_id)
|
|
|
|
{
|
|
|
|
if !cpu_widget_state.is_legend_hidden {
|
|
|
|
if let Some(new_widget_id) = current_widget.right_neighbour {
|
|
|
|
if let Some(new_widget) = self.widget_map.get(&new_widget_id) {
|
|
|
|
self.current_widget = new_widget.clone();
|
2020-04-02 00:31:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-03-08 20:17:28 +00:00
|
|
|
}
|
|
|
|
}
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn move_widget_selection_up(&mut self) {
|
|
|
|
if !self.is_in_dialog() && !self.is_expanded {
|
2020-04-02 00:31:43 +00:00
|
|
|
if let Some(current_widget) = self.widget_map.get(&self.current_widget.widget_id) {
|
|
|
|
if let Some(new_widget_id) = current_widget.up_neighbour {
|
|
|
|
if let Some(new_widget) = self.widget_map.get(&new_widget_id) {
|
|
|
|
match new_widget.widget_type {
|
|
|
|
BottomWidgetType::CpuLegend => {
|
|
|
|
if let Some(cpu_widget_state) =
|
|
|
|
self.cpu_state.widget_states.get(&(new_widget_id - 1))
|
|
|
|
{
|
|
|
|
if cpu_widget_state.is_legend_hidden {
|
|
|
|
if let Some(next_new_widget) =
|
|
|
|
self.widget_map.get(&(new_widget_id - 1))
|
|
|
|
{
|
|
|
|
self.current_widget = next_new_widget.clone();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
self.current_widget = new_widget.clone();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
BottomWidgetType::ProcSearch => {
|
|
|
|
if let Some(proc_widget_state) =
|
|
|
|
self.proc_state.widget_states.get(&(new_widget_id - 1))
|
|
|
|
{
|
|
|
|
if proc_widget_state.is_search_enabled() {
|
|
|
|
self.current_widget = new_widget.clone();
|
|
|
|
} else if let Some(next_new_widget_id) = new_widget.up_neighbour
|
|
|
|
{
|
|
|
|
if let Some(next_new_widget) =
|
|
|
|
self.widget_map.get(&next_new_widget_id)
|
|
|
|
{
|
|
|
|
self.current_widget = next_new_widget.clone();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
BottomWidgetType::BasicTables => {
|
|
|
|
if let Some(next_new_widget_id) = new_widget.up_neighbour {
|
|
|
|
if let Some(next_new_widget) =
|
|
|
|
self.widget_map.get(&next_new_widget_id)
|
|
|
|
{
|
|
|
|
self.current_widget = next_new_widget.clone();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_ => {
|
|
|
|
self.current_widget = new_widget.clone();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-03-02 04:53:49 +00:00
|
|
|
}
|
|
|
|
}
|
2020-02-29 22:05:01 +00:00
|
|
|
} else if self.is_expanded {
|
2020-04-02 00:31:43 +00:00
|
|
|
if let BottomWidgetType::ProcSearch = self.current_widget.widget_type {
|
|
|
|
if let Some(current_widget) = self.widget_map.get(&self.current_widget.widget_id) {
|
|
|
|
if let Some(new_widget_id) = current_widget.up_neighbour {
|
|
|
|
if let Some(new_widget) = self.widget_map.get(&new_widget_id) {
|
|
|
|
self.current_widget = new_widget.clone();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
self.reset_multi_tap_keys();
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn move_widget_selection_down(&mut self) {
|
|
|
|
if !self.is_in_dialog() && !self.is_expanded {
|
2020-04-02 00:31:43 +00:00
|
|
|
if let Some(current_widget) = self.widget_map.get(&self.current_widget.widget_id) {
|
|
|
|
if let Some(new_widget_id) = current_widget.down_neighbour {
|
|
|
|
if let Some(new_widget) = self.widget_map.get(&new_widget_id) {
|
|
|
|
match new_widget.widget_type {
|
|
|
|
BottomWidgetType::CpuLegend => {
|
|
|
|
if let Some(cpu_widget_state) =
|
|
|
|
self.cpu_state.widget_states.get(&(new_widget_id - 1))
|
|
|
|
{
|
|
|
|
if cpu_widget_state.is_legend_hidden {
|
|
|
|
if let Some(next_new_widget) =
|
|
|
|
self.widget_map.get(&(new_widget_id - 1))
|
|
|
|
{
|
|
|
|
self.current_widget = next_new_widget.clone();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
self.current_widget = new_widget.clone();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
BottomWidgetType::ProcSearch => {
|
|
|
|
if let Some(proc_widget_state) =
|
|
|
|
self.proc_state.widget_states.get(&(new_widget_id - 1))
|
|
|
|
{
|
|
|
|
if proc_widget_state.is_search_enabled() {
|
|
|
|
self.current_widget = new_widget.clone();
|
|
|
|
} else if let Some(next_new_widget_id) =
|
|
|
|
new_widget.down_neighbour
|
|
|
|
{
|
|
|
|
if let Some(next_new_widget) =
|
|
|
|
self.widget_map.get(&next_new_widget_id)
|
|
|
|
{
|
|
|
|
self.current_widget = next_new_widget.clone();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
BottomWidgetType::BasicTables => {
|
|
|
|
// This means we're in basic mode. As such, then
|
|
|
|
// we want to move DOWN to the currently shown widget
|
|
|
|
if let Some(basic_table_widget_state) =
|
|
|
|
&self.basic_table_widget_state
|
|
|
|
{
|
|
|
|
if let Some(next_new_widget) = self.widget_map.get(
|
|
|
|
&basic_table_widget_state.currently_displayed_widget_id,
|
|
|
|
) {
|
|
|
|
self.current_widget = next_new_widget.clone();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_ => {
|
|
|
|
self.current_widget = new_widget.clone();
|
|
|
|
}
|
2020-03-02 04:53:49 +00:00
|
|
|
}
|
|
|
|
}
|
2020-04-02 00:31:43 +00:00
|
|
|
}
|
2020-03-02 04:53:49 +00:00
|
|
|
}
|
2020-02-29 22:05:01 +00:00
|
|
|
} else if self.is_expanded {
|
2020-04-02 00:31:43 +00:00
|
|
|
if let BottomWidgetType::Proc = self.current_widget.widget_type {
|
|
|
|
if let Some(current_widget) = self.widget_map.get(&self.current_widget.widget_id) {
|
|
|
|
if let Some(new_widget_id) = current_widget.down_neighbour {
|
|
|
|
if let Some(new_widget) = self.widget_map.get(&new_widget_id) {
|
|
|
|
if let Some(proc_widget_state) = self
|
|
|
|
.proc_state
|
|
|
|
.widget_states
|
|
|
|
.get(&self.current_widget.widget_id)
|
|
|
|
{
|
|
|
|
if proc_widget_state.is_search_enabled() {
|
|
|
|
self.current_widget = new_widget.clone();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
|
|
|
}
|
2020-04-02 00:31:43 +00:00
|
|
|
}
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
self.reset_multi_tap_keys();
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn skip_to_first(&mut self) {
|
|
|
|
if !self.is_in_dialog() {
|
2020-04-02 00:31:43 +00:00
|
|
|
match self.current_widget.widget_type {
|
|
|
|
BottomWidgetType::Proc => {
|
|
|
|
if let Some(proc_widget_state) = self
|
|
|
|
.proc_state
|
|
|
|
.widget_states
|
|
|
|
.get_mut(&self.current_widget.widget_id)
|
|
|
|
{
|
|
|
|
proc_widget_state.scroll_state.current_scroll_position = 0;
|
|
|
|
proc_widget_state.scroll_state.scroll_direction = ScrollDirection::UP;
|
|
|
|
}
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
2020-04-02 00:31:43 +00:00
|
|
|
BottomWidgetType::Temp => {
|
|
|
|
if let Some(temp_widget_state) = self
|
|
|
|
.temp_state
|
|
|
|
.widget_states
|
|
|
|
.get_mut(&self.current_widget.widget_id)
|
|
|
|
{
|
|
|
|
temp_widget_state.scroll_state.current_scroll_position = 0;
|
|
|
|
temp_widget_state.scroll_state.scroll_direction = ScrollDirection::UP;
|
|
|
|
}
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
2020-04-02 00:31:43 +00:00
|
|
|
BottomWidgetType::Disk => {
|
|
|
|
if let Some(disk_widget_state) = self
|
|
|
|
.disk_state
|
|
|
|
.widget_states
|
|
|
|
.get_mut(&self.current_widget.widget_id)
|
|
|
|
{
|
|
|
|
disk_widget_state.scroll_state.current_scroll_position = 0;
|
|
|
|
disk_widget_state.scroll_state.scroll_direction = ScrollDirection::UP;
|
|
|
|
}
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
2020-04-02 00:31:43 +00:00
|
|
|
BottomWidgetType::CpuLegend => {
|
|
|
|
if let Some(cpu_widget_state) = self
|
|
|
|
.cpu_state
|
|
|
|
.widget_states
|
2020-04-07 03:04:04 +00:00
|
|
|
.get_mut(&(self.current_widget.widget_id - 1))
|
2020-04-02 00:31:43 +00:00
|
|
|
{
|
|
|
|
cpu_widget_state.scroll_state.current_scroll_position = 0;
|
|
|
|
cpu_widget_state.scroll_state.scroll_direction = ScrollDirection::UP;
|
|
|
|
}
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
self.reset_multi_tap_keys();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn skip_to_last(&mut self) {
|
|
|
|
if !self.is_in_dialog() {
|
2020-04-02 00:31:43 +00:00
|
|
|
match self.current_widget.widget_type {
|
|
|
|
BottomWidgetType::Proc => {
|
|
|
|
if let Some(proc_widget_state) = self
|
|
|
|
.proc_state
|
|
|
|
.widget_states
|
|
|
|
.get_mut(&self.current_widget.widget_id)
|
|
|
|
{
|
|
|
|
if let Some(finalized_process_data) = self
|
|
|
|
.canvas_data
|
|
|
|
.finalized_process_data_map
|
|
|
|
.get(&self.current_widget.widget_id)
|
|
|
|
{
|
|
|
|
if !self.canvas_data.finalized_process_data_map.is_empty() {
|
|
|
|
proc_widget_state.scroll_state.current_scroll_position =
|
|
|
|
finalized_process_data.len() as u64 - 1;
|
|
|
|
proc_widget_state.scroll_state.scroll_direction =
|
|
|
|
ScrollDirection::DOWN;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
2020-04-02 00:31:43 +00:00
|
|
|
BottomWidgetType::Temp => {
|
|
|
|
if let Some(temp_widget_state) = self
|
|
|
|
.temp_state
|
|
|
|
.widget_states
|
|
|
|
.get_mut(&self.current_widget.widget_id)
|
|
|
|
{
|
|
|
|
if !self.canvas_data.temp_sensor_data.is_empty() {
|
|
|
|
temp_widget_state.scroll_state.current_scroll_position =
|
|
|
|
self.canvas_data.temp_sensor_data.len() as u64 - 1;
|
|
|
|
temp_widget_state.scroll_state.scroll_direction = ScrollDirection::DOWN;
|
|
|
|
}
|
|
|
|
}
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
2020-04-02 00:31:43 +00:00
|
|
|
BottomWidgetType::Disk => {
|
|
|
|
if let Some(disk_widget_state) = self
|
|
|
|
.disk_state
|
|
|
|
.widget_states
|
|
|
|
.get_mut(&self.current_widget.widget_id)
|
|
|
|
{
|
|
|
|
if !self.canvas_data.disk_data.is_empty() {
|
|
|
|
disk_widget_state.scroll_state.current_scroll_position =
|
|
|
|
self.canvas_data.disk_data.len() as u64 - 1;
|
|
|
|
disk_widget_state.scroll_state.scroll_direction = ScrollDirection::DOWN;
|
|
|
|
}
|
|
|
|
}
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
2020-04-02 00:31:43 +00:00
|
|
|
BottomWidgetType::CpuLegend => {
|
|
|
|
let is_filtering_or_searching = self.is_filtering_or_searching();
|
|
|
|
if let Some(cpu_widget_state) = self
|
|
|
|
.cpu_state
|
|
|
|
.widget_states
|
2020-04-07 03:04:04 +00:00
|
|
|
.get_mut(&(self.current_widget.widget_id - 1))
|
2020-04-02 00:31:43 +00:00
|
|
|
{
|
|
|
|
let cap = if is_filtering_or_searching {
|
|
|
|
self.canvas_data.cpu_data.len()
|
|
|
|
} else {
|
|
|
|
cpu_widget_state.num_cpus_shown
|
|
|
|
} as u64;
|
|
|
|
|
|
|
|
if cap > 0 {
|
|
|
|
cpu_widget_state.scroll_state.current_scroll_position = cap - 1;
|
|
|
|
cpu_widget_state.scroll_state.scroll_direction = ScrollDirection::DOWN;
|
|
|
|
}
|
|
|
|
}
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
self.reset_multi_tap_keys();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn decrement_position_count(&mut self) {
|
|
|
|
if !self.is_in_dialog() {
|
2020-04-02 00:31:43 +00:00
|
|
|
match self.current_widget.widget_type {
|
|
|
|
BottomWidgetType::Proc => self.change_process_position(-1),
|
|
|
|
BottomWidgetType::Temp => self.change_temp_position(-1),
|
|
|
|
BottomWidgetType::Disk => self.change_disk_position(-1),
|
|
|
|
BottomWidgetType::CpuLegend => self.change_cpu_table_position(-1),
|
2020-02-29 22:05:01 +00:00
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
self.reset_multi_tap_keys();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn increment_position_count(&mut self) {
|
|
|
|
if !self.is_in_dialog() {
|
2020-04-02 00:31:43 +00:00
|
|
|
match self.current_widget.widget_type {
|
|
|
|
BottomWidgetType::Proc => self.change_process_position(1),
|
|
|
|
BottomWidgetType::Temp => self.change_temp_position(1),
|
|
|
|
BottomWidgetType::Disk => self.change_disk_position(1),
|
|
|
|
BottomWidgetType::CpuLegend => self.change_cpu_table_position(1),
|
2020-02-29 22:05:01 +00:00
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
self.reset_multi_tap_keys();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn change_cpu_table_position(&mut self, num_to_change_by: i64) {
|
2020-04-02 00:31:43 +00:00
|
|
|
let is_filtering_or_searching = self.is_filtering_or_searching();
|
|
|
|
if let Some(cpu_widget_state) = self
|
|
|
|
.cpu_state
|
|
|
|
.widget_states
|
|
|
|
.get_mut(&(self.current_widget.widget_id - 1))
|
|
|
|
{
|
|
|
|
let current_posn = cpu_widget_state.scroll_state.current_scroll_position;
|
2020-02-29 22:05:01 +00:00
|
|
|
|
2020-04-02 00:31:43 +00:00
|
|
|
let cap = if is_filtering_or_searching {
|
|
|
|
self.canvas_data.cpu_data.len()
|
|
|
|
} else {
|
|
|
|
cpu_widget_state.num_cpus_shown
|
|
|
|
};
|
2020-03-11 01:36:13 +00:00
|
|
|
|
2020-04-02 00:31:43 +00:00
|
|
|
if current_posn as i64 + num_to_change_by >= 0
|
|
|
|
&& current_posn as i64 + num_to_change_by < cap as i64
|
|
|
|
{
|
|
|
|
cpu_widget_state.scroll_state.current_scroll_position =
|
|
|
|
(current_posn as i64 + num_to_change_by) as u64;
|
|
|
|
}
|
|
|
|
|
|
|
|
if num_to_change_by < 0 {
|
|
|
|
cpu_widget_state.scroll_state.scroll_direction = ScrollDirection::UP;
|
|
|
|
} else {
|
|
|
|
cpu_widget_state.scroll_state.scroll_direction = ScrollDirection::DOWN;
|
|
|
|
}
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn change_process_position(&mut self, num_to_change_by: i64) {
|
2020-04-02 00:31:43 +00:00
|
|
|
if let Some(proc_widget_state) = self
|
|
|
|
.proc_state
|
|
|
|
.widget_states
|
|
|
|
.get_mut(&self.current_widget.widget_id)
|
2020-02-29 22:05:01 +00:00
|
|
|
{
|
2020-04-02 00:31:43 +00:00
|
|
|
let current_posn = proc_widget_state.scroll_state.current_scroll_position;
|
|
|
|
|
|
|
|
if let Some(finalized_process_data) = self
|
|
|
|
.canvas_data
|
|
|
|
.finalized_process_data_map
|
|
|
|
.get(&self.current_widget.widget_id)
|
|
|
|
{
|
|
|
|
if current_posn as i64 + num_to_change_by >= 0
|
|
|
|
&& current_posn as i64 + num_to_change_by < finalized_process_data.len() as i64
|
|
|
|
{
|
|
|
|
proc_widget_state.scroll_state.current_scroll_position =
|
|
|
|
(current_posn as i64 + num_to_change_by) as u64;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if num_to_change_by < 0 {
|
|
|
|
proc_widget_state.scroll_state.scroll_direction = ScrollDirection::UP;
|
|
|
|
} else {
|
|
|
|
proc_widget_state.scroll_state.scroll_direction = ScrollDirection::DOWN;
|
|
|
|
}
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn change_temp_position(&mut self, num_to_change_by: i64) {
|
2020-04-02 00:31:43 +00:00
|
|
|
if let Some(temp_widget_state) = self
|
|
|
|
.temp_state
|
|
|
|
.widget_states
|
|
|
|
.get_mut(&self.current_widget.widget_id)
|
2020-02-29 22:05:01 +00:00
|
|
|
{
|
2020-04-02 00:31:43 +00:00
|
|
|
let current_posn = temp_widget_state.scroll_state.current_scroll_position;
|
|
|
|
|
|
|
|
if current_posn as i64 + num_to_change_by >= 0
|
|
|
|
&& current_posn as i64 + num_to_change_by
|
|
|
|
< self.canvas_data.temp_sensor_data.len() as i64
|
|
|
|
{
|
|
|
|
temp_widget_state.scroll_state.current_scroll_position =
|
|
|
|
(current_posn as i64 + num_to_change_by) as u64;
|
|
|
|
}
|
|
|
|
|
|
|
|
if num_to_change_by < 0 {
|
|
|
|
temp_widget_state.scroll_state.scroll_direction = ScrollDirection::UP;
|
|
|
|
} else {
|
|
|
|
temp_widget_state.scroll_state.scroll_direction = ScrollDirection::DOWN;
|
|
|
|
}
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn change_disk_position(&mut self, num_to_change_by: i64) {
|
2020-04-02 00:31:43 +00:00
|
|
|
if let Some(disk_widget_state) = self
|
|
|
|
.disk_state
|
|
|
|
.widget_states
|
|
|
|
.get_mut(&self.current_widget.widget_id)
|
2020-02-29 22:05:01 +00:00
|
|
|
{
|
2020-04-02 00:31:43 +00:00
|
|
|
let current_posn = disk_widget_state.scroll_state.current_scroll_position;
|
|
|
|
|
|
|
|
if current_posn as i64 + num_to_change_by >= 0
|
|
|
|
&& current_posn as i64 + num_to_change_by < self.canvas_data.disk_data.len() as i64
|
|
|
|
{
|
|
|
|
disk_widget_state.scroll_state.current_scroll_position =
|
|
|
|
(current_posn as i64 + num_to_change_by) as u64;
|
|
|
|
}
|
|
|
|
|
|
|
|
if num_to_change_by < 0 {
|
|
|
|
disk_widget_state.scroll_state.scroll_direction = ScrollDirection::UP;
|
|
|
|
} else {
|
|
|
|
disk_widget_state.scroll_state.scroll_direction = ScrollDirection::DOWN;
|
|
|
|
}
|
2020-02-29 22:05:01 +00:00
|
|
|
}
|
|
|
|
}
|
2020-03-08 20:17:28 +00:00
|
|
|
|
|
|
|
pub fn handle_scroll_up(&mut self) {
|
2020-04-02 00:31:43 +00:00
|
|
|
if self.current_widget.widget_type.is_widget_graph() {
|
2020-03-08 20:17:28 +00:00
|
|
|
self.zoom_in();
|
2020-04-02 00:31:43 +00:00
|
|
|
} else if self.current_widget.widget_type.is_widget_table() {
|
2020-03-08 20:17:28 +00:00
|
|
|
self.decrement_position_count();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn handle_scroll_down(&mut self) {
|
2020-04-02 00:31:43 +00:00
|
|
|
if self.current_widget.widget_type.is_widget_graph() {
|
2020-03-08 20:17:28 +00:00
|
|
|
self.zoom_out();
|
2020-04-02 00:31:43 +00:00
|
|
|
} else if self.current_widget.widget_type.is_widget_table() {
|
2020-03-08 20:17:28 +00:00
|
|
|
self.increment_position_count();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-08 23:47:10 +00:00
|
|
|
fn zoom_out(&mut self) {
|
2020-04-02 00:31:43 +00:00
|
|
|
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_time = cpu_widget_state.current_display_time
|
|
|
|
+ self.app_config_fields.time_interval;
|
|
|
|
if new_time <= constants::STALE_MAX_MILLISECONDS {
|
|
|
|
cpu_widget_state.current_display_time = new_time;
|
|
|
|
self.cpu_state.force_update = Some(self.current_widget.widget_id);
|
|
|
|
if self.app_config_fields.autohide_time {
|
|
|
|
cpu_widget_state.autohide_timer = Some(Instant::now());
|
|
|
|
}
|
|
|
|
} else if cpu_widget_state.current_display_time
|
|
|
|
!= constants::STALE_MAX_MILLISECONDS
|
|
|
|
{
|
|
|
|
cpu_widget_state.current_display_time = constants::STALE_MAX_MILLISECONDS;
|
|
|
|
self.cpu_state.force_update = Some(self.current_widget.widget_id);
|
|
|
|
if self.app_config_fields.autohide_time {
|
|
|
|
cpu_widget_state.autohide_timer = Some(Instant::now());
|
|
|
|
}
|
2020-03-09 04:52:29 +00:00
|
|
|
}
|
2020-03-08 23:47:10 +00:00
|
|
|
}
|
|
|
|
}
|
2020-04-02 00:31:43 +00:00
|
|
|
BottomWidgetType::Mem => {
|
|
|
|
if let Some(mem_widget_state) = self
|
|
|
|
.mem_state
|
|
|
|
.widget_states
|
|
|
|
.get_mut(&self.current_widget.widget_id)
|
|
|
|
{
|
|
|
|
let new_time = mem_widget_state.current_display_time
|
|
|
|
+ self.app_config_fields.time_interval;
|
|
|
|
if new_time <= constants::STALE_MAX_MILLISECONDS {
|
|
|
|
mem_widget_state.current_display_time = new_time;
|
|
|
|
self.mem_state.force_update = Some(self.current_widget.widget_id);
|
|
|
|
if self.app_config_fields.autohide_time {
|
|
|
|
mem_widget_state.autohide_timer = Some(Instant::now());
|
|
|
|
}
|
|
|
|
} else if mem_widget_state.current_display_time
|
|
|
|
!= constants::STALE_MAX_MILLISECONDS
|
|
|
|
{
|
|
|
|
mem_widget_state.current_display_time = constants::STALE_MAX_MILLISECONDS;
|
|
|
|
self.mem_state.force_update = Some(self.current_widget.widget_id);
|
|
|
|
if self.app_config_fields.autohide_time {
|
|
|
|
mem_widget_state.autohide_timer = Some(Instant::now());
|
|
|
|
}
|
2020-03-09 04:52:29 +00:00
|
|
|
}
|
2020-03-08 23:47:10 +00:00
|
|
|
}
|
|
|
|
}
|
2020-04-02 00:31:43 +00:00
|
|
|
BottomWidgetType::Net => {
|
|
|
|
if let Some(net_widget_state) = self
|
|
|
|
.net_state
|
|
|
|
.widget_states
|
|
|
|
.get_mut(&self.current_widget.widget_id)
|
|
|
|
{
|
|
|
|
let new_time = net_widget_state.current_display_time
|
|
|
|
+ self.app_config_fields.time_interval;
|
|
|
|
if new_time <= constants::STALE_MAX_MILLISECONDS {
|
|
|
|
net_widget_state.current_display_time = new_time;
|
|
|
|
self.net_state.force_update = Some(self.current_widget.widget_id);
|
|
|
|
if self.app_config_fields.autohide_time {
|
|
|
|
net_widget_state.autohide_timer = Some(Instant::now());
|
|
|
|
}
|
|
|
|
} else if net_widget_state.current_display_time
|
|
|
|
!= constants::STALE_MAX_MILLISECONDS
|
|
|
|
{
|
|
|
|
net_widget_state.current_display_time = constants::STALE_MAX_MILLISECONDS;
|
|
|
|
self.net_state.force_update = Some(self.current_widget.widget_id);
|
|
|
|
if self.app_config_fields.autohide_time {
|
|
|
|
net_widget_state.autohide_timer = Some(Instant::now());
|
|
|
|
}
|
2020-03-09 04:52:29 +00:00
|
|
|
}
|
2020-03-08 23:47:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
}
|
2020-03-08 20:17:28 +00:00
|
|
|
|
2020-03-08 23:47:10 +00:00
|
|
|
fn zoom_in(&mut self) {
|
2020-04-02 00:31:43 +00:00
|
|
|
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_time = cpu_widget_state.current_display_time
|
|
|
|
- self.app_config_fields.time_interval;
|
|
|
|
if new_time >= constants::STALE_MIN_MILLISECONDS {
|
|
|
|
cpu_widget_state.current_display_time = new_time;
|
|
|
|
self.cpu_state.force_update = Some(self.current_widget.widget_id);
|
|
|
|
if self.app_config_fields.autohide_time {
|
|
|
|
cpu_widget_state.autohide_timer = Some(Instant::now());
|
|
|
|
}
|
|
|
|
} else if cpu_widget_state.current_display_time
|
|
|
|
!= constants::STALE_MIN_MILLISECONDS
|
|
|
|
{
|
|
|
|
cpu_widget_state.current_display_time = constants::STALE_MIN_MILLISECONDS;
|
|
|
|
self.cpu_state.force_update = Some(self.current_widget.widget_id);
|
|
|
|
if self.app_config_fields.autohide_time {
|
|
|
|
cpu_widget_state.autohide_timer = Some(Instant::now());
|
|
|
|
}
|
2020-03-09 04:52:29 +00:00
|
|
|
}
|
2020-03-08 23:47:10 +00:00
|
|
|
}
|
|
|
|
}
|
2020-04-02 00:31:43 +00:00
|
|
|
BottomWidgetType::Mem => {
|
|
|
|
if let Some(mem_widget_state) = self
|
|
|
|
.mem_state
|
|
|
|
.widget_states
|
|
|
|
.get_mut(&self.current_widget.widget_id)
|
|
|
|
{
|
|
|
|
let new_time = mem_widget_state.current_display_time
|
|
|
|
- self.app_config_fields.time_interval;
|
|
|
|
if new_time >= constants::STALE_MIN_MILLISECONDS {
|
|
|
|
mem_widget_state.current_display_time = new_time;
|
|
|
|
self.mem_state.force_update = Some(self.current_widget.widget_id);
|
|
|
|
if self.app_config_fields.autohide_time {
|
|
|
|
mem_widget_state.autohide_timer = Some(Instant::now());
|
|
|
|
}
|
|
|
|
} else if mem_widget_state.current_display_time
|
|
|
|
!= constants::STALE_MIN_MILLISECONDS
|
|
|
|
{
|
|
|
|
mem_widget_state.current_display_time = constants::STALE_MIN_MILLISECONDS;
|
|
|
|
self.mem_state.force_update = Some(self.current_widget.widget_id);
|
|
|
|
if self.app_config_fields.autohide_time {
|
|
|
|
mem_widget_state.autohide_timer = Some(Instant::now());
|
|
|
|
}
|
2020-03-09 04:52:29 +00:00
|
|
|
}
|
2020-03-08 23:47:10 +00:00
|
|
|
}
|
|
|
|
}
|
2020-04-02 00:31:43 +00:00
|
|
|
BottomWidgetType::Net => {
|
|
|
|
if let Some(net_widget_state) = self
|
|
|
|
.net_state
|
|
|
|
.widget_states
|
|
|
|
.get_mut(&self.current_widget.widget_id)
|
|
|
|
{
|
|
|
|
let new_time = net_widget_state.current_display_time
|
|
|
|
- self.app_config_fields.time_interval;
|
|
|
|
if new_time >= constants::STALE_MIN_MILLISECONDS {
|
|
|
|
net_widget_state.current_display_time = new_time;
|
|
|
|
self.net_state.force_update = Some(self.current_widget.widget_id);
|
|
|
|
if self.app_config_fields.autohide_time {
|
|
|
|
net_widget_state.autohide_timer = Some(Instant::now());
|
|
|
|
}
|
|
|
|
} else if net_widget_state.current_display_time
|
|
|
|
!= constants::STALE_MIN_MILLISECONDS
|
|
|
|
{
|
|
|
|
net_widget_state.current_display_time = constants::STALE_MIN_MILLISECONDS;
|
|
|
|
self.net_state.force_update = Some(self.current_widget.widget_id);
|
|
|
|
if self.app_config_fields.autohide_time {
|
|
|
|
net_widget_state.autohide_timer = Some(Instant::now());
|
|
|
|
}
|
2020-03-09 04:52:29 +00:00
|
|
|
}
|
2020-03-08 23:47:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-13 05:07:24 +00:00
|
|
|
fn reset_cpu_zoom(&mut self) {
|
2020-04-02 00:31:43 +00:00
|
|
|
if let Some(cpu_widget_state) = self
|
|
|
|
.cpu_state
|
|
|
|
.widget_states
|
|
|
|
.get_mut(&self.current_widget.widget_id)
|
|
|
|
{
|
|
|
|
cpu_widget_state.current_display_time = self.app_config_fields.default_time_value;
|
|
|
|
self.cpu_state.force_update = Some(self.current_widget.widget_id);
|
|
|
|
if self.app_config_fields.autohide_time {
|
|
|
|
cpu_widget_state.autohide_timer = Some(Instant::now());
|
|
|
|
}
|
2020-03-13 05:07:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn reset_mem_zoom(&mut self) {
|
2020-04-02 00:31:43 +00:00
|
|
|
if let Some(mem_widget_state) = self
|
|
|
|
.mem_state
|
|
|
|
.widget_states
|
|
|
|
.get_mut(&self.current_widget.widget_id)
|
|
|
|
{
|
|
|
|
mem_widget_state.current_display_time = self.app_config_fields.default_time_value;
|
|
|
|
self.mem_state.force_update = Some(self.current_widget.widget_id);
|
|
|
|
if self.app_config_fields.autohide_time {
|
|
|
|
mem_widget_state.autohide_timer = Some(Instant::now());
|
|
|
|
}
|
2020-03-13 05:07:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn reset_net_zoom(&mut self) {
|
2020-04-02 00:31:43 +00:00
|
|
|
if let Some(net_widget_state) = self
|
|
|
|
.net_state
|
|
|
|
.widget_states
|
|
|
|
.get_mut(&self.current_widget.widget_id)
|
|
|
|
{
|
|
|
|
net_widget_state.current_display_time = self.app_config_fields.default_time_value;
|
|
|
|
self.net_state.force_update = Some(self.current_widget.widget_id);
|
|
|
|
if self.app_config_fields.autohide_time {
|
|
|
|
net_widget_state.autohide_timer = Some(Instant::now());
|
|
|
|
}
|
2020-03-13 05:07:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-08 23:47:10 +00:00
|
|
|
fn reset_zoom(&mut self) {
|
2020-04-02 00:31:43 +00:00
|
|
|
match self.current_widget.widget_type {
|
|
|
|
BottomWidgetType::Cpu => self.reset_cpu_zoom(),
|
|
|
|
BottomWidgetType::Mem => self.reset_mem_zoom(),
|
|
|
|
BottomWidgetType::Net => self.reset_net_zoom(),
|
2020-03-08 23:47:10 +00:00
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
}
|
2019-09-08 23:56:23 +00:00
|
|
|
}
|