summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClement Tsang <34804052+ClementTsang@users.noreply.github.com>2020-08-29 18:54:18 -0400
committerGitHub <noreply@github.com>2020-08-29 18:54:18 -0400
commit3d2fc76aa24047deb167768940c5969d2bb2a595 (patch)
tree9732b15a1570a83ffc7fa0db4d78773ceda30dd6
parentb6363096b416ddbe8f4a207cdd896194ba3e6e95 (diff)
feature: Add mouse click support for moving between widgets (#208)
Adds mouse support to the application, to move between widgets and click on elements. List of things to added: - Click to move between widgets - Click to move between widgets in basic mode - Click on widget entries - Ability to disable mouse if you don't like it, I guess
-rw-r--r--.vscode/settings.json5
-rw-r--r--CHANGELOG.md4
-rw-r--r--README.md77
-rw-r--r--src/app.rs349
-rw-r--r--src/app/layout_manager.rs10
-rw-r--r--src/app/states.rs4
-rw-r--r--src/bin/main.rs6
-rw-r--r--src/canvas.rs41
-rw-r--r--src/canvas/dialogs/help_dialog.rs2
-rw-r--r--src/canvas/widgets/basic_table_arrows.rs211
-rw-r--r--src/canvas/widgets/battery_display.rs23
-rw-r--r--src/canvas/widgets/cpu_basic.rs13
-rw-r--r--src/canvas/widgets/cpu_graph.rs68
-rw-r--r--src/canvas/widgets/disk_table.rs34
-rw-r--r--src/canvas/widgets/mem_basic.rs9
-rw-r--r--src/canvas/widgets/mem_graph.rs9
-rw-r--r--src/canvas/widgets/network_basic.rs9
-rw-r--r--src/canvas/widgets/network_graph.rs19
-rw-r--r--src/canvas/widgets/process_table.rs222
-rw-r--r--src/canvas/widgets/temp_table.rs35
-rw-r--r--src/lib.rs15
-rw-r--r--src/options.rs60
-rw-r--r--tests/layout_movement_tests.rs9
23 files changed, 901 insertions, 333 deletions
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`<br>`Shift-Left`<br>`H`<br>`A` | Move widget selection left |
-| `Ctrl-Right`<br>`Shift-Right`<br>`L`<br>`D` | Move widget selection right |
-| `Ctrl-Up`<br>`Shift-Up`<br>`K`<br>`W` | Move widget selection up |
-| `Ctrl-Down`<br>`Shift-Down`<br>`J`<br>`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<br>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`<br>`Shift-Left`<br>`H`<br>`A` | Move widget selection left |
+| `Ctrl-Right`<br>`Shift-Right`<br>`L`<br>`D` | Move widget selection right |
+| `Ctrl-Up`<br>`Shift-Up`<br>`K`<br>`W` | Move widget selection up |
+| `Ctrl-Down`<br>`Shift-Down`<br>`J`<br>`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.
| -------- | ---------------------------------------------------- | -------------------------- |
| `()` | `(<CONDITION 1> AND <CONDITION 2>) OR <CONDITION 3>` | Group together a condition |
+### Mousebindings
+
+#### General
+
+| | |
+| ------------ | --------------------------------------------------------------------------------------------------------------------- |
+| Mouse scroll | Table: Scroll<br>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
<!-- markdownlint-enable -->
<!-- prettier-ignore-end -->
+
<!-- ALL-CONTRIBUTORS-LIST:END -->
## 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)]
@@ -81,6 +82,9 @@ pub struct App {
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,
pub cpu_state: CpuState,
@@ -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<BasicTableWidgetState>,
-
pub app_config_fields: AppConfigFields,
pub widget_map: HashMap<u64, BottomWidget>,
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();
+