diff options
author | ClementTsang <cjhtsang@uwaterloo.ca> | 2021-09-07 21:40:47 -0400 |
---|---|---|
committer | ClementTsang <cjhtsang@uwaterloo.ca> | 2021-09-07 22:49:10 -0400 |
commit | 955840b412a341a08f582529064d31cc821ccff3 (patch) | |
tree | d92fca67fa6944cf9b9a09adf3cc310680b2f5b1 /src | |
parent | d8a6a2344e813bb72a21bac0b050a79ab595bd5f (diff) |
refactor: Add back scroll position and expanded
Diffstat (limited to 'src')
-rw-r--r-- | src/app/layout_manager.rs | 3 | ||||
-rw-r--r-- | src/app/widgets.rs | 3 | ||||
-rw-r--r-- | src/app/widgets/base/scrollable.rs | 9 | ||||
-rw-r--r-- | src/app/widgets/base/sort_menu.rs | 11 | ||||
-rw-r--r-- | src/app/widgets/base/sort_text_table.rs | 17 | ||||
-rw-r--r-- | src/app/widgets/base/text_table.rs | 18 | ||||
-rw-r--r-- | src/app/widgets/bottom_widgets/basic_cpu.rs | 1 | ||||
-rw-r--r-- | src/app/widgets/bottom_widgets/basic_mem.rs | 4 | ||||
-rw-r--r-- | src/app/widgets/bottom_widgets/basic_net.rs | 1 | ||||
-rw-r--r-- | src/app/widgets/bottom_widgets/battery.rs | 4 | ||||
-rw-r--r-- | src/app/widgets/bottom_widgets/cpu.rs | 22 | ||||
-rw-r--r-- | src/app/widgets/bottom_widgets/disk.rs | 24 | ||||
-rw-r--r-- | src/app/widgets/bottom_widgets/mem.rs | 8 | ||||
-rw-r--r-- | src/app/widgets/bottom_widgets/net.rs | 24 | ||||
-rw-r--r-- | src/app/widgets/bottom_widgets/process.rs | 28 | ||||
-rw-r--r-- | src/app/widgets/bottom_widgets/temp.rs | 24 | ||||
-rw-r--r-- | src/app/widgets/tui_stuff/block_builder.rs | 69 | ||||
-rw-r--r-- | src/canvas.rs | 5 |
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); } } } |