mirror of
https://github.com/ClementTsang/bottom.git
synced 2025-07-25 06:35:07 +02:00
refactor: Add back scroll position and expanded
This commit is contained in:
parent
d8a6a2344e
commit
955840b412
@ -1140,6 +1140,7 @@ pub fn create_layout_tree(
|
|||||||
.width(width)
|
.width(width)
|
||||||
.height(height)
|
.height(height)
|
||||||
.basic_mode(app_config_fields.use_basic_mode)
|
.basic_mode(app_config_fields.use_basic_mode)
|
||||||
|
.show_scroll_index(app_config_fields.show_table_scroll_position)
|
||||||
.into(),
|
.into(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -1151,6 +1152,7 @@ pub fn create_layout_tree(
|
|||||||
.width(width)
|
.width(width)
|
||||||
.height(height)
|
.height(height)
|
||||||
.basic_mode(app_config_fields.use_basic_mode)
|
.basic_mode(app_config_fields.use_basic_mode)
|
||||||
|
.show_scroll_index(app_config_fields.show_table_scroll_position)
|
||||||
.into(),
|
.into(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -1161,6 +1163,7 @@ pub fn create_layout_tree(
|
|||||||
.width(width)
|
.width(width)
|
||||||
.height(height)
|
.height(height)
|
||||||
.basic_mode(app_config_fields.use_basic_mode)
|
.basic_mode(app_config_fields.use_basic_mode)
|
||||||
|
.show_scroll_index(app_config_fields.show_table_scroll_position)
|
||||||
.into(),
|
.into(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -117,7 +117,7 @@ pub trait Widget {
|
|||||||
/// Returns a [`Widget`]'s "pretty" display name.
|
/// Returns a [`Widget`]'s "pretty" display name.
|
||||||
fn get_pretty_name(&self) -> &'static str;
|
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.
|
/// The default implementation builds a [`Block`] that has all 4 borders with no selection or expansion.
|
||||||
fn block(&self) -> BlockBuilder {
|
fn block(&self) -> BlockBuilder {
|
||||||
BlockBuilder::new(self.get_pretty_name())
|
BlockBuilder::new(self.get_pretty_name())
|
||||||
@ -126,6 +126,7 @@ pub trait Widget {
|
|||||||
/// Draws a [`Widget`]. The default implementation draws nothing.
|
/// Draws a [`Widget`]. The default implementation draws nothing.
|
||||||
fn draw<B: Backend>(
|
fn draw<B: Backend>(
|
||||||
&mut self, painter: &Painter, f: &mut Frame<'_, B>, area: Rect, selected: bool,
|
&mut self, painter: &Painter, f: &mut Frame<'_, B>, area: Rect, selected: bool,
|
||||||
|
expanded: bool,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,6 +67,15 @@ impl Scrollable {
|
|||||||
self.current_index
|
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.
|
/// Returns the start of the [`Scrollable`] when displayed.
|
||||||
pub fn get_list_start(&mut self, num_visible_rows: usize) -> usize {
|
pub fn get_list_start(&mut self, num_visible_rows: usize) -> usize {
|
||||||
// So it's probably confusing - what is the "window index"?
|
// So it's probably confusing - what is the "window index"?
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
use crossterm::event::{KeyEvent, MouseEvent};
|
use crossterm::event::{KeyEvent, MouseEvent};
|
||||||
use tui::{backend::Backend, layout::Rect, widgets::Block, Frame};
|
use tui::{backend::Backend, layout::Rect, Frame};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
app::{event::WidgetEventResult, text_table::SimpleColumn, Component, TextTable},
|
app::{
|
||||||
|
event::WidgetEventResult, text_table::SimpleColumn, widgets::tui_stuff::BlockBuilder,
|
||||||
|
Component, TextTable,
|
||||||
|
},
|
||||||
canvas::Painter,
|
canvas::Painter,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -42,7 +45,7 @@ impl SortMenu {
|
|||||||
|
|
||||||
/// Draws a [`tui::widgets::Table`] on screen corresponding to the sort columns of this [`SortableTextTable`].
|
/// Draws a [`tui::widgets::Table`] on screen corresponding to the sort columns of this [`SortableTextTable`].
|
||||||
pub fn draw_sort_menu<B: Backend, C: SortableColumn>(
|
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,
|
block_area: Rect,
|
||||||
) {
|
) {
|
||||||
self.set_bounds(block_area);
|
self.set_bounds(block_area);
|
||||||
@ -53,7 +56,7 @@ impl SortMenu {
|
|||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
self.table
|
self.table
|
||||||
.draw_tui_table(painter, f, &data, block, block_area, true);
|
.draw_tui_table(painter, f, &data, block, block_area, true, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
use crossterm::event::{KeyCode, KeyEvent, KeyModifiers, MouseButton, MouseEvent, MouseEventKind};
|
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::{
|
use crate::{
|
||||||
app::{
|
app::{
|
||||||
event::{ReturnSignal, WidgetEventResult},
|
event::{ReturnSignal, WidgetEventResult},
|
||||||
|
widgets::tui_stuff::BlockBuilder,
|
||||||
Component, TextTable,
|
Component, TextTable,
|
||||||
},
|
},
|
||||||
canvas::Painter,
|
canvas::Painter,
|
||||||
@ -371,10 +372,18 @@ where
|
|||||||
/// it will only create as many columns as it can grab data from both sources from.
|
/// it will only create as many columns as it can grab data from both sources from.
|
||||||
pub fn draw_tui_table<B: Backend>(
|
pub fn draw_tui_table<B: Backend>(
|
||||||
&mut self, painter: &Painter, f: &mut Frame<'_, B>, data: &TextTableDataRef,
|
&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
|
self.table.draw_tui_table(
|
||||||
.draw_tui_table(painter, f, data, block, block_area, show_selected_entry);
|
painter,
|
||||||
|
f,
|
||||||
|
data,
|
||||||
|
block,
|
||||||
|
block_area,
|
||||||
|
show_selected_entry,
|
||||||
|
show_scroll_position,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,13 +9,13 @@ use tui::{
|
|||||||
layout::{Constraint, Rect},
|
layout::{Constraint, Rect},
|
||||||
style::Style,
|
style::Style,
|
||||||
text::Text,
|
text::Text,
|
||||||
widgets::{Block, Table},
|
widgets::Table,
|
||||||
Frame,
|
Frame,
|
||||||
};
|
};
|
||||||
use unicode_segmentation::UnicodeSegmentation;
|
use unicode_segmentation::UnicodeSegmentation;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
app::{event::WidgetEventResult, Component, Scrollable},
|
app::{event::WidgetEventResult, widgets::tui_stuff::BlockBuilder, Component, Scrollable},
|
||||||
canvas::Painter,
|
canvas::Painter,
|
||||||
constants::TABLE_GAP_HEIGHT_LIMIT,
|
constants::TABLE_GAP_HEIGHT_LIMIT,
|
||||||
};
|
};
|
||||||
@ -381,10 +381,21 @@ where
|
|||||||
/// Draws a [`Table`] on screen corresponding to the [`TextTable`].
|
/// Draws a [`Table`] on screen corresponding to the [`TextTable`].
|
||||||
pub fn draw_tui_table<B: Backend>(
|
pub fn draw_tui_table<B: Backend>(
|
||||||
&mut self, painter: &Painter, f: &mut Frame<'_, B>, data: &TextTableDataRef,
|
&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;
|
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);
|
let inner_area = block.inner(block_area);
|
||||||
if inner_area.height < 1 {
|
if inner_area.height < 1 {
|
||||||
f.render_widget(block, block_area);
|
f.render_widget(block, block_area);
|
||||||
@ -396,7 +407,6 @@ where
|
|||||||
1
|
1
|
||||||
};
|
};
|
||||||
|
|
||||||
self.set_num_items(data.len());
|
|
||||||
self.set_border_bounds(block_area);
|
self.set_border_bounds(block_area);
|
||||||
self.set_bounds(inner_area);
|
self.set_bounds(inner_area);
|
||||||
let table_extras = 1 + table_gap;
|
let table_extras = 1 + table_gap;
|
||||||
|
@ -59,6 +59,7 @@ impl Widget for BasicCpu {
|
|||||||
|
|
||||||
fn draw<B: Backend>(
|
fn draw<B: Backend>(
|
||||||
&mut self, painter: &Painter, f: &mut Frame<'_, B>, area: Rect, selected: bool,
|
&mut self, painter: &Painter, f: &mut Frame<'_, B>, area: Rect, selected: bool,
|
||||||
|
_expanded: bool,
|
||||||
) {
|
) {
|
||||||
const CONSTRAINTS: [Constraint; 2 * REQUIRED_COLUMNS - 1] = [
|
const CONSTRAINTS: [Constraint; 2 * REQUIRED_COLUMNS - 1] = [
|
||||||
Constraint::Ratio(1, REQUIRED_COLUMNS as u32),
|
Constraint::Ratio(1, REQUIRED_COLUMNS as u32),
|
||||||
|
@ -8,8 +8,7 @@ use tui::{
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
app::{
|
app::{
|
||||||
event::WidgetEventResult, widgets::tui_stuff::PipeGauge, Component, DataCollection,
|
event::WidgetEventResult, widgets::tui_stuff::PipeGauge, Component, DataCollection, Widget,
|
||||||
Widget,
|
|
||||||
},
|
},
|
||||||
canvas::Painter,
|
canvas::Painter,
|
||||||
constants::SIDE_BORDERS,
|
constants::SIDE_BORDERS,
|
||||||
@ -73,6 +72,7 @@ impl Widget for BasicMem {
|
|||||||
|
|
||||||
fn draw<B: Backend>(
|
fn draw<B: Backend>(
|
||||||
&mut self, painter: &Painter, f: &mut Frame<'_, B>, area: Rect, selected: bool,
|
&mut self, painter: &Painter, f: &mut Frame<'_, B>, area: Rect, selected: bool,
|
||||||
|
_expanded: bool,
|
||||||
) {
|
) {
|
||||||
let block = Block::default()
|
let block = Block::default()
|
||||||
.borders(*SIDE_BORDERS)
|
.borders(*SIDE_BORDERS)
|
||||||
|
@ -68,6 +68,7 @@ impl Widget for BasicNet {
|
|||||||
|
|
||||||
fn draw<B: Backend>(
|
fn draw<B: Backend>(
|
||||||
&mut self, painter: &Painter, f: &mut Frame<'_, B>, area: Rect, selected: bool,
|
&mut self, painter: &Painter, f: &mut Frame<'_, B>, area: Rect, selected: bool,
|
||||||
|
_expanded: bool,
|
||||||
) {
|
) {
|
||||||
let block = Block::default()
|
let block = Block::default()
|
||||||
.borders(*SIDE_BORDERS)
|
.borders(*SIDE_BORDERS)
|
||||||
|
@ -177,12 +177,14 @@ impl Widget for BatteryTable {
|
|||||||
|
|
||||||
fn draw<B: Backend>(
|
fn draw<B: Backend>(
|
||||||
&mut self, painter: &Painter, f: &mut Frame<'_, B>, area: Rect, selected: bool,
|
&mut self, painter: &Painter, f: &mut Frame<'_, B>, area: Rect, selected: bool,
|
||||||
|
expanded: bool,
|
||||||
) {
|
) {
|
||||||
let block = self
|
let block = self
|
||||||
.block()
|
.block()
|
||||||
.selected(selected)
|
.selected(selected)
|
||||||
.borders(self.block_border)
|
.borders(self.block_border)
|
||||||
.build(painter);
|
.expanded(expanded)
|
||||||
|
.build(painter, area);
|
||||||
|
|
||||||
let inner_area = block.inner(area);
|
let inner_area = block.inner(area);
|
||||||
const CONSTRAINTS: [Constraint; 2] = [Constraint::Length(1), Constraint::Min(0)];
|
const CONSTRAINTS: [Constraint; 2] = [Constraint::Length(1), Constraint::Min(0)];
|
||||||
|
@ -4,7 +4,6 @@ use crossterm::event::{KeyEvent, MouseEvent};
|
|||||||
use tui::{
|
use tui::{
|
||||||
backend::Backend,
|
backend::Backend,
|
||||||
layout::{Constraint, Direction, Layout, Rect},
|
layout::{Constraint, Direction, Layout, Rect},
|
||||||
widgets::{Block, Borders},
|
|
||||||
Frame,
|
Frame,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -164,6 +163,7 @@ impl Widget for CpuGraph {
|
|||||||
|
|
||||||
fn draw<B: Backend>(
|
fn draw<B: Backend>(
|
||||||
&mut self, painter: &Painter, f: &mut Frame<'_, B>, area: Rect, selected: bool,
|
&mut self, painter: &Painter, f: &mut Frame<'_, B>, area: Rect, selected: bool,
|
||||||
|
expanded: bool,
|
||||||
) {
|
) {
|
||||||
let constraints = {
|
let constraints = {
|
||||||
const CPU_LEGEND_MIN_WIDTH: u16 = 10;
|
const CPU_LEGEND_MIN_WIDTH: u16 = 10;
|
||||||
@ -230,7 +230,8 @@ impl Widget for CpuGraph {
|
|||||||
let graph_block = self
|
let graph_block = self
|
||||||
.block()
|
.block()
|
||||||
.selected(selected && matches!(&self.selected, CpuGraphSelection::Graph))
|
.selected(selected && matches!(&self.selected, CpuGraphSelection::Graph))
|
||||||
.build(painter);
|
.expanded(expanded)
|
||||||
|
.build(painter, graph_block_area);
|
||||||
|
|
||||||
self.graph.draw_tui_chart(
|
self.graph.draw_tui_chart(
|
||||||
painter,
|
painter,
|
||||||
@ -243,17 +244,11 @@ impl Widget for CpuGraph {
|
|||||||
graph_block_area,
|
graph_block_area,
|
||||||
);
|
);
|
||||||
|
|
||||||
let legend_block = Block::default()
|
let legend_block = self
|
||||||
.border_style(if selected {
|
.block()
|
||||||
if let CpuGraphSelection::Legend = &self.selected {
|
.selected(selected && matches!(&self.selected, CpuGraphSelection::Legend))
|
||||||
painter.colours.highlighted_border_style
|
.expanded(expanded)
|
||||||
} else {
|
.hide_title(true);
|
||||||
painter.colours.border_style
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
painter.colours.border_style
|
|
||||||
})
|
|
||||||
.borders(Borders::ALL);
|
|
||||||
|
|
||||||
let legend_data = self
|
let legend_data = self
|
||||||
.display_data
|
.display_data
|
||||||
@ -294,6 +289,7 @@ impl Widget for CpuGraph {
|
|||||||
legend_block,
|
legend_block,
|
||||||
legend_block_area,
|
legend_block_area,
|
||||||
true,
|
true,
|
||||||
|
false,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,6 +48,7 @@ pub struct DiskTable {
|
|||||||
width: LayoutRule,
|
width: LayoutRule,
|
||||||
height: LayoutRule,
|
height: LayoutRule,
|
||||||
block_border: Borders,
|
block_border: Borders,
|
||||||
|
show_scroll_index: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for DiskTable {
|
impl Default for DiskTable {
|
||||||
@ -69,6 +70,7 @@ impl Default for DiskTable {
|
|||||||
width: LayoutRule::default(),
|
width: LayoutRule::default(),
|
||||||
height: LayoutRule::default(),
|
height: LayoutRule::default(),
|
||||||
block_border: Borders::ALL,
|
block_border: Borders::ALL,
|
||||||
|
show_scroll_index: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -94,6 +96,12 @@ impl DiskTable {
|
|||||||
|
|
||||||
self
|
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 {
|
impl Component for DiskTable {
|
||||||
@ -121,15 +129,23 @@ impl Widget for DiskTable {
|
|||||||
|
|
||||||
fn draw<B: Backend>(
|
fn draw<B: Backend>(
|
||||||
&mut self, painter: &Painter, f: &mut Frame<'_, B>, area: Rect, selected: bool,
|
&mut self, painter: &Painter, f: &mut Frame<'_, B>, area: Rect, selected: bool,
|
||||||
|
expanded: bool,
|
||||||
) {
|
) {
|
||||||
let block = self
|
let block = self
|
||||||
.block()
|
.block()
|
||||||
.selected(selected)
|
.selected(selected)
|
||||||
.borders(self.block_border)
|
.borders(self.block_border)
|
||||||
.build(painter);
|
.expanded(expanded);
|
||||||
|
|
||||||
self.table
|
self.table.draw_tui_table(
|
||||||
.draw_tui_table(painter, f, &self.display_data, block, area, selected);
|
painter,
|
||||||
|
f,
|
||||||
|
&self.display_data,
|
||||||
|
block,
|
||||||
|
area,
|
||||||
|
selected,
|
||||||
|
self.show_scroll_index,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_data(&mut self, data_collection: &DataCollection) {
|
fn update_data(&mut self, data_collection: &DataCollection) {
|
||||||
|
@ -87,9 +87,13 @@ impl Widget for MemGraph {
|
|||||||
|
|
||||||
fn draw<B: Backend>(
|
fn draw<B: Backend>(
|
||||||
&mut self, painter: &crate::canvas::Painter, f: &mut tui::Frame<'_, B>, area: Rect,
|
&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);
|
let mut chart_data = Vec::with_capacity(2);
|
||||||
if let Some((label_percent, label_frac)) = &self.mem_labels {
|
if let Some((label_percent, label_frac)) = &self.mem_labels {
|
||||||
|
@ -3,14 +3,14 @@ use std::{borrow::Cow, collections::HashMap, time::Instant};
|
|||||||
use tui::{
|
use tui::{
|
||||||
backend::Backend,
|
backend::Backend,
|
||||||
layout::{Constraint, Direction, Layout, Rect},
|
layout::{Constraint, Direction, Layout, Rect},
|
||||||
widgets::{Block, Borders},
|
|
||||||
Frame,
|
Frame,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
app::{
|
app::{
|
||||||
data_farmer::DataCollection, text_table::SimpleColumn, time_graph::TimeGraphData,
|
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,
|
canvas::Painter,
|
||||||
data_conversion::convert_network_data_points,
|
data_conversion::convert_network_data_points,
|
||||||
@ -517,8 +517,13 @@ impl Widget for NetGraph {
|
|||||||
|
|
||||||
fn draw<B: Backend>(
|
fn draw<B: Backend>(
|
||||||
&mut self, painter: &Painter, f: &mut Frame<'_, B>, area: Rect, selected: bool,
|
&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();
|
self.set_draw_cache();
|
||||||
|
|
||||||
@ -660,6 +665,7 @@ impl Widget for OldNetGraph {
|
|||||||
|
|
||||||
fn draw<B: Backend>(
|
fn draw<B: Backend>(
|
||||||
&mut self, painter: &Painter, f: &mut Frame<'_, B>, area: Rect, selected: bool,
|
&mut self, painter: &Painter, f: &mut Frame<'_, B>, area: Rect, selected: bool,
|
||||||
|
expanded: bool,
|
||||||
) {
|
) {
|
||||||
const CONSTRAINTS: [Constraint; 2] = [Constraint::Min(0), Constraint::Length(4)];
|
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 graph_area = split_area[0];
|
||||||
let table_area = split_area[1];
|
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()
|
let table_block = BlockBuilder::new("").hide_title(true);
|
||||||
.border_style(if selected {
|
|
||||||
painter.colours.highlighted_border_style
|
|
||||||
} else {
|
|
||||||
painter.colours.border_style
|
|
||||||
})
|
|
||||||
.borders(Borders::ALL);
|
|
||||||
|
|
||||||
self.table.draw_tui_table(
|
self.table.draw_tui_table(
|
||||||
painter,
|
painter,
|
||||||
@ -701,6 +702,7 @@ impl Widget for OldNetGraph {
|
|||||||
table_block,
|
table_block,
|
||||||
table_area,
|
table_area,
|
||||||
selected,
|
selected,
|
||||||
|
false,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -789,6 +789,8 @@ pub struct ProcessManager {
|
|||||||
|
|
||||||
width: LayoutRule,
|
width: LayoutRule,
|
||||||
height: LayoutRule,
|
height: LayoutRule,
|
||||||
|
|
||||||
|
show_scroll_index: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ProcessManager {
|
impl ProcessManager {
|
||||||
@ -825,6 +827,7 @@ impl ProcessManager {
|
|||||||
block_border: Borders::ALL,
|
block_border: Borders::ALL,
|
||||||
width: LayoutRule::default(),
|
width: LayoutRule::default(),
|
||||||
height: LayoutRule::default(),
|
height: LayoutRule::default(),
|
||||||
|
show_scroll_index: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
manager.set_tree_mode(process_defaults.is_tree);
|
manager.set_tree_mode(process_defaults.is_tree);
|
||||||
@ -856,6 +859,12 @@ impl ProcessManager {
|
|||||||
self.in_tree_mode = in_tree_mode;
|
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 {
|
fn open_search(&mut self) -> WidgetEventResult {
|
||||||
if let ProcessManagerSelection::Search = self.selected {
|
if let ProcessManagerSelection::Search = self.selected {
|
||||||
WidgetEventResult::NoRedraw
|
WidgetEventResult::NoRedraw
|
||||||
@ -1147,6 +1156,7 @@ impl Widget for ProcessManager {
|
|||||||
|
|
||||||
fn draw<B: Backend>(
|
fn draw<B: Backend>(
|
||||||
&mut self, painter: &Painter, f: &mut Frame<'_, B>, area: Rect, selected: bool,
|
&mut self, painter: &Painter, f: &mut Frame<'_, B>, area: Rect, selected: bool,
|
||||||
|
expanded: bool,
|
||||||
) {
|
) {
|
||||||
let area = if self.show_search {
|
let area = if self.show_search {
|
||||||
const SEARCH_CONSTRAINTS: [Constraint; 2] = [Constraint::Min(0), Constraint::Length(4)];
|
const SEARCH_CONSTRAINTS: [Constraint; 2] = [Constraint::Min(0), Constraint::Length(4)];
|
||||||
@ -1209,17 +1219,10 @@ impl Widget for ProcessManager {
|
|||||||
.constraints(SORT_CONSTRAINTS)
|
.constraints(SORT_CONSTRAINTS)
|
||||||
.split(area);
|
.split(area);
|
||||||
|
|
||||||
let sort_block = Block::default()
|
let sort_block = self
|
||||||
.border_style(if selected {
|
.block()
|
||||||
if let ProcessManagerSelection::Sort = self.selected {
|
.selected(selected && matches!(self.selected, ProcessManagerSelection::Sort))
|
||||||
painter.colours.highlighted_border_style
|
.hide_title(true);
|
||||||
} else {
|
|
||||||
painter.colours.border_style
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
painter.colours.border_style
|
|
||||||
})
|
|
||||||
.borders(Borders::ALL);
|
|
||||||
self.sort_menu.draw_sort_menu(
|
self.sort_menu.draw_sort_menu(
|
||||||
painter,
|
painter,
|
||||||
f,
|
f,
|
||||||
@ -1237,7 +1240,7 @@ impl Widget for ProcessManager {
|
|||||||
.block()
|
.block()
|
||||||
.selected(selected && matches!(self.selected, ProcessManagerSelection::Processes))
|
.selected(selected && matches!(self.selected, ProcessManagerSelection::Processes))
|
||||||
.borders(self.block_border)
|
.borders(self.block_border)
|
||||||
.build(painter);
|
.expanded(expanded && !self.show_sort && !self.show_search);
|
||||||
|
|
||||||
self.process_table.draw_tui_table(
|
self.process_table.draw_tui_table(
|
||||||
painter,
|
painter,
|
||||||
@ -1246,6 +1249,7 @@ impl Widget for ProcessManager {
|
|||||||
process_block,
|
process_block,
|
||||||
area,
|
area,
|
||||||
selected,
|
selected,
|
||||||
|
self.show_scroll_index,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,6 +56,7 @@ pub struct TempTable {
|
|||||||
width: LayoutRule,
|
width: LayoutRule,
|
||||||
height: LayoutRule,
|
height: LayoutRule,
|
||||||
block_border: Borders,
|
block_border: Borders,
|
||||||
|
show_scroll_index: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for TempTable {
|
impl Default for TempTable {
|
||||||
@ -74,6 +75,7 @@ impl Default for TempTable {
|
|||||||
width: LayoutRule::default(),
|
width: LayoutRule::default(),
|
||||||
height: LayoutRule::default(),
|
height: LayoutRule::default(),
|
||||||
block_border: Borders::ALL,
|
block_border: Borders::ALL,
|
||||||
|
show_scroll_index: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -105,6 +107,12 @@ impl TempTable {
|
|||||||
|
|
||||||
self
|
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 {
|
impl Component for TempTable {
|
||||||
@ -132,15 +140,23 @@ impl Widget for TempTable {
|
|||||||
|
|
||||||
fn draw<B: Backend>(
|
fn draw<B: Backend>(
|
||||||
&mut self, painter: &Painter, f: &mut Frame<'_, B>, area: Rect, selected: bool,
|
&mut self, painter: &Painter, f: &mut Frame<'_, B>, area: Rect, selected: bool,
|
||||||
|
expanded: bool,
|
||||||
) {
|
) {
|
||||||
let block = self
|
let block = self
|
||||||
.block()
|
.block()
|
||||||
.selected(selected)
|
.selected(selected)
|
||||||
.borders(self.block_border)
|
.borders(self.block_border)
|
||||||
.build(painter);
|
.expanded(expanded);
|
||||||
|
|
||||||
self.table
|
self.table.draw_tui_table(
|
||||||
.draw_tui_table(painter, f, &self.display_data, block, area, selected);
|
painter,
|
||||||
|
f,
|
||||||
|
&self.display_data,
|
||||||
|
block,
|
||||||
|
area,
|
||||||
|
selected,
|
||||||
|
self.show_scroll_index,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_data(&mut self, data_collection: &DataCollection) {
|
fn update_data(&mut self, data_collection: &DataCollection) {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use tui::{
|
use tui::{
|
||||||
|
layout::Rect,
|
||||||
text::Span,
|
text::Span,
|
||||||
widgets::{Block, Borders},
|
widgets::{Block, Borders},
|
||||||
};
|
};
|
||||||
@ -11,6 +12,7 @@ pub struct BlockBuilder {
|
|||||||
selected: bool,
|
selected: bool,
|
||||||
expanded: bool,
|
expanded: bool,
|
||||||
name: &'static str,
|
name: &'static str,
|
||||||
|
hide_title: bool,
|
||||||
extra_text: Option<String>,
|
extra_text: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -22,6 +24,7 @@ impl BlockBuilder {
|
|||||||
selected: false,
|
selected: false,
|
||||||
expanded: false,
|
expanded: false,
|
||||||
name,
|
name,
|
||||||
|
hide_title: false,
|
||||||
extra_text: None,
|
extra_text: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -39,8 +42,8 @@ impl BlockBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Indicates that this block has some extra text beyond the name.
|
/// Indicates that this block has some extra text beyond the name.
|
||||||
pub fn extra_text(mut self, extra_text: String) -> Self {
|
pub fn extra_text(mut self, extra_text: Option<String>) -> Self {
|
||||||
self.extra_text = Some(extra_text);
|
self.extra_text = extra_text;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,9 +53,16 @@ impl BlockBuilder {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build<'a>(self, painter: &'a Painter) -> Block<'a> {
|
/// Forcibly hides the title of the built [`Block`].
|
||||||
let has_top_bottom_border =
|
pub fn hide_title(mut self, hide_title: bool) -> Self {
|
||||||
self.borders.contains(Borders::TOP) || self.borders.contains(Borders::BOTTOM);
|
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()
|
let block = Block::default()
|
||||||
.border_style(if self.selected {
|
.border_style(if self.selected {
|
||||||
@ -62,11 +72,54 @@ impl BlockBuilder {
|
|||||||
})
|
})
|
||||||
.borders(self.borders);
|
.borders(self.borders);
|
||||||
|
|
||||||
if has_top_bottom_border {
|
let inner_width = block.inner(area).width as usize;
|
||||||
block.title(Span::styled(
|
|
||||||
|
if has_title {
|
||||||
|
let name = Span::styled(
|
||||||
format!(" {} ", self.name),
|
format!(" {} ", self.name),
|
||||||
painter.colours.widget_title_style,
|
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 {
|
} else {
|
||||||
block
|
block
|
||||||
}
|
}
|
||||||
|
@ -336,7 +336,7 @@ impl Painter {
|
|||||||
.get_mut(&app_state.selected_widget)
|
.get_mut(&app_state.selected_widget)
|
||||||
{
|
{
|
||||||
current_widget.set_bounds(draw_area);
|
current_widget.set_bounds(draw_area);
|
||||||
current_widget.draw(self, f, draw_area, true);
|
current_widget.draw(self, f, draw_area, true, true);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/// A simple traversal through the `arena`, drawing all leaf elements.
|
/// A simple traversal through the `arena`, drawing all leaf elements.
|
||||||
@ -398,12 +398,13 @@ impl Painter {
|
|||||||
f,
|
f,
|
||||||
remaining_area,
|
remaining_area,
|
||||||
selected_id == to_draw_node,
|
selected_id == to_draw_node,
|
||||||
|
false,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
widget.set_bounds(area);
|
widget.set_bounds(area);
|
||||||
widget.draw(painter, f, area, selected_id == node);
|
widget.draw(painter, f, area, selected_id == node, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user