mirror of
https://github.com/ClementTsang/bottom
synced 2024-11-22 20:23:12 +00:00
refactor: separate state to different file
This commit is contained in:
parent
3d6ebc5152
commit
8534d42f1b
5 changed files with 467 additions and 445 deletions
|
@ -418,8 +418,8 @@ and get the following CPU donut:
|
|||
### Battery
|
||||
|
||||
You can get battery statistics (charge, time to fill/discharge, consumption in watts, and battery health) via the battery widget.
|
||||
Since this is only useful for devices like laptops, it is off by default. Currently, the only way to use it is to set it
|
||||
as a widget via [layouts](#layout).
|
||||
|
||||
Since this is only useful for devices like laptops, it is off by default. You can either enable the widget in the default layout via the `--battery` flag, or by specifying the widget in a [layout](#layout).
|
||||
|
||||
So with this slightly silly layout:
|
||||
|
||||
|
|
445
src/app.rs
445
src/app.rs
|
@ -3,13 +3,12 @@ use std::{cmp::max, collections::HashMap, time::Instant};
|
|||
use unicode_segmentation::GraphemeCursor;
|
||||
use unicode_width::{UnicodeWidthChar, UnicodeWidthStr};
|
||||
|
||||
use tui::widgets::TableState;
|
||||
|
||||
use typed_builder::*;
|
||||
|
||||
use data_farmer::*;
|
||||
use data_harvester::{processes, temperature};
|
||||
use layout_manager::*;
|
||||
pub use states::*;
|
||||
|
||||
use crate::{
|
||||
canvas, constants,
|
||||
|
@ -20,60 +19,10 @@ pub mod data_farmer;
|
|||
pub mod data_harvester;
|
||||
pub mod layout_manager;
|
||||
mod process_killer;
|
||||
pub mod states;
|
||||
|
||||
const MAX_SEARCH_LENGTH: usize = 200;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ScrollDirection {
|
||||
// UP means scrolling up --- this usually DECREMENTS
|
||||
UP,
|
||||
// DOWN means scrolling down --- this usually INCREMENTS
|
||||
DOWN,
|
||||
}
|
||||
|
||||
impl Default for ScrollDirection {
|
||||
fn default() -> Self {
|
||||
ScrollDirection::DOWN
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum CursorDirection {
|
||||
LEFT,
|
||||
RIGHT,
|
||||
}
|
||||
|
||||
/// AppScrollWidgetState deals with fields for a scrollable app's current state.
|
||||
#[derive(Default)]
|
||||
pub struct AppScrollWidgetState {
|
||||
pub current_scroll_position: u64,
|
||||
pub previous_scroll_position: u64,
|
||||
pub scroll_direction: ScrollDirection,
|
||||
pub table_state: TableState,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct AppDeleteDialogState {
|
||||
pub is_showing_dd: bool,
|
||||
pub is_on_yes: bool, // Defaults to "No"
|
||||
}
|
||||
|
||||
pub struct AppHelpDialogState {
|
||||
pub is_showing_help: bool,
|
||||
pub scroll_state: ParagraphScrollState,
|
||||
pub index_shortcuts: Vec<u16>,
|
||||
}
|
||||
|
||||
impl Default for AppHelpDialogState {
|
||||
fn default() -> Self {
|
||||
AppHelpDialogState {
|
||||
is_showing_help: false,
|
||||
scroll_state: ParagraphScrollState::default(),
|
||||
index_shortcuts: vec![0; constants::HELP_TEXT.len()],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// AppConfigFields is meant to cover basic fields that would normally be set
|
||||
/// by config files or launch options.
|
||||
pub struct AppConfigFields {
|
||||
|
@ -93,396 +42,6 @@ pub struct AppConfigFields {
|
|||
pub table_gap: u16,
|
||||
}
|
||||
|
||||
/// AppSearchState deals with generic searching (I might do this in the future).
|
||||
pub struct AppSearchState {
|
||||
pub is_enabled: bool,
|
||||
pub current_search_query: String,
|
||||
pub current_regex: Option<std::result::Result<regex::Regex, regex::Error>>,
|
||||
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,
|
||||
}
|
||||
|
||||
impl Default for AppSearchState {
|
||||
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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AppSearchState {
|
||||
/// Returns a reset but still enabled app search state
|
||||
pub fn reset(&mut self) {
|
||||
*self = AppSearchState {
|
||||
is_enabled: self.is_enabled,
|
||||
..AppSearchState::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_invalid_or_blank_search(&self) -> bool {
|
||||
self.is_blank_search || self.is_invalid_search
|
||||
}
|
||||
}
|
||||
|
||||
/// ProcessSearchState only deals with process' search's current settings and state.
|
||||
pub struct ProcessSearchState {
|
||||
pub search_state: AppSearchState,
|
||||
pub is_searching_with_pid: bool,
|
||||
pub is_ignoring_case: bool,
|
||||
pub is_searching_whole_word: bool,
|
||||
pub is_searching_with_regex: bool,
|
||||
}
|
||||
|
||||
impl Default for ProcessSearchState {
|
||||
fn default() -> Self {
|
||||
ProcessSearchState {
|
||||
search_state: AppSearchState::default(),
|
||||
is_searching_with_pid: false,
|
||||
is_ignoring_case: true,
|
||||
is_searching_whole_word: false,
|
||||
is_searching_with_regex: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ProcessSearchState {
|
||||
pub fn search_toggle_ignore_case(&mut self) {
|
||||
self.is_ignoring_case = !self.is_ignoring_case;
|
||||
}
|
||||
|
||||
pub fn search_toggle_whole_word(&mut self) {
|
||||
self.is_searching_whole_word = !self.is_searching_whole_word;
|
||||
}
|
||||
|
||||
pub fn search_toggle_regex(&mut self) {
|
||||
self.is_searching_with_regex = !self.is_searching_with_regex;
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
ProcWidgetState {
|
||||
process_search_state,
|
||||
is_grouped,
|
||||
scroll_state: AppScrollWidgetState::default(),
|
||||
process_sorting_type: processes::ProcessSorting::CPU,
|
||||
process_sorting_reverse: true,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_cursor_position(&self) -> usize {
|
||||
self.process_search_state
|
||||
.search_state
|
||||
.grapheme_cursor
|
||||
.cur_cursor()
|
||||
}
|
||||
|
||||
pub fn get_char_cursor_position(&self) -> usize {
|
||||
self.process_search_state.search_state.char_cursor_position
|
||||
}
|
||||
|
||||
pub fn is_search_enabled(&self) -> bool {
|
||||
self.process_search_state.search_state.is_enabled
|
||||
}
|
||||
|
||||
pub fn get_current_search_query(&self) -> &String {
|
||||
&self.process_search_state.search_state.current_search_query
|
||||
}
|
||||
|
||||
pub fn update_regex(&mut self) {
|
||||
if self
|
||||
.process_search_state
|
||||
.search_state
|
||||
.current_search_query
|
||||
.is_empty()
|
||||
{
|
||||
self.process_search_state.search_state.is_invalid_search = false;
|
||||
self.process_search_state.search_state.is_blank_search = true;
|
||||
} else {
|
||||
let regex_string = &self.process_search_state.search_state.current_search_query;
|
||||
let escaped_regex: String;
|
||||
let final_regex_string = &format!(
|
||||
"{}{}{}{}",
|
||||
if self.process_search_state.is_searching_whole_word {
|
||||
"^"
|
||||
} else {
|
||||
""
|
||||
},
|
||||
if self.process_search_state.is_ignoring_case {
|
||||
"(?i)"
|
||||
} else {
|
||||
""
|
||||
},
|
||||
if !self.process_search_state.is_searching_with_regex {
|
||||
escaped_regex = regex::escape(regex_string);
|
||||
&escaped_regex
|
||||
} else {
|
||||
regex_string
|
||||
},
|
||||
if self.process_search_state.is_searching_whole_word {
|
||||
"$"
|
||||
} else {
|
||||
""
|
||||
},
|
||||
);
|
||||
|
||||
let new_regex = regex::Regex::new(final_regex_string);
|
||||
self.process_search_state.search_state.is_blank_search = false;
|
||||
self.process_search_state.search_state.is_invalid_search = new_regex.is_err();
|
||||
|
||||
self.process_search_state.search_state.current_regex = Some(new_regex);
|
||||
}
|
||||
self.scroll_state.previous_scroll_position = 0;
|
||||
self.scroll_state.current_scroll_position = 0;
|
||||
}
|
||||
|
||||
pub fn clear_search(&mut self) {
|
||||
self.process_search_state.search_state.reset();
|
||||
}
|
||||
|
||||
pub fn search_walk_forward(&mut self, start_position: usize) {
|
||||
self.process_search_state
|
||||
.search_state
|
||||
.grapheme_cursor
|
||||
.next_boundary(
|
||||
&self.process_search_state.search_state.current_search_query[start_position..],
|
||||
start_position,
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
pub fn search_walk_back(&mut self, start_position: usize) {
|
||||
self.process_search_state
|
||||
.search_state
|
||||
.grapheme_cursor
|
||||
.prev_boundary(
|
||||
&self.process_search_state.search_state.current_search_query[..start_position],
|
||||
0,
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ProcState {
|
||||
pub widget_states: HashMap<u64, ProcWidgetState>,
|
||||
pub force_update: Option<u64>,
|
||||
pub force_update_all: bool,
|
||||
}
|
||||
|
||||
impl ProcState {
|
||||
pub fn init(widget_states: HashMap<u64, ProcWidgetState>) -> Self {
|
||||
ProcState {
|
||||
widget_states,
|
||||
force_update: None,
|
||||
force_update_all: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct NetWidgetState {
|
||||
pub current_display_time: u64,
|
||||
pub autohide_timer: Option<Instant>,
|
||||
}
|
||||
|
||||
impl NetWidgetState {
|
||||
pub fn init(current_display_time: u64, autohide_timer: Option<Instant>) -> Self {
|
||||
NetWidgetState {
|
||||
current_display_time,
|
||||
autohide_timer,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct NetState {
|
||||
pub force_update: Option<u64>,
|
||||
pub widget_states: HashMap<u64, NetWidgetState>,
|
||||
}
|
||||
|
||||
impl NetState {
|
||||
pub fn init(widget_states: HashMap<u64, NetWidgetState>) -> Self {
|
||||
NetState {
|
||||
force_update: None,
|
||||
widget_states,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CpuWidgetState {
|
||||
pub current_display_time: u64,
|
||||
pub is_legend_hidden: bool,
|
||||
pub is_showing_tray: bool,
|
||||
pub core_show_vec: Vec<bool>,
|
||||
pub num_cpus_shown: usize,
|
||||
pub autohide_timer: Option<Instant>,
|
||||
pub scroll_state: AppScrollWidgetState,
|
||||
}
|
||||
|
||||
impl CpuWidgetState {
|
||||
pub fn init(current_display_time: u64, autohide_timer: Option<Instant>) -> Self {
|
||||
CpuWidgetState {
|
||||
current_display_time,
|
||||
is_legend_hidden: false,
|
||||
is_showing_tray: false,
|
||||
core_show_vec: Vec::new(),
|
||||
num_cpus_shown: 0,
|
||||
autohide_timer,
|
||||
scroll_state: AppScrollWidgetState::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CpuState {
|
||||
pub force_update: Option<u64>,
|
||||
pub widget_states: HashMap<u64, CpuWidgetState>,
|
||||
pub num_cpus_total: usize,
|
||||
}
|
||||
|
||||
impl CpuState {
|
||||
pub fn init(widget_states: HashMap<u64, CpuWidgetState>) -> Self {
|
||||
CpuState {
|
||||
force_update: None,
|
||||
widget_states,
|
||||
num_cpus_total: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MemWidgetState {
|
||||
pub current_display_time: u64,
|
||||
pub autohide_timer: Option<Instant>,
|
||||
}
|
||||
|
||||
impl MemWidgetState {
|
||||
pub fn init(current_display_time: u64, autohide_timer: Option<Instant>) -> Self {
|
||||
MemWidgetState {
|
||||
current_display_time,
|
||||
autohide_timer,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MemState {
|
||||
pub force_update: Option<u64>,
|
||||
pub widget_states: HashMap<u64, MemWidgetState>,
|
||||
}
|
||||
|
||||
impl MemState {
|
||||
pub fn init(widget_states: HashMap<u64, MemWidgetState>) -> Self {
|
||||
MemState {
|
||||
force_update: None,
|
||||
widget_states,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TempWidgetState {
|
||||
pub scroll_state: AppScrollWidgetState,
|
||||
}
|
||||
|
||||
impl TempWidgetState {
|
||||
pub fn init() -> Self {
|
||||
TempWidgetState {
|
||||
scroll_state: AppScrollWidgetState::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TempState {
|
||||
pub widget_states: HashMap<u64, TempWidgetState>,
|
||||
}
|
||||
|
||||
impl TempState {
|
||||
pub fn init(widget_states: HashMap<u64, TempWidgetState>) -> Self {
|
||||
TempState { widget_states }
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DiskWidgetState {
|
||||
pub scroll_state: AppScrollWidgetState,
|
||||
}
|
||||
|
||||
impl DiskWidgetState {
|
||||
pub fn init() -> Self {
|
||||
DiskWidgetState {
|
||||
scroll_state: AppScrollWidgetState::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DiskState {
|
||||
pub widget_states: HashMap<u64, DiskWidgetState>,
|
||||
}
|
||||
|
||||
impl DiskState {
|
||||
pub fn init(widget_states: HashMap<u64, DiskWidgetState>) -> Self {
|
||||
DiskState { widget_states }
|
||||
}
|
||||
}
|
||||
pub struct BasicTableWidgetState {
|
||||
// Since this is intended (currently) to only be used for ONE widget, that's
|
||||
// how it's going to be written. If we want to allow for multiple of these,
|
||||
// then we can expand outwards with a normal BasicTableState and a hashmap
|
||||
pub currently_displayed_widget_type: BottomWidgetType,
|
||||
pub currently_displayed_widget_id: u64,
|
||||
pub widget_id: i64,
|
||||
}
|
||||
|
||||
#[derive(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 }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct ParagraphScrollState {
|
||||
pub current_scroll_index: u16,
|
||||
pub max_scroll_index: u16,
|
||||
}
|
||||
|
||||
#[derive(TypedBuilder)]
|
||||
pub struct App {
|
||||
#[builder(default = false, setter(skip))]
|
||||
|
|
448
src/app/states.rs
Normal file
448
src/app/states.rs
Normal file
|
@ -0,0 +1,448 @@
|
|||
use std::{collections::HashMap, time::Instant};
|
||||
|
||||
use unicode_segmentation::GraphemeCursor;
|
||||
|
||||
use tui::widgets::TableState;
|
||||
|
||||
use crate::{app::layout_manager::BottomWidgetType, constants, data_harvester::processes};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ScrollDirection {
|
||||
// UP means scrolling up --- this usually DECREMENTS
|
||||
UP,
|
||||
// DOWN means scrolling down --- this usually INCREMENTS
|
||||
DOWN,
|
||||
}
|
||||
|
||||
impl Default for ScrollDirection {
|
||||
fn default() -> Self {
|
||||
ScrollDirection::DOWN
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum CursorDirection {
|
||||
LEFT,
|
||||
RIGHT,
|
||||
}
|
||||
|
||||
/// AppScrollWidgetState deals with fields for a scrollable app's current state.
|
||||
#[derive(Default)]
|
||||
pub struct AppScrollWidgetState {
|
||||
pub current_scroll_position: u64,
|
||||
pub previous_scroll_position: u64,
|
||||
pub scroll_direction: ScrollDirection,
|
||||
pub table_state: TableState,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct AppDeleteDialogState {
|
||||
pub is_showing_dd: bool,
|
||||
pub is_on_yes: bool, // Defaults to "No"
|
||||
}
|
||||
|
||||
pub struct AppHelpDialogState {
|
||||
pub is_showing_help: bool,
|
||||
pub scroll_state: ParagraphScrollState,
|
||||
pub index_shortcuts: Vec<u16>,
|
||||
}
|
||||
|
||||
impl Default for AppHelpDialogState {
|
||||
fn default() -> Self {
|
||||
AppHelpDialogState {
|
||||
is_showing_help: false,
|
||||
scroll_state: ParagraphScrollState::default(),
|
||||
index_shortcuts: vec![0; constants::HELP_TEXT.len()],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// AppSearchState deals with generic searching (I might do this in the future).
|
||||
pub struct AppSearchState {
|
||||
pub is_enabled: bool,
|
||||
pub current_search_query: String,
|
||||
pub current_regex: Option<std::result::Result<regex::Regex, regex::Error>>,
|
||||
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,
|
||||
}
|
||||
|
||||
impl Default for AppSearchState {
|
||||
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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AppSearchState {
|
||||
/// Returns a reset but still enabled app search state
|
||||
pub fn reset(&mut self) {
|
||||
*self = AppSearchState {
|
||||
is_enabled: self.is_enabled,
|
||||
..AppSearchState::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_invalid_or_blank_search(&self) -> bool {
|
||||
self.is_blank_search || self.is_invalid_search
|
||||
}
|
||||
}
|
||||
|
||||
/// ProcessSearchState only deals with process' search's current settings and state.
|
||||
pub struct ProcessSearchState {
|
||||
pub search_state: AppSearchState,
|
||||
pub is_searching_with_pid: bool,
|
||||
pub is_ignoring_case: bool,
|
||||
pub is_searching_whole_word: bool,
|
||||
pub is_searching_with_regex: bool,
|
||||
}
|
||||
|
||||
impl Default for ProcessSearchState {
|
||||
fn default() -> Self {
|
||||
ProcessSearchState {
|
||||
search_state: AppSearchState::default(),
|
||||
is_searching_with_pid: false,
|
||||
is_ignoring_case: true,
|
||||
is_searching_whole_word: false,
|
||||
is_searching_with_regex: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ProcessSearchState {
|
||||
pub fn search_toggle_ignore_case(&mut self) {
|
||||
self.is_ignoring_case = !self.is_ignoring_case;
|
||||
}
|
||||
|
||||
pub fn search_toggle_whole_word(&mut self) {
|
||||
self.is_searching_whole_word = !self.is_searching_whole_word;
|
||||
}
|
||||
|
||||
pub fn search_toggle_regex(&mut self) {
|
||||
self.is_searching_with_regex = !self.is_searching_with_regex;
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
ProcWidgetState {
|
||||
process_search_state,
|
||||
is_grouped,
|
||||
scroll_state: AppScrollWidgetState::default(),
|
||||
process_sorting_type: processes::ProcessSorting::CPU,
|
||||
process_sorting_reverse: true,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_cursor_position(&self) -> usize {
|
||||
self.process_search_state
|
||||
.search_state
|
||||
.grapheme_cursor
|
||||
.cur_cursor()
|
||||
}
|
||||
|
||||
pub fn get_char_cursor_position(&self) -> usize {
|
||||
self.process_search_state.search_state.char_cursor_position
|
||||
}
|
||||
|
||||
pub fn is_search_enabled(&self) -> bool {
|
||||
self.process_search_state.search_state.is_enabled
|
||||
}
|
||||
|
||||
pub fn get_current_search_query(&self) -> &String {
|
||||
&self.process_search_state.search_state.current_search_query
|
||||
}
|
||||
|
||||
pub fn update_regex(&mut self) {
|
||||
if self
|
||||
.process_search_state
|
||||
.search_state
|
||||
.current_search_query
|
||||
.is_empty()
|
||||
{
|
||||
self.process_search_state.search_state.is_invalid_search = false;
|
||||
self.process_search_state.search_state.is_blank_search = true;
|
||||
} else {
|
||||
let regex_string = &self.process_search_state.search_state.current_search_query;
|
||||
let escaped_regex: String;
|
||||
let final_regex_string = &format!(
|
||||
"{}{}{}{}",
|
||||
if self.process_search_state.is_searching_whole_word {
|
||||
"^"
|
||||
} else {
|
||||
""
|
||||
},
|
||||
if self.process_search_state.is_ignoring_case {
|
||||
"(?i)"
|
||||
} else {
|
||||
""
|
||||
},
|
||||
if !self.process_search_state.is_searching_with_regex {
|
||||
escaped_regex = regex::escape(regex_string);
|
||||
&escaped_regex
|
||||
} else {
|
||||
regex_string
|
||||
},
|
||||
if self.process_search_state.is_searching_whole_word {
|
||||
"$"
|
||||
} else {
|
||||
""
|
||||
},
|
||||
);
|
||||
|
||||
let new_regex = regex::Regex::new(final_regex_string);
|
||||
self.process_search_state.search_state.is_blank_search = false;
|
||||
self.process_search_state.search_state.is_invalid_search = new_regex.is_err();
|
||||
|
||||
self.process_search_state.search_state.current_regex = Some(new_regex);
|
||||
}
|
||||
self.scroll_state.previous_scroll_position = 0;
|
||||
self.scroll_state.current_scroll_position = 0;
|
||||
}
|
||||
|
||||
pub fn clear_search(&mut self) {
|
||||
self.process_search_state.search_state.reset();
|
||||
}
|
||||
|
||||
pub fn search_walk_forward(&mut self, start_position: usize) {
|
||||
self.process_search_state
|
||||
.search_state
|
||||
.grapheme_cursor
|
||||
.next_boundary(
|
||||
&self.process_search_state.search_state.current_search_query[start_position..],
|
||||
start_position,
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
pub fn search_walk_back(&mut self, start_position: usize) {
|
||||
self.process_search_state
|
||||
.search_state
|
||||
.grapheme_cursor
|
||||
.prev_boundary(
|
||||
&self.process_search_state.search_state.current_search_query[..start_position],
|
||||
0,
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ProcState {
|
||||
pub widget_states: HashMap<u64, ProcWidgetState>,
|
||||
pub force_update: Option<u64>,
|
||||
pub force_update_all: bool,
|
||||
}
|
||||
|
||||
impl ProcState {
|
||||
pub fn init(widget_states: HashMap<u64, ProcWidgetState>) -> Self {
|
||||
ProcState {
|
||||
widget_states,
|
||||
force_update: None,
|
||||
force_update_all: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct NetWidgetState {
|
||||
pub current_display_time: u64,
|
||||
pub autohide_timer: Option<Instant>,
|
||||
}
|
||||
|
||||
impl NetWidgetState {
|
||||
pub fn init(current_display_time: u64, autohide_timer: Option<Instant>) -> Self {
|
||||
NetWidgetState {
|
||||
current_display_time,
|
||||
autohide_timer,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct NetState {
|
||||
pub force_update: Option<u64>,
|
||||
pub widget_states: HashMap<u64, NetWidgetState>,
|
||||
}
|
||||
|
||||
impl NetState {
|
||||
pub fn init(widget_states: HashMap<u64, NetWidgetState>) -> Self {
|
||||
NetState {
|
||||
force_update: None,
|
||||
widget_states,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CpuWidgetState {
|
||||
pub current_display_time: u64,
|
||||
pub is_legend_hidden: bool,
|
||||
pub is_showing_tray: bool,
|
||||
pub core_show_vec: Vec<bool>,
|
||||
pub num_cpus_shown: usize,
|
||||
pub autohide_timer: Option<Instant>,
|
||||
pub scroll_state: AppScrollWidgetState,
|
||||
}
|
||||
|
||||
impl CpuWidgetState {
|
||||
pub fn init(current_display_time: u64, autohide_timer: Option<Instant>) -> Self {
|
||||
CpuWidgetState {
|
||||
current_display_time,
|
||||
is_legend_hidden: false,
|
||||
is_showing_tray: false,
|
||||
core_show_vec: Vec::new(),
|
||||
num_cpus_shown: 0,
|
||||
autohide_timer,
|
||||
scroll_state: AppScrollWidgetState::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CpuState {
|
||||
pub force_update: Option<u64>,
|
||||
pub widget_states: HashMap<u64, CpuWidgetState>,
|
||||
pub num_cpus_total: usize,
|
||||
}
|
||||
|
||||
impl CpuState {
|
||||
pub fn init(widget_states: HashMap<u64, CpuWidgetState>) -> Self {
|
||||
CpuState {
|
||||
force_update: None,
|
||||
widget_states,
|
||||
num_cpus_total: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MemWidgetState {
|
||||
pub current_display_time: u64,
|
||||
pub autohide_timer: Option<Instant>,
|
||||
}
|
||||
|
||||
impl MemWidgetState {
|
||||
pub fn init(current_display_time: u64, autohide_timer: Option<Instant>) -> Self {
|
||||
MemWidgetState {
|
||||
current_display_time,
|
||||
autohide_timer,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MemState {
|
||||
pub force_update: Option<u64>,
|
||||
pub widget_states: HashMap<u64, MemWidgetState>,
|
||||
}
|
||||
|
||||
impl MemState {
|
||||
pub fn init(widget_states: HashMap<u64, MemWidgetState>) -> Self {
|
||||
MemState {
|
||||
force_update: None,
|
||||
widget_states,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TempWidgetState {
|
||||
pub scroll_state: AppScrollWidgetState,
|
||||
}
|
||||
|
||||
impl TempWidgetState {
|
||||
pub fn init() -> Self {
|
||||
TempWidgetState {
|
||||
scroll_state: AppScrollWidgetState::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TempState {
|
||||
pub widget_states: HashMap<u64, TempWidgetState>,
|
||||
}
|
||||
|
||||
impl TempState {
|
||||
pub fn init(widget_states: HashMap<u64, TempWidgetState>) -> Self {
|
||||
TempState { widget_states }
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DiskWidgetState {
|
||||
pub scroll_state: AppScrollWidgetState,
|
||||
}
|
||||
|
||||
impl DiskWidgetState {
|
||||
pub fn init() -> Self {
|
||||
DiskWidgetState {
|
||||
scroll_state: AppScrollWidgetState::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DiskState {
|
||||
pub widget_states: HashMap<u64, DiskWidgetState>,
|
||||
}
|
||||
|
||||
impl DiskState {
|
||||
pub fn init(widget_states: HashMap<u64, DiskWidgetState>) -> Self {
|
||||
DiskState { widget_states }
|
||||
}
|
||||
}
|
||||
pub struct BasicTableWidgetState {
|
||||
// Since this is intended (currently) to only be used for ONE widget, that's
|
||||
// how it's going to be written. If we want to allow for multiple of these,
|
||||
// then we can expand outwards with a normal BasicTableState and a hashmap
|
||||
pub currently_displayed_widget_type: BottomWidgetType,
|
||||
pub currently_displayed_widget_id: u64,
|
||||
pub widget_id: i64,
|
||||
}
|
||||
|
||||
#[derive(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 }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct ParagraphScrollState {
|
||||
pub current_scroll_index: u16,
|
||||
pub max_scroll_index: u16,
|
||||
}
|
|
@ -92,6 +92,7 @@ fn get_matches() -> clap::ArgMatches<'static> {
|
|||
(@arg DEFAULT_WIDGET_COUNT: --default_widget_count +takes_value "Which number of the selected widget type to select, from left to right, top to bottom. Defaults to 1.")
|
||||
(@arg USE_OLD_NETWORK_LEGEND: --use_old_network_legend "Use the older (pre-0.4) network widget legend.")
|
||||
(@arg HIDE_TABLE_GAP: --hide_table_gap "Hides the spacing between the table headers and entries.")
|
||||
(@arg BATTERY: --battery "Shows the battery widget in default or basic mode. No effect on custom layouts.")
|
||||
)
|
||||
.get_matches()
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@ pub struct ConfigFlags {
|
|||
pub default_widget_count: Option<u64>,
|
||||
pub use_old_network_legend: Option<bool>,
|
||||
pub hide_table_gap: Option<bool>,
|
||||
pub battery: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Default, Deserialize)]
|
||||
|
@ -636,3 +637,16 @@ pub fn get_hide_table_gap(matches: &clap::ArgMatches<'static>, config: &Config)
|
|||
}
|
||||
false
|
||||
}
|
||||
|
||||
pub fn get_use_battery(matches: &clap::ArgMatches<'static>, config: &Config) -> bool {
|
||||
if matches.is_present("BATTERY") {
|
||||
return true;
|
||||
} else if let Some(flags) = &config.flags {
|
||||
if let Some(battery) = flags.battery {
|
||||
if battery {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue