summaryrefslogtreecommitdiffstats
path: root/src/app
diff options
context:
space:
mode:
authorClementTsang <cjhtsang@uwaterloo.ca>2021-08-29 20:05:17 -0400
committerClementTsang <cjhtsang@uwaterloo.ca>2021-08-30 00:51:09 -0400
commit3fa50605b334909d8a0225eaefb6c91feb551ce5 (patch)
tree407ef6a31fcb87d72c384c85871adb9af765b3bf /src/app
parent48c572dbafb443d505fc73fa0d598db3c727593f (diff)
bug: fix bug causing click bounds to fail
There were three bugs: 1. The click bounds calculation was incorrect. I did the silly mistake of checking for <= bounds for the bottom and right sections of a Rect when checking if the mouse intersected - this is WRONG. For example, let's say you want to calculate if an x value of 5 falls between something that starts at 0 and is 5 long. It shouldn't, right? Because it draws from 0 to 4? But if you just did <= Rect.right(), you would get a hit - because it just does (start + width), so you get 5, and 5 <= 5! So, easy fix, change all far bounds checks to <. 2. The second bug is a mistake where I accidentally did not include bounds sets for my memory and net widgets. Instead, they set their bounds to the underlying graph representation, which is WRONG, since that bound gets updated on draw, and gets set to a slightly smaller rect due to borders! 3. A slightly sneakier one. This broke my bounds checks for the CPU widget - and it would have broken my process widget too. The problem lies in the concept of widgets that handle multiple "sub"-blocks internally, and how I was doing click detection internally - I would check if the bounds of the internal Components were hit. Say, the CPU, I would check if the internal graph was hit, then if the internal table was hit. But wait! I said in point 2 that a graph gets its borders updated on draw to something slightly smaller, due to borders! And there's the problem - it affected tables too. I was setting the bounds of components to that of the *internal* representation - without borders - but my click detection *needed* borders included! Solution? Add another trait function to check bordered bounds, and make the default implementation just check the existing bounds. For cases like internal Components that may need it, I add a separate implementation. I also switched over all border bounds checks for Widgets to that, since it's a bit more consistent.
Diffstat (limited to 'src/app')
-rw-r--r--src/app/event.rs3
-rw-r--r--src/app/layout_manager.rs5
-rw-r--r--src/app/widgets.rs33
-rw-r--r--src/app/widgets/base/scrollable.rs2
-rw-r--r--src/app/widgets/base/sort_text_table.rs66
-rw-r--r--src/app/widgets/base/text_input.rs9
-rw-r--r--src/app/widgets/base/text_table.rs16
-rw-r--r--src/app/widgets/base/time_graph.rs11
-rw-r--r--src/app/widgets/cpu.rs19
-rw-r--r--src/app/widgets/disk.rs16
-rw-r--r--src/app/widgets/mem.rs6
-rw-r--r--src/app/widgets/net.rs7
-rw-r--r--src/app/widgets/process.rs14
-rw-r--r--src/app/widgets/temp.rs11
14 files changed, 167 insertions, 51 deletions
diff --git a/src/app/event.rs b/src/app/event.rs
index a776a493..a6afb2d8 100644
--- a/src/app/event.rs
+++ b/src/app/event.rs
@@ -4,6 +4,7 @@ const MAX_TIMEOUT: Duration = Duration::from_millis(400);
/// These are "signals" that are sent along with an [`WidgetEventResult`] to signify a potential additional action
/// that the caller must do, along with the "core" result of either drawing or redrawing.
+#[derive(Debug)]
pub enum ReturnSignal {
/// A signal returned when some process widget was told to try to kill a process (or group of processes).
///
@@ -18,6 +19,7 @@ pub enum ReturnSignal {
}
/// The results of handling an event by the [`AppState`].
+#[derive(Debug)]
pub enum EventResult {
/// Kill the program.
Quit,
@@ -29,6 +31,7 @@ pub enum EventResult {
/// The results of a widget handling some event, like a mouse or key event,
/// signifying what the program should then do next.
+#[derive(Debug)]
pub enum WidgetEventResult {
/// Kill the program.
Quit,
diff --git a/src/app/layout_manager.rs b/src/app/layout_manager.rs
index d2927a35..7105fa73 100644
--- a/src/app/layout_manager.rs
+++ b/src/app/layout_manager.rs
@@ -1001,13 +1001,16 @@ pub struct ColLayout {
}
/// A [`LayoutNode`] represents a single node in the overall widget hierarchy. Each node is one of:
-/// - [`LayoutNode::Row`] (a a non-leaf that distributes its children horizontally)
+/// - [`LayoutNode::Row`] (a non-leaf that distributes its children horizontally)
/// - [`LayoutNode::Col`] (a non-leaf node that distributes its children vertically)
/// - [`LayoutNode::Widget`] (a leaf node that contains the ID of the widget it is associated with)
#[derive(PartialEq, Eq)]
pub enum LayoutNode {
+ /// A non-leaf that distributes its children horizontally
Row(RowLayout),
+ /// A non-leaf node that distributes its children vertically
Col(ColLayout),
+ /// A leaf node that contains the ID of the widget it is associated with
Widget,
}
diff --git a/src/app/widgets.rs b/src/app/widgets.rs
index 751157c7..104e6ac4 100644
--- a/src/app/widgets.rs
+++ b/src/app/widgets.rs
@@ -6,7 +6,7 @@ use tui::{backend::Backend, layout::Rect, widgets::TableState, Frame};
use crate::{
app::{
- event::{WidgetEventResult, SelectionAction},
+ event::{SelectionAction, WidgetEventResult},
layout_manager::BottomWidgetType,
},
canvas::Painter,
@@ -63,15 +63,36 @@ pub trait Component {
/// coordinates.
fn bounds(&self) -> Rect;
- /// Updates a [`Component`]s bounding box to `new_bounds`.
+ /// Updates a [`Component`]'s bounding box to `new_bounds`.
fn set_bounds(&mut self, new_bounds: Rect);
- /// Returns whether a [`MouseEvent`] intersects a [`Component`].
- fn does_intersect_mouse(&self, event: &MouseEvent) -> bool {
+ /// Returns a [`Component`]'s bounding box, *including the border*. Defaults to just returning the normal bounds.
+ /// Note that these are defined in *global*, *absolute* coordinates.
+ fn border_bounds(&self) -> Rect {
+ self.bounds()
+ }
+
+ /// Updates a [`Component`]'s bounding box to `new_bounds`. Defaults to just setting the normal bounds.
+ fn set_border_bounds(&mut self, new_bounds: Rect) {
+ self.set_bounds(new_bounds);
+ }
+
+ /// Returns whether a [`MouseEvent`] intersects a [`Component`]'s bounds.
+ fn does_bounds_intersect_mouse(&self, event: &MouseEvent) -> bool {
+ let x = event.column;
+ let y = event.row;
+ let bounds = self.bounds();
+
+ x >= bounds.left() && x < bounds.right() && y >= bounds.top() && y < bounds.bottom()
+ }
+
+ /// Returns whether a [`MouseEvent`] intersects a [`Component`]'s bounds, including any borders, if there are.
+ fn does_border_intersect_mouse(&self, event: &MouseEvent) -> bool {
let x = event.column;
let y = event.row;
- let rect = self.bounds();
- x >= rect.left() && x <= rect.right() && y >= rect.top() && y <= rect.bottom()
+ let bounds = self.border_bounds();
+
+ x >= bounds.left() && x < bounds.right() && y >= bounds.top() && y < bounds.bottom()
}
}
diff --git a/src/app/widgets/base/scrollable.rs b/src/app/widgets/base/scrollable.rs
index 811d7017..54000a06 100644
--- a/src/app/widgets/base/scrollable.rs
+++ b/src/app/widgets/base/scrollable.rs
@@ -224,7 +224,7 @@ impl Component for Scrollable {
fn handle_mouse_event(&mut self, event: MouseEvent) -> WidgetEventResult {
match event.kind {
MouseEventKind::Down(MouseButton::Left) => {
- if self.does_intersect_mouse(&event) {
+ if self.does_bounds_intersect_mouse(&event) {
// This requires a bit of fancy calculation. The main trick is remembering that
// we are using a *visual* index here - not what is the actual index! Luckily, we keep track of that
// inside our linked copy of TableState!
diff --git a/src/app/widgets/base/sort_text_table.rs b/src/app/widgets/base/sort_text_table.rs
index 23f46250..cc95f2c0 100644
--- a/src/app/widgets/base/sort_text_table.rs
+++ b/src/app/widgets/base/sort_text_table.rs
@@ -1,7 +1,7 @@
use std::borrow::Cow;
use crossterm::event::{KeyCode, KeyEvent, KeyModifiers, MouseButton, MouseEvent, MouseEventKind};
-use tui::{backend::Backend, layout::Rect, widgets::Block};
+use tui::{backend::Backend, layout::Rect, widgets::Block, Frame};
use crate::{
app::{
@@ -60,6 +60,9 @@ pub enum SortStatus {
/// A trait for sortable columns.
pub trait SortableColumn {
+ /// Returns the original name of the column.
+ fn original_name(&self) -> &Cow<'static, str>;
+
/// Returns the shortcut for the column, if it exists.
fn shortcut(&self) -> &Option<(KeyEvent, String)>;
@@ -73,12 +76,18 @@ pub trait SortableColumn {
/// Sets the sorting status.
fn set_sorting_status(&mut self, sorting_status: SortStatus);
+ // ----- The following are required since SortableColumn implements TableColumn -----
+
+ /// Returns the displayed name on the column when drawing.
fn display_name(&self) -> Cow<'static, str>;
+ /// Returns the desired width of the column when drawing.
fn get_desired_width(&self) -> &DesiredColumnWidth;
+ /// Returns the x bounds of a column. The y is assumed to be 0, relative to the table..
fn get_x_bounds(&self) -> Option<(u16, u16)>;
+ /// Sets the x bounds of a column.
fn set_x_bounds(&mut self, x_bounds: Option<(u16, u16)>);
}
@@ -106,8 +115,11 @@ where
/// A [`SimpleSortableColumn`] represents some column in a [`SortableTextTable`].
#[derive(Debug)]
pub struct SimpleSortableColumn {
+ original_name: Cow<'static, str>,
pub shortcut: Option<(KeyEvent, String)>,
pub default_descending: bool,
+ x_bounds: Option<(u16, u16)>,
+
pub internal: SimpleColumn,
/// Whether this column is currently selected for sorting, and which direction.
@@ -117,12 +129,15 @@ pub struct SimpleSortableColumn {
impl SimpleSortableColumn {
/// Creates a new [`SimpleSortableColumn`].
fn new(
- full_name: Cow<'static, str>, shortcut: Option<(KeyEvent, String)>,
- default_descending: bool, desired_width: DesiredColumnWidth,
+ original_name: Cow<'static, str>, full_name: Cow<'static, str>,
+ shortcut: Option<(KeyEvent, String)>, default_descending: bool,
+ desired_width: DesiredColumnWidth,
) -> Self {
Self {
+ original_name,
shortcut,
default_descending,
+ x_bounds: None,
internal: SimpleColumn::new(full_name, desired_width),
sorting_status: SortStatus::NotSorting,
}
@@ -141,11 +156,12 @@ impl SimpleSortableColumn {
Some((shortcut, shortcut_name)),
)
} else {
- (name, None)
+ (name.clone(), None)
};
let full_name_len = full_name.len();
SimpleSortableColumn::new(
+ name,
full_name,
shortcut,
default_descending,
@@ -165,11 +181,12 @@ impl SimpleSortableColumn {
Some((shortcut, shortcut_name)),
)
} else {
- (name, None)
+ (name.clone(), None)
};
let full_name_len = full_name.len();
SimpleSortableColumn::new(
+ name,
full_name,
shortcut,
default_descending,
@@ -182,6 +199,10 @@ impl SimpleSortableColumn {
}
impl SortableColumn for SimpleSortableColumn {
+ fn original_name(&self) -> &Cow<'static, str> {
+ &self.original_name
+ }
+
fn shortcut(&self) -> &Option<(KeyEvent, String)> {
&self.shortcut
}
@@ -236,6 +257,9 @@ where
/// The underlying [`TextTable`].
pub table: TextTable<S>,
+
+ /// A corresponding "sort" menu.
+ pub sort_menu: TextTable,
}
impl<S> SortableTextTable<S>
@@ -244,9 +268,15 @@ where
{
/// Creates a new [`SortableTextTable`]. Note that `columns` cannot be empty.
pub fn new(columns: Vec<S>) -> Self {
+ let sort_menu_columns = columns
+ .iter()
+ .map(|column| SimpleColumn::new_hard(column.original_name().clone(), None))
+ .collect::<Vec<_>>();
+
let mut st = Self {
sort_index: 0,
table: TextTable::new(columns),
+ sort_menu: TextTable::new(sort_menu_columns),
};
st.set_sort_index(0);
st
@@ -317,15 +347,21 @@ where
/// Draws a [`tui::widgets::Table`] on screen.
///
- /// Note if the number of columns don't match in the [`TextTable`] and data,
+ /// Note if the number of columns don't match in the [`SortableTextTable`] and data,
/// it will only create as many columns as it can grab data from both sources from.
pub fn draw_tui_table<B: Backend>(
- &mut self, painter: &Painter, f: &mut tui::Frame<'_, B>, data: &TextTableData,
- block: Block<'_>, block_area: Rect, show_selected_entry: bool,
+ &mut self, painter: &Painter, f: &mut Frame<'_, B>, data: &TextTableData, block: Block<'_>,
+ block_area: Rect, show_selected_entry: bool,
) {
self.table
.draw_tui_table(painter, f, data, block, block_area, show_selected_entry);
}
+
+ /// Draws a [`tui::widgets::Table`] on screen corresponding to the sort columns of this [`SortableTextTable`].
+ pub fn draw_sort_table<B: Backend>(
+ &mut self, painter: &Painter, f: &mut Frame<'_, B>, block: Block<'_>, block_area: Rect,
+ ) {
+ }
}
impl<S> Component for SortableTextTable<S>
@@ -347,7 +383,7 @@ where
fn handle_mouse_event(&mut self, event: MouseEvent) -> WidgetEventResult {
if let MouseEventKind::Down(MouseButton::Left) = event.kind {
- if !self.does_intersect_mouse(&event) {
+ if !self.does_bounds_intersect_mouse(&event) {
return WidgetEventResult::NoRedraw;
}
@@ -373,10 +409,18 @@ where
}
fn bounds(&self) -> Rect {
- self.table.bounds
+ self.table.bounds()
}
fn set_bounds(&mut self, new_bounds: Rect) {
- self.table.bounds = new_bounds;
+ self.table.set_bounds(new_bounds)
+ }
+
+ fn border_bounds(&self) -> Rect {
+ self.table.border_bounds()
+ }
+
+ fn set_border_bounds(&mut self, new_bounds: Rect) {
+ self.table.set_border_bounds(new_bounds)
}
}
diff --git a/src/app/widgets/base/text_input.rs b/src/app/widgets/base/text_input.rs
index dfe776de..597dff6e 100644
--- a/src/app/widgets/base/text_input.rs
+++ b/src/app/widgets/base/text_input.rs
@@ -12,6 +12,7 @@ pub struct TextInput {
text: String,
cursor_index: usize,
bounds: Rect,
+ border_bounds: Rect,
}
impl TextInput {
@@ -92,6 +93,14 @@ impl Component for TextInput {
self.bounds = new_bounds;
}
+ fn border_bounds(&self) -> Rect {
+ self.border_bounds
+ }
+
+ fn set_border_bounds(&mut self, new_bounds: Rect) {
+ self.border_bounds = new_bounds;
+ }
+
fn handle_key_event(&mut self, event: KeyEvent) -> WidgetEventResult {
if event.modifiers.is_empty() {
match event.code {
diff --git a/src/app/widgets/base/text_table.rs b/src/app/widgets/base/text_table.rs
index 20d78b8e..87f3f69d 100644
--- a/src/app/widgets/base/text_table.rs
+++ b/src/app/widgets/base/text_table.rs
@@ -131,6 +131,9 @@ where
/// The bounding box of the [`TextTable`].
pub bounds: Rect, // TODO: Consider moving bounds to something else???
+ /// The bounds including the border, if there is one.
+ pub border_bounds: Rect,
+
/// Whether we draw columns from left-to-right.
pub left_to_right: bool,
@@ -149,6 +152,7 @@ where
cached_column_widths: CachedColumnWidths::Uncached,
show_gap: true,
bounds: Rect::default(),
+ border_bounds: Rect::default(),
left_to_right: true,
selectable: true,
}
@@ -342,7 +346,7 @@ where
}
}
- /// Draws a [`Table`] on screen..
+ /// Draws a [`Table`] on screen corresponding to the [`TextTable`].
///
/// Note if the number of columns don't match in the [`TextTable`] and data,
/// it will only create as many columns as it can grab data from both sources from.
@@ -353,7 +357,6 @@ where
use tui::widgets::Row;
let inner_area = block.inner(block_area);
-
let table_gap = if !self.show_gap || inner_area.height < TABLE_GAP_HEIGHT_LIMIT {
0
} else {
@@ -361,6 +364,7 @@ where
};
self.set_num_items(data.len());
+ self.set_border_bounds(block_area);
self.set_bounds(inner_area);
let table_extras = 1 + table_gap;
let scrollable_height = inner_area.height.saturating_sub(table_extras);
@@ -466,4 +470,12 @@ where
fn set_bounds(&mut self, new_bounds: Rect) {
self.bounds = new_bounds;
}
+
+ fn border_bounds(&self) -> Rect {
+ self.border_bounds
+ }
+
+ fn set_border_bounds(&mut self, new_bounds: Rect) {
+ self.border_bounds = new_bounds;
+ }
}
diff --git a/src/app/widgets/base/time_graph.rs b/src/app/widgets/base/time_graph.rs
index 1f8399ff..1bfd4a8b 100644
--- a/src/app/widgets/base/time_graph.rs
+++ b/src/app/widgets/base/time_graph.rs
@@ -111,6 +111,7 @@ pub struct TimeGraph {
time_interval: u64,
bounds: Rect,
+ border_bounds: Rect,
use_dot: bool,
}
@@ -129,6 +130,7 @@ impl TimeGraph {
max_duration,
time_interval,
bounds: Rect::default(),
+ border_bounds: Rect::default(),
use_dot,
}
}
@@ -236,6 +238,7 @@ impl TimeGraph {
) {
let inner_area = block.inner(block_area);
+ self.set_border_bounds(block_area);
self.set_bounds(inner_area);
let time_start = -(self.current_display_time as f64);
@@ -324,4 +327,12 @@ impl Component for TimeGraph {
fn set_bounds(&mut self, new_bounds: Rect) {
self.bounds = new_bounds;
}
+
+ fn border_bounds(&self) -> Rect {
+ self.border_bounds
+ }
+
+ fn set_border_bounds(&mut self, new_bounds: Rect) {
+ self.border_bounds = new_bounds;
+ }
}
diff --git a/src/app/widgets/cpu.rs b/src/app/widgets/cpu.rs
index 566ce4cc..12647a47 100644
--- a/src/app/widgets/cpu.rs
+++ b/src/app/widgets/cpu.rs
@@ -16,9 +16,7 @@ use crate::{
data_conversion::{convert_cpu_data_points, ConvertedCpuData},
};
-use super::{
- AppScrollWidgetState, CanvasTableWidthState, Component, SortableTextTable, TimeGraph, Widget,
-};
+use super::{AppScrollWidgetState, CanvasTableWidthState, Component, TextTable, TimeGraph, Widget};
pub struct CpuWidgetState {
pub current_display_time: u64,
@@ -77,10 +75,10 @@ pub enum CpuGraphLegendPosition {
Right,
}
-/// A widget designed to show CPU usage via a graph, along with a side legend implemented as a [`TextTable`].
+/// A widget designed to show CPU usage via a graph, along with a side legend in a table.
pub struct CpuGraph {
graph: TimeGraph,
- legend: SortableTextTable,
+ legend: TextTable<SimpleSortableColumn>,
legend_position: CpuGraphLegendPosition,
showing_avg: bool,
@@ -95,7 +93,7 @@ impl CpuGraph {
/// Creates a new [`CpuGraph`] from a config.
pub fn from_config(app_config_fields: &AppConfigFields) -> Self {
let graph = TimeGraph::from_config(app_config_fields);
- let legend = SortableTextTable::new(vec![
+ let legend = TextTable::new(vec![
SimpleSortableColumn::new_flex("CPU".into(), None, false, 0.5),
SimpleSortableColumn::new_flex("Use%".into(), None, false, 0.5),
]);
@@ -129,7 +127,7 @@ impl Component for CpuGraph {
}
fn handle_mouse_event(&mut self, event: MouseEvent) -> WidgetEventResult {
- if self.graph.does_intersect_mouse(&event) {
+ if self.graph.does_border_intersect_mouse(&event) {
if let CpuGraphSelection::Graph = self.selected {
self.graph.handle_mouse_event(event)
} else {
@@ -137,7 +135,7 @@ impl Component for CpuGraph {
self.graph.handle_mouse_event(event);
WidgetEventResult::Redraw
}
- } else if self.legend.does_intersect_mouse(&event) {
+ } else if self.legend.does_border_intersect_mouse(&event) {
if let CpuGraphSelection::Legend = self.selected {
self.legend.handle_mouse_event(event)
} else {
@@ -176,11 +174,16 @@ impl Widget for CpuGraph {
}
};
+ // debug!("Area: {:?}", area);
+
let split_area = Layout::default()
+ .margin(0)
.direction(Direction::Horizontal)
.constraints(constraints)
.split(area);
+ // debug!("Split area: {:?}", split_area);
+
const Y_BOUNDS: [f64; 2] = [0.0, 100.5];
let y_bound_labels: [Cow<'static, str>; 2] = ["0%".into(), "100%".into()];
diff --git a/src/app/widgets/disk.rs b/src/app/widgets/disk.rs
index 92340e67..a9a35e19 100644
--- a/src/app/widgets/disk.rs
+++ b/src/app/widgets/disk.rs
@@ -9,14 +9,17 @@ use tui::{
};
use crate::{
- app::{data_farmer::DataCollection, event::WidgetEventResult, sort_text_table::SimpleSortableColumn},
+ app::{
+ data_farmer::DataCollection, event::WidgetEventResult,
+ sort_text_table::SimpleSortableColumn,
+ },
canvas::Painter,
data_conversion::convert_disk_row,
};
use super::{
- text_table::TextTableData, AppScrollWidgetState, CanvasTableWidthState, Component,
- SortableTextTable, Widget,
+ text_table::TextTableData, AppScrollWidgetState, CanvasTableWidthState, Component, TextTable,
+ Widget,
};
pub struct DiskWidgetState {
@@ -52,9 +55,9 @@ impl DiskState {
}
}
-/// A table displaying disk data. Essentially a wrapper around a [`TextTable`].
+/// A table displaying disk data.
pub struct DiskTable {
- table: SortableTextTable,
+ table: TextTable<SimpleSortableColumn>,
bounds: Rect,
display_data: TextTableData,
@@ -62,7 +65,7 @@ pub struct DiskTable {
impl Default for DiskTable {
fn default() -> Self {
- let table = SortableTextTable::new(vec![
+ let table = TextTable::new(vec![
SimpleSortableColumn::new_flex("Disk".into(), None, false, 0.2),
SimpleSortableColumn::new_flex("Mount".into(), None, false, 0.2),
SimpleSortableColumn::new_hard("Used".into(), None, false, Some(5)),
@@ -115,7 +118,6 @@ impl Widget for DiskTable {
.borders(Borders::ALL);
self.table
- .table
.draw_tui_table(painter, f, &self.display_data, block, area, selected);
}
diff --git a/src/app/widgets/mem.rs b/src/app/widgets/mem.rs
index 997c9850..437410e5 100644
--- a/src/app/widgets/mem.rs
+++ b/src/app/widgets/mem.rs
@@ -59,6 +59,7 @@ pub struct MemGraph {
swap_labels: Option<(String, String)>,
mem_data: Vec<(f64, f64)>,
swap_data: Vec<(f64, f64)>,
+ bounds: Rect,
}
impl MemGraph {
@@ -70,6 +71,7 @@ impl MemGraph {
swap_labels: Default::default(),
mem_data: Default::default(),
swap_data: Default::default(),
+ bounds: Rect::default(),
}
}
}
@@ -84,11 +86,11 @@ impl Component for MemGraph {
}
fn bounds(&self) -> Rect {
- self.graph.bounds()
+ self.bounds
}
fn set_bounds(&mut self, new_bounds: Rect) {
- self.graph.set_bounds(new_bounds);
+ self.bounds = new_bounds;
}
}
diff --git a/src/app/widgets/net.rs b/src/app/widgets/net.rs
index 84d0d3cc..10a676e3 100644
--- a/src/app/widgets/net.rs
+++ b/src/app/widgets/net.rs
@@ -434,6 +434,8 @@ pub struct NetGraph {
pub use_binary_prefix: bool,
hide_legend: bool,
+
+ bounds: Rect,
}
impl NetGraph {
@@ -454,6 +456,7 @@ impl NetGraph {
unit_type: app_config_fields.network_unit_type.clone(),
use_binary_prefix: app_config_fields.network_use_binary_prefix,
hide_legend: false,
+ bounds: Rect::default(),
}
}
@@ -514,11 +517,11 @@ impl NetGraph {
impl Component for NetGraph {
fn bounds(&self) -> Rect {
- self.graph.bounds()
+ self.bounds
}
fn set_bounds(&mut self, new_bounds: Rect) {
- self.graph.set_bounds(new_bounds);
+ self.bounds = new_bounds;
}
fn handle_key_event(
diff --git a/src/app/widgets/process.rs b/src/app/widgets/process.rs
index 3ece0532..735616e1 100644
--- a/src/app/widgets/process.rs
+++ b/src/app/widgets/process.rs
@@ -1,4 +1,4 @@
-use std::collections::HashMap;
+use std::{borrow::Cow, collections::HashMap};
use crossterm::event::{KeyCode, KeyEvent, KeyModifiers, MouseButton, MouseEvent, MouseEventKind};
use float_ord::FloatOrd;
@@ -799,6 +799,10 @@ impl ProcessSortColumn {
}
impl SortableColumn for ProcessSortColumn {
+ fn original_name(&self) -> &Cow<'static, str> {
+ self.sortable_column.original_name()
+ }
+
fn shortcut(&self) -> &Option<(KeyEvent, String)> {
self.sortable_column.shortcut()
}
@@ -815,7 +819,7 @@ impl SortableColumn for ProcessSortColumn {
self.sortable_column.set_sorting_status(sorting_status)
}
- fn display_name(&self) -> std::borrow::Cow<'static, str> {
+ fn display_name(&self) -> Cow<'static, str> {
self.sortable_column.display_name()
}
@@ -1024,7 +1028,7 @@ impl Component for ProcessManager {
fn handle_mouse_event(&mut self, event: MouseEvent) -> WidgetEventResult {
match &event.kind {
MouseEventKind::Down(MouseButton::Left) => {
- if self.process_table.does_intersect_mouse(&event) {
+ if self.process_table.does_border_intersect_mouse(&event) {
if let ProcessManagerSelection::Processes = self.selected {
self.process_table.handle_mouse_event(event)
} else {
@@ -1037,7 +1041,7 @@ impl Component for ProcessManager {
WidgetEventResult::Signal(s) => WidgetEventResult::Signal(s),
}
}
- } else if self.sort_table.does_intersect_mouse(&event) {
+ } else if self.sort_table.does_border_intersect_mouse(&event) {
if let ProcessManagerSelection::Sort = self.selected {
self.sort_table.handle_mouse_event(event)
} else {
@@ -1045,7 +1049,7 @@ impl Component for ProcessManager {
self.sort_table.handle_mouse_event(event);
WidgetEventResult::Redraw
}
- } else if self.search_input.does_intersect_mouse(&event) {
+ } else if self.search_input.does_border_intersect_mouse(&event) {
if let ProcessManagerSelection::Search = self.selected {
self.search_input.handle_mouse_event(event)
} else {
diff --git a/src/app/widgets/temp.rs b/src/app/widgets/temp.rs
index 6c07570d..3d648da8 100644
--- a/src/app/widgets/temp.rs
+++ b/src/app/widgets/temp.rs
@@ -18,8 +18,8 @@ use crate::{
};
use super::{
- text_table::TextTableData, AppScrollWidgetState, CanvasTableWidthState, Component,
- SortableTextTable, Widget,
+ text_table::TextTableData, AppScrollWidgetState, CanvasTableWidthState, Component, TextTable,
+ Widget,
};
pub struct TempWidgetState {
@@ -55,9 +55,9 @@ impl TempState {
}
}
-/// A table displaying disk data. Essentially a wrapper around a [`TextTable`].
+/// A table displaying disk data..
pub struct TempTable {
- table: SortableTextTable,
+ table: TextTable<SimpleSortableColumn>,
bounds: Rect,
display_data: TextTableData,
temp_type: TemperatureType,
@@ -65,7 +65,7 @@ pub struct TempTable {
impl Default for TempTable {
fn default() -> Self {
- let table = SortableTextTable::new(vec![
+ let table = TextTable::new(vec![
SimpleSortableColumn::new_flex("Sensor".into(), None, false, 0.8),
SimpleSortableColumn::new_hard("Temp".into(), None, false, Some(5)),
])
@@ -123,7 +123,6 @@ impl Widget for TempTable {
.borders(Borders::ALL); // TODO: Also do the scrolling indicator!
self.table
- .table
.draw_tui_table(painter, f, &self.display_data, block, area, selected);
}