diff --git a/.vscode/settings.json b/.vscode/settings.json
index dacfb4b4..554f5994 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,5 +1,7 @@
{
"cSpell.words": [
+ "Artem",
+ "COPR",
"DWORD",
"Deque",
"EINVAL",
@@ -14,8 +16,10 @@
"MSRV",
"Mahmoud",
"Marcin",
+ "Mousebindings",
"Nonexhaustive",
"PKGBUILD",
+ "Polishchuk",
"Qudsi",
"SIGTERM",
"TEBI",
@@ -26,6 +30,7 @@
"WASD",
"Wojnarowski",
"andys",
+ "atim",
"choco",
"cmdline",
"commandline",
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 55f8c06f..fa1f2b1e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,11 +11,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- [#206](https://github.com/ClementTsang/bottom/pull/206): Adaptive network graphs --- prior to this update, graphs were stuck at a range from 0B to 1GiB. Now, they adjust to your current usage and time span, so if you're using, say, less than a MiB, it will cap at a MiB. If you're using 10GiB, then the graph will reflect that and span to a bit greater than 10GiB.
+- [#208](https://github.com/ClementTsang/bottom/pull/208): Mouse support for tables and moving to widgets.
+
### Changes
### Bug Fixes
-- [211](https://github.com/ClementTsang/bottom/pull/211): Fixes a bug where you could move down in the process widget even if the process widget search was closed.
+- [#211](https://github.com/ClementTsang/bottom/pull/211): Fixes a bug where you could move down in the process widget even if the process widget search was closed.
## [0.4.7] - 2020-08-26
diff --git a/README.md b/README.md
index 68e5da17..82a355a8 100644
--- a/README.md
+++ b/README.md
@@ -25,7 +25,6 @@ A cross-platform graphical process/system monitor with a customizable interface
- [Options](#options)
- [Keybindings](#keybindings)
- [General](#general)
- - [CPU bindings](#cpu-bindings)
- [Process bindings](#process-bindings)
- [Process search bindings](#process-search-bindings)
- [Process sort bindings](#process-sort-bindings)
@@ -35,6 +34,9 @@ A cross-platform graphical process/system monitor with a customizable interface
- [Supported comparison operators](#supported-comparison-operators)
- [Supported logical operators](#supported-logical-operators)
- [Supported units](#supported-units)
+- [Mousebindings](#mousebindings)
+ - [General](#general-1)
+ - [CPU bindings](#cpu-bindings)
- [Features](#features)
- [Processes](#processes)
- [Process searching](#process-searching)
@@ -43,7 +45,7 @@ A cross-platform graphical process/system monitor with a customizable interface
- [Expanding](#expanding)
- [Basic mode](#basic-mode)
- [Config files](#config-files)
- - [Config flags](#config-flags)
+ - [Config flags and options](#config-flags-and-options)
- [Theming](#theming)
- [Layout](#layout)
- [Battery](#battery)
@@ -176,6 +178,7 @@ Run using `btm`.
--use_old_network_legend Use the older (pre-0.4) network legend which is separate from the network chart
--hide_table_gap Hides the spacing between table headers and data
--battery Displays the battery widget for default and basic layouts
+ --disable_click Disables mouse clicks from interacting with the program
```
### Options
@@ -193,34 +196,27 @@ Run using `btm`.
#### General
-| | |
-| ------------------------------------------- | ---------------------------------------------------------------------------- |
-| `q`, `Ctrl-c` | Quit |
-| `Esc` | Close dialog windows, search, widgets, or exit expanded mode |
-| `Ctrl-r` | Reset display and any collected data |
-| `f` | Freeze/unfreeze updating with new data |
-| `Ctrl-Left`
`Shift-Left`
`H`
`A` | Move widget selection left |
-| `Ctrl-Right`
`Shift-Right`
`L`
`D` | Move widget selection right |
-| `Ctrl-Up`
`Shift-Up`
`K`
`W` | Move widget selection up |
-| `Ctrl-Down`
`Shift-Down`
`J`
`S` | Move widget selection down |
-| `Left`, `h` | Move left within widget |
-| `Down`, `j` | Move down within widget |
-| `Up`,`k` | Move up within widget |
-| `Right`, `l` | Move right within widget |
-| `?` | Open help menu |
-| `gg`, `Home` | Jump to the first entry |
-| `Shift-g`, `End` | Jump to the last entry |
-| `e` | Toggle expanding the currently selected widget |
-| `+` | Zoom in on chart (decrease time range) |
-| `-` | Zoom out on chart (increase time range) |
-| `=` | Reset zoom |
-| Mouse scroll | Table: Scroll
Chart: Zooms in or out by scrolling up or down respectively |
-
-#### CPU bindings
-
-| | |
-| ------------ | --------------------------------------------------------------------- |
-| Mouse scroll | Scrolling over an CPU core/average shows only that entry on the chart |
+| | |
+| ------------------------------------------- | ------------------------------------------------------------ |
+| `q`, `Ctrl-c` | Quit |
+| `Esc` | Close dialog windows, search, widgets, or exit expanded mode |
+| `Ctrl-r` | Reset display and any collected data |
+| `f` | Freeze/unfreeze updating with new data |
+| `Ctrl-Left`
`Shift-Left`
`H`
`A` | Move widget selection left |
+| `Ctrl-Right`
`Shift-Right`
`L`
`D` | Move widget selection right |
+| `Ctrl-Up`
`Shift-Up`
`K`
`W` | Move widget selection up |
+| `Ctrl-Down`
`Shift-Down`
`J`
`S` | Move widget selection down |
+| `Left`, `h` | Move left within widget |
+| `Down`, `j` | Move down within widget |
+| `Up`,`k` | Move up within widget |
+| `Right`, `l` | Move right within widget |
+| `?` | Open help menu |
+| `gg`, `Home` | Jump to the first entry |
+| `Shift-g`, `End` | Jump to the last entry |
+| `e` | Toggle expanding the currently selected widget |
+| `+` | Zoom in on chart (decrease time range) |
+| `-` | Zoom out on chart (increase time range) |
+| `=` | Reset zoom |
#### Process bindings
@@ -340,6 +336,21 @@ Note that the `and` operator takes precedence over the `or` operator.
| -------- | ---------------------------------------------------- | -------------------------- |
| `()` | `( AND ) OR ` | Group together a condition |
+### Mousebindings
+
+#### General
+
+| | |
+| ------------ | --------------------------------------------------------------------------------------------------------------------- |
+| Mouse scroll | Table: Scroll
Chart: Zooms in or out by scrolling up or down respectively |
+| Mouse click | Selects the clicked widget. For tables, clicking can also select a specific entry. Can be disabled via options/flags. |
+
+#### CPU bindings
+
+| | |
+| ------------ | --------------------------------------------------------------------- |
+| Mouse scroll | Scrolling over an CPU core/average shows only that entry on the chart |
+
## Features
As yet _another_ process/system visualization and management application, bottom supports the typical features:
@@ -434,11 +445,11 @@ By default, bottom will look at (based on [dirs](https://github.com/dirs-dev/dir
Note that if a config file does not exist at either the default location or the passed in location via `-C` or `--config`, one is automatically created with no settings applied.
-#### Config flags
+#### Config flags and options
The following options can be set under `[flags]` to achieve the same effect as passing in a flag on runtime. Note that if a flag is given, it will override the config file.
-These are the following supported flag config values:
+These are the following supported flag config values, which correspond to the flag of the same name described in [Flags](#flags) and [Options](#options):
| Field | Type |
| ------------------------ | ------------------------------------------------------------------------------------- |
@@ -461,6 +472,7 @@ These are the following supported flag config values:
| `temperature_type` | String (one of ["k", "f", "c", "kelvin", "fahrenheit", "celsius"]) |
| `default_widget_type` | String (one of ["cpu", "proc", "net", "temp", "mem", "disk"], same as layout options) |
| `default_widget_count` | Unsigned Int (represents which `default_widget_type`) |
+| `disable_click` | Boolean |
#### Theming
@@ -614,6 +626,7 @@ Thanks to all contributors ([emoji key](https://allcontributors.org/docs/en/emoj
+
## Thanks
diff --git a/src/app.rs b/src/app.rs
index 2d3e494f..f84dfadc 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -40,6 +40,7 @@ pub struct AppConfigFields {
pub autohide_time: bool,
pub use_old_network_legend: bool,
pub table_gap: u16,
+ pub disable_click: bool,
}
#[derive(TypedBuilder)]
@@ -80,6 +81,9 @@ pub struct App {
#[builder(default = false, setter(skip))]
pub is_force_redraw: bool,
+ #[builder(default = false, setter(skip))]
+ pub is_determining_widget_boundary: bool,
+
#[builder(default = false, setter(skip))]
pub basic_mode_use_percent: bool,
@@ -90,9 +94,7 @@ pub struct App {
pub temp_state: TempState,
pub disk_state: DiskState,
pub battery_state: BatteryState,
-
pub basic_table_widget_state: Option,
-
pub app_config_fields: AppConfigFields,
pub widget_map: HashMap,
pub current_widget: BottomWidget,
@@ -133,6 +135,10 @@ impl App {
self.data_collection.reset();
}
+ pub fn should_get_widget_bounds(&self) -> bool {
+ self.is_force_redraw || self.is_determining_widget_boundary
+ }
+
fn close_dd(&mut self) {
self.delete_dialog_state.is_showing_dd = false;
self.delete_dialog_state.is_on_yes = false;
@@ -279,11 +285,9 @@ impl App {
}
}
- /// "On space" if we don't want to treat is as a character.
- pub fn on_space(&mut self) {}
-
pub fn on_slash(&mut self) {
if !self.is_in_dialog() {
+ // FIXME: Add ProcSort too, it's annoying
if let BottomWidgetType::Proc = self.current_widget.widget_type {
// Toggle on
if let Some(proc_widget_state) = self
@@ -295,6 +299,7 @@ impl App {
.search_state
.is_enabled = true;
self.move_widget_selection(&WidgetDirection::Down);
+ self.is_force_redraw = true;
}
}
}
@@ -302,6 +307,7 @@ impl App {
pub fn toggle_sort(&mut self) {
match &self.current_widget.widget_type {
+ // FIXME: [REFACTOR] Remove these @'s if unneeded, they were an idea but they're ultimately useless for me here...?
widget_type @ BottomWidgetType::Proc | widget_type @ BottomWidgetType::ProcSort => {
let widget_id = self.current_widget.widget_id
- match &widget_type {
@@ -326,6 +332,8 @@ impl App {
self.move_widget_selection(&WidgetDirection::Right);
}
}
+
+ self.is_force_redraw = true;
}
_ => {}
}
@@ -1151,7 +1159,6 @@ impl App {
'L' | 'D' => self.move_widget_selection(&WidgetDirection::Right),
'K' | 'W' => self.move_widget_selection(&WidgetDirection::Up),
'J' | 'S' => self.move_widget_selection(&WidgetDirection::Down),
- ' ' => self.on_space(),
'+' => self.zoom_in(),
'-' => self.zoom_out(),
'=' => self.reset_zoom(),
@@ -1214,7 +1221,16 @@ impl App {
}
pub fn move_widget_selection(&mut self, direction: &WidgetDirection) {
+ // Since we only want to call reset once, we do it like this to avoid
+ // redundant calls on recursion.
+ self.move_widget_selection_logic(direction);
+ self.reset_multi_tap_keys();
+ }
+
+ fn move_widget_selection_logic(&mut self, direction: &WidgetDirection) {
/*
+ The actual logic for widget movement.
+
We follow these following steps:
1. Send a movement signal in `direction`.
2. Check if this new widget we've landed on is hidden. If not, halt.
@@ -1234,7 +1250,6 @@ impl App {
match &new_widget.widget_type {
BottomWidgetType::Temp
| BottomWidgetType::Proc
- | BottomWidgetType::ProcSearch
| BottomWidgetType::ProcSort
| BottomWidgetType::Disk
| BottomWidgetType::Battery
@@ -1272,13 +1287,16 @@ impl App {
basic_table_widget_state.currently_displayed_widget_type =
self.current_widget.widget_type.clone();
}
+
+ // And let's not forget:
+ self.is_determining_widget_boundary = true;
}
BottomWidgetType::BasicTables => {
match &direction {
WidgetDirection::Up => {
// Note this case would fail if it moved up into a hidden
// widget, but it's for basic so whatever, it's all hard-coded
- // right now anyways.
+ // right now anyways...
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)
@@ -1288,11 +1306,22 @@ impl App {
}
}
WidgetDirection::Down => {
- // This means we're in basic mode. As such, then
- // we want to move DOWN to the currently shown widget
+ // Assuming we're in basic mode (BasicTables), then
+ // we want to move DOWN to the currently shown widget.
if let Some(basic_table_widget_state) =
- &self.basic_table_widget_state
+ &mut self.basic_table_widget_state
{
+ // We also want to move towards Proc if we had set it to ProcSort.
+ if let BottomWidgetType::ProcSort =
+ basic_table_widget_state.currently_displayed_widget_type
+ {
+ basic_table_widget_state
+ .currently_displayed_widget_type =
+ BottomWidgetType::Proc;
+ basic_table_widget_state
+ .currently_displayed_widget_id -= 2;
+ }
+
if let Some(next_new_widget) = self.widget_map.get(
&basic_table_widget_state.currently_displayed_widget_id,
) {
@@ -1308,13 +1337,13 @@ impl App {
if let Some((parent_direction, offset)) = &new_widget.parent_reflector {
if direction.is_opposite(parent_direction) {
// Keep going in the current direction if hidden...
- let next_neighbour_id = match &direction {
+ // unless we hit a wall of sorts.
+ let option_next_neighbour_id = match &direction {
WidgetDirection::Left => new_widget.left_neighbour,
WidgetDirection::Right => new_widget.right_neighbour,
WidgetDirection::Up => new_widget.up_neighbour,
WidgetDirection::Down => new_widget.down_neighbour,
- }
- .unwrap_or(*new_widget_id);
+ };
match &new_widget.widget_type {
BottomWidgetType::CpuLegend => {
if let Some(cpu_widget_state) = self
@@ -1323,11 +1352,15 @@ impl App {
.get(&(new_widget_id - *offset))
{
if cpu_widget_state.is_legend_hidden {
- if let Some(next_neighbour_widget) =
- self.widget_map.get(&next_neighbour_id)
+ if let Some(next_neighbour_id) =
+ option_next_neighbour_id
{
- self.current_widget =
- next_neighbour_widget.clone();
+ if let Some(next_neighbour_widget) =
+ self.widget_map.get(&next_neighbour_id)
+ {
+ self.current_widget =
+ next_neighbour_widget.clone();
+ }
}
} else {
self.current_widget = new_widget.clone();
@@ -1344,12 +1377,17 @@ impl App {
match &new_widget.widget_type {
BottomWidgetType::ProcSearch => {
if !proc_widget_state.is_search_enabled() {
- if let Some(next_neighbour_widget) =
- self.widget_map
- .get(&next_neighbour_id)
+ if let Some(next_neighbour_id) =
+ option_next_neighbour_id
{
- self.current_widget =
- next_neighbour_widget.clone();
+ if let Some(next_neighbour_widget) =
+ self.widget_map
+ .get(&next_neighbour_id)
+ {
+ self.current_widget =
+ next_neighbour_widget
+ .clone();
+ }
}
} else {
self.current_widget =
@@ -1358,12 +1396,17 @@ impl App {
}
BottomWidgetType::ProcSort => {
if !proc_widget_state.is_sort_open {
- if let Some(next_neighbour_widget) =
- self.widget_map
- .get(&next_neighbour_id)
+ if let Some(next_neighbour_id) =
+ option_next_neighbour_id
{
- self.current_widget =
- next_neighbour_widget.clone();
+ if let Some(next_neighbour_widget) =
+ self.widget_map
+ .get(&next_neighbour_id)
+ {
+ self.current_widget =
+ next_neighbour_widget
+ .clone();
+ }
}
} else {
self.current_widget =
@@ -1498,7 +1541,7 @@ impl App {
}
if let Some(ref_dir) = &reflection_dir {
- self.move_widget_selection(ref_dir);
+ self.move_widget_selection_logic(ref_dir);
}
}
}
@@ -1544,8 +1587,6 @@ impl App {
},
}
}
-
- self.reset_multi_tap_keys();
}
fn handle_left_expanded_movement(&mut self) {
@@ -1768,11 +1809,11 @@ impl App {
pub fn decrement_position_count(&mut self) {
if !self.is_in_dialog() {
match self.current_widget.widget_type {
- BottomWidgetType::Proc => self.change_process_position(-1),
- BottomWidgetType::ProcSort => self.change_process_sort_position(-1),
- BottomWidgetType::Temp => self.change_temp_position(-1),
- BottomWidgetType::Disk => self.change_disk_position(-1),
- BottomWidgetType::CpuLegend => self.change_cpu_table_position(-1),
+ BottomWidgetType::Proc => self.increment_process_position(-1),
+ BottomWidgetType::ProcSort => self.increment_process_sort_position(-1),
+ BottomWidgetType::Temp => self.increment_temp_position(-1),
+ BottomWidgetType::Disk => self.increment_disk_position(-1),
+ BottomWidgetType::CpuLegend => self.increment_cpu_legend_position(-1),
_ => {}
}
}
@@ -1781,17 +1822,17 @@ impl App {
pub fn increment_position_count(&mut self) {
if !self.is_in_dialog() {
match self.current_widget.widget_type {
- BottomWidgetType::Proc => self.change_process_position(1),
- BottomWidgetType::ProcSort => self.change_process_sort_position(1),
- BottomWidgetType::Temp => self.change_temp_position(1),
- BottomWidgetType::Disk => self.change_disk_position(1),
- BottomWidgetType::CpuLegend => self.change_cpu_table_position(1),
+ BottomWidgetType::Proc => self.increment_process_position(1),
+ BottomWidgetType::ProcSort => self.increment_process_sort_position(1),
+ BottomWidgetType::Temp => self.increment_temp_position(1),
+ BottomWidgetType::Disk => self.increment_disk_position(1),
+ BottomWidgetType::CpuLegend => self.increment_cpu_legend_position(1),
_ => {}
}
}
}
- fn change_process_sort_position(&mut self, num_to_change_by: i64) {
+ fn increment_process_sort_position(&mut self, num_to_change_by: i64) {
if let Some(proc_widget_state) = self
.proc_state
.get_mut_widget_state(self.current_widget.widget_id - 2)
@@ -1814,7 +1855,7 @@ impl App {
}
}
- fn change_cpu_table_position(&mut self, num_to_change_by: i64) {
+ fn increment_cpu_legend_position(&mut self, num_to_change_by: i64) {
if let Some(cpu_widget_state) = self
.cpu_state
.widget_states
@@ -1838,13 +1879,12 @@ impl App {
}
}
- fn change_process_position(&mut self, num_to_change_by: i64) {
+ fn increment_process_position(&mut self, num_to_change_by: i64) {
if let Some(proc_widget_state) = self
.proc_state
.get_mut_widget_state(self.current_widget.widget_id)
{
let current_posn = proc_widget_state.scroll_state.current_scroll_position;
-
if let Some(finalized_process_data) = self
.canvas_data
.finalized_process_data_map
@@ -1866,7 +1906,7 @@ impl App {
}
}
- fn change_temp_position(&mut self, num_to_change_by: i64) {
+ fn increment_temp_position(&mut self, num_to_change_by: i64) {
if let Some(temp_widget_state) = self
.temp_state
.widget_states
@@ -1890,7 +1930,7 @@ impl App {
}
}
- fn change_disk_position(&mut self, num_to_change_by: i64) {
+ fn increment_disk_position(&mut self, num_to_change_by: i64) {
if let Some(disk_widget_state) = self
.disk_state
.widget_states
@@ -2168,4 +2208,219 @@ impl App {
_ => {}
}
}
+
+ /// Moves the mouse to the widget that was clicked on, then propagates the click down to be
+ /// handled by the widget specifically.
+ pub fn left_mouse_click_movement(&mut self, x: u16, y: u16) {
+ // Pretty dead simple - iterate through the widget map and go to the widget where the click
+ // is within.
+ if let Some(bt) = &mut self.basic_table_widget_state {
+ if let (
+ Some((left_tlc_x, left_tlc_y)),
+ Some((left_brc_x, left_brc_y)),
+ Some((right_tlc_x, right_tlc_y)),
+ Some((right_brc_x, right_brc_y)),
+ ) = (bt.left_tlc, bt.left_brc, bt.right_tlc, bt.right_brc)
+ {
+ if (x >= left_tlc_x && y >= left_tlc_y) && (x <= left_brc_x && y <= left_brc_y) {
+ if let Some(new_widget) =
+ self.widget_map.get(&(bt.currently_displayed_widget_id))
+ {
+ // We have to move to the current table widget first...
+ self.current_widget = new_widget.clone();
+
+ if let BottomWidgetType::Proc = &new_widget.widget_type {
+ if let Some(proc_widget_state) =
+ self.proc_state.get_widget_state(new_widget.widget_id)
+ {
+ if proc_widget_state.is_sort_open {
+ self.move_widget_selection(&WidgetDirection::Left);
+ }
+ }
+ }
+ self.move_widget_selection(&WidgetDirection::Left);
+ return;
+ }
+ } else if (x >= right_tlc_x && y >= right_tlc_y)
+ && (x <= right_brc_x && y <= right_brc_y)
+ {
+ if let Some(new_widget) =
+ self.widget_map.get(&(bt.currently_displayed_widget_id))
+ {
+ // We have to move to the current table widget first...
+ self.current_widget = new_widget.clone();
+
+ if let BottomWidgetType::ProcSort = &new_widget.widget_type {
+ if let Some(proc_widget_state) =
+ self.proc_state.get_widget_state(new_widget.widget_id - 2)
+ {
+ if proc_widget_state.is_sort_open {
+ self.move_widget_selection(&WidgetDirection::Right);
+ }
+ }
+ }
+ }
+ self.move_widget_selection(&WidgetDirection::Right);
+ // Bit extra logic to ensure you always land on a proc widget, not the sort
+ if let BottomWidgetType::ProcSort = &self.current_widget.widget_type {
+ self.move_widget_selection(&WidgetDirection::Right);
+ }
+ return;
+ }
+ }
+ }
+
+ let mut failed_to_get = true;
+ // TODO: [MOUSE] We could use a better data structure for this? Currently it's a blind
+ // traversal through a hashmap, using a 2d binary tree of sorts would be better.
+ for (new_widget_id, widget) in &self.widget_map {
+ if let (Some((tlc_x, tlc_y)), Some((brc_x, brc_y))) =
+ (widget.top_left_corner, widget.bottom_right_corner)
+ {
+ if (x >= tlc_x && y >= tlc_y) && (x <= brc_x && y <= brc_y) {
+ if let Some(new_widget) = self.widget_map.get(&new_widget_id) {
+ self.current_widget = new_widget.clone();
+
+ match &self.current_widget.widget_type {
+ BottomWidgetType::Temp
+ | BottomWidgetType::Proc
+ | BottomWidgetType::ProcSort
+ | BottomWidgetType::Disk
+ | BottomWidgetType::Battery => {
+ if let Some(basic_table_widget_state) =
+ &mut self.basic_table_widget_state
+ {
+ basic_table_widget_state.currently_displayed_widget_id =
+ self.current_widget.widget_id;
+ basic_table_widget_state.currently_displayed_widget_type =
+ self.current_widget.widget_type.clone();
+ }
+ }
+ _ => {}
+ }
+
+ failed_to_get = false;
+ break;
+ }
+ }
+ }
+ }
+
+ if failed_to_get {
+ return;
+ }
+
+ // Now handle click propagation down to widget.
+ if let Some((_tlc_x, tlc_y)) = &self.current_widget.top_left_corner {
+ match &self.current_widget.widget_type {
+ BottomWidgetType::Proc
+ | BottomWidgetType::ProcSort
+ | BottomWidgetType::CpuLegend
+ | BottomWidgetType::Temp
+ | BottomWidgetType::Disk => {
+ // Get our index...
+ let clicked_entry = y - *tlc_y;
+ // + 1 so we start at 0.
+ let offset = 1
+ + if self.is_drawing_border() { 1 } else { 0 }
+ + if self.is_drawing_gap(&self.current_widget) {
+ self.app_config_fields.table_gap
+ } else {
+ 0
+ };
+ if clicked_entry >= offset {
+ let offset_clicked_entry = clicked_entry - offset;
+ match &self.current_widget.widget_type {
+ BottomWidgetType::Proc => {
+ if let Some(proc_widget_state) = self
+ .proc_state
+ .get_widget_state(self.current_widget.widget_id)
+ {
+ if let Some(visual_index) =
+ proc_widget_state.scroll_state.table_state.selected()
+ {
+ self.increment_process_position(
+ offset_clicked_entry as i64 - visual_index as i64,
+ );
+ }
+ }
+ }
+ BottomWidgetType::ProcSort => {
+ if let Some(proc_widget_state) = self
+ .proc_state
+ .get_widget_state(self.current_widget.widget_id - 2)
+ {
+ if let Some(visual_index) =
+ proc_widget_state.columns.column_state.selected()
+ {
+ self.increment_process_sort_position(
+ offset_clicked_entry as i64 - visual_index as i64,
+ );
+ }
+ }
+ }
+ BottomWidgetType::CpuLegend => {
+ if let Some(cpu_widget_state) = self
+ .cpu_state
+ .get_widget_state(self.current_widget.widget_id - 1)
+ {
+ if let Some(visual_index) =
+ cpu_widget_state.scroll_state.table_state.selected()
+ {
+ self.increment_cpu_legend_position(
+ offset_clicked_entry as i64 - visual_index as i64,
+ );
+ }
+ }
+ }
+ BottomWidgetType::Temp => {
+ if let Some(temp_widget_state) = self
+ .temp_state
+ .get_widget_state(self.current_widget.widget_id)
+ {
+ if let Some(visual_index) =
+ temp_widget_state.scroll_state.table_state.selected()
+ {
+ self.increment_temp_position(
+ offset_clicked_entry as i64 - visual_index as i64,
+ );
+ }
+ }
+ }
+ BottomWidgetType::Disk => {
+ if let Some(disk_widget_state) = self
+ .disk_state
+ .get_widget_state(self.current_widget.widget_id)
+ {
+ if let Some(visual_index) =
+ disk_widget_state.scroll_state.table_state.selected()
+ {
+ self.increment_disk_position(
+ offset_clicked_entry as i64 - visual_index as i64,
+ );
+ }
+ }
+ }
+ _ => {}
+ }
+ }
+ }
+ _ => {}
+ }
+ }
+ }
+
+ fn is_drawing_border(&self) -> bool {
+ self.is_expanded || !self.app_config_fields.use_basic_mode
+ }
+
+ fn is_drawing_gap(&self, widget: &BottomWidget) -> bool {
+ if let (Some((_tlc_x, tlc_y)), Some((_brc_x, brc_y))) =
+ (widget.top_left_corner, widget.bottom_right_corner)
+ {
+ brc_y - tlc_y >= constants::TABLE_GAP_HEIGHT_LIMIT
+ } else {
+ self.app_config_fields.table_gap == 0
+ }
+ }
}
diff --git a/src/app/layout_manager.rs b/src/app/layout_manager.rs
index 8b5ba40d..35c6e02f 100644
--- a/src/app/layout_manager.rs
+++ b/src/app/layout_manager.rs
@@ -867,6 +867,14 @@ pub struct BottomWidget {
/// The value is the direction to bounce, as well as the parent offset.
#[builder(default = None)]
pub parent_reflector: Option<(WidgetDirection, u64)>,
+
+ /// Top left corner when drawn, for mouse click detection
+ #[builder(default = None)]
+ pub top_left_corner: Option<(u16, u16)>,
+
+ /// Bottom right corner when drawn, for mouse click detection
+ #[builder(default = None)]
+ pub bottom_right_corner: Option<(u16, u16)>,
}
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
@@ -935,7 +943,7 @@ impl std::str::FromStr for BottomWidgetType {
"empty" => Ok(BottomWidgetType::Empty),
"battery" | "batt" => Ok(BottomWidgetType::Battery),
_ => Err(BottomError::ConfigError(format!(
- "invalid widget type: {}",
+ "invalid widget type: {}", // FIXME: Make this more helpful, specify valid widget types (just go through the list)
s
))),
}
diff --git a/src/app/states.rs b/src/app/states.rs
index 9bd61e1f..cf9123db 100644
--- a/src/app/states.rs
+++ b/src/app/states.rs
@@ -730,6 +730,10 @@ pub struct BasicTableWidgetState {
pub currently_displayed_widget_type: BottomWidgetType,
pub currently_displayed_widget_id: u64,
pub widget_id: i64,
+ pub left_tlc: Option<(u16, u16)>,
+ pub left_brc: Option<(u16, u16)>,
+ pub right_tlc: Option<(u16, u16)>,
+ pub right_brc: Option<(u16, u16)>,
}
#[derive(Default)]
diff --git a/src/bin/main.rs b/src/bin/main.rs
index c443bb1f..34c8c2b7 100644
--- a/src/bin/main.rs
+++ b/src/bin/main.rs
@@ -47,7 +47,11 @@ fn main() -> error::Result<()> {
)?;
// Create painter and set colours.
- let mut painter = canvas::Painter::init(widget_layout, app.app_config_fields.table_gap);
+ let mut painter = canvas::Painter::init(
+ widget_layout,
+ app.app_config_fields.table_gap,
+ app.app_config_fields.use_basic_mode,
+ );
generate_config_colours(&config, &mut painter)?;
painter.colours.generate_remaining_cpu_colours();
painter.complete_painter_init();
diff --git a/src/canvas.rs b/src/canvas.rs
index e6538001..7036bd49 100644
--- a/src/canvas.rs
+++ b/src/canvas.rs
@@ -68,10 +68,11 @@ pub struct Painter {
widget_layout: BottomLayout,
derived_widget_draw_locs: Vec>>>,
table_height_offset: u16,
+ requires_boundary_recalculation: bool,
}
impl Painter {
- pub fn init(widget_layout: BottomLayout, table_gap: u16) -> Self {
+ pub fn init(widget_layout: BottomLayout, table_gap: u16, is_basic_mode: bool) -> Self {
// Now for modularity; we have to also initialize the base layouts!
// We want to do this ONCE and reuse; after this we can just construct
// based on the console size.
@@ -151,7 +152,8 @@ impl Painter {
layout_constraints,
widget_layout,
derived_widget_draw_locs: Vec::default(),
- table_height_offset: 4 + table_gap,
+ table_height_offset: if is_basic_mode { 2 } else { 4 } + table_gap,
+ requires_boundary_recalculation: true,
}
}
@@ -208,6 +210,14 @@ impl Painter {
self.width = current_width;
}
+ if app_state.should_get_widget_bounds() {
+ // If we're force drawing, reset ALL mouse boundaries.
+ for widget in app_state.widget_map.values_mut() {
+ widget.top_left_corner = None;
+ widget.bottom_right_corner = None;
+ }
+ }
+
terminal.autoresize()?;
terminal.draw(|mut f| {
if app_state.help_dialog_state.is_showing_help {
@@ -398,6 +408,14 @@ impl Painter {
} else {
1
});
+
+ // A little hack to force the widget boundary recalculation. This is required here
+ // as basic mode has a height of 0 initially, which breaks things.
+ if self.requires_boundary_recalculation {
+ app_state.is_determining_widget_boundary = true;
+ }
+ self.requires_boundary_recalculation = cpu_height == 0;
+
let vertical_chunks = Layout::default()
.direction(Direction::Vertical)
.constraints(
@@ -419,18 +437,11 @@ impl Painter {
self.draw_basic_cpu(&mut f, app_state, vertical_chunks[0], 1);
self.draw_basic_memory(&mut f, app_state, middle_chunks[0], 2);
self.draw_basic_network(&mut f, app_state, middle_chunks[1], 3);
+
+ let mut later_widget_id: Option = None;
if let Some(basic_table_widget_state) = &app_state.basic_table_widget_state {
let widget_id = basic_table_widget_state.currently_displayed_widget_id;
-
- if let Some(current_table) = app_state.widget_map.get(&widget_id) {
- self.draw_basic_table_arrows(
- &mut f,
- app_state,
- vertical_chunks[3],
- current_table,
- );
- }
-
+ later_widget_id = Some(widget_id);
match basic_table_widget_state.currently_displayed_widget_type {
Disk => self.draw_disk_table(
&mut f,
@@ -442,6 +453,7 @@ impl Painter {
Proc | ProcSort => {
let wid = widget_id
- match basic_table_widget_state.currently_displayed_widget_type {
+ ProcSearch => 1,
ProcSort => 2,
_ => 0,
};
@@ -470,6 +482,10 @@ impl Painter {
_ => {}
}
}
+
+ if let Some(widget_id) = later_widget_id {
+ self.draw_basic_table_arrows(&mut f, app_state, vertical_chunks[3], widget_id);
+ }
} else {
// Draws using the passed in (or default) layout. NOT basic so far.
if self.derived_widget_draw_locs.is_empty() || app_state.is_force_redraw {
@@ -570,6 +586,7 @@ impl Painter {
})?;
app_state.is_force_redraw = false;
+ app_state.is_determining_widget_boundary = false;
Ok(())
}
diff --git a/src/canvas/dialogs/help_dialog.rs b/src/canvas/dialogs/help_dialog.rs
index dbd5c74c..2b148f16 100644
--- a/src/canvas/dialogs/help_dialog.rs
+++ b/src/canvas/dialogs/help_dialog.rs
@@ -36,7 +36,7 @@ impl HelpDialog for Painter {
"─".repeat(usize::from(draw_loc.width).saturating_sub(HELP_BASE.chars().count() + 2))
);
- if app_state.is_force_redraw {
+ if app_state.should_get_widget_bounds() {
// We must also recalculate how many lines are wrapping to properly get scrolling to work on
// small terminal sizes... oh joy.
diff --git a/src/canvas/widgets/basic_table_arrows.rs b/src/canvas/widgets/basic_table_arrows.rs
index 591f71c6..fd64e8dc 100644
--- a/src/canvas/widgets/basic_table_arrows.rs
+++ b/src/canvas/widgets/basic_table_arrows.rs
@@ -1,116 +1,149 @@
use crate::{
- app::{
- layout_manager::{BottomWidget, BottomWidgetType},
- App,
- },
+ app::{layout_manager::BottomWidgetType, App},
canvas::Painter,
};
use tui::{
backend::Backend,
- layout::{Constraint, Layout, Rect},
+ layout::{Alignment, Constraint, Direction, Layout, Rect},
terminal::Frame,
widgets::{Block, Paragraph, Text},
};
pub trait BasicTableArrows {
fn draw_basic_table_arrows(
- &self, f: &mut Frame<'_, B>, app_state: &App, draw_loc: Rect, current_table: &BottomWidget,
+ &self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect, widget_id: u64,
);
}
impl BasicTableArrows for Painter {
fn draw_basic_table_arrows(
- &self, f: &mut Frame<'_, B>, app_state: &App, draw_loc: Rect, current_table: &BottomWidget,
+ &self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect, widget_id: u64,
) {
- let current_table = if let BottomWidgetType::ProcSort = current_table.widget_type {
- current_table
- .right_neighbour
- .map(|id| app_state.widget_map.get(&id).unwrap())
- .unwrap()
- } else {
- current_table
- };
-
- // Effectively a paragraph with a ton of spacing
- let (left_table, right_table) = (
- {
- current_table
- .left_neighbour
- .map(|left_widget_id| {
- app_state
- .widget_map
- .get(&left_widget_id)
- .map(|left_widget| {
- if left_widget.widget_type == BottomWidgetType::ProcSort {
- left_widget
- .left_neighbour
- .map(|left_left_widget_id| {
- app_state.widget_map.get(&left_left_widget_id).map(
- |left_left_widget| &left_left_widget.widget_type,
- )
- })
- .unwrap_or_else(|| Some(&BottomWidgetType::Temp))
- .unwrap_or_else(|| &BottomWidgetType::Temp)
- } else {
- &left_widget.widget_type
- }
- })
- .unwrap_or_else(|| &BottomWidgetType::Temp)
- })
- .unwrap_or_else(|| &BottomWidgetType::Temp)
- },
- {
+ if let Some(current_table) = app_state.widget_map.get(&widget_id) {
+ let current_table = if let BottomWidgetType::ProcSort = current_table.widget_type {
current_table
.right_neighbour
- .map(|right_widget_id| {
- app_state
- .widget_map
- .get(&right_widget_id)
- .map(|right_widget| {
- if right_widget.widget_type == BottomWidgetType::ProcSort {
- right_widget
- .right_neighbour
- .map(|right_right_widget_id| {
- app_state.widget_map.get(&right_right_widget_id).map(
- |right_right_widget| {
- &right_right_widget.widget_type
- },
- )
- })
- .unwrap_or_else(|| Some(&BottomWidgetType::Disk))
- .unwrap_or_else(|| &BottomWidgetType::Disk)
- } else {
- &right_widget.widget_type
- }
- })
- .unwrap_or_else(|| &BottomWidgetType::Disk)
- })
- .unwrap_or_else(|| &BottomWidgetType::Disk)
- },
- );
+ .map(|id| app_state.widget_map.get(&id).unwrap())
+ .unwrap()
+ } else {
+ current_table
+ };
- let left_name = left_table.get_pretty_name();
- let right_name = right_table.get_pretty_name();
+ let (left_table, right_table) = (
+ {
+ current_table
+ .left_neighbour
+ .map(|left_widget_id| {
+ app_state
+ .widget_map
+ .get(&left_widget_id)
+ .map(|left_widget| {
+ if left_widget.widget_type == BottomWidgetType::ProcSort {
+ left_widget
+ .left_neighbour
+ .map(|left_left_widget_id| {
+ app_state.widget_map.get(&left_left_widget_id).map(
+ |left_left_widget| {
+ &left_left_widget.widget_type
+ },
+ )
+ })
+ .unwrap_or_else(|| Some(&BottomWidgetType::Temp))
+ .unwrap_or_else(|| &BottomWidgetType::Temp)
+ } else {
+ &left_widget.widget_type
+ }
+ })
+ .unwrap_or_else(|| &BottomWidgetType::Temp)
+ })
+ .unwrap_or_else(|| &BottomWidgetType::Temp)
+ },
+ {
+ current_table
+ .right_neighbour
+ .map(|right_widget_id| {
+ app_state
+ .widget_map
+ .get(&right_widget_id)
+ .map(|right_widget| {
+ if right_widget.widget_type == BottomWidgetType::ProcSort {
+ right_widget
+ .right_neighbour
+ .map(|right_right_widget_id| {
+ app_state
+ .widget_map
+ .get(&right_right_widget_id)
+ .map(|right_right_widget| {
+ &right_right_widget.widget_type
+ })
+ })
+ .unwrap_or_else(|| Some(&BottomWidgetType::Disk))
+ .unwrap_or_else(|| &BottomWidgetType::Disk)
+ } else {
+ &right_widget.widget_type
+ }
+ })
+ .unwrap_or_else(|| &BottomWidgetType::Disk)
+ })
+ .unwrap_or_else(|| &BottomWidgetType::Disk)
+ },
+ );
- let num_spaces =
- usize::from(draw_loc.width).saturating_sub(6 + left_name.len() + right_name.len());
+ let left_name = left_table.get_pretty_name();
+ let right_name = right_table.get_pretty_name();
- let arrow_text = vec![
- Text::raw("\n"),
- Text::styled(format!("◄ {}", left_name), self.colours.text_style),
- Text::raw(" ".repeat(num_spaces)),
- Text::styled(format!("{} ►", right_name), self.colours.text_style),
- ];
+ let num_spaces =
+ usize::from(draw_loc.width).saturating_sub(6 + left_name.len() + right_name.len());
- let margined_draw_loc = Layout::default()
- .constraints([Constraint::Percentage(100)].as_ref())
- .horizontal_margin(1)
- .split(draw_loc);
+ let left_arrow_text = vec![
+ Text::raw("\n"),
+ Text::styled(format!("◄ {}", left_name), self.colours.text_style),
+ ];
- f.render_widget(
- Paragraph::new(arrow_text.iter()).block(Block::default()),
- margined_draw_loc[0],
- );
+ let right_arrow_text = vec![
+ Text::raw("\n"),
+ Text::styled(format!("{} ►", right_name), self.colours.text_style),
+ ];
+
+ let margined_draw_loc = Layout::default()
+ .direction(Direction::Horizontal)
+ .constraints(
+ [
+ Constraint::Length(2 + left_name.len() as u16),
+ Constraint::Length(num_spaces as u16),
+ Constraint::Length(2 + right_name.len() as u16),
+ ]
+ .as_ref(),
+ )
+ .horizontal_margin(1)
+ .split(draw_loc);
+
+ f.render_widget(
+ Paragraph::new(left_arrow_text.iter()).block(Block::default()),
+ margined_draw_loc[0],
+ );
+ f.render_widget(
+ Paragraph::new(right_arrow_text.iter())
+ .block(Block::default())
+ .alignment(Alignment::Right),
+ margined_draw_loc[2],
+ );
+
+ if app_state.should_get_widget_bounds() {
+ if let Some(basic_table) = &mut app_state.basic_table_widget_state {
+ basic_table.left_tlc = Some((margined_draw_loc[0].x, margined_draw_loc[0].y));
+ basic_table.left_brc = Some((
+ margined_draw_loc[0].x + margined_draw_loc[0].width,
+ margined_draw_loc[0].y + margined_draw_loc[0].height,
+ ));
+ basic_table.right_tlc = Some((margined_draw_loc[2].x, margined_draw_loc[2].y));
+ basic_table.right_brc = Some((
+ margined_draw_loc[2].x + margined_draw_loc[2].width,
+ margined_draw_loc[2].y + margined_draw_loc[2].height,
+ ));
+ }
+ }
+ }
}
}
diff --git a/src/canvas/widgets/battery_display.rs b/src/canvas/widgets/battery_display.rs
index 7c3b7896..9166d50c 100644
--- a/src/canvas/widgets/battery_display.rs
+++ b/src/canvas/widgets/battery_display.rs
@@ -6,7 +6,7 @@ use crate::{
use tui::{
backend::Backend,
- layout::{Constraint, Rect},
+ layout::{Constraint, Direction, Layout, Rect},
terminal::Frame,
widgets::{Block, Borders, Paragraph, Row, Table, Tabs, Text},
};
@@ -109,6 +109,12 @@ impl BatteryDisplayWidget for Painter {
// draw_loc,
// );
+ let margined_draw_loc = Layout::default()
+ .constraints([Constraint::Percentage(100)].as_ref())
+ .horizontal_margin(if is_on_widget || draw_border { 0 } else { 1 })
+ .direction(Direction::Horizontal)
+ .split(draw_loc)[0];
+
if let Some(battery_details) = app_state
.canvas_data
.battery_data
@@ -166,7 +172,7 @@ impl BatteryDisplayWidget for Painter {
.block(battery_block)
.header_style(self.colours.table_header_style)
.widths([Constraint::Percentage(50), Constraint::Percentage(50)].as_ref()),
- draw_loc,
+ margined_draw_loc,
);
} else {
f.render_widget(
@@ -178,7 +184,7 @@ impl BatteryDisplayWidget for Painter {
.iter(),
)
.block(battery_block),
- draw_loc,
+ margined_draw_loc,
);
}
@@ -209,6 +215,17 @@ impl BatteryDisplayWidget for Painter {
.select(battery_widget_state.currently_selected_battery_index),
draw_loc,
);
+
+ if app_state.should_get_widget_bounds() {
+ // Update draw loc in widget map
+ if let Some(widget) = app_state.widget_map.get_mut(&widget_id) {
+ widget.top_left_corner = Some((margined_draw_loc.x, margined_draw_loc.y));
+ widget.bottom_right_corner = Some((
+ margined_draw_loc.x + margined_draw_loc.width,
+ margined_draw_loc.y + margined_draw_loc.height,
+ ));
+ }
+ }
}
}
}
diff --git a/src/canvas/widgets/cpu_basic.rs b/src/canvas/widgets/cpu_basic.rs
index 4683a677..7f9381f9 100644
--- a/src/canvas/widgets/cpu_basic.rs
+++ b/src/canvas/widgets/cpu_basic.rs
@@ -127,14 +127,23 @@ impl CpuBasicWidget for Painter {
.direction(Direction::Horizontal)
.constraints([Constraint::Percentage(100)].as_ref())
.horizontal_margin(1)
- .split(*chunk);
+ .split(*chunk)[0];
f.render_widget(
Paragraph::new(cpu_column.iter()).block(Block::default()),
- margined_loc[0],
+ margined_loc,
);
}
}
}
+
+ if app_state.should_get_widget_bounds() {
+ // Update draw loc in widget map
+ if let Some(widget) = app_state.widget_map.get_mut(&widget_id) {
+ widget.top_left_corner = Some((draw_loc.x, draw_loc.y));
+ widget.bottom_right_corner =
+ Some((draw_loc.x + draw_loc.width, draw_loc.y + draw_loc.height));
+ }
+ }
}
}
diff --git a/src/canvas/widgets/cpu_graph.rs b/src/canvas/widgets/cpu_graph.rs
index bd931deb..e000b66f 100644
--- a/src/canvas/widgets/cpu_graph.rs
+++ b/src/canvas/widgets/cpu_graph.rs
@@ -65,6 +65,15 @@ impl CpuGraphWidget for Painter {
if let Some(cpu_widget_state) = app_state.cpu_state.widget_states.get_mut(&widget_id) {
cpu_widget_state.is_legend_hidden = true;
}
+
+ // Update draw loc in widget map
+ if app_state.should_get_widget_bounds() {
+ if let Some(bottom_widget) = app_state.widget_map.get_mut(&widget_id) {
+ bottom_widget.top_left_corner = Some((draw_loc.x, draw_loc.y));
+ bottom_widget.bottom_right_corner =
+ Some((draw_loc.x + draw_loc.width, draw_loc.y + draw_loc.height));
+ }
+ }
} else {
let (graph_index, legend_index, constraints) =
if app_state.app_config_fields.left_legend {
@@ -94,6 +103,35 @@ impl CpuGraphWidget for Painter {
partitioned_draw_loc[legend_index],
widget_id + 1,
);
+
+ if app_state.should_get_widget_bounds() {
+ // Update draw loc in widget map
+ if let Some(cpu_widget) = app_state.widget_map.get_mut(&widget_id) {
+ cpu_widget.top_left_corner = Some((
+ partitioned_draw_loc[graph_index].x,
+ partitioned_draw_loc[graph_index].y,
+ ));
+ cpu_widget.bottom_right_corner = Some((
+ partitioned_draw_loc[graph_index].x
+ + partitioned_draw_loc[graph_index].width,
+ partitioned_draw_loc[graph_index].y
+ + partitioned_draw_loc[graph_index].height,
+ ));
+ }
+
+ if let Some(legend_widget) = app_state.widget_map.get_mut(&(widget_id + 1)) {
+ legend_widget.top_left_corner = Some((
+ partitioned_draw_loc[legend_index].x,
+ partitioned_draw_loc[legend_index].y,
+ ));
+ legend_widget.bottom_right_corner = Some((
+ partitioned_draw_loc[legend_index].x
+ + partitioned_draw_loc[legend_index].width,
+ partitioned_draw_loc[legend_index].y
+ + partitioned_draw_loc[legend_index].height,
+ ));
+ }
+ }
}
}
@@ -239,20 +277,35 @@ impl CpuGraphWidget for Painter {
{
cpu_widget_state.is_legend_hidden = false;
let cpu_data: &mut [ConvertedCpuData] = &mut app_state.canvas_data.cpu_data;
-
+ let cpu_table_state = &mut cpu_widget_state.scroll_state.table_state;
+ let is_on_widget = widget_id == app_state.current_widget.widget_id;
+ let table_gap = if draw_loc.height < TABLE_GAP_HEIGHT_LIMIT {
+ 0
+ } else {
+ app_state.app_config_fields.table_gap
+ };
let start_position = get_start_position(
- usize::from(draw_loc.height.saturating_sub(self.table_height_offset)),
+ usize::from(
+ (draw_loc.height + (1 - table_gap)).saturating_sub(self.table_height_offset),
+ ),
&cpu_widget_state.scroll_state.scroll_direction,
&mut cpu_widget_state.scroll_state.previous_scroll_position,
cpu_widget_state.scroll_state.current_scroll_position,
app_state.is_force_redraw,
);
- let is_on_widget = widget_id == app_state.current_widget.widget_id;
+ cpu_table_state.select(Some(
+ cpu_widget_state
+ .scroll_state
+ .current_scroll_position
+ .saturating_sub(start_position),
+ ));
let sliced_cpu_data = &cpu_data[start_position..];
- let mut offset_scroll_index =
- cpu_widget_state.scroll_state.current_scroll_position - start_position;
+ let mut offset_scroll_index = cpu_widget_state
+ .scroll_state
+ .current_scroll_position
+ .saturating_sub(start_position);
let show_avg_cpu = app_state.app_config_fields.show_average_cpu;
let cpu_rows = sliced_cpu_data.iter().enumerate().filter_map(|(itx, cpu)| {
@@ -306,7 +359,7 @@ impl CpuGraphWidget for Painter {
};
// Draw
- f.render_widget(
+ f.render_stateful_widget(
Table::new(CPU_LEGEND_HEADER.iter(), cpu_rows)
.block(
Block::default()
@@ -321,8 +374,9 @@ impl CpuGraphWidget for Painter {
.map(|calculated_width| Constraint::Length(*calculated_width as u16))
.collect::>()),
)
- .header_gap(app_state.app_config_fields.table_gap),
+ .header_gap(table_gap),
draw_loc,
+ cpu_table_state,
);
}
}
diff --git a/src/canvas/widgets/disk_table.rs b/src/canvas/widgets/disk_table.rs
index fdb9fc31..f791500b 100644
--- a/src/canvas/widgets/disk_table.rs
+++ b/src/canvas/widgets/disk_table.rs
@@ -39,8 +39,15 @@ impl DiskTableWidget for Painter {
) {
if let Some(disk_widget_state) = app_state.disk_state.widget_states.get_mut(&widget_id) {
let disk_data: &mut [Vec] = &mut app_state.canvas_data.disk_data;
+ let table_gap = if draw_loc.height < TABLE_GAP_HEIGHT_LIMIT {
+ 0
+ } else {
+ app_state.app_config_fields.table_gap
+ };
let start_position = get_start_position(
- usize::from(draw_loc.height.saturating_sub(self.table_height_offset)),
+ usize::from(
+ (draw_loc.height + (1 - table_gap)).saturating_sub(self.table_height_offset),
+ ),
&disk_widget_state.scroll_state.scroll_direction,
&mut disk_widget_state.scroll_state.previous_scroll_position,
disk_widget_state.scroll_state.current_scroll_position,
@@ -49,15 +56,13 @@ impl DiskTableWidget for Painter {
let is_on_widget = app_state.current_widget.widget_id == widget_id;
let disk_table_state = &mut disk_widget_state.scroll_state.table_state;
disk_table_state.select(Some(
- disk_widget_state.scroll_state.current_scroll_position - start_position,
+ disk_widget_state
+ .scroll_state
+ .current_scroll_position
+ .saturating_sub(start_position),
));
let sliced_vec = &mut disk_data[start_position..];
let disk_rows = sliced_vec.iter().map(|disk| Row::Data(disk.iter()));
- let table_gap = if draw_loc.height < TABLE_GAP_HEIGHT_LIMIT {
- 0
- } else {
- app_state.app_config_fields.table_gap
- };
// Calculate widths
// TODO: [PRETTY] Ellipsis on strings?
@@ -133,7 +138,7 @@ impl DiskTableWidget for Painter {
.constraints([Constraint::Percentage(100)].as_ref())
.horizontal_margin(if is_on_widget || draw_border { 0 } else { 1 })
.direction(Direction::Horizontal)
- .split(draw_loc);
+ .split(draw_loc)[0];
// Draw!
f.render_stateful_widget(
@@ -149,9 +154,20 @@ impl DiskTableWidget for Painter {
.collect::>()),
)
.header_gap(table_gap),
- margined_draw_loc[0],
+ margined_draw_loc,
disk_table_state,
);
+
+ if app_state.should_get_widget_bounds() {
+ // Update draw loc in widget map
+ if let Some(widget) = app_state.widget_map.get_mut(&widget_id) {
+ widget.top_left_corner = Some((margined_draw_loc.x, margined_draw_loc.y));
+ widget.bottom_right_corner = Some((
+ margined_draw_loc.x + margined_draw_loc.width,
+ margined_draw_loc.y + margined_draw_loc.height,
+ ));
+ }
+ }
}
}
}
diff --git a/src/canvas/widgets/mem_basic.rs b/src/canvas/widgets/mem_basic.rs
index aa069f47..89f96dd5 100644
--- a/src/canvas/widgets/mem_basic.rs
+++ b/src/canvas/widgets/mem_basic.rs
@@ -115,5 +115,14 @@ impl MemBasicWidget for Painter {
Paragraph::new(mem_text.iter()).block(Block::default()),
margined_loc[0],
);
+
+ // Update draw loc in widget map
+ if app_state.should_get_widget_bounds() {
+ if let Some(widget) = app_state.widget_map.get_mut(&widget_id) {
+ widget.top_left_corner = Some((draw_loc.x, draw_loc.y));
+ widget.bottom_right_corner =
+ Some((draw_loc.x + draw_loc.width, draw_loc.y + draw_loc.height));
+ }
+ }
}
}
diff --git a/src/canvas/widgets/mem_graph.rs b/src/canvas/widgets/mem_graph.rs
index b6cb1af1..7accfa55 100644
--- a/src/canvas/widgets/mem_graph.rs
+++ b/src/canvas/widgets/mem_graph.rs
@@ -133,5 +133,14 @@ impl MemGraphWidget for Painter {
draw_loc,
);
}
+
+ if app_state.should_get_widget_bounds() {
+ // Update draw loc in widget map
+ if let Some(widget) = app_state.widget_map.get_mut(&widget_id) {
+ widget.top_left_corner = Some((draw_loc.x, draw_loc.y));
+ widget.bottom_right_corner =
+ Some((draw_loc.x + draw_loc.width, draw_loc.y + draw_loc.height));
+ }
+ }
}
}
diff --git a/src/canvas/widgets/network_basic.rs b/src/canvas/widgets/network_basic.rs
index 2d8c6340..126c8ae0 100644
--- a/src/canvas/widgets/network_basic.rs
+++ b/src/canvas/widgets/network_basic.rs
@@ -67,5 +67,14 @@ impl NetworkBasicWidget for Painter {
Paragraph::new(total_net_text.iter()).block(Block::default()),
total_loc[0],
);
+
+ // Update draw loc in widget map
+ if app_state.should_get_widget_bounds() {
+ if let Some(widget) = app_state.widget_map.get_mut(&widget_id) {
+ widget.top_left_corner = Some((draw_loc.x, draw_loc.y));
+ widget.bottom_right_corner =
+ Some((draw_loc.x + draw_loc.width, draw_loc.y + draw_loc.height));
+ }
+ }
}
}
diff --git a/src/canvas/widgets/network_graph.rs b/src/canvas/widgets/network_graph.rs
index d69f68f3..32887c32 100644
--- a/src/canvas/widgets/network_graph.rs
+++ b/src/canvas/widgets/network_graph.rs
@@ -62,6 +62,17 @@ impl NetworkGraphWidget for Painter {
} else {
self.draw_network_graph(f, app_state, draw_loc, widget_id, false);
}
+
+ if app_state.should_get_widget_bounds() {
+ // Update draw loc in widget map
+ // Note that in both cases, we always go to the same widget id so it's fine to do it like
+ // this lol.
+ if let Some(network_widget) = app_state.widget_map.get_mut(&widget_id) {
+ network_widget.top_left_corner = Some((draw_loc.x, draw_loc.y));
+ network_widget.bottom_right_corner =
+ Some((draw_loc.x + draw_loc.width, draw_loc.y + draw_loc.height));
+ }
+ }
}
fn draw_network_graph(
@@ -93,12 +104,8 @@ impl NetworkGraphWidget for Painter {
}
}
- // Main idea is that we have some "limits" --- if we're, say, under a logged kibibyte,
- // then we are just gonna set the cap at a kibibyte.
- // For gibi/giga and beyond, we instead start going up by 1 rather than jumping to a tera/tebi.
- // So, it would look a bit like:
- // - < Kibi => Kibi => Mebi => Gibi => 2 Gibi => ... => 999 Gibi => Tebi => 2 Tebi => ...
-
+ // FIXME [NETWORKING]: Do ya think it would be possible for a more granular approach?
+ // Currently we do 32 -> 33... which skips some gigabit values
let true_max_val: f64;
let mut labels = vec![];
if max_val_bytes < LOG_KIBI_LIMIT {
diff --git a/src/canvas/widgets/process_table.rs b/src/canvas/widgets/process_table.rs
index ca5642ba..8d6ea0bb 100644
--- a/src/canvas/widgets/process_table.rs
+++ b/src/canvas/widgets/process_table.rs
@@ -109,6 +109,65 @@ impl ProcessTableWidget for Painter {
widget_id: u64,
) {
if let Some(proc_widget_state) = app_state.proc_state.widget_states.get_mut(&widget_id) {
+ let is_on_widget = widget_id == app_state.current_widget.widget_id;
+ let margined_draw_loc = Layout::default()
+ .constraints([Constraint::Percentage(100)].as_ref())
+ .horizontal_margin(if is_on_widget || draw_border { 0 } else { 1 })
+ .direction(Direction::Horizontal)
+ .split(draw_loc)[0];
+
+ let (border_and_title_style, highlight_style) = if is_on_widget {
+ (
+ self.colours.highlighted_border_style,
+ self.colours.currently_selected_text_style,
+ )
+ } else {
+ (self.colours.border_style, self.colours.text_style)
+ };
+
+ let title = if draw_border {
+ if app_state.is_expanded
+ && !proc_widget_state
+ .process_search_state
+ .search_state
+ .is_enabled
+ && !proc_widget_state.is_sort_open
+ {
+ const TITLE_BASE: &str = " Processes ── Esc to go back ";
+ format!(
+ " Processes ─{}─ Esc to go back ",
+ "─".repeat(
+ usize::from(draw_loc.width)
+ .saturating_sub(TITLE_BASE.chars().count() + 2)
+ )
+ )
+ } else {
+ " Processes ".to_string()
+ }
+ } else {
+ String::default()
+ };
+
+ let title_style = if app_state.is_expanded {
+ border_and_title_style
+ } else {
+ self.colours.widget_title_style
+ };
+
+ let process_block = if draw_border {
+ Block::default()
+ .title(&title)
+ .title_style(title_style)
+ .borders(Borders::ALL)
+ .border_style(border_and_title_style)
+ } else if is_on_widget {
+ Block::default()
+ .borders(*SIDE_BORDERS)
+ .border_style(self.colours.highlighted_border_style)
+ } else {
+ Block::default().borders(Borders::NONE)
+ };
+
if let Some(process_data) = &app_state
.canvas_data
.finalized_process_data_map
@@ -122,10 +181,17 @@ impl ProcessTableWidget for Painter {
// hit the process we've currently scrolled to.
// We also need to move the list - we can
// do so by hiding some elements!
- let is_on_widget = widget_id == app_state.current_widget.widget_id;
+ let table_gap = if draw_loc.height < TABLE_GAP_HEIGHT_LIMIT {
+ 0
+ } else {
+ app_state.app_config_fields.table_gap
+ };
let position = get_start_position(
- usize::from(draw_loc.height.saturating_sub(self.table_height_offset)),
+ usize::from(
+ (draw_loc.height + (1 - table_gap))
+ .saturating_sub(self.table_height_offset),
+ ),
&proc_widget_state.scroll_state.scroll_direction,
&mut proc_widget_state.scroll_state.previous_scroll_position,
proc_widget_state.scroll_state.current_scroll_position,
@@ -142,13 +208,11 @@ impl ProcessTableWidget for Painter {
let sliced_vec = &process_data[start_position..];
let proc_table_state = &mut proc_widget_state.scroll_state.table_state;
proc_table_state.select(Some(
- proc_widget_state.scroll_state.current_scroll_position - start_position,
+ proc_widget_state
+ .scroll_state
+ .current_scroll_position
+ .saturating_sub(start_position),
));
- let table_gap = if draw_loc.height < TABLE_GAP_HEIGHT_LIMIT {
- 0
- } else {
- app_state.app_config_fields.table_gap
- };
// Draw!
let is_proc_widget_grouped = proc_widget_state.is_grouped;
@@ -216,64 +280,6 @@ impl ProcessTableWidget for Painter {
let intrinsic_widths =
&(variable_intrinsic_results.0)[0..variable_intrinsic_results.1];
- let (border_and_title_style, highlight_style) = if is_on_widget {
- (
- self.colours.highlighted_border_style,
- self.colours.currently_selected_text_style,
- )
- } else {
- (self.colours.border_style, self.colours.text_style)
- };
-
- let title = if draw_border {
- if app_state.is_expanded
- && !proc_widget_state
- .process_search_state
- .search_state
- .is_enabled
- && !proc_widget_state.is_sort_open
- {
- const TITLE_BASE: &str = " Processes ── Esc to go back ";
- format!(
- " Processes ─{}─ Esc to go back ",
- "─".repeat(
- usize::from(draw_loc.width)
- .saturating_sub(TITLE_BASE.chars().count() + 2)
- )
- )
- } else {
- " Processes ".to_string()
- }
- } else {
- String::default()
- };
-
- let title_style = if app_state.is_expanded {
- border_and_title_style
- } else {
- self.colours.widget_title_style
- };
-
- let process_block = if draw_border {
- Block::default()
- .title(&title)
- .title_style(title_style)
- .borders(Borders::ALL)
- .border_style(border_and_title_style)
- } else if is_on_widget {
- Block::default()
- .borders(*SIDE_BORDERS)
- .border_style(self.colours.highlighted_border_style)
- } else {
- Block::default().borders(Borders::NONE)
- };
-
- let margined_draw_loc = Layout::default()
- .constraints([Constraint::Percentage(100)].as_ref())
- .horizontal_margin(if is_on_widget || draw_border { 0 } else { 1 })
- .direction(Direction::Horizontal)
- .split(draw_loc);
-
f.render_stateful_widget(
Table::new(process_headers.iter(), process_rows)
.block(process_block)
@@ -289,9 +295,22 @@ impl ProcessTableWidget for Painter {
.collect::>()),
)
.header_gap(table_gap),
- margined_draw_loc[0],
+ margined_draw_loc,
proc_table_state,
);
+ } else {
+ f.render_widget(process_block, margined_draw_loc);
+ }
+
+ if app_state.should_get_widget_bounds() {
+ // Update draw loc in widget map
+ if let Some(widget) = app_state.widget_map.get_mut(&widget_id) {
+ widget.top_left_corner = Some((margined_draw_loc.x, margined_draw_loc.y));
+ widget.bottom_right_corner = Some((
+ margined_draw_loc.x + margined_draw_loc.width,
+ margined_draw_loc.y + margined_draw_loc.height,
+ ));
+ }
}
}
}
@@ -497,15 +516,26 @@ impl ProcessTableWidget for Painter {
.constraints([Constraint::Percentage(100)].as_ref())
.horizontal_margin(if is_on_widget || draw_border { 0 } else { 1 })
.direction(Direction::Horizontal)
- .split(draw_loc);
+ .split(draw_loc)[0];
f.render_widget(
Paragraph::new(search_text.iter())
.block(process_search_block)
.style(self.colours.text_style)
.alignment(Alignment::Left),
- margined_draw_loc[0],
+ margined_draw_loc,
);
+
+ if app_state.should_get_widget_bounds() {
+ // Update draw loc in widget map
+ if let Some(widget) = app_state.widget_map.get_mut(&widget_id) {
+ widget.top_left_corner = Some((margined_draw_loc.x, margined_draw_loc.y));
+ widget.bottom_right_corner = Some((
+ margined_draw_loc.x + margined_draw_loc.width,
+ margined_draw_loc.y + margined_draw_loc.height,
+ ));
+ }
+ }
}
}
@@ -531,21 +561,18 @@ impl ProcessTableWidget for Painter {
.unwrap()
.enabled
})
- .enumerate()
- .map(|(itx, column_type)| {
- if current_scroll_position == itx {
- (
- column_type.to_string(),
- self.colours.currently_selected_text_style,
- )
- } else {
- (column_type.to_string(), self.colours.text_style)
- }
- })
+ .map(|column_type| column_type.to_string())
.collect::>();
+ let table_gap = if draw_loc.height < TABLE_GAP_HEIGHT_LIMIT {
+ 0
+ } else {
+ app_state.app_config_fields.table_gap
+ };
let position = get_start_position(
- usize::from(draw_loc.height.saturating_sub(self.table_height_offset)),
+ usize::from(
+ (draw_loc.height + (1 - table_gap)).saturating_sub(self.table_height_offset),
+ ),
&proc_widget_state.columns.scroll_direction,
&mut proc_widget_state.columns.previous_scroll_position,
current_scroll_position,
@@ -563,9 +590,15 @@ impl ProcessTableWidget for Painter {
let sort_options = sliced_vec
.iter()
- .map(|(column, style)| Row::StyledData(vec![column].into_iter(), *style));
+ .map(|column| Row::Data(vec![column].into_iter()));
let column_state = &mut proc_widget_state.columns.column_state;
+ column_state.select(Some(
+ proc_widget_state
+ .columns
+ .current_scroll_position
+ .saturating_sub(start_position),
+ ));
let current_border_style = if proc_widget_state
.process_search_state
.search_state
@@ -590,21 +623,40 @@ impl ProcessTableWidget for Painter {
Block::default().borders(Borders::NONE)
};
+ let highlight_style = if is_on_widget {
+ self.colours.currently_selected_text_style
+ } else {
+ self.colours.text_style
+ };
+
let margined_draw_loc = Layout::default()
.constraints([Constraint::Percentage(100)].as_ref())
.horizontal_margin(if is_on_widget || draw_border { 0 } else { 1 })
.direction(Direction::Horizontal)
- .split(draw_loc);
+ .split(draw_loc)[0];
f.render_stateful_widget(
Table::new(["Sort By"].iter(), sort_options)
.block(process_sort_block)
+ .highlight_style(highlight_style)
+ .style(self.colours.text_style)
.header_style(self.colours.table_header_style)
.widths(&[Constraint::Percentage(100)])
- .header_gap(1),
- margined_draw_loc[0],
+ .header_gap(table_gap),
+ margined_draw_loc,
column_state,
);
+
+ if app_state.should_get_widget_bounds() {
+ // Update draw loc in widget map
+ if let Some(widget) = app_state.widget_map.get_mut(&widget_id) {
+ widget.top_left_corner = Some((margined_draw_loc.x, margined_draw_loc.y));
+ widget.bottom_right_corner = Some((
+ margined_draw_loc.x + margined_draw_loc.width,
+ margined_draw_loc.y + margined_draw_loc.height,
+ ));
+ }
+ }
}
}
}
diff --git a/src/canvas/widgets/temp_table.rs b/src/canvas/widgets/temp_table.rs
index 23822b68..9ab6f985 100644
--- a/src/canvas/widgets/temp_table.rs
+++ b/src/canvas/widgets/temp_table.rs
@@ -40,8 +40,15 @@ impl TempTableWidget for Painter {
if let Some(temp_widget_state) = app_state.temp_state.widget_states.get_mut(&widget_id) {
let temp_sensor_data: &mut [Vec] = &mut app_state.canvas_data.temp_sensor_data;
+ let table_gap = if draw_loc.height < TABLE_GAP_HEIGHT_LIMIT {
+ 0
+ } else {
+ app_state.app_config_fields.table_gap
+ };
let start_position = get_start_position(
- usize::from(draw_loc.height.saturating_sub(self.table_height_offset)),
+ usize::from(
+ (draw_loc.height + (1 - table_gap)).saturating_sub(self.table_height_offset),
+ ),
&temp_widget_state.scroll_state.scroll_direction,
&mut temp_widget_state.scroll_state.previous_scroll_position,
temp_widget_state.scroll_state.current_scroll_position,
@@ -50,15 +57,13 @@ impl TempTableWidget for Painter {
let is_on_widget = widget_id == app_state.current_widget.widget_id;
let temp_table_state = &mut temp_widget_state.scroll_state.table_state;
temp_table_state.select(Some(
- temp_widget_state.scroll_state.current_scroll_position - start_position,
+ temp_widget_state
+ .scroll_state
+ .current_scroll_position
+ .saturating_sub(start_position),
));
let sliced_vec = &temp_sensor_data[start_position..];
let temperature_rows = sliced_vec.iter().map(|temp_row| Row::Data(temp_row.iter()));
- let table_gap = if draw_loc.height < TABLE_GAP_HEIGHT_LIMIT {
- 0
- } else {
- app_state.app_config_fields.table_gap
- };
// Calculate widths
let width = f64::from(draw_loc.width);
@@ -113,7 +118,7 @@ impl TempTableWidget for Painter {
.constraints([Constraint::Percentage(100)].as_ref())
.horizontal_margin(if is_on_widget || draw_border { 0 } else { 1 })
.direction(Direction::Horizontal)
- .split(draw_loc);
+ .split(draw_loc)[0];
// Draw
f.render_stateful_widget(
@@ -129,9 +134,21 @@ impl TempTableWidget for Painter {
.collect::>()),
)
.header_gap(table_gap),
- margined_draw_loc[0],
+ margined_draw_loc,
temp_table_state,
);
+
+ if app_state.should_get_widget_bounds() {
+ // Update draw loc in widget map
+ // Note there is no difference between this and using draw_loc, but I'm too lazy to fix it.
+ if let Some(widget) = app_state.widget_map.get_mut(&widget_id) {
+ widget.top_left_corner = Some((margined_draw_loc.x, margined_draw_loc.y));
+ widget.bottom_right_corner = Some((
+ margined_draw_loc.x + margined_draw_loc.width,
+ margined_draw_loc.y + margined_draw_loc.height,
+ ));
+ }
+ }
}
}
}
diff --git a/src/lib.rs b/src/lib.rs
index a5689747..2022e1b5 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -85,6 +85,7 @@ pub fn get_matches() -> clap::ArgMatches<'static> {
(@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.")
+ (@arg DISABLE_CLICK: --disable_click "Disables mouse clicks from interacting with the program.")
)
.get_matches()
}
@@ -93,6 +94,20 @@ pub fn handle_mouse_event(event: MouseEvent, app: &mut App) {
match event {
MouseEvent::ScrollUp(_x, _y, _modifiers) => app.handle_scroll_up(),
MouseEvent::ScrollDown(_x, _y, _modifiers) => app.handle_scroll_down(),
+ MouseEvent::Down(button, x, y, _modifiers) => {
+ // debug!("Button down: {:?}, x: {}, y: {}", button, x, y);
+
+ if !app.app_config_fields.disable_click {
+ match button {
+ crossterm::event::MouseButton::Left => {
+ // Trigger left click widget activity
+ app.left_mouse_click_movement(x, y);
+ }
+ crossterm::event::MouseButton::Right => {}
+ _ => {}
+ }
+ }
+ }
_ => {}
};
}
diff --git a/src/options.rs b/src/options.rs
index d772ed9e..41059f9c 100644
--- a/src/options.rs
+++ b/src/options.rs
@@ -42,6 +42,7 @@ pub struct ConfigFlags {
pub use_old_network_legend: Option,
pub hide_table_gap: Option,
pub battery: Option,
+ pub disable_click: Option,
}
#[derive(Default, Deserialize)]
@@ -192,11 +193,19 @@ pub fn build_app(
currently_displayed_widget_type: initial_widget_type,
currently_displayed_widget_id: initial_widget_id,
widget_id: 100,
+ left_tlc: None,
+ left_brc: None,
+ right_tlc: None,
+ right_brc: None,
},
_ => BasicTableWidgetState {
currently_displayed_widget_type: Proc,
currently_displayed_widget_id: DEFAULT_WIDGET_ID,
widget_id: 100,
+ left_tlc: None,
+ left_brc: None,
+ right_tlc: None,
+ right_brc: None,
},
})
} else {
@@ -221,6 +230,7 @@ pub fn build_app(
} else {
1
},
+ disable_click: get_disable_click(matches, config),
};
let used_widgets = UsedWidgets {
@@ -259,6 +269,7 @@ pub fn get_widget_layout(
let bottom_layout = if get_use_basic_mode(matches, config) {
default_widget_id = DEFAULT_WIDGET_ID;
+
BottomLayout::init_basic_default(get_use_battery(matches, config))
} else {
let ref_row: Vec; // Required to handle reference
@@ -297,7 +308,7 @@ pub fn get_widget_layout(
total_row_height_ratio: total_height_ratio,
};
- // Confirm that we have at least ONE widget - if not, error out!
+ // Confirm that we have at least ONE widget left - if not, error out!
if iter_id > 0 {
ret_bottom_layout.get_movement_mappings();
// debug!("Bottom layout: {:#?}", ret_bottom_layout);
@@ -489,9 +500,7 @@ pub fn get_app_grouping(matches: &clap::ArgMatches<'static>, config: &Config) ->
return true;
} else if let Some(flags) = &config.flags {
if let Some(grouping) = flags.group_processes {
- if grouping {
- return true;
- }
+ return grouping;
}
}
false
@@ -502,9 +511,7 @@ pub fn get_app_case_sensitive(matches: &clap::ArgMatches<'static>, config: &Conf
return true;
} else if let Some(flags) = &config.flags {
if let Some(case_sensitive) = flags.case_sensitive {
- if case_sensitive {
- return true;
- }
+ return case_sensitive;
}
}
false
@@ -515,9 +522,7 @@ pub fn get_app_match_whole_word(matches: &clap::ArgMatches<'static>, config: &Co
return true;
} else if let Some(flags) = &config.flags {
if let Some(whole_word) = flags.whole_word {
- if whole_word {
- return true;
- }
+ return whole_word;
}
}
false
@@ -528,9 +533,7 @@ pub fn get_app_use_regex(matches: &clap::ArgMatches<'static>, config: &Config) -
return true;
} else if let Some(flags) = &config.flags {
if let Some(regex) = flags.regex {
- if regex {
- return true;
- }
+ return regex;
}
}
false
@@ -541,9 +544,7 @@ fn get_hide_time(matches: &clap::ArgMatches<'static>, config: &Config) -> bool {
return true;
} else if let Some(flags) = &config.flags {
if let Some(hide_time) = flags.hide_time {
- if hide_time {
- return true;
- }
+ return hide_time;
}
}
false
@@ -554,9 +555,7 @@ fn get_autohide_time(matches: &clap::ArgMatches<'static>, config: &Config) -> bo
return true;
} else if let Some(flags) = &config.flags {
if let Some(autohide_time) = flags.autohide_time {
- if autohide_time {
- return true;
- }
+ return autohide_time;
}
}
@@ -613,14 +612,23 @@ fn get_default_widget_and_count(
}
}
+fn get_disable_click(matches: &clap::ArgMatches<'static>, config: &Config) -> bool {
+ if matches.is_present("DISABLE_CLICK") {
+ return true;
+ } else if let Some(flags) = &config.flags {
+ if let Some(disable_click) = flags.disable_click {
+ return disable_click;
+ }
+ }
+ false
+}
+
pub fn get_use_old_network_legend(matches: &clap::ArgMatches<'static>, config: &Config) -> bool {
if matches.is_present("USE_OLD_NETWORK_LEGEND") {
return true;
} else if let Some(flags) = &config.flags {
if let Some(use_old_network_legend) = flags.use_old_network_legend {
- if use_old_network_legend {
- return true;
- }
+ return use_old_network_legend;
}
}
false
@@ -631,9 +639,7 @@ pub fn get_hide_table_gap(matches: &clap::ArgMatches<'static>, config: &Config)
return true;
} else if let Some(flags) = &config.flags {
if let Some(hide_table_gap) = flags.hide_table_gap {
- if hide_table_gap {
- return true;
- }
+ return hide_table_gap;
}
}
false
@@ -644,9 +650,7 @@ pub fn get_use_battery(matches: &clap::ArgMatches<'static>, config: &Config) ->
return true;
} else if let Some(flags) = &config.flags {
if let Some(battery) = flags.battery {
- if battery {
- return true;
- }
+ return battery;
}
}
false
diff --git a/tests/layout_movement_tests.rs b/tests/layout_movement_tests.rs
new file mode 100644
index 00000000..ef73c683
--- /dev/null
+++ b/tests/layout_movement_tests.rs
@@ -0,0 +1,9 @@
+// TODO: Test basic mode
+// #[test]
+// fn test_basic_mode() {
+// let ret_bottom_layout = BottomLayout::init_basic_default(false);
+// }
+
+// TODO: Test moving around with procs and their hidden children.
+
+// TODO: Test moving around with cpus if they get hidden.
\ No newline at end of file