diff --git a/src/canvas/components/data_table/column.rs b/src/canvas/components/data_table/column.rs index 8e547d80..cee061e8 100644 --- a/src/canvas/components/data_table/column.rs +++ b/src/canvas/components/data_table/column.rs @@ -62,6 +62,8 @@ pub trait DataTableColumn { fn is_hidden(&self) -> bool; + fn set_hidden(&mut self, hidden: bool); + /// The actually displayed "header". fn header(&self) -> Cow<'static, str>; @@ -112,12 +114,25 @@ impl DataTableColumn for Column { self.is_hidden } + #[inline] + fn set_hidden(&mut self, hidden: bool) { + self.is_hidden = hidden; + } + fn header(&self) -> Cow<'static, str> { self.inner.text() } } impl Column { + pub const fn new(inner: H) -> Self { + Self { + inner, + bounds: ColumnWidthBounds::FollowHeader, + is_hidden: false, + } + } + pub const fn hard(inner: H, width: u16) -> Self { Self { inner, @@ -177,7 +192,7 @@ where continue; } - match &column.bounds() { + let new_width = match &column.bounds() { ColumnWidthBounds::Soft { desired, max_percentage, @@ -195,50 +210,22 @@ where }, min_width, ); - let space_taken = min(min(soft_limit, *desired), total_width_left); - if stop_allocating_space(space_taken, total_width_left) { - break; - } else { - total_width_left = - total_width_left.saturating_sub(space_taken + COLUMN_SPACING); - - // SAFETY: This is safe as we call `stop_allocating_space` which checks that - // the value pushed is greater than zero. - unsafe { - calculated_widths.push(NonZeroU16::new_unchecked(space_taken)); - } - } + min(min(soft_limit, *desired), total_width_left) } - ColumnWidthBounds::Hard(width) => { - let min_width = *width; - if stop_allocating_space(min_width, total_width_left) { - break; - } else { - total_width_left = - total_width_left.saturating_sub(min_width + COLUMN_SPACING); + ColumnWidthBounds::Hard(width) => *width, + ColumnWidthBounds::FollowHeader => column.header_len() as u16, + }; - // SAFETY: This is safe as we call `stop_allocating_space` which checks that - // the value pushed is greater than zero. - unsafe { - calculated_widths.push(NonZeroU16::new_unchecked(min_width)); - } - } - } - ColumnWidthBounds::FollowHeader => { - let min_width = column.header_len() as u16; - if stop_allocating_space(min_width, total_width_left) { - break; - } else { - total_width_left = - total_width_left.saturating_sub(min_width + COLUMN_SPACING); + if stop_allocating_space(new_width, total_width_left) { + break; + } else { + total_width_left = total_width_left.saturating_sub(new_width + COLUMN_SPACING); - // SAFETY: This is safe as we call `stop_allocating_space` which checks that - // the value pushed is greater than zero. - unsafe { - calculated_widths.push(NonZeroU16::new_unchecked(min_width)); - } - } + // SAFETY: This is safe as we call `stop_allocating_space` which checks that + // the value pushed is greater than zero. + unsafe { + calculated_widths.push(NonZeroU16::new_unchecked(new_width)); } } } diff --git a/src/canvas/components/data_table/draw.rs b/src/canvas/components/data_table/draw.rs index 7ff14e24..2cbd9384 100644 --- a/src/canvas/components/data_table/draw.rs +++ b/src/canvas/components/data_table/draw.rs @@ -50,8 +50,7 @@ pub struct DrawInfo { impl DrawInfo { pub fn is_on_widget(&self) -> bool { - matches!(self.selection_state, SelectionState::Selected) - || matches!(self.selection_state, SelectionState::Expanded) + !matches!(self.selection_state, SelectionState::NotSelected) } pub fn is_expanded(&self) -> bool { diff --git a/src/canvas/components/data_table/sortable.rs b/src/canvas/components/data_table/sortable.rs index 1509553c..69e36fc0 100644 --- a/src/canvas/components/data_table/sortable.rs +++ b/src/canvas/components/data_table/sortable.rs @@ -8,7 +8,7 @@ use super::{ ColumnHeader, ColumnWidthBounds, DataTable, DataTableColumn, DataTableProps, DataTableState, DataTableStyling, DataToCell, }; -use crate::utils::strings::truncate_to_text; +use crate::{canvas::components::data_table::Column, utils::strings::truncate_to_text}; /// Denotes the sort order. #[derive(Clone, Copy, Debug, PartialEq, Eq)] @@ -123,53 +123,52 @@ pub trait SortsRow { fn sort_data(&self, data: &mut [Self::DataType], descending: bool); } +/// A wrapper around [`Column`] that also has sorting capabilities. #[derive(Debug, Clone)] -pub struct SortColumn { +pub struct SortColumn { /// The inner column header. - inner: T, + column: Column, /// The default sort order. pub default_order: SortOrder, - - /// A restriction on this column's width. - pub bounds: ColumnWidthBounds, - - /// Marks that this column is currently "hidden", and should *always* be - /// skipped. - pub is_hidden: bool, } -impl DataTableColumn for SortColumn +impl DataTableColumn for SortColumn where - T: ColumnHeader + SortsRow, + H: ColumnHeader + SortsRow, { #[inline] - fn inner(&self) -> &T { - &self.inner + fn inner(&self) -> &H { + self.column.inner() } #[inline] - fn inner_mut(&mut self) -> &mut T { - &mut self.inner + fn inner_mut(&mut self) -> &mut H { + self.column.inner_mut() } #[inline] fn bounds(&self) -> ColumnWidthBounds { - self.bounds + self.column.bounds() } #[inline] fn bounds_mut(&mut self) -> &mut ColumnWidthBounds { - &mut self.bounds + self.column.bounds_mut() } #[inline] fn is_hidden(&self) -> bool { - self.is_hidden + self.column.is_hidden() + } + + #[inline] + fn set_hidden(&mut self, hidden: bool) { + self.column.set_hidden(hidden); } fn header(&self) -> Cow<'static, str> { - self.inner.header() + self.column.header() } fn header_len(&self) -> usize { @@ -186,10 +185,8 @@ where /// ([`SortOrder::Ascending`]). pub fn new(inner: T) -> Self { Self { - inner, - bounds: ColumnWidthBounds::FollowHeader, - is_hidden: false, - default_order: SortOrder::default(), + column: Column::new(inner), + default_order: SortOrder::const_default(), } } @@ -197,9 +194,7 @@ where /// and sorts by default in ascending order ([`SortOrder::Ascending`]). pub const fn hard(inner: T, width: u16) -> Self { Self { - inner, - bounds: ColumnWidthBounds::Hard(width), - is_hidden: false, + column: Column::hard(inner, width), default_order: SortOrder::const_default(), } } @@ -208,12 +203,7 @@ where /// and sorts by default in ascending order ([`SortOrder::Ascending`]). pub const fn soft(inner: T, max_percentage: Option) -> Self { Self { - inner, - bounds: ColumnWidthBounds::Soft { - desired: 0, - max_percentage, - }, - is_hidden: false, + column: Column::soft(inner, max_percentage), default_order: SortOrder::const_default(), } } @@ -228,7 +218,7 @@ where /// associated data. pub fn sort_by(&self, data: &mut [D], order: SortOrder) { let descending = matches!(order, SortOrder::Descending); - self.inner.sort_data(data, descending); + self.column.inner().sort_data(data, descending); } } @@ -277,10 +267,7 @@ where /// Toggles the current sort order. pub fn toggle_order(&mut self) { - self.sort_type.order = match self.sort_type.order { - SortOrder::Ascending => SortOrder::Descending, - SortOrder::Descending => SortOrder::Ascending, - } + self.sort_type.order = self.sort_type.order.rev(); } /// Given some `x` and `y`, if possible, select the corresponding column or diff --git a/src/widgets/process_table.rs b/src/widgets/process_table.rs index 8097e333..06c9a1ba 100644 --- a/src/widgets/process_table.rs +++ b/src/widgets/process_table.rs @@ -925,7 +925,7 @@ impl ProcWidgetState { fn hide_column(&mut self, column: ProcWidgetColumn) { if let Some(index) = self.column_mapping.get_index_of(&column) { if let Some(col) = self.table.columns.get_mut(index) { - col.is_hidden = true; + col.set_hidden(true); if self.table.sort_index() == index { self.table.set_sort_index(self.default_sort_index); @@ -939,7 +939,7 @@ impl ProcWidgetState { fn show_column(&mut self, column: ProcWidgetColumn) { if let Some(index) = self.column_mapping.get_index_of(&column) { if let Some(col) = self.table.columns.get_mut(index) { - col.is_hidden = false; + col.set_hidden(false); } } } @@ -1061,7 +1061,7 @@ impl ProcWidgetState { self.table .columns .iter() - .filter(|c| !c.is_hidden) + .filter(|c| !c.is_hidden()) .map(|c| c.inner().text()) .collect::>() }