opt: Only recalculate rect layout if resize or startup

This commit is contained in:
ClementTsang 2020-04-06 23:38:00 -04:00
parent 9127cb1468
commit 07efc3f301

View file

@ -4,9 +4,9 @@ use std::collections::HashMap;
use tui::{ use tui::{
backend::Backend, backend::Backend,
layout::{Constraint, Direction, Layout}, layout::{Constraint, Direction, Layout, Rect},
widgets::Text, widgets::Text,
Terminal, Frame, Terminal,
}; };
use canvas_colours::*; use canvas_colours::*;
@ -17,7 +17,8 @@ use crate::{
app::{ app::{
self, self,
data_harvester::processes::ProcessHarvest, data_harvester::processes::ProcessHarvest,
layout_manager::{BottomLayout, BottomWidgetType}, layout_manager::{BottomColRow, BottomLayout, BottomWidgetType},
App,
}, },
constants::*, constants::*,
data_conversion::{ConvertedCpuData, ConvertedProcessData}, data_conversion::{ConvertedCpuData, ConvertedProcessData},
@ -66,6 +67,7 @@ pub struct Painter {
col_row_constraints: Vec<Vec<Vec<Constraint>>>, col_row_constraints: Vec<Vec<Vec<Constraint>>>,
layout_constraints: Vec<Vec<Vec<Vec<Constraint>>>>, layout_constraints: Vec<Vec<Vec<Vec<Constraint>>>>,
widget_layout: BottomLayout, widget_layout: BottomLayout,
derived_widget_draw_locs: Vec<Vec<Vec<Vec<Rect>>>>,
} }
impl Painter { impl Painter {
@ -150,6 +152,7 @@ impl Painter {
col_row_constraints, col_row_constraints,
layout_constraints, layout_constraints,
widget_layout, widget_layout,
derived_widget_draw_locs: Vec::new(),
} }
} }
@ -435,109 +438,101 @@ impl Painter {
} }
} else { } else {
// Draws using the passed in (or default) layout. NOT basic so far. // Draws using the passed in (or default) layout. NOT basic so far.
let row_draw_locs = Layout::default() if self.derived_widget_draw_locs.is_empty() || app_state.is_resized {
.margin(0) debug!("Calculating draw locs");
.constraints(self.row_constraints.as_ref()) let row_draw_locs = Layout::default()
.direction(Direction::Vertical) .margin(0)
.split(f.size()); .constraints(self.row_constraints.as_ref())
let col_draw_locs = self .direction(Direction::Vertical)
.col_constraints .split(f.size());
.iter() let col_draw_locs = self
.zip(&row_draw_locs) .col_constraints
.map(|(col_constraint, row_draw_loc)| { .iter()
Layout::default() .zip(&row_draw_locs)
.constraints(col_constraint.as_ref()) .map(|(col_constraint, row_draw_loc)| {
.direction(Direction::Horizontal) Layout::default()
.split(*row_draw_loc) .constraints(col_constraint.as_ref())
}) .direction(Direction::Horizontal)
.collect::<Vec<_>>(); .split(*row_draw_loc)
let col_row_draw_locs = self })
.col_row_constraints .collect::<Vec<_>>();
.iter() let col_row_draw_locs = self
.zip(&col_draw_locs) .col_row_constraints
.map(|(col_row_constraints, row_draw_loc)| { .iter()
col_row_constraints .zip(&col_draw_locs)
.iter() .map(|(col_row_constraints, row_draw_loc)| {
.zip(row_draw_loc) col_row_constraints
.map(|(col_row_constraint, col_draw_loc)| { .iter()
Layout::default() .zip(row_draw_loc)
.constraints(col_row_constraint.as_ref()) .map(|(col_row_constraint, col_draw_loc)| {
.direction(Direction::Vertical) Layout::default()
.split(*col_draw_loc) .constraints(col_row_constraint.as_ref())
}) .direction(Direction::Vertical)
.collect::<Vec<_>>() .split(*col_draw_loc)
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>()
})
.collect::<Vec<_>>();
// Now... draw! // Now... draw!
izip!( let mut new_derived_widget_draw_locs = Vec::new();
&self.layout_constraints, izip!(
col_row_draw_locs, &self.layout_constraints,
&self.widget_layout.rows col_row_draw_locs,
) &self.widget_layout.rows
.for_each(|(row_constraint_vec, row_draw_loc, cols)| { )
izip!(row_constraint_vec, row_draw_loc, &cols.children).for_each( .for_each(|(row_constraint_vec, row_draw_loc, cols)| {
|(col_constraint_vec, col_draw_loc, col_rows)| { let mut derived_row_draw_locs = Vec::new();
izip!(col_constraint_vec, col_draw_loc, &col_rows.children).for_each( izip!(row_constraint_vec, row_draw_loc, &cols.children).for_each(
|(col_row_constraint_vec, col_row_draw_loc, widgets)| { |(col_constraint_vec, col_draw_loc, col_rows)| {
// Note that col_row_constraint_vec CONTAINS the widget constraints let mut derived_col_draw_locs = Vec::new();
let widget_draw_locs = Layout::default() izip!(col_constraint_vec, col_draw_loc, &col_rows.children)
.constraints(col_row_constraint_vec.as_ref()) .for_each(
.direction(Direction::Horizontal) |(col_row_constraint_vec, col_row_draw_loc, widgets)| {
.split(col_row_draw_loc); // Note that col_row_constraint_vec CONTAINS the widget constraints
let widget_draw_locs = Layout::default()
.constraints(col_row_constraint_vec.as_ref())
.direction(Direction::Horizontal)
.split(col_row_draw_loc);
for (widget, widget_draw_loc) in self.draw_widgets_with_constraints(
widgets.children.iter().zip(widget_draw_locs)
{
match widget.widget_type {
Empty => {}
Cpu => self.draw_cpu(
&mut f, &mut f,
app_state, app_state,
widget_draw_loc, widgets,
widget.widget_id, &widget_draw_locs,
), );
Mem => self.draw_memory_graph(
derived_col_draw_locs.push(widget_draw_locs);
},
);
derived_row_draw_locs.push(derived_col_draw_locs);
},
);
new_derived_widget_draw_locs.push(derived_row_draw_locs);
});
self.derived_widget_draw_locs = new_derived_widget_draw_locs;
} else {
self.widget_layout
.rows
.iter()
.zip(&self.derived_widget_draw_locs)
.for_each(|(cols, row_layout)| {
cols.children.iter().zip(row_layout).for_each(
|(col_rows, col_row_layout)| {
col_rows.children.iter().zip(col_row_layout).for_each(
|(widgets, widget_draw_locs)| {
self.draw_widgets_with_constraints(
&mut f, &mut f,
app_state, app_state,
widget_draw_loc, widgets,
widget.widget_id, &widget_draw_locs,
), );
Net => self.draw_network( },
&mut f, );
app_state,
widget_draw_loc,
widget.widget_id,
),
Temp => self.draw_temp_table(
&mut f,
app_state,
widget_draw_loc,
true,
widget.widget_id,
),
Disk => self.draw_disk_table(
&mut f,
app_state,
widget_draw_loc,
true,
widget.widget_id,
),
Proc => self.draw_process_and_search(
&mut f,
app_state,
widget_draw_loc,
true,
widget.widget_id,
),
_ => {}
}
}
}, },
); );
}, });
); }
});
} }
})?; })?;
@ -545,4 +540,33 @@ impl Painter {
Ok(()) Ok(())
} }
fn draw_widgets_with_constraints<B: Backend>(
&self, f: &mut Frame<'_, B>, app_state: &mut App, widgets: &BottomColRow,
widget_draw_locs: &[Rect],
) {
use BottomWidgetType::*;
for (widget, widget_draw_loc) in widgets.children.iter().zip(widget_draw_locs) {
match &widget.widget_type {
Empty => {}
Cpu => self.draw_cpu(f, app_state, *widget_draw_loc, widget.widget_id),
Mem => self.draw_memory_graph(f, app_state, *widget_draw_loc, widget.widget_id),
Net => self.draw_network(f, app_state, *widget_draw_loc, widget.widget_id),
Temp => {
self.draw_temp_table(f, app_state, *widget_draw_loc, true, widget.widget_id)
}
Disk => {
self.draw_disk_table(f, app_state, *widget_draw_loc, true, widget.widget_id)
}
Proc => self.draw_process_and_search(
f,
app_state,
*widget_draw_loc,
true,
widget.widget_id,
),
_ => {}
}
}
}
} }