mirror of
https://github.com/ClementTsang/bottom.git
synced 2025-07-23 05:34:57 +02:00
Refactoring - moved canvas into its own struct... time to do some more fun optimization.
This commit is contained in:
parent
41d56d8a9b
commit
e0115624a9
@ -155,9 +155,13 @@ fn gen_n_colours(num_to_gen: i32) -> Vec<Color> {
|
|||||||
colour_vec
|
colour_vec
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused_variables)]
|
#[derive(Default)]
|
||||||
|
/// Handles the canvas' state.
|
||||||
|
pub struct Painter {}
|
||||||
|
|
||||||
|
impl Painter {
|
||||||
pub fn draw_data<B: backend::Backend>(
|
pub fn draw_data<B: backend::Backend>(
|
||||||
terminal: &mut Terminal<B>, app_state: &mut app::App,
|
&mut self, terminal: &mut Terminal<B>, app_state: &mut app::App,
|
||||||
) -> error::Result<()> {
|
) -> error::Result<()> {
|
||||||
terminal.autoresize()?;
|
terminal.autoresize()?;
|
||||||
terminal.draw(|mut f| {
|
terminal.draw(|mut f| {
|
||||||
@ -279,6 +283,7 @@ pub fn draw_data<B: backend::Backend>(
|
|||||||
app_state.show_dd = false;
|
app_state.show_dd = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// TODO: [TUI] Change this back to a more even 33/33/34 when TUI releases
|
||||||
let vertical_chunks = Layout::default()
|
let vertical_chunks = Layout::default()
|
||||||
.direction(Direction::Vertical)
|
.direction(Direction::Vertical)
|
||||||
.margin(1)
|
.margin(1)
|
||||||
@ -304,12 +309,6 @@ pub fn draw_data<B: backend::Backend>(
|
|||||||
.constraints([Constraint::Percentage(50), Constraint::Percentage(50)].as_ref())
|
.constraints([Constraint::Percentage(50), Constraint::Percentage(50)].as_ref())
|
||||||
.split(middle_chunks[1]);
|
.split(middle_chunks[1]);
|
||||||
|
|
||||||
let middle_divide_chunk_3 = Layout::default()
|
|
||||||
.direction(Direction::Horizontal)
|
|
||||||
.margin(0)
|
|
||||||
.constraints([Constraint::Percentage(40), Constraint::Percentage(60)].as_ref())
|
|
||||||
.split(middle_divided_chunk_2[0]);
|
|
||||||
|
|
||||||
let bottom_chunks = Layout::default()
|
let bottom_chunks = Layout::default()
|
||||||
.direction(Direction::Horizontal)
|
.direction(Direction::Horizontal)
|
||||||
.margin(0)
|
.margin(0)
|
||||||
@ -355,24 +354,24 @@ pub fn draw_data<B: backend::Backend>(
|
|||||||
|
|
||||||
// Set up blocks and their components
|
// Set up blocks and their components
|
||||||
// CPU graph
|
// CPU graph
|
||||||
draw_cpu_graph(&mut f, &app_state, cpu_chunk[graph_index]);
|
self.draw_cpu_graph(&mut f, &app_state, cpu_chunk[graph_index]);
|
||||||
|
|
||||||
// CPU legend
|
// CPU legend
|
||||||
draw_cpu_legend(&mut f, app_state, cpu_chunk[legend_index]);
|
self.draw_cpu_legend(&mut f, app_state, cpu_chunk[legend_index]);
|
||||||
|
|
||||||
//Memory usage graph
|
//Memory usage graph
|
||||||
draw_memory_graph(&mut f, &app_state, middle_chunks[0]);
|
self.draw_memory_graph(&mut f, &app_state, middle_chunks[0]);
|
||||||
|
|
||||||
// Network graph
|
// Network graph
|
||||||
draw_network_graph(&mut f, &app_state, network_chunk[0]);
|
self.draw_network_graph(&mut f, &app_state, network_chunk[0]);
|
||||||
|
|
||||||
draw_network_labels(&mut f, app_state, network_chunk[1]);
|
self.draw_network_labels(&mut f, app_state, network_chunk[1]);
|
||||||
|
|
||||||
// Temperature table
|
// Temperature table
|
||||||
draw_temp_table(&mut f, app_state, middle_divided_chunk_2[0]);
|
self.draw_temp_table(&mut f, app_state, middle_divided_chunk_2[0]);
|
||||||
|
|
||||||
// Disk usage table
|
// Disk usage table
|
||||||
draw_disk_table(&mut f, app_state, middle_divided_chunk_2[1]);
|
self.draw_disk_table(&mut f, app_state, middle_divided_chunk_2[1]);
|
||||||
|
|
||||||
// Processes table
|
// Processes table
|
||||||
if app_state.is_searching() {
|
if app_state.is_searching() {
|
||||||
@ -395,10 +394,10 @@ pub fn draw_data<B: backend::Backend>(
|
|||||||
)
|
)
|
||||||
.split(bottom_chunks[1]);
|
.split(bottom_chunks[1]);
|
||||||
|
|
||||||
draw_processes_table(&mut f, app_state, processes_chunk[0]);
|
self.draw_processes_table(&mut f, app_state, processes_chunk[0]);
|
||||||
draw_search_field(&mut f, app_state, processes_chunk[1]);
|
self.draw_search_field(&mut f, app_state, processes_chunk[1]);
|
||||||
} else {
|
} else {
|
||||||
draw_processes_table(&mut f, app_state, bottom_chunks[1]);
|
self.draw_processes_table(&mut f, app_state, bottom_chunks[1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})?;
|
})?;
|
||||||
@ -406,7 +405,9 @@ pub fn draw_data<B: backend::Backend>(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_cpu_graph<B: backend::Backend>(f: &mut Frame<B>, app_state: &app::App, draw_loc: Rect) {
|
fn draw_cpu_graph<B: backend::Backend>(
|
||||||
|
&self, f: &mut Frame<B>, app_state: &app::App, draw_loc: Rect,
|
||||||
|
) {
|
||||||
let cpu_data: &[ConvertedCpuData] = &app_state.canvas_data.cpu_data;
|
let cpu_data: &[ConvertedCpuData] = &app_state.canvas_data.cpu_data;
|
||||||
|
|
||||||
// CPU usage graph
|
// CPU usage graph
|
||||||
@ -474,7 +475,7 @@ fn draw_cpu_graph<B: backend::Backend>(f: &mut Frame<B>, app_state: &app::App, d
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn draw_cpu_legend<B: backend::Backend>(
|
fn draw_cpu_legend<B: backend::Backend>(
|
||||||
f: &mut Frame<B>, app_state: &mut app::App, draw_loc: Rect,
|
&self, f: &mut Frame<B>, app_state: &mut app::App, draw_loc: Rect,
|
||||||
) {
|
) {
|
||||||
let cpu_data: &[ConvertedCpuData] = &(app_state.canvas_data.cpu_data);
|
let cpu_data: &[ConvertedCpuData] = &(app_state.canvas_data.cpu_data);
|
||||||
|
|
||||||
@ -590,7 +591,9 @@ fn draw_memory_table<B: backend::Backend>(
|
|||||||
.render(f, draw_loc);
|
.render(f, draw_loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_memory_graph<B: backend::Backend>(f: &mut Frame<B>, app_state: &app::App, draw_loc: Rect) {
|
fn draw_memory_graph<B: backend::Backend>(
|
||||||
|
&self, f: &mut Frame<B>, app_state: &app::App, draw_loc: Rect,
|
||||||
|
) {
|
||||||
let mem_data: &[(f64, f64)] = &(app_state.canvas_data.mem_data);
|
let mem_data: &[(f64, f64)] = &(app_state.canvas_data.mem_data);
|
||||||
let swap_data: &[(f64, f64)] = &(app_state.canvas_data.swap_data);
|
let swap_data: &[(f64, f64)] = &(app_state.canvas_data.swap_data);
|
||||||
|
|
||||||
@ -644,7 +647,9 @@ fn draw_memory_graph<B: backend::Backend>(f: &mut Frame<B>, app_state: &app::App
|
|||||||
.render(f, draw_loc);
|
.render(f, draw_loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_network_graph<B: backend::Backend>(f: &mut Frame<B>, app_state: &app::App, draw_loc: Rect) {
|
fn draw_network_graph<B: backend::Backend>(
|
||||||
|
&self, f: &mut Frame<B>, app_state: &app::App, draw_loc: Rect,
|
||||||
|
) {
|
||||||
let network_data_rx: &[(f64, f64)] = &(app_state.canvas_data.network_data_rx);
|
let network_data_rx: &[(f64, f64)] = &(app_state.canvas_data.network_data_rx);
|
||||||
let network_data_tx: &[(f64, f64)] = &(app_state.canvas_data.network_data_tx);
|
let network_data_tx: &[(f64, f64)] = &(app_state.canvas_data.network_data_tx);
|
||||||
|
|
||||||
@ -691,7 +696,7 @@ fn draw_network_graph<B: backend::Backend>(f: &mut Frame<B>, app_state: &app::Ap
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn draw_network_labels<B: backend::Backend>(
|
fn draw_network_labels<B: backend::Backend>(
|
||||||
f: &mut Frame<B>, app_state: &mut app::App, draw_loc: Rect,
|
&self, f: &mut Frame<B>, app_state: &mut app::App, draw_loc: Rect,
|
||||||
) {
|
) {
|
||||||
let rx_display: String = app_state.canvas_data.rx_display.clone();
|
let rx_display: String = app_state.canvas_data.rx_display.clone();
|
||||||
let tx_display: String = app_state.canvas_data.tx_display.clone();
|
let tx_display: String = app_state.canvas_data.tx_display.clone();
|
||||||
@ -756,7 +761,7 @@ fn draw_network_labels<B: backend::Backend>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn draw_temp_table<B: backend::Backend>(
|
fn draw_temp_table<B: backend::Backend>(
|
||||||
f: &mut Frame<B>, app_state: &mut app::App, draw_loc: Rect,
|
&self, f: &mut Frame<B>, app_state: &mut app::App, draw_loc: Rect,
|
||||||
) {
|
) {
|
||||||
let temp_sensor_data: &[Vec<String>] = &(app_state.canvas_data.temp_sensor_data);
|
let temp_sensor_data: &[Vec<String>] = &(app_state.canvas_data.temp_sensor_data);
|
||||||
|
|
||||||
@ -823,7 +828,7 @@ fn draw_temp_table<B: backend::Backend>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn draw_disk_table<B: backend::Backend>(
|
fn draw_disk_table<B: backend::Backend>(
|
||||||
f: &mut Frame<B>, app_state: &mut app::App, draw_loc: Rect,
|
&self, f: &mut Frame<B>, app_state: &mut app::App, draw_loc: Rect,
|
||||||
) {
|
) {
|
||||||
let disk_data: &[Vec<String>] = &(app_state.canvas_data.disk_data);
|
let disk_data: &[Vec<String>] = &(app_state.canvas_data.disk_data);
|
||||||
let num_rows = max(0, i64::from(draw_loc.height) - 5) as u64;
|
let num_rows = max(0, i64::from(draw_loc.height) - 5) as u64;
|
||||||
@ -890,7 +895,7 @@ fn draw_disk_table<B: backend::Backend>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn draw_search_field<B: backend::Backend>(
|
fn draw_search_field<B: backend::Backend>(
|
||||||
f: &mut Frame<B>, app_state: &mut app::App, draw_loc: Rect,
|
&self, f: &mut Frame<B>, app_state: &mut app::App, draw_loc: Rect,
|
||||||
) {
|
) {
|
||||||
let width = max(0, draw_loc.width as i64 - 34) as u64;
|
let width = max(0, draw_loc.width as i64 - 34) as u64;
|
||||||
let query = app_state.get_current_search_query();
|
let query = app_state.get_current_search_query();
|
||||||
@ -902,9 +907,8 @@ fn draw_search_field<B: backend::Backend>(
|
|||||||
|
|
||||||
let cursor_position = app_state.get_cursor_position();
|
let cursor_position = app_state.get_cursor_position();
|
||||||
|
|
||||||
let query_with_cursor: Vec<Text> = if let app::WidgetPosition::ProcessSearch =
|
let query_with_cursor: Vec<Text> =
|
||||||
app_state.current_widget_selected
|
if let app::WidgetPosition::ProcessSearch = app_state.current_widget_selected {
|
||||||
{
|
|
||||||
if cursor_position >= query.len() {
|
if cursor_position >= query.len() {
|
||||||
let mut q = vec![Text::styled(
|
let mut q = vec![Text::styled(
|
||||||
shrunk_query.to_string(),
|
shrunk_query.to_string(),
|
||||||
@ -922,7 +926,9 @@ fn draw_search_field<B: backend::Backend>(
|
|||||||
.chars()
|
.chars()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(itx, c)| {
|
.map(|(itx, c)| {
|
||||||
if let app::WidgetPosition::ProcessSearch = app_state.current_widget_selected {
|
if let app::WidgetPosition::ProcessSearch =
|
||||||
|
app_state.current_widget_selected
|
||||||
|
{
|
||||||
if itx == cursor_position {
|
if itx == cursor_position {
|
||||||
return Text::styled(
|
return Text::styled(
|
||||||
c.to_string(),
|
c.to_string(),
|
||||||
@ -1008,7 +1014,7 @@ fn draw_search_field<B: backend::Backend>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn draw_processes_table<B: backend::Backend>(
|
fn draw_processes_table<B: backend::Backend>(
|
||||||
f: &mut Frame<B>, app_state: &mut app::App, draw_loc: Rect,
|
&self, f: &mut Frame<B>, app_state: &mut app::App, draw_loc: Rect,
|
||||||
) {
|
) {
|
||||||
let process_data: &[ConvertedProcessData] = &app_state.canvas_data.finalized_process_data;
|
let process_data: &[ConvertedProcessData] = &app_state.canvas_data.finalized_process_data;
|
||||||
|
|
||||||
@ -1036,7 +1042,8 @@ fn draw_processes_table<B: backend::Backend>(
|
|||||||
position
|
position
|
||||||
};
|
};
|
||||||
|
|
||||||
let sliced_vec: Vec<ConvertedProcessData> = (&process_data[start_position as usize..]).to_vec();
|
let sliced_vec: Vec<ConvertedProcessData> =
|
||||||
|
(&process_data[start_position as usize..]).to_vec();
|
||||||
let mut process_counter: i64 = 0;
|
let mut process_counter: i64 = 0;
|
||||||
|
|
||||||
// Draw!
|
// Draw!
|
||||||
@ -1130,6 +1137,7 @@ fn draw_processes_table<B: backend::Backend>(
|
|||||||
)
|
)
|
||||||
.render(f, draw_loc);
|
.render(f, draw_loc);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A somewhat jury-rigged solution to simulate a variable intrinsic layout for
|
/// A somewhat jury-rigged solution to simulate a variable intrinsic layout for
|
||||||
/// table widths. Note that this will do one main pass to try to properly
|
/// table widths. Note that this will do one main pass to try to properly
|
||||||
|
23
src/main.rs
23
src/main.rs
@ -230,8 +230,9 @@ fn main() -> error::Result<()> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut painter = canvas::Painter::default();
|
||||||
loop {
|
loop {
|
||||||
// TODO: [OPT] this should not block... let's properly use tick rates and non-blocking, okay?
|
// TODO: [OPT] this should not block...
|
||||||
if let Ok(recv) = rx.recv_timeout(Duration::from_millis(TICK_RATE_IN_MILLISECONDS)) {
|
if let Ok(recv) = rx.recv_timeout(Duration::from_millis(TICK_RATE_IN_MILLISECONDS)) {
|
||||||
match recv {
|
match recv {
|
||||||
Event::KeyInput(event) => {
|
Event::KeyInput(event) => {
|
||||||
@ -372,18 +373,26 @@ fn main() -> error::Result<()> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw!
|
try_drawing(&mut terminal, &mut app, &mut painter)?;
|
||||||
if let Err(err) = canvas::draw_data(&mut terminal, &mut app) {
|
|
||||||
cleanup_terminal(&mut terminal)?;
|
|
||||||
error!("{}", err);
|
|
||||||
return Err(err);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanup_terminal(&mut terminal)?;
|
cleanup_terminal(&mut terminal)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn try_drawing(
|
||||||
|
terminal: &mut tui::terminal::Terminal<tui::backend::CrosstermBackend<std::io::Stdout>>,
|
||||||
|
app: &mut app::App, painter: &mut canvas::Painter,
|
||||||
|
) -> error::Result<()> {
|
||||||
|
if let Err(err) = painter.draw_data(terminal, app) {
|
||||||
|
cleanup_terminal(terminal)?;
|
||||||
|
error!("{}", err);
|
||||||
|
return Err(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn cleanup_terminal(
|
fn cleanup_terminal(
|
||||||
terminal: &mut tui::terminal::Terminal<tui::backend::CrosstermBackend<std::io::Stdout>>,
|
terminal: &mut tui::terminal::Terminal<tui::backend::CrosstermBackend<std::io::Stdout>>,
|
||||||
) -> error::Result<()> {
|
) -> error::Result<()> {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user