summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorClementTsang <cjhtsang@uwaterloo.ca>2021-09-07 21:40:47 -0400
committerClementTsang <cjhtsang@uwaterloo.ca>2021-09-07 22:49:10 -0400
commit955840b412a341a08f582529064d31cc821ccff3 (patch)
treed92fca67fa6944cf9b9a09adf3cc310680b2f5b1 /src
parentd8a6a2344e813bb72a21bac0b050a79ab595bd5f (diff)
refactor: Add back scroll position and expanded
Diffstat (limited to 'src')
-rw-r--r--src/app/layout_manager.rs3
-rw-r--r--src/app/widgets.rs3
-rw-r--r--src/app/widgets/base/scrollable.rs9
-rw-r--r--src/app/widgets/base/sort_menu.rs11
-rw-r--r--src/app/widgets/base/sort_text_table.rs17
-rw-r--r--src/app/widgets/base/text_table.rs18
-rw-r--r--src/app/widgets/bottom_widgets/basic_cpu.rs1
-rw-r--r--src/app/widgets/bottom_widgets/basic_mem.rs4
-rw-r--r--src/app/widgets/bottom_widgets/basic_net.rs1
-rw-r--r--src/app/widgets/bottom_widgets/battery.rs4
-rw-r--r--src/app/widgets/bottom_widgets/cpu.rs22
-rw-r--r--src/app/widgets/bottom_widgets/disk.rs24
-rw-r--r--src/app/widgets/bottom_widgets/mem.rs8
-rw-r--r--src/app/widgets/bottom_widgets/net.rs24
-rw-r--r--src/app/widgets/bottom_widgets/process.rs28
-rw-r--r--src/app/widgets/bottom_widgets/temp.rs24
-rw-r--r--src/app/widgets/tui_stuff/block_builder.rs69
-rw-r--r--src/canvas.rs5
18 files changed, 203 insertions, 72 deletions
diff --git a/src/app/layout_manager.rs b/src/app/layout_manager.rs
index e215e04c..9b88fb8a 100644
--- a/src/app/layout_manager.rs
+++ b/src/app/layout_manager.rs
@@ -1140,6 +1140,7 @@ pub fn create_layout_tree(
.width(width)
.height(height)
.basic_mode(app_config_fields.use_basic_mode)
+ .show_scroll_index(app_config_fields.show_table_scroll_position)
.into(),
);
}
@@ -1151,6 +1152,7 @@ pub fn create_layout_tree(
.width(width)
.height(height)
.basic_mode(app_config_fields.use_basic_mode)
+ .show_scroll_index(app_config_fields.show_table_scroll_position)
.into(),
);
}
@@ -1161,6 +1163,7 @@ pub fn create_layout_tree(
.width(width)
.height(height)
.basic_mode(app_config_fields.use_basic_mode)
+ .show_scroll_index(app_config_fields.show_table_scroll_position)
.into(),
);
}
diff --git a/src/app/widgets.rs b/src/app/widgets.rs
index 44633e0e..cac6a032 100644
--- a/src/app/widgets.rs
+++ b/src/app/widgets.rs
@@ -117,7 +117,7 @@ pub trait Widget {
/// Returns a [`Widget`]'s "pretty" display name.
fn get_pretty_name(&self) -> &'static str;
- /// Returns a new [`BlockBuilder`], which can become a [`Block`] if [`BlockBuilder::build`] is called.
+ /// Returns a new [`BlockBuilder`], which can become a [`tui::widgets::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())
@@ -126,6 +126,7 @@ pub trait Widget {
/// Draws a [`Widget`]. The default implementation draws nothing.
fn draw<B: Backend>(
&mut self, painter: &Painter, f: &mut Frame<'_, B>, area: Rect, selected: bool,
+ expanded: bool,
) {
}
diff --git a/src/app/widgets/base/scrollable.rs b/src/app/widgets/base/scrollable.rs
index c02b1a54..ba4faa5f 100644
--- a/src/app/widgets/base/scrollable.rs
+++ b/src/app/widgets/base/scrollable.rs
@@ -67,6 +67,15 @@ impl Scrollable {
self.current_index
}
+ /// Returns the text indicator [`String`].
+ pub fn text_indicator(&self) -> String {
+ format!(
+ "({} of {})",
+ min(self.current_index + 1, self.num_items),
+ self.num_items
+ )
+ }
+
/// Returns the start of the [`Scrollable`] when displayed.
pub fn get_list_start(&mut self, num_visible_rows: usize) -> usize {
// So it's probably confusing - what is the "window index"?
diff --git a/src/app/widgets/base/sort_menu.rs b/src/app/widgets/base/sort_menu.rs
index 3265cb59..b893a418 100644
--- a/src/app/widgets/base/sort_menu.rs
+++ b/src/app/widgets/base/sort_menu.rs
@@ -1,8 +1,11 @@
use crossterm::event::{KeyEvent, MouseEvent};
-use tui::{backend::Backend, layout::Rect, widgets::Block, Frame};
+use tui::{backend::Backend, layout::Rect, Frame};
use crate::{
- app::{event::WidgetEventResult, text_table::SimpleColumn, Component, TextTable},
+ app::{
+ event::WidgetEventResult, text_table::SimpleColumn, widgets::tui_stuff::BlockBuilder,
+ Component, TextTable,
+ },
canvas::Painter,
};
@@ -42,7 +45,7 @@ impl SortMenu {
/// Draws a [`tui::widgets::Table`] on screen corresponding to the sort columns of this [`SortableTextTable`].
pub fn draw_sort_menu<B: Backend, C: SortableColumn>(
- &mut self, painter: &Painter, f: &mut Frame<'_, B>, columns: &[C], block: Block<'_>,
+ &mut self, painter: &Painter, f: &mut Frame<'_, B>, columns: &[C], block: BlockBuilder,
block_area: Rect,
) {
self.set_bounds(block_area);
@@ -53,7 +56,7 @@ impl SortMenu {
.collect::<Vec<_>>();
self.table
- .draw_tui_table(painter, f, &data, block, block_area, true);
+ .draw_tui_table(painter, f, &data, block, block_area, true, false);
}
}
diff --git a/src/app/widgets/base/sort_text_table.rs b/src/app/widgets/base/sort_text_table.rs
index ceb7eb09..64766041 100644
--- a/src/app/widgets/base/sort_text_table.rs
+++ b/src/app/widgets/base/sort_text_table.rs
@@ -1,11 +1,12 @@
use std::borrow::Cow;
use crossterm::event::{KeyCode, KeyEvent, KeyModifiers, MouseButton, MouseEvent, MouseEventKind};
-use tui::{backend::Backend, layout::Rect, widgets::Block, Frame};
+use tui::{backend::Backend, layout::Rect, Frame};
use crate::{
app::{
event::{ReturnSignal, WidgetEventResult},
+ widgets::tui_stuff::BlockBuilder,
Component, TextTable,
},
canvas::Painter,
@@ -371,10 +372,18 @@ where
/// 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 Frame<'_, B>, data: &TextTableDataRef,
- block: Block<'_>, block_area: Rect, show_selected_entry: bool,
+ block: BlockBuilder, block_area: Rect, show_selected_entry: bool,
+ show_scroll_position: bool,
) {
- self.table
- .draw_tui_table(painter, f, data, block, block_area, show_selected_entry);
+ self.table.draw_tui_table(
+ painter,
+ f,
+ data,
+ block,
+ block_area,
+ show_selected_entry,
+ show_scroll_position,
+ );
}
}
diff --git a/src/app/widgets/base/text_table.rs b/src/app/widgets/base/text_table.rs
index 227979b3..0814555c 100644
--- a/src/app/widgets/base/text_table.rs
+++ b/src/app/widgets/base/text_table.rs
@@ -9,13 +9,13 @@ use tui::{
layout::{Constraint, Rect},
style::Style,
text::Text,
- widgets::{Block, Table},
+ widgets::Table,
Frame,
};
use unicode_segmentation::UnicodeSegmentation;
use crate::{
- app::{event::WidgetEventResult, Component, Scrollable},
+ app::{event::WidgetEventResult, widgets::tui_stuff::BlockBuilder, Component, Scrollable},
canvas::Painter,
constants::TABLE_GAP_HEIGHT_LIMIT,
};
@@ -381,10 +381,21 @@ where
/// Draws a [`Table`] on screen corresponding to the [`TextTable`].
pub fn draw_tui_table<B: Backend>(
&mut self, painter: &Painter, f: &mut Frame<'_, B>, data: &TextTableDataRef,
- block: Block<'_>, block_area: Rect, show_selected_entry: bool,
+ block: BlockBuilder, block_area: Rect, show_selected_entry: bool,
+ show_scroll_position: bool,
) {
use tui::widgets::Row;
+ self.set_num_items(data.len());
+
+ let block = block
+ .extra_text(if show_scroll_position {
+ Some(self.scrollable.text_indicator())
+ } else {
+ None
+ })
+ .build(painter, block_area);
+
let inner_area = block.inner(block_area);
if inner_area.height < 1 {
f.render_widget(block, block_area);
@@ -396,7 +407,6 @@ where
1
};
- self.set_num_items(data.len());
self.set_border_bounds(block_area);
self.set_bounds(inner_area);
let table_extras = 1 + table_gap;
diff --git a/src/app/widgets/bottom_widgets/basic_cpu.rs b/src/app/widgets/bottom_widgets/basic_cpu.rs
index 027281f2..f4aa4435 100644
--- a/src/app/widgets/bottom_widgets/basic_cpu.rs
+++ b/src/app/widgets/bottom_widgets/basic_cpu.rs
@@ -59,6 +59,7 @@ impl Widget for BasicCpu {
fn draw<B: Backend>(
&mut self, painter: &Painter, f: &mut Frame<'_, B>, area: Rect, selected: bool,
+ _expanded: bool,
) {
const CONSTRAINTS: [Constraint; 2 * REQUIRED_COLUMNS - 1] = [
Constraint::Ratio(1, REQUIRED_COLUMNS as u32),
diff --git a/src/app/widgets/bottom_widgets/basic_mem.rs b/src/app/widgets/bottom_widgets/basic_mem.rs
index 7ab6a370..2f33183f 100644
--- a/src/app/widgets/bottom_widgets/basic_mem.rs
+++ b/src/app/widgets/bottom_widgets/basic_mem.rs
@@ -8,8 +8,7 @@ use tui::{
use crate::{
app::{
- event::WidgetEventResult, widgets::tui_stuff::PipeGauge, Component, DataCollection,
- Widget,
+ event::WidgetEventResult, widgets::tui_stuff::PipeGauge, Component, DataCollection, Widget,
},
canvas::Painter,
constants::SIDE_BORDERS,
@@ -73,6 +72,7 @@ impl Widget for BasicMem {
fn draw<B: Backend>(
&mut self, painter: &Painter, f: &mut Frame<'_, B>, area: Rect, selected: bool,
+ _expanded: bool,
) {
let block = Block::default()
.borders(*SIDE_BORDERS)
diff --git a/src/app/widgets/bottom_widgets/basic_net.rs b/src/app/widgets/bottom_widgets/basic_net.rs
index 60b0c44b..bdb15554 100644
--- a/src/app/widgets/bottom_widgets/basic_net.rs
+++ b/src/app/widgets/bottom_widgets/basic_net.rs
@@ -68,6 +68,7 @@ impl Widget for BasicNet {
fn draw<B: Backend>(
&mut self, painter: &Painter, f: &mut Frame<'_, B>, area: Rect, selected: bool,
+ _expanded: bool,
) {
let block = Block::default()
.borders(*SIDE_BORDERS)
diff --git a/src/app/widgets/bottom_widgets/battery.rs b/src/app/widgets/bottom_widgets/battery.rs
index 56ea60b4..1d0c9c8b 100644
--- a/src/app/widgets/bottom_widgets/battery.rs
+++ b/src/app/widgets/bottom_widgets/battery.rs
@@ -177,12 +177,14 @@ impl Widget for BatteryTable {
fn draw<B: Backend>(
&mut self, painter: &Painter, f: &mut Frame<'_, B>, area: Rect, selected: bool,
+ expanded: bool,
) {
let block = self
.block()
.selected(selected)
.borders(self.block_border)
- .build(painter);
+ .expanded(expanded)
+ .build(painter, area);
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 35dd07ef..0b5cbae2 100644
--- a/src/app/widgets/bottom_widgets/cpu.rs
+++ b/src/app/widgets/bottom_widgets/cpu.rs
@@ -4,7 +4,6 @@ use crossterm::event::{KeyEvent, MouseEvent};
use tui::{
backend::Backend,
layout::{Constraint, Direction, Layout, Rect},
- widgets::{Block, Borders},
Frame,
};
@@ -164,6 +163,7 @@ impl Widget for CpuGraph {
fn draw<B: Backend>(
&mut self, painter: &Painter, f: &mut Frame<'_, B>, area: Rect, selected: bool,
+ expanded: bool,
) {
let constraints = {
const CPU_LEGEND_MIN_WIDTH: u16 = 10;
@@ -230,7 +230,8 @@ impl Widget for CpuGraph {
let graph_block = self
.block()
.selected(selected && matches!(&self.selected, CpuGraphSelection::Graph))
- .build(painter);
+ .expanded(expanded)
+ .build(painter, graph_block_area);
self.graph.draw_tui_chart(
painter,
@@ -243,17 +244,11 @@ impl Widget for CpuGraph {
graph_block_area,
);
- let legend_block = Block::default()
- .border_style(if selected {
- if let CpuGraphSelection::Legend = &self.selected {
- painter.colours.highlighted_border_style
- } else {
- painter.colours.border_style
- }
- } else {
- painter.colours.border_style
- })
- .borders(Borders::ALL);
+ let legend_block = self
+ .block()
+ .selected(selected && matches!(&self.selected, CpuGraphSelection::Legend))
+ .expanded(expanded)
+ .hide_title(true);
let legend_data = self
.display_data
@@ -294,6 +289,7 @@ impl Widget for CpuGraph {
legend_block,
legend_block_area,
true,
+ false,
);
}
diff --git a/src/app/widgets/bottom_widgets/disk.rs b/src/app/widgets/bottom_widgets/disk.rs
index 9d128475..1f5383da 100644
--- a/src/app/widgets/bottom_widgets/disk.rs
+++ b/src/app/widgets/bottom_widgets/disk.rs
@@ -48,6 +48,7 @@ pub struct DiskTable {
width: LayoutRule,
height: LayoutRule,
block_border: Borders,
+ show_scroll_index: bool,
}
impl Default for DiskTable {
@@ -69,6 +70,7 @@ impl Default for DiskTable {
width: LayoutRule::default(),
height: LayoutRule::default(),
block_border: Borders::ALL,
+ show_scroll_index: false,
}
}
}
@@ -94,6 +96,12 @@ impl DiskTable {
self
}
+
+ /// Sets whether to show the scroll index.
+ pub fn show_scroll_index(mut self, show_scroll_index: bool) -> Self {
+ self.show_scroll_index = show_scroll_index;
+ self
+ }
}
impl Component for DiskTable {
@@ -121,15 +129,23 @@ impl Widget for DiskTable {
fn draw<B: Backend>(
&mut self, painter: &Painter, f: &mut Frame<'_, B>, area: Rect, selected: bool,
+ expanded: bool,
) {
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);
+ .expanded(expanded);
+
+ self.table.draw_tui_table(
+ painter,
+ f,
+ &self.display_data,
+ block,
+ area,
+ selected,
+ self.show_scroll_index,
+ );
}
fn update_data(&mut self, data_collection: &DataCollection) {
diff --git a/src/app/widgets/bottom_widgets/mem.rs b/src/app/widgets/bottom_widgets/mem.rs
index ccee3bf3..1531290b 100644
--- a/src/app/widgets/bottom_widgets/mem.rs
+++ b/src/app/widgets/bottom_widgets/mem.rs
@@ -87,9 +87,13 @@ impl Widget for MemGraph {
fn draw<B: Backend>(
&mut self, painter: &crate::canvas::Painter, f: &mut tui::Frame<'_, B>, area: Rect,
- selected: bool,
+ selected: bool, expanded: bool,
) {
- let block = self.block().selected(selected).build(painter);
+ let block = self
+ .block()
+ .selected(selected)
+ .expanded(expanded)
+ .build(painter, area);
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 c4d01961..d9c0b799 100644
--- a/src/app/widgets/bottom_widgets/net.rs
+++ b/src/app/widgets/bottom_widgets/net.rs
@@ -3,14 +3,14 @@ use std::{borrow::Cow, collections::HashMap, time::Instant};
use tui::{
backend::Backend,
layout::{Constraint, Direction, Layout, Rect},
- widgets::{Block, Borders},
Frame,
};
use crate::{
app::{
data_farmer::DataCollection, text_table::SimpleColumn, time_graph::TimeGraphData,
- AppConfigFields, AxisScaling, Component, TextTable, TimeGraph, Widget,
+ widgets::tui_stuff::BlockBuilder, AppConfigFields, AxisScaling, Component, TextTable,
+ TimeGraph, Widget,
},
canvas::Painter,
data_conversion::convert_network_data_points,
@@ -517,8 +517,13 @@ impl Widget for NetGraph {
fn draw<B: Backend>(
&mut self, painter: &Painter, f: &mut Frame<'_, B>, area: Rect, selected: bool,
+ expanded: bool,
) {
- let block = self.block().selected(selected).build(painter);
+ let block = self
+ .block()
+ .selected(selected)
+ .expanded(expanded)
+ .build(painter, area);
self.set_draw_cache();
@@ -660,6 +665,7 @@ impl Widget for OldNetGraph {
fn draw<B: Backend>(
&mut self, painter: &Painter, f: &mut Frame<'_, B>, area: Rect, selected: bool,
+ expanded: bool,
) {
const CONSTRAINTS: [Constraint; 2] = [Constraint::Min(0), Constraint::Length(4)];
@@ -671,15 +677,10 @@ impl Widget for OldNetGraph {
let graph_area = split_area[0];
let table_area = split_area[1];
- self.net_graph.draw(painter, f, graph_area, selected);
+ self.net_graph
+ .draw(painter, f, graph_area, selected, expanded);
- let table_block = Block::default()
- .border_style(if selected {
- painter.colours.highlighted_border_style
- } else {
- painter.colours.border_style
- })
- .borders(Borders::ALL);
+ let table_block = BlockBuilder::new("").hide_title(true);
self.table.draw_tui_table(
painter,
@@ -701,6 +702,7 @@ impl Widget for OldNetGraph {
table_block,
table_area,
selected,
+ false,
);
}
diff --git a/src/app/widgets/bottom_widgets/process.rs b/src/app/widgets/bottom_widgets/process.rs
index c9416432..bc664a17 100644
--- a/src/app/widgets/bottom_widgets/process.rs
+++ b/src/app/widgets/bottom_widgets/process.rs
@@ -789,6 +789,8 @@ pub struct ProcessManager {
width: LayoutRule,
height: LayoutRule,
+
+ show_scroll_index: bool,
}
impl ProcessManager {
@@ -825,6 +827,7 @@ impl ProcessManager {
block_border: Borders::ALL,
width: LayoutRule::default(),
height: LayoutRule::default(),
+ show_scroll_index: false,
};
manager.set_tree_mode(process_defaults.is_tree);
@@ -856,6 +859,12 @@ impl ProcessManager {
self.in_tree_mode = in_tree_mode;
}
+ /// Sets whether to show the scroll index.
+ pub fn show_scroll_index(mut self, show_scroll_index: bool) -> Self {
+ self.show_scroll_index = show_scroll_index;
+ self
+ }
+
fn open_search(&mut self) -> WidgetEventResult {
if let ProcessManagerSelection::Search = self.selected {
WidgetEventResult::NoRedraw
@@ -1147,6 +1156,7 @@ impl Widget for ProcessManager {
fn draw<B: Backend>(
&mut self, painter: &Painter, f: &mut Frame<'_, B>, area: Rect, selected: bool,
+ expanded: bool,
) {
let area = if self.show_search {
const SEARCH_CONSTRAINTS: [Constraint; 2] = [Constraint::Min(0), Constraint::Length(4)];
@@ -1209,17 +1219,10 @@ impl Widget for ProcessManager {
.constraints(SORT_CONSTRAINTS)
.split(area);
- let sort_block = Block::default()
- .border_style(if selected {
- if let ProcessManagerSelection::Sort = self.selected {
- painter.colours.highlighted_border_style
- } else {
- painter.colours.border_style
- }
- } else {
- painter.colours.border_style
- })
- .borders(Borders::ALL);
+ let sort_block = self
+ .block()
+ .selected(selected && matches!(self.selected, ProcessManagerSelection::Sort))
+ .hide_title(true);
self.sort_menu.draw_sort_menu(
painter,
f,
@@ -1237,7 +1240,7 @@ impl Widget for ProcessManager {
.block()
.selected(selected && matches!(self.selected, ProcessManagerSelection::Processes))
.borders(self.block_border)
- .build(painter);
+ .expanded(expanded && !self.show_sort && !self.show_search);
self.process_table.draw_tui_table(
painter,
@@ -1246,6 +1249,7 @@ impl Widget for ProcessManager {
process_block,
area,
selected,
+ self.show_scroll_index,
);
}
diff --git a/src/app/widgets/bottom_widgets/temp.rs b/src/app/widgets/bottom_widgets/temp.rs
index b48d874f..9d5ef4f9 100644
--- a/src/app/widgets/bottom_widgets/temp.rs
+++ b/src/app/widgets/bottom_widgets/temp.rs
@@ -56,6 +56,7 @@ pub struct TempTable {
width: LayoutRule,
height: LayoutRule,
block_border: Borders,
+ show_scroll_index: bool,
}
impl Default for TempTable {
@@ -74,6 +75,7 @@ impl Default for TempTable {
width: LayoutRule::default(),
height: LayoutRule::default(),
block_border: Borders::ALL,
+ show_scroll_index: false,
}
}
}
@@ -105,6 +107,12 @@ impl TempTable {
self
}
+
+ /// Sets whether to show the scroll index.
+ pub fn show_scroll_index(mut self, show_scroll_index: bool) -> Self {
+ self.show_scroll_index = show_scroll_index;
+ self
+ }
}
impl Component for TempTable {
@@ -132,15 +140,23 @@ impl Widget for TempTable {
fn draw<B: Backend>(
&mut self, painter: &Painter, f: &mut Frame<'_, B>, area: Rect, selected: bool,
+ expanded: bool,
) {
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);
+ .expanded(expanded);
+
+ self.table.draw_tui_table(
+ painter,
+ f,
+ &self.display_data,
+ block,
+ area,
+ selected,
+ self.show_scroll_index,
+ );
}
fn update_data(&mut self, data_collection: &DataCollection) {
diff --git a/src/app/widgets/tui_stuff/block_builder.rs b/src/app/widgets/tui_stuff/block_builder.rs
index 9d1ccd75..6f9801c8 100644
--- a/src/app/widgets/tui_stuff/block_builder.rs
+++ b/src/app/widgets/tui_stuff/block_builder.rs
@@ -1,4 +1,5 @@
use tui::{
+ layout::Rect,
text::Span,
widgets::{Block, Borders},
};
@@ -11,6 +12,7 @@ pub struct BlockBuilder {
selected: bool,
expanded: bool,
name: &'static str,
+ hide_title: bool,
extra_text: Option<String>,
}
@@ -22,6 +24,7 @@ impl BlockBuilder {
selected: false,
expanded: false,
name,
+ hide_title: false,
extra_text: None,
}
}
@@ -39,8 +42,8 @@ impl BlockBuilder {
}
/// 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);
+ pub fn extra_text(mut self, extra_text: Option<String>) -> Self {
+ self.extra_text = extra_text;
self
}
@@ -50,9 +53,16 @@ impl BlockBuilder {
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);
+ /// Forcibly hides the title of the built [`Block`].
+ pub fn hide_title(mut self, hide_title: bool) -> Self {
+ self.hide_title = hide_title;
+ self
+ }
+
+ /// Converts the [`BlockBuilder`] into an actual [`Block`].
+ pub fn build(self, painter: &Painter, area: Rect) -> Block<'static> {
+ let has_title = !self.hide_title
+ && (self.borders.contains(Borders::TOP) || self.borders.contains(Borders::BOTTOM));
let block = Block::default()
.border_style(if self.selected {
@@ -62,11 +72,54 @@ impl BlockBuilder {
})
.borders(self.borders);
- if has_top_bottom_border {
- block.title(Span::styled(
+ let inner_width = block.inner(area).width as usize;
+
+ if has_title {
+ let name = Span::styled(
format!(" {} ", self.name),
painter.colours.widget_title_style,
- ))
+ );
+ let mut title_len = name.width();
+ let mut title = vec![name, Span::from(""), Span::from(""), Span::from("")];
+
+ if self.expanded {
+ const EXPAND_TEXT: &str = " Esc to go back ";
+ const EXPAND_TEXT_LEN: usize = EXPAND_TEXT.len();
+
+ let expand_span =
+ Span::styled(EXPAND_TEXT, painter.colours.highlighted_border_style);
+
+ if title_len + EXPAND_TEXT_LEN <= inner_width {
+ title_len += EXPAND_TEXT_LEN;
+ title[3] = expand_span;
+ }
+ }
+
+ if let Some(extra_text) = self.extra_text {
+ let extra_span = Span::styled(
+ format!("{} ", extra_text),
+ painter.colours.widget_title_style,
+ );
+ let width = extra_span.width();
+ if title_len + width <= inner_width {
+ title_len += width;
+ title[1] = extra_span;
+ }
+ }
+
+ if self.expanded {
+ let difference = inner_width.saturating_sub(title_len);
+ title[2] = Span::styled(
+ "─".repeat(difference),
+ if self.selected {
+ painter.colours.highlighted_border_style
+ } else {
+ painter.colours.border_style
+ },
+ );
+ }
+
+ block.title(title)
} else {
block
}
diff --git a/src/canvas.rs b/src/canvas.rs
index eec228ed..ecf40633 100644
--- a/src/canvas.rs
+++ b/src/canvas.rs
@@ -336,7 +336,7 @@ impl Painter {
.get_mut(&app_state.selected_widget)
{
current_widget.set_bounds(draw_area);
- current_widget.draw(self, f, draw_area, true);
+ current_widget.draw(self, f, draw_area, true, true);
}
} else {
/// A simple traversal through the `arena`, drawing all leaf elements.
@@ -398,12 +398,13 @@ impl Painter {
f,
remaining_area,
selected_id == to_draw_node,
+ false,
);
}
}
} else {
widget.set_bounds(area);
- widget.draw(painter, f, area, selected_id == node);
+ widget.draw(painter, f, area, selected_id == node, false);
}
}
}