From d8a6a2344e813bb72a21bac0b050a79ab595bd5f Mon Sep 17 00:00:00 2001 From: ClementTsang Date: Tue, 7 Sep 2021 21:37:11 -0400 Subject: [PATCH] refactor: use a builder for block building --- src/app/widgets.rs | 38 ++-------- src/app/widgets/base/time_graph.rs | 2 +- src/app/widgets/bottom_widgets/basic_cpu.rs | 2 +- src/app/widgets/bottom_widgets/basic_mem.rs | 2 +- src/app/widgets/bottom_widgets/battery.rs | 8 +- src/app/widgets/bottom_widgets/cpu.rs | 9 +-- src/app/widgets/bottom_widgets/disk.rs | 6 +- src/app/widgets/bottom_widgets/mem.rs | 4 +- src/app/widgets/bottom_widgets/net.rs | 2 +- src/app/widgets/bottom_widgets/process.rs | 10 +-- src/app/widgets/bottom_widgets/temp.rs | 6 +- .../widgets/{tui_widgets.rs => tui_stuff.rs} | 3 + src/app/widgets/tui_stuff/block_builder.rs | 74 +++++++++++++++++++ .../custom_legend_chart.rs | 0 .../{tui_widgets => tui_stuff}/pipe_gauge.rs | 0 15 files changed, 116 insertions(+), 50 deletions(-) rename src/app/widgets/{tui_widgets.rs => tui_stuff.rs} (66%) create mode 100644 src/app/widgets/tui_stuff/block_builder.rs rename src/app/widgets/{tui_widgets => tui_stuff}/custom_legend_chart.rs (100%) rename src/app/widgets/{tui_widgets => tui_stuff}/pipe_gauge.rs (100%) diff --git a/src/app/widgets.rs b/src/app/widgets.rs index 8ccaa3bd..44633e0e 100644 --- a/src/app/widgets.rs +++ b/src/app/widgets.rs @@ -3,13 +3,7 @@ use std::time::Instant; use crossterm::event::{KeyEvent, MouseEvent}; use enum_dispatch::enum_dispatch; use indextree::NodeId; -use tui::{ - backend::Backend, - layout::Rect, - text::Span, - widgets::{Block, Borders, TableState}, - Frame, -}; +use tui::{backend::Backend, layout::Rect, widgets::TableState, Frame}; use crate::{ app::{ @@ -21,7 +15,7 @@ use crate::{ options::layout_options::LayoutRule, }; -mod tui_widgets; +mod tui_stuff; pub mod base; pub use base::*; @@ -29,6 +23,8 @@ pub use base::*; pub mod bottom_widgets; pub use bottom_widgets::*; +use self::tui_stuff::BlockBuilder; + use super::data_farmer::DataCollection; /// A trait for things that are drawn with state. @@ -121,28 +117,10 @@ pub trait Widget { /// Returns a [`Widget`]'s "pretty" display name. fn get_pretty_name(&self) -> &'static str; - /// Returns a new [`Block`]. The default implementation returns - /// a basic [`Block`] with different border colours based on selected state. - fn block<'a>(&self, painter: &'a Painter, is_selected: bool, borders: Borders) -> Block<'a> { - let has_top_bottom_border = - borders.contains(Borders::TOP) || borders.contains(Borders::BOTTOM); - - let block = Block::default() - .border_style(if is_selected { - painter.colours.highlighted_border_style - } else { - painter.colours.border_style - }) - .borders(borders); - - if has_top_bottom_border { - block.title(Span::styled( - format!(" {} ", self.get_pretty_name()), - painter.colours.widget_title_style, - )) - } else { - block - } + /// Returns a new [`BlockBuilder`], which can become a [`Block`] if [`BlockBuilder::build`] is called. + /// The default implementation builds a [`Block`] that has all 4 borders with no selection or expansion. + fn block(&self) -> BlockBuilder { + BlockBuilder::new(self.get_pretty_name()) } /// Draws a [`Widget`]. The default implementation draws nothing. diff --git a/src/app/widgets/base/time_graph.rs b/src/app/widgets/base/time_graph.rs index 21c6e827..94e5f847 100644 --- a/src/app/widgets/base/time_graph.rs +++ b/src/app/widgets/base/time_graph.rs @@ -16,7 +16,7 @@ use tui::{ use crate::{ app::{ event::WidgetEventResult, - widgets::tui_widgets::{ + widgets::tui_stuff::{ custom_legend_chart::{Axis, Dataset}, TimeChart, }, diff --git a/src/app/widgets/bottom_widgets/basic_cpu.rs b/src/app/widgets/bottom_widgets/basic_cpu.rs index 871edc4e..027281f2 100644 --- a/src/app/widgets/bottom_widgets/basic_cpu.rs +++ b/src/app/widgets/bottom_widgets/basic_cpu.rs @@ -8,7 +8,7 @@ use tui::{ }; use crate::{ - app::{widgets::tui_widgets::PipeGauge, AppConfigFields, Component, DataCollection, Widget}, + app::{widgets::tui_stuff::PipeGauge, AppConfigFields, Component, DataCollection, Widget}, canvas::Painter, constants::SIDE_BORDERS, options::layout_options::LayoutRule, diff --git a/src/app/widgets/bottom_widgets/basic_mem.rs b/src/app/widgets/bottom_widgets/basic_mem.rs index 7fbd1fd0..7ab6a370 100644 --- a/src/app/widgets/bottom_widgets/basic_mem.rs +++ b/src/app/widgets/bottom_widgets/basic_mem.rs @@ -8,7 +8,7 @@ use tui::{ use crate::{ app::{ - event::WidgetEventResult, widgets::tui_widgets::PipeGauge, Component, DataCollection, + event::WidgetEventResult, widgets::tui_stuff::PipeGauge, Component, DataCollection, Widget, }, canvas::Painter, diff --git a/src/app/widgets/bottom_widgets/battery.rs b/src/app/widgets/bottom_widgets/battery.rs index 0130f1f9..56ea60b4 100644 --- a/src/app/widgets/bottom_widgets/battery.rs +++ b/src/app/widgets/bottom_widgets/battery.rs @@ -15,7 +15,7 @@ use tui::{ use crate::{ app::{ data_farmer::DataCollection, does_bound_intersect_coordinate, event::WidgetEventResult, - widgets::tui_widgets::PipeGauge, Component, Widget, + widgets::tui_stuff::PipeGauge, Component, Widget, }, canvas::Painter, constants::TABLE_GAP_HEIGHT_LIMIT, @@ -178,7 +178,11 @@ impl Widget for BatteryTable { fn draw( &mut self, painter: &Painter, f: &mut Frame<'_, B>, area: Rect, selected: bool, ) { - let block = self.block(painter, selected, self.block_border); + let block = self + .block() + .selected(selected) + .borders(self.block_border) + .build(painter); let inner_area = block.inner(area); const CONSTRAINTS: [Constraint; 2] = [Constraint::Length(1), Constraint::Min(0)]; diff --git a/src/app/widgets/bottom_widgets/cpu.rs b/src/app/widgets/bottom_widgets/cpu.rs index 73465211..35dd07ef 100644 --- a/src/app/widgets/bottom_widgets/cpu.rs +++ b/src/app/widgets/bottom_widgets/cpu.rs @@ -227,11 +227,10 @@ impl Widget for CpuGraph { }) .collect::>(); - let graph_block = self.block( - painter, - selected && matches!(&self.selected, CpuGraphSelection::Graph), - Borders::ALL, - ); + let graph_block = self + .block() + .selected(selected && matches!(&self.selected, CpuGraphSelection::Graph)) + .build(painter); self.graph.draw_tui_chart( painter, diff --git a/src/app/widgets/bottom_widgets/disk.rs b/src/app/widgets/bottom_widgets/disk.rs index f7ec0cd0..9d128475 100644 --- a/src/app/widgets/bottom_widgets/disk.rs +++ b/src/app/widgets/bottom_widgets/disk.rs @@ -122,7 +122,11 @@ impl Widget for DiskTable { fn draw( &mut self, painter: &Painter, f: &mut Frame<'_, B>, area: Rect, selected: bool, ) { - let block = self.block(painter, selected, self.block_border); + let block = self + .block() + .selected(selected) + .borders(self.block_border) + .build(painter); self.table .draw_tui_table(painter, f, &self.display_data, block, area, selected); diff --git a/src/app/widgets/bottom_widgets/mem.rs b/src/app/widgets/bottom_widgets/mem.rs index c938b55a..ccee3bf3 100644 --- a/src/app/widgets/bottom_widgets/mem.rs +++ b/src/app/widgets/bottom_widgets/mem.rs @@ -1,7 +1,7 @@ use std::{borrow::Cow, collections::HashMap, time::Instant}; use crossterm::event::{KeyEvent, MouseEvent}; -use tui::{backend::Backend, layout::Rect, widgets::Borders}; +use tui::{backend::Backend, layout::Rect}; use crate::{ app::{event::WidgetEventResult, time_graph::TimeGraphData, DataCollection}, @@ -89,7 +89,7 @@ impl Widget for MemGraph { &mut self, painter: &crate::canvas::Painter, f: &mut tui::Frame<'_, B>, area: Rect, selected: bool, ) { - let block = self.block(painter, selected, Borders::ALL); + let block = self.block().selected(selected).build(painter); let mut chart_data = Vec::with_capacity(2); if let Some((label_percent, label_frac)) = &self.mem_labels { diff --git a/src/app/widgets/bottom_widgets/net.rs b/src/app/widgets/bottom_widgets/net.rs index 91eb929e..c4d01961 100644 --- a/src/app/widgets/bottom_widgets/net.rs +++ b/src/app/widgets/bottom_widgets/net.rs @@ -518,7 +518,7 @@ impl Widget for NetGraph { fn draw( &mut self, painter: &Painter, f: &mut Frame<'_, B>, area: Rect, selected: bool, ) { - let block = self.block(painter, selected, Borders::ALL); + let block = self.block().selected(selected).build(painter); self.set_draw_cache(); diff --git a/src/app/widgets/bottom_widgets/process.rs b/src/app/widgets/bottom_widgets/process.rs index c277e1a0..c9416432 100644 --- a/src/app/widgets/bottom_widgets/process.rs +++ b/src/app/widgets/bottom_widgets/process.rs @@ -1233,11 +1233,11 @@ impl Widget for ProcessManager { area }; - let process_block = self.block( - painter, - selected && matches!(self.selected, ProcessManagerSelection::Processes), - self.block_border, - ); + let process_block = self + .block() + .selected(selected && matches!(self.selected, ProcessManagerSelection::Processes)) + .borders(self.block_border) + .build(painter); self.process_table.draw_tui_table( painter, diff --git a/src/app/widgets/bottom_widgets/temp.rs b/src/app/widgets/bottom_widgets/temp.rs index f8a25e2a..b48d874f 100644 --- a/src/app/widgets/bottom_widgets/temp.rs +++ b/src/app/widgets/bottom_widgets/temp.rs @@ -133,7 +133,11 @@ impl Widget for TempTable { fn draw( &mut self, painter: &Painter, f: &mut Frame<'_, B>, area: Rect, selected: bool, ) { - let block = self.block(painter, selected, self.block_border); + let block = self + .block() + .selected(selected) + .borders(self.block_border) + .build(painter); self.table .draw_tui_table(painter, f, &self.display_data, block, area, selected); diff --git a/src/app/widgets/tui_widgets.rs b/src/app/widgets/tui_stuff.rs similarity index 66% rename from src/app/widgets/tui_widgets.rs rename to src/app/widgets/tui_stuff.rs index 1c0eaab3..fdaf8a85 100644 --- a/src/app/widgets/tui_widgets.rs +++ b/src/app/widgets/tui_stuff.rs @@ -3,3 +3,6 @@ pub use custom_legend_chart::TimeChart; pub mod pipe_gauge; pub use pipe_gauge::PipeGauge; + +pub mod block_builder; +pub use block_builder::BlockBuilder; diff --git a/src/app/widgets/tui_stuff/block_builder.rs b/src/app/widgets/tui_stuff/block_builder.rs new file mode 100644 index 00000000..9d1ccd75 --- /dev/null +++ b/src/app/widgets/tui_stuff/block_builder.rs @@ -0,0 +1,74 @@ +use tui::{ + text::Span, + widgets::{Block, Borders}, +}; + +use crate::canvas::Painter; + +/// A factory pattern builder for a tui [`Block`]. +pub struct BlockBuilder { + borders: Borders, + selected: bool, + expanded: bool, + name: &'static str, + extra_text: Option, +} + +impl BlockBuilder { + /// Creates a new [`BlockBuilder`] with the name of block. + pub fn new(name: &'static str) -> Self { + Self { + borders: Borders::ALL, + selected: false, + expanded: false, + name, + extra_text: None, + } + } + + /// Indicates that this block is currently selected, and should be drawn as such. + pub fn selected(mut self, selected: bool) -> Self { + self.selected = selected; + self + } + + /// Indicates that this block is currently expanded, and should be drawn as such. + pub fn expanded(mut self, expanded: bool) -> Self { + self.expanded = expanded; + self + } + + /// Indicates that this block has some extra text beyond the name. + pub fn extra_text(mut self, extra_text: String) -> Self { + self.extra_text = Some(extra_text); + self + } + + /// Determines the borders of the built [`Block`]. + pub fn borders(mut self, borders: Borders) -> Self { + self.borders = borders; + self + } + + pub fn build<'a>(self, painter: &'a Painter) -> Block<'a> { + let has_top_bottom_border = + self.borders.contains(Borders::TOP) || self.borders.contains(Borders::BOTTOM); + + let block = Block::default() + .border_style(if self.selected { + painter.colours.highlighted_border_style + } else { + painter.colours.border_style + }) + .borders(self.borders); + + if has_top_bottom_border { + block.title(Span::styled( + format!(" {} ", self.name), + painter.colours.widget_title_style, + )) + } else { + block + } + } +} diff --git a/src/app/widgets/tui_widgets/custom_legend_chart.rs b/src/app/widgets/tui_stuff/custom_legend_chart.rs similarity index 100% rename from src/app/widgets/tui_widgets/custom_legend_chart.rs rename to src/app/widgets/tui_stuff/custom_legend_chart.rs diff --git a/src/app/widgets/tui_widgets/pipe_gauge.rs b/src/app/widgets/tui_stuff/pipe_gauge.rs similarity index 100% rename from src/app/widgets/tui_widgets/pipe_gauge.rs rename to src/app/widgets/tui_stuff/pipe_gauge.rs