mirror of
https://github.com/ClementTsang/bottom.git
synced 2025-07-25 06:35:07 +02:00
Added proper navigation for basic mode.
This commit is contained in:
parent
63f2ead48b
commit
7f34061e68
148
src/app.rs
148
src/app.rs
@ -23,6 +23,21 @@ pub enum WidgetPosition {
|
|||||||
Network,
|
Network,
|
||||||
Process,
|
Process,
|
||||||
ProcessSearch,
|
ProcessSearch,
|
||||||
|
BasicCpu,
|
||||||
|
BasicMem,
|
||||||
|
BasicNet,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WidgetPosition {
|
||||||
|
pub fn is_widget_table(self) -> bool {
|
||||||
|
match self {
|
||||||
|
WidgetPosition::Disk
|
||||||
|
| WidgetPosition::Process
|
||||||
|
| WidgetPosition::ProcessSearch
|
||||||
|
| WidgetPosition::Temp => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -244,6 +259,7 @@ pub struct App {
|
|||||||
pub update_process_gui: bool,
|
pub update_process_gui: bool,
|
||||||
pub app_scroll_positions: AppScrollState,
|
pub app_scroll_positions: AppScrollState,
|
||||||
pub current_widget_selected: WidgetPosition,
|
pub current_widget_selected: WidgetPosition,
|
||||||
|
pub last_basic_table_widget_selected: WidgetPosition,
|
||||||
awaiting_second_char: bool,
|
awaiting_second_char: bool,
|
||||||
second_char: Option<char>,
|
second_char: Option<char>,
|
||||||
pub dd_err: Option<String>,
|
pub dd_err: Option<String>,
|
||||||
@ -277,6 +293,11 @@ impl App {
|
|||||||
process_sorting_reverse: true,
|
process_sorting_reverse: true,
|
||||||
update_process_gui: false,
|
update_process_gui: false,
|
||||||
current_widget_selected,
|
current_widget_selected,
|
||||||
|
last_basic_table_widget_selected: if current_widget_selected.is_widget_table() {
|
||||||
|
current_widget_selected
|
||||||
|
} else {
|
||||||
|
WidgetPosition::Process
|
||||||
|
},
|
||||||
app_scroll_positions: AppScrollState::default(),
|
app_scroll_positions: AppScrollState::default(),
|
||||||
awaiting_second_char: false,
|
awaiting_second_char: false,
|
||||||
second_char: None,
|
second_char: None,
|
||||||
@ -568,10 +589,6 @@ impl App {
|
|||||||
self.process_search_state.search_state.char_cursor_position
|
self.process_search_state.search_state.char_cursor_position
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn move_basic_left(&mut self) {}
|
|
||||||
|
|
||||||
pub fn move_basic_right(&mut self) {}
|
|
||||||
|
|
||||||
/// One of two functions allowed to run while in a dialog...
|
/// One of two functions allowed to run while in a dialog...
|
||||||
pub fn on_enter(&mut self) {
|
pub fn on_enter(&mut self) {
|
||||||
if self.delete_dialog_state.is_showing_dd {
|
if self.delete_dialog_state.is_showing_dd {
|
||||||
@ -1051,7 +1068,7 @@ impl App {
|
|||||||
self.to_delete_process_list.clone()
|
self.to_delete_process_list.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
// For now, these are hard coded --- in the future, they shouldn't be!
|
// TODO: [MODULARITY] Do NOT hard code this in thu future!
|
||||||
//
|
//
|
||||||
// General idea for now:
|
// General idea for now:
|
||||||
// CPU -(down)> MEM
|
// CPU -(down)> MEM
|
||||||
@ -1063,13 +1080,24 @@ impl App {
|
|||||||
// PROC_SEARCH -(up)> PROC, -(left)> Network
|
// PROC_SEARCH -(up)> PROC, -(left)> Network
|
||||||
pub fn move_widget_selection_left(&mut self) {
|
pub fn move_widget_selection_left(&mut self) {
|
||||||
if !self.is_in_dialog() && !self.is_expanded {
|
if !self.is_in_dialog() && !self.is_expanded {
|
||||||
self.current_widget_selected = match self.current_widget_selected {
|
if self.app_config_fields.use_basic_mode {
|
||||||
WidgetPosition::Process => WidgetPosition::Network,
|
self.current_widget_selected = match self.current_widget_selected {
|
||||||
WidgetPosition::ProcessSearch => WidgetPosition::Network,
|
WidgetPosition::BasicNet => WidgetPosition::BasicMem,
|
||||||
WidgetPosition::Disk => WidgetPosition::Mem,
|
WidgetPosition::Process => WidgetPosition::Disk,
|
||||||
WidgetPosition::Temp => WidgetPosition::Mem,
|
WidgetPosition::ProcessSearch => WidgetPosition::Disk,
|
||||||
_ => self.current_widget_selected,
|
WidgetPosition::Disk => WidgetPosition::Temp,
|
||||||
};
|
WidgetPosition::Temp => WidgetPosition::Process,
|
||||||
|
_ => self.current_widget_selected,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
self.current_widget_selected = match self.current_widget_selected {
|
||||||
|
WidgetPosition::Process => WidgetPosition::Network,
|
||||||
|
WidgetPosition::ProcessSearch => WidgetPosition::Network,
|
||||||
|
WidgetPosition::Disk => WidgetPosition::Mem,
|
||||||
|
WidgetPosition::Temp => WidgetPosition::Mem,
|
||||||
|
_ => self.current_widget_selected,
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.reset_multi_tap_keys();
|
self.reset_multi_tap_keys();
|
||||||
@ -1077,11 +1105,22 @@ impl App {
|
|||||||
|
|
||||||
pub fn move_widget_selection_right(&mut self) {
|
pub fn move_widget_selection_right(&mut self) {
|
||||||
if !self.is_in_dialog() && !self.is_expanded {
|
if !self.is_in_dialog() && !self.is_expanded {
|
||||||
self.current_widget_selected = match self.current_widget_selected {
|
if self.app_config_fields.use_basic_mode {
|
||||||
WidgetPosition::Mem => WidgetPosition::Temp,
|
self.current_widget_selected = match self.current_widget_selected {
|
||||||
WidgetPosition::Network => WidgetPosition::Process,
|
WidgetPosition::BasicMem => WidgetPosition::BasicNet,
|
||||||
_ => self.current_widget_selected,
|
WidgetPosition::Process => WidgetPosition::Temp,
|
||||||
};
|
WidgetPosition::ProcessSearch => WidgetPosition::Temp,
|
||||||
|
WidgetPosition::Disk => WidgetPosition::Process,
|
||||||
|
WidgetPosition::Temp => WidgetPosition::Disk,
|
||||||
|
_ => self.current_widget_selected,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
self.current_widget_selected = match self.current_widget_selected {
|
||||||
|
WidgetPosition::Mem => WidgetPosition::Temp,
|
||||||
|
WidgetPosition::Network => WidgetPosition::Process,
|
||||||
|
_ => self.current_widget_selected,
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.reset_multi_tap_keys();
|
self.reset_multi_tap_keys();
|
||||||
@ -1089,15 +1128,30 @@ impl App {
|
|||||||
|
|
||||||
pub fn move_widget_selection_up(&mut self) {
|
pub fn move_widget_selection_up(&mut self) {
|
||||||
if !self.is_in_dialog() && !self.is_expanded {
|
if !self.is_in_dialog() && !self.is_expanded {
|
||||||
self.current_widget_selected = match self.current_widget_selected {
|
if self.app_config_fields.use_basic_mode {
|
||||||
WidgetPosition::Mem => WidgetPosition::Cpu,
|
if self.current_widget_selected.is_widget_table() {
|
||||||
WidgetPosition::Network => WidgetPosition::Mem,
|
self.last_basic_table_widget_selected = self.current_widget_selected;
|
||||||
WidgetPosition::Process => WidgetPosition::Disk,
|
}
|
||||||
WidgetPosition::ProcessSearch => WidgetPosition::Process,
|
self.current_widget_selected = match self.current_widget_selected {
|
||||||
WidgetPosition::Temp => WidgetPosition::Cpu,
|
WidgetPosition::BasicMem => WidgetPosition::BasicCpu,
|
||||||
WidgetPosition::Disk => WidgetPosition::Temp,
|
WidgetPosition::BasicNet => WidgetPosition::BasicCpu,
|
||||||
_ => self.current_widget_selected,
|
WidgetPosition::Process => WidgetPosition::BasicMem,
|
||||||
};
|
WidgetPosition::ProcessSearch => WidgetPosition::Process,
|
||||||
|
WidgetPosition::Temp => WidgetPosition::BasicMem,
|
||||||
|
WidgetPosition::Disk => WidgetPosition::BasicMem,
|
||||||
|
_ => self.current_widget_selected,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
self.current_widget_selected = match self.current_widget_selected {
|
||||||
|
WidgetPosition::Mem => WidgetPosition::Cpu,
|
||||||
|
WidgetPosition::Network => WidgetPosition::Mem,
|
||||||
|
WidgetPosition::Process => WidgetPosition::Disk,
|
||||||
|
WidgetPosition::ProcessSearch => WidgetPosition::Process,
|
||||||
|
WidgetPosition::Temp => WidgetPosition::Cpu,
|
||||||
|
WidgetPosition::Disk => WidgetPosition::Temp,
|
||||||
|
_ => self.current_widget_selected,
|
||||||
|
};
|
||||||
|
}
|
||||||
} else if self.is_expanded {
|
} else if self.is_expanded {
|
||||||
self.current_widget_selected = match self.current_widget_selected {
|
self.current_widget_selected = match self.current_widget_selected {
|
||||||
WidgetPosition::ProcessSearch => WidgetPosition::Process,
|
WidgetPosition::ProcessSearch => WidgetPosition::Process,
|
||||||
@ -1110,20 +1164,36 @@ impl App {
|
|||||||
|
|
||||||
pub fn move_widget_selection_down(&mut self) {
|
pub fn move_widget_selection_down(&mut self) {
|
||||||
if !self.is_in_dialog() && !self.is_expanded {
|
if !self.is_in_dialog() && !self.is_expanded {
|
||||||
self.current_widget_selected = match self.current_widget_selected {
|
if self.app_config_fields.use_basic_mode {
|
||||||
WidgetPosition::Cpu => WidgetPosition::Mem,
|
self.current_widget_selected = match self.current_widget_selected {
|
||||||
WidgetPosition::Mem => WidgetPosition::Network,
|
WidgetPosition::BasicMem => self.last_basic_table_widget_selected,
|
||||||
WidgetPosition::Temp => WidgetPosition::Disk,
|
WidgetPosition::BasicNet => self.last_basic_table_widget_selected,
|
||||||
WidgetPosition::Disk => WidgetPosition::Process,
|
WidgetPosition::BasicCpu => WidgetPosition::BasicMem,
|
||||||
WidgetPosition::Process => {
|
WidgetPosition::Process => {
|
||||||
if self.is_searching() {
|
if self.is_searching() {
|
||||||
WidgetPosition::ProcessSearch
|
WidgetPosition::ProcessSearch
|
||||||
} else {
|
} else {
|
||||||
WidgetPosition::Process
|
WidgetPosition::Process
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
_ => self.current_widget_selected,
|
||||||
_ => self.current_widget_selected,
|
};
|
||||||
};
|
} else {
|
||||||
|
self.current_widget_selected = match self.current_widget_selected {
|
||||||
|
WidgetPosition::Cpu => WidgetPosition::Mem,
|
||||||
|
WidgetPosition::Mem => WidgetPosition::Network,
|
||||||
|
WidgetPosition::Temp => WidgetPosition::Disk,
|
||||||
|
WidgetPosition::Disk => WidgetPosition::Process,
|
||||||
|
WidgetPosition::Process => {
|
||||||
|
if self.is_searching() {
|
||||||
|
WidgetPosition::ProcessSearch
|
||||||
|
} else {
|
||||||
|
WidgetPosition::Process
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => self.current_widget_selected,
|
||||||
|
};
|
||||||
|
}
|
||||||
} else if self.is_expanded {
|
} else if self.is_expanded {
|
||||||
self.current_widget_selected = match self.current_widget_selected {
|
self.current_widget_selected = match self.current_widget_selected {
|
||||||
WidgetPosition::Process => {
|
WidgetPosition::Process => {
|
||||||
|
310
src/canvas.rs
310
src/canvas.rs
@ -151,6 +151,20 @@ impl Painter {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn draw_specific_table<B: Backend>(
|
||||||
|
&self, f: &mut Frame<'_, B>, app_state: &mut app::App, draw_loc: Rect, draw_border: bool,
|
||||||
|
widget_selected: WidgetPosition,
|
||||||
|
) {
|
||||||
|
match widget_selected {
|
||||||
|
WidgetPosition::Process | WidgetPosition::ProcessSearch => {
|
||||||
|
self.draw_process_and_search(f, app_state, draw_loc, draw_border)
|
||||||
|
}
|
||||||
|
WidgetPosition::Temp => self.draw_temp_table(f, app_state, draw_loc, draw_border),
|
||||||
|
WidgetPosition::Disk => self.draw_disk_table(f, app_state, draw_loc, draw_border),
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: [REFACTOR] We should clean this up tbh
|
// TODO: [REFACTOR] We should clean this up tbh
|
||||||
// TODO: [FEATURE] Auto-resizing dialog sizes.
|
// TODO: [FEATURE] Auto-resizing dialog sizes.
|
||||||
#[allow(clippy::cognitive_complexity)]
|
#[allow(clippy::cognitive_complexity)]
|
||||||
@ -361,7 +375,7 @@ impl Painter {
|
|||||||
.constraints([Constraint::Percentage(100)].as_ref())
|
.constraints([Constraint::Percentage(100)].as_ref())
|
||||||
.split(f.size());
|
.split(f.size());
|
||||||
match &app_state.current_widget_selected {
|
match &app_state.current_widget_selected {
|
||||||
WidgetPosition::Cpu => {
|
WidgetPosition::Cpu | WidgetPosition::BasicCpu=> {
|
||||||
let cpu_chunk = Layout::default()
|
let cpu_chunk = Layout::default()
|
||||||
.direction(Direction::Horizontal)
|
.direction(Direction::Horizontal)
|
||||||
.margin(0)
|
.margin(0)
|
||||||
@ -389,7 +403,7 @@ impl Painter {
|
|||||||
self.draw_cpu_graph(&mut f, &app_state, cpu_chunk[graph_index]);
|
self.draw_cpu_graph(&mut f, &app_state, cpu_chunk[graph_index]);
|
||||||
self.draw_cpu_legend(&mut f, app_state, cpu_chunk[legend_index]);
|
self.draw_cpu_legend(&mut f, app_state, cpu_chunk[legend_index]);
|
||||||
}
|
}
|
||||||
WidgetPosition::Mem => {
|
WidgetPosition::Mem | WidgetPosition::BasicMem => {
|
||||||
self.draw_memory_graph(&mut f, &app_state, rect[0]);
|
self.draw_memory_graph(&mut f, &app_state, rect[0]);
|
||||||
}
|
}
|
||||||
WidgetPosition::Disk => {
|
WidgetPosition::Disk => {
|
||||||
@ -398,7 +412,7 @@ impl Painter {
|
|||||||
WidgetPosition::Temp => {
|
WidgetPosition::Temp => {
|
||||||
self.draw_temp_table(&mut f, app_state, rect[0], true);
|
self.draw_temp_table(&mut f, app_state, rect[0], true);
|
||||||
}
|
}
|
||||||
WidgetPosition::Network => {
|
WidgetPosition::Network | WidgetPosition::BasicNet => {
|
||||||
self.draw_network_graph(&mut f, &app_state, rect[0]);
|
self.draw_network_graph(&mut f, &app_state, rect[0]);
|
||||||
}
|
}
|
||||||
WidgetPosition::Process | WidgetPosition::ProcessSearch => {
|
WidgetPosition::Process | WidgetPosition::ProcessSearch => {
|
||||||
@ -431,7 +445,6 @@ impl Painter {
|
|||||||
1
|
1
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
debug!("C: {}", cpu_height);
|
|
||||||
let vertical_chunks = Layout::default()
|
let vertical_chunks = Layout::default()
|
||||||
.direction(Direction::Vertical)
|
.direction(Direction::Vertical)
|
||||||
.constraints([
|
.constraints([
|
||||||
@ -448,11 +461,14 @@ impl Painter {
|
|||||||
Constraint::Percentage(50),
|
Constraint::Percentage(50),
|
||||||
].as_ref())
|
].as_ref())
|
||||||
.split(vertical_chunks[1]);
|
.split(vertical_chunks[1]);
|
||||||
|
|
||||||
self.draw_basic_cpu(&mut f, app_state, vertical_chunks[0]);
|
self.draw_basic_cpu(&mut f, app_state, vertical_chunks[0]);
|
||||||
self.draw_basic_memory(&mut f, app_state, middle_chunks[0]);
|
self.draw_basic_memory(&mut f, app_state, middle_chunks[0]);
|
||||||
self.draw_basic_network(&mut f, app_state, middle_chunks[1]);
|
self.draw_basic_network(&mut f, app_state, middle_chunks[1]);
|
||||||
self.draw_process_and_search(&mut f, app_state, vertical_chunks[2], false);
|
if app_state.current_widget_selected.is_widget_table() {
|
||||||
|
self.draw_specific_table(&mut f, app_state, vertical_chunks[2], false, app_state.current_widget_selected);
|
||||||
|
} else {
|
||||||
|
self.draw_specific_table(&mut f, app_state, vertical_chunks[2], false, app_state.last_basic_table_widget_selected);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// TODO: [TUI] Change this back to a more even 33/33/34 when TUI releases
|
// 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()
|
||||||
@ -1070,30 +1086,50 @@ impl Painter {
|
|||||||
);
|
);
|
||||||
|
|
||||||
result_title
|
result_title
|
||||||
|
} else if app_state.app_config_fields.use_basic_mode {
|
||||||
|
String::new()
|
||||||
} else {
|
} else {
|
||||||
" Temperatures ".to_string()
|
" Temperatures ".to_string()
|
||||||
};
|
};
|
||||||
|
|
||||||
// Draw
|
let temp_block = if draw_border {
|
||||||
Table::new(TEMP_HEADERS.iter(), temperature_rows)
|
Block::default()
|
||||||
.block(
|
.title(&title)
|
||||||
Block::default()
|
.title_style(if app_state.is_expanded {
|
||||||
.title(&title)
|
match app_state.current_widget_selected {
|
||||||
.title_style(if app_state.is_expanded {
|
|
||||||
self.colours.highlighted_border_style
|
|
||||||
} else {
|
|
||||||
self.colours.widget_title_style
|
|
||||||
})
|
|
||||||
.borders(if draw_border {
|
|
||||||
Borders::ALL
|
|
||||||
} else {
|
|
||||||
Borders::NONE
|
|
||||||
})
|
|
||||||
.border_style(match app_state.current_widget_selected {
|
|
||||||
app::WidgetPosition::Temp => self.colours.highlighted_border_style,
|
app::WidgetPosition::Temp => self.colours.highlighted_border_style,
|
||||||
_ => self.colours.border_style,
|
_ => self.colours.border_style,
|
||||||
}),
|
}
|
||||||
)
|
} else {
|
||||||
|
self.colours.widget_title_style
|
||||||
|
})
|
||||||
|
.borders(Borders::ALL)
|
||||||
|
.border_style(match app_state.current_widget_selected {
|
||||||
|
app::WidgetPosition::Temp => self.colours.highlighted_border_style,
|
||||||
|
_ => self.colours.border_style,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
match app_state.current_widget_selected {
|
||||||
|
app::WidgetPosition::Temp => Block::default()
|
||||||
|
.borders(*SIDE_BORDERS)
|
||||||
|
.border_style(self.colours.highlighted_border_style),
|
||||||
|
_ => Block::default().borders(Borders::NONE),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let margined_draw_loc = Layout::default()
|
||||||
|
.constraints([Constraint::Percentage(100)].as_ref())
|
||||||
|
.horizontal_margin(match app_state.current_widget_selected {
|
||||||
|
app::WidgetPosition::Temp => 0,
|
||||||
|
_ if !draw_border => 1,
|
||||||
|
_ => 0,
|
||||||
|
})
|
||||||
|
.direction(Direction::Horizontal)
|
||||||
|
.split(draw_loc);
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
Table::new(TEMP_HEADERS.iter(), temperature_rows)
|
||||||
|
.block(temp_block)
|
||||||
.header_style(self.colours.table_header_style)
|
.header_style(self.colours.table_header_style)
|
||||||
.widths(
|
.widths(
|
||||||
&(intrinsic_widths
|
&(intrinsic_widths
|
||||||
@ -1101,7 +1137,7 @@ impl Painter {
|
|||||||
.map(|calculated_width| Constraint::Length(*calculated_width as u16))
|
.map(|calculated_width| Constraint::Length(*calculated_width as u16))
|
||||||
.collect::<Vec<_>>()),
|
.collect::<Vec<_>>()),
|
||||||
)
|
)
|
||||||
.render(f, draw_loc);
|
.render(f, margined_draw_loc[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_disk_table<B: Backend>(
|
fn draw_disk_table<B: Backend>(
|
||||||
@ -1170,32 +1206,51 @@ impl Painter {
|
|||||||
" Disk ─{}─ Esc to go back ",
|
" Disk ─{}─ Esc to go back ",
|
||||||
"─".repeat(repeat_num as usize)
|
"─".repeat(repeat_num as usize)
|
||||||
);
|
);
|
||||||
|
|
||||||
result_title
|
result_title
|
||||||
|
} else if app_state.app_config_fields.use_basic_mode {
|
||||||
|
String::new()
|
||||||
} else {
|
} else {
|
||||||
" Disk ".to_string()
|
" Disk ".to_string()
|
||||||
};
|
};
|
||||||
|
|
||||||
// Draw!
|
let disk_block = if draw_border {
|
||||||
Table::new(DISK_HEADERS.iter(), disk_rows)
|
Block::default()
|
||||||
.block(
|
.title(&title)
|
||||||
Block::default()
|
.title_style(if app_state.is_expanded {
|
||||||
.title(&title)
|
match app_state.current_widget_selected {
|
||||||
.title_style(if app_state.is_expanded {
|
|
||||||
self.colours.highlighted_border_style
|
|
||||||
} else {
|
|
||||||
self.colours.widget_title_style
|
|
||||||
})
|
|
||||||
.borders(if draw_border {
|
|
||||||
Borders::ALL
|
|
||||||
} else {
|
|
||||||
Borders::NONE
|
|
||||||
})
|
|
||||||
.border_style(match app_state.current_widget_selected {
|
|
||||||
app::WidgetPosition::Disk => self.colours.highlighted_border_style,
|
app::WidgetPosition::Disk => self.colours.highlighted_border_style,
|
||||||
_ => self.colours.border_style,
|
_ => self.colours.border_style,
|
||||||
}),
|
}
|
||||||
)
|
} else {
|
||||||
|
self.colours.widget_title_style
|
||||||
|
})
|
||||||
|
.borders(Borders::ALL)
|
||||||
|
.border_style(match app_state.current_widget_selected {
|
||||||
|
app::WidgetPosition::Disk => self.colours.highlighted_border_style,
|
||||||
|
_ => self.colours.border_style,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
match app_state.current_widget_selected {
|
||||||
|
app::WidgetPosition::Disk => Block::default()
|
||||||
|
.borders(*SIDE_BORDERS)
|
||||||
|
.border_style(self.colours.highlighted_border_style),
|
||||||
|
_ => Block::default().borders(Borders::NONE),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let margined_draw_loc = Layout::default()
|
||||||
|
.constraints([Constraint::Percentage(100)].as_ref())
|
||||||
|
.horizontal_margin(match app_state.current_widget_selected {
|
||||||
|
app::WidgetPosition::Disk => 0,
|
||||||
|
_ if !draw_border => 1,
|
||||||
|
_ => 0,
|
||||||
|
})
|
||||||
|
.direction(Direction::Horizontal)
|
||||||
|
.split(draw_loc);
|
||||||
|
|
||||||
|
// Draw!
|
||||||
|
Table::new(DISK_HEADERS.iter(), disk_rows)
|
||||||
|
.block(disk_block)
|
||||||
.header_style(self.colours.table_header_style)
|
.header_style(self.colours.table_header_style)
|
||||||
.widths(
|
.widths(
|
||||||
&(intrinsic_widths
|
&(intrinsic_widths
|
||||||
@ -1203,7 +1258,7 @@ impl Painter {
|
|||||||
.map(|calculated_width| Constraint::Length(*calculated_width as u16))
|
.map(|calculated_width| Constraint::Length(*calculated_width as u16))
|
||||||
.collect::<Vec<_>>()),
|
.collect::<Vec<_>>()),
|
||||||
)
|
)
|
||||||
.render(f, draw_loc);
|
.render(f, margined_draw_loc[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_search_field<B: Backend>(
|
fn draw_search_field<B: Backend>(
|
||||||
@ -1367,22 +1422,37 @@ impl Painter {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Paragraph::new(search_text.iter())
|
let process_search_block = if draw_border {
|
||||||
.block(
|
Block::default()
|
||||||
Block::default()
|
.title(&title)
|
||||||
.borders(if draw_border {
|
.title_style(current_border_style)
|
||||||
Borders::ALL
|
.borders(Borders::ALL)
|
||||||
} else {
|
.border_style(current_border_style)
|
||||||
Borders::NONE
|
} else {
|
||||||
})
|
match app_state.current_widget_selected {
|
||||||
.title(&title)
|
app::WidgetPosition::ProcessSearch => Block::default()
|
||||||
.title_style(current_border_style)
|
.borders(*SIDE_BORDERS)
|
||||||
.border_style(current_border_style),
|
.border_style(current_border_style),
|
||||||
)
|
_ => Block::default().borders(Borders::NONE),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let margined_draw_loc = Layout::default()
|
||||||
|
.constraints([Constraint::Percentage(100)].as_ref())
|
||||||
|
.horizontal_margin(match app_state.current_widget_selected {
|
||||||
|
app::WidgetPosition::ProcessSearch => 0,
|
||||||
|
_ if !draw_border => 1,
|
||||||
|
_ => 0,
|
||||||
|
})
|
||||||
|
.direction(Direction::Horizontal)
|
||||||
|
.split(draw_loc);
|
||||||
|
|
||||||
|
Paragraph::new(search_text.iter())
|
||||||
|
.block(process_search_block)
|
||||||
.style(self.colours.text_style)
|
.style(self.colours.text_style)
|
||||||
.alignment(Alignment::Left)
|
.alignment(Alignment::Left)
|
||||||
.wrap(false)
|
.wrap(false)
|
||||||
.render(f, draw_loc);
|
.render(f, margined_draw_loc[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_processes_table<B: Backend>(
|
fn draw_processes_table<B: Backend>(
|
||||||
@ -1580,7 +1650,7 @@ impl Painter {
|
|||||||
// Then, from this, split the row space across ALL columns. From there, generate
|
// Then, from this, split the row space across ALL columns. From there, generate
|
||||||
// the desired lengths.
|
// the desired lengths.
|
||||||
|
|
||||||
if let WidgetPosition::Cpu = app_state.current_widget_selected {
|
if let WidgetPosition::BasicCpu = app_state.current_widget_selected {
|
||||||
Block::default()
|
Block::default()
|
||||||
.borders(*SIDE_BORDERS)
|
.borders(*SIDE_BORDERS)
|
||||||
.border_style(self.colours.highlighted_border_style)
|
.border_style(self.colours.highlighted_border_style)
|
||||||
@ -1588,78 +1658,74 @@ impl Painter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let num_cpus = cpu_data.len();
|
let num_cpus = cpu_data.len();
|
||||||
if draw_loc.height > 0 {
|
let remaining_height = draw_loc.height as usize;
|
||||||
let remaining_height = draw_loc.height as usize;
|
const REQUIRED_COLUMNS: usize = 4;
|
||||||
let required_columns = 4;
|
|
||||||
|
|
||||||
let chunk_vec =
|
let chunk_vec =
|
||||||
vec![Constraint::Percentage((100 / required_columns) as u16); required_columns];
|
vec![Constraint::Percentage((100 / REQUIRED_COLUMNS) as u16); REQUIRED_COLUMNS];
|
||||||
let chunks = Layout::default()
|
let chunks = Layout::default()
|
||||||
.constraints(chunk_vec.as_ref())
|
.constraints(chunk_vec.as_ref())
|
||||||
.direction(Direction::Horizontal)
|
.direction(Direction::Horizontal)
|
||||||
.split(draw_loc);
|
.split(draw_loc);
|
||||||
|
|
||||||
// +9 due to 3 + 4 + 2 columns for the name & space + percentage + bar bounds
|
// +9 due to 3 + 4 + 2 columns for the name & space + percentage + bar bounds
|
||||||
let margin_space = 2;
|
let margin_space = 2;
|
||||||
let remaining_width = max(
|
let remaining_width = max(
|
||||||
0,
|
0,
|
||||||
draw_loc.width as i64
|
draw_loc.width as i64 - ((9 + margin_space) * REQUIRED_COLUMNS - margin_space) as i64,
|
||||||
- ((9 + margin_space) * required_columns - margin_space) as i64,
|
) as usize;
|
||||||
) as usize;
|
|
||||||
|
|
||||||
let bar_length = remaining_width / required_columns;
|
let bar_length = remaining_width / REQUIRED_COLUMNS;
|
||||||
|
|
||||||
let cpu_bars = (0..num_cpus)
|
let cpu_bars = (0..num_cpus)
|
||||||
|
.map(|cpu_index| {
|
||||||
|
let use_percentage = if let Some(cpu_usage) = cpu_data[cpu_index].cpu_data.last() {
|
||||||
|
cpu_usage.1
|
||||||
|
} else {
|
||||||
|
0.0
|
||||||
|
};
|
||||||
|
|
||||||
|
let num_bars = calculate_basic_use_bars(use_percentage, bar_length);
|
||||||
|
format!(
|
||||||
|
"{:3}[{}{}{:3.0}%]\n",
|
||||||
|
if app_state.app_config_fields.show_average_cpu {
|
||||||
|
if cpu_index == 0 {
|
||||||
|
"AVG".to_string()
|
||||||
|
} else {
|
||||||
|
(cpu_index - 1).to_string()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cpu_index.to_string()
|
||||||
|
},
|
||||||
|
"|".repeat(num_bars),
|
||||||
|
" ".repeat(bar_length - num_bars),
|
||||||
|
use_percentage.round(),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
for (current_row, chunk) in chunks.iter().enumerate() {
|
||||||
|
let start_index = (current_row * remaining_height) as usize;
|
||||||
|
let end_index = min(start_index + remaining_height, num_cpus);
|
||||||
|
let cpu_column: Vec<Text<'_>> = (start_index..end_index)
|
||||||
.map(|cpu_index| {
|
.map(|cpu_index| {
|
||||||
let use_percentage =
|
Text::Styled(
|
||||||
if let Some(cpu_usage) = cpu_data[cpu_index].cpu_data.last() {
|
(&cpu_bars[cpu_index]).into(),
|
||||||
cpu_usage.1
|
self.colours.cpu_colour_styles
|
||||||
} else {
|
[cpu_index as usize % self.colours.cpu_colour_styles.len()],
|
||||||
0.0
|
|
||||||
};
|
|
||||||
|
|
||||||
let num_bars = calculate_basic_use_bars(use_percentage, bar_length);
|
|
||||||
format!(
|
|
||||||
"{:3}[{}{}{:3.0}%]\n",
|
|
||||||
if app_state.app_config_fields.show_average_cpu {
|
|
||||||
if cpu_index == 0 {
|
|
||||||
"AVG".to_string()
|
|
||||||
} else {
|
|
||||||
(cpu_index - 1).to_string()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
cpu_index.to_string()
|
|
||||||
},
|
|
||||||
"|".repeat(num_bars),
|
|
||||||
" ".repeat(bar_length - num_bars),
|
|
||||||
use_percentage.round(),
|
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
for (current_row, chunk) in chunks.iter().enumerate() {
|
let margined_loc = Layout::default()
|
||||||
let start_index = (current_row * remaining_height) as usize;
|
.direction(Direction::Horizontal)
|
||||||
let end_index = min(start_index + remaining_height, num_cpus);
|
.constraints([Constraint::Percentage(100)].as_ref())
|
||||||
let cpu_column: Vec<Text<'_>> = (start_index..end_index)
|
.horizontal_margin(1)
|
||||||
.map(|cpu_index| {
|
.split(*chunk);
|
||||||
Text::Styled(
|
|
||||||
(&cpu_bars[cpu_index]).into(),
|
|
||||||
self.colours.cpu_colour_styles
|
|
||||||
[cpu_index as usize % self.colours.cpu_colour_styles.len()],
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
let margined_loc = Layout::default()
|
Paragraph::new(cpu_column.iter())
|
||||||
.direction(Direction::Horizontal)
|
.block(Block::default())
|
||||||
.constraints([Constraint::Percentage(100)].as_ref())
|
.render(f, margined_loc[0]);
|
||||||
.horizontal_margin(1)
|
|
||||||
.split(*chunk);
|
|
||||||
|
|
||||||
Paragraph::new(cpu_column.iter())
|
|
||||||
.block(Block::default())
|
|
||||||
.render(f, margined_loc[0]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1674,7 +1740,7 @@ impl Painter {
|
|||||||
.horizontal_margin(1)
|
.horizontal_margin(1)
|
||||||
.split(draw_loc);
|
.split(draw_loc);
|
||||||
|
|
||||||
if let WidgetPosition::Mem = app_state.current_widget_selected {
|
if let WidgetPosition::BasicMem = app_state.current_widget_selected {
|
||||||
Block::default()
|
Block::default()
|
||||||
.borders(*SIDE_BORDERS)
|
.borders(*SIDE_BORDERS)
|
||||||
.border_style(self.colours.highlighted_border_style)
|
.border_style(self.colours.highlighted_border_style)
|
||||||
@ -1738,7 +1804,7 @@ impl Painter {
|
|||||||
.horizontal_margin(1)
|
.horizontal_margin(1)
|
||||||
.split(divided_loc[1]);
|
.split(divided_loc[1]);
|
||||||
|
|
||||||
if let WidgetPosition::Network = app_state.current_widget_selected {
|
if let WidgetPosition::BasicNet = app_state.current_widget_selected {
|
||||||
Block::default()
|
Block::default()
|
||||||
.borders(*SIDE_BORDERS)
|
.borders(*SIDE_BORDERS)
|
||||||
.border_style(self.colours.highlighted_border_style)
|
.border_style(self.colours.highlighted_border_style)
|
||||||
|
@ -361,8 +361,10 @@ fn handle_key_event_or_break(
|
|||||||
KeyCode::Char('u') => app.clear_search(),
|
KeyCode::Char('u') => app.clear_search(),
|
||||||
KeyCode::Char('a') => app.skip_cursor_beginning(),
|
KeyCode::Char('a') => app.skip_cursor_beginning(),
|
||||||
KeyCode::Char('e') => app.skip_cursor_end(),
|
KeyCode::Char('e') => app.skip_cursor_end(),
|
||||||
KeyCode::Char('h') => app.move_basic_left(),
|
// KeyCode::Char('j') => {}, // Move down
|
||||||
KeyCode::Char('l') => app.move_basic_right(),
|
// KeyCode::Char('k') => {}, // Move up
|
||||||
|
// KeyCode::Char('h') => {}, // Move right
|
||||||
|
// KeyCode::Char('l') => {}, // Move left
|
||||||
// Can't do now, CTRL+BACKSPACE doesn't work and graphemes
|
// Can't do now, CTRL+BACKSPACE doesn't work and graphemes
|
||||||
// are hard to iter while truncating last (eloquently).
|
// are hard to iter while truncating last (eloquently).
|
||||||
// KeyCode::Backspace => app.skip_word_backspace(),
|
// KeyCode::Backspace => app.skip_word_backspace(),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user