feat: change log panel size, closes #50
This commit is contained in:
@@ -241,7 +241,10 @@ mod tests {
|
||||
}
|
||||
|
||||
// Control panel now selected, should have a blue border
|
||||
setup.gui_state.lock().next_panel();
|
||||
setup
|
||||
.gui_state
|
||||
.lock()
|
||||
.selectable_panel_next(&setup.app_data);
|
||||
let fd = FrameData::from((&setup.app_data, &setup.gui_state));
|
||||
setup
|
||||
.terminal
|
||||
|
||||
@@ -157,7 +157,10 @@ mod tests {
|
||||
let mut setup = test_setup(40, 6, true, true);
|
||||
setup.app_data.lock().containers = StatefulList::new(vec![]);
|
||||
|
||||
setup.gui_state.lock().next_panel();
|
||||
setup
|
||||
.gui_state
|
||||
.lock()
|
||||
.selectable_panel_next(&setup.app_data);
|
||||
let fd = FrameData::from((&setup.app_data, &setup.gui_state));
|
||||
let colors = setup.app_data.lock().config.app_colors;
|
||||
|
||||
@@ -184,7 +187,10 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
setup.gui_state.lock().previous_panel();
|
||||
setup
|
||||
.gui_state
|
||||
.lock()
|
||||
.selectable_panel_previous(&setup.app_data);
|
||||
let fd = FrameData::from((&setup.app_data, &setup.gui_state));
|
||||
|
||||
setup
|
||||
@@ -255,7 +261,10 @@ mod tests {
|
||||
}
|
||||
|
||||
// Change selected panel, border is now no longer blue
|
||||
setup.gui_state.lock().next_panel();
|
||||
setup
|
||||
.gui_state
|
||||
.lock()
|
||||
.selectable_panel_next(&setup.app_data);
|
||||
let fd = FrameData::from((&setup.app_data, &setup.gui_state));
|
||||
setup
|
||||
.terminal
|
||||
|
||||
+49
-29
@@ -85,6 +85,7 @@ impl HelpInfo {
|
||||
}
|
||||
|
||||
/// Generate the button information span + metadata
|
||||
#[allow(clippy::too_many_lines)]
|
||||
fn gen_keymap_info(colors: AppColors, zone: Option<&TimeZone>, show_timestamp: bool) -> Self {
|
||||
let button_item = |x: &str| Self::highlighted_text_span(&format!(" ( {x} ) "), colors);
|
||||
let button_desc = |x: &str| Self::text_span(x, colors);
|
||||
@@ -152,6 +153,16 @@ impl HelpInfo {
|
||||
button_item("1 - 9"),
|
||||
button_desc("sort by header - or click header"),
|
||||
]),
|
||||
Line::from(vec![
|
||||
space(),
|
||||
button_item("- ="),
|
||||
button_desc("change log section height"),
|
||||
]),
|
||||
Line::from(vec![
|
||||
space(),
|
||||
button_item("\\"),
|
||||
button_desc("toggle log section visibility"),
|
||||
]),
|
||||
Line::from(vec![
|
||||
space(),
|
||||
button_item("esc"),
|
||||
@@ -212,15 +223,6 @@ impl HelpInfo {
|
||||
fn custom_text<'a>(colors: AppColors, _keymap: &Keymap, zone: Option<&TimeZone>) -> Line<'a> {
|
||||
let highlighted = |x: &str| Self::highlighted_text_span(x, colors);
|
||||
let text = |x: &str| Self::text_span(x, colors);
|
||||
|
||||
// if keymap != &Keymap::new() {
|
||||
// op.push(highlighted("customised keymap, "));
|
||||
// }
|
||||
|
||||
// if colors != AppColors::new() {
|
||||
// op.push(highlighted("customised app colors, "));
|
||||
// };
|
||||
|
||||
let zone = zone.and_then(|i| i.iana_name()).unwrap_or("Etc/UTC");
|
||||
Line::from(Vec::from([text("logs timezone: "), highlighted(zone)])).centered()
|
||||
}
|
||||
@@ -295,6 +297,15 @@ impl HelpInfo {
|
||||
or_secondary(km.sort_by_image, "sort containers by image"),
|
||||
or_secondary(km.sort_by_rx, "sort containers by rx"),
|
||||
or_secondary(km.sort_by_tx, "sort containers by tx"),
|
||||
or_secondary(
|
||||
km.log_section_height_decrease,
|
||||
"decrease log section height",
|
||||
),
|
||||
or_secondary(
|
||||
km.log_section_height_increase,
|
||||
"increase log section height",
|
||||
),
|
||||
or_secondary(km.log_section_toggle, "toggle log section visibility"),
|
||||
or_secondary(km.clear, "close dialog"),
|
||||
or_secondary(km.quit, "quit at any time"),
|
||||
];
|
||||
@@ -426,7 +437,7 @@ mod tests {
|
||||
#[test]
|
||||
/// This will cause issues once the version has more than the current 5 chars (0.5.0)
|
||||
fn test_draw_blocks_help() {
|
||||
let mut setup = test_setup(87, 33, true, true);
|
||||
let mut setup = test_setup(87, 35, true, true);
|
||||
let tz = setup.app_data.lock().config.timezone.clone();
|
||||
|
||||
setup
|
||||
@@ -448,29 +459,29 @@ mod tests {
|
||||
for (result_cell_index, result_cell) in result_row.iter().enumerate() {
|
||||
match (row_index, result_cell_index) {
|
||||
// first & last row, and first & last char on each row, is reset/reset, making sure that the help info is centered in the given area
|
||||
(0 | 32, _) | (0..=33, 0 | 86) => {
|
||||
(0 | 34, _) | (0..=33, 0 | 86) => {
|
||||
assert_eq!(result_cell.bg, Color::Reset);
|
||||
assert_eq!(result_cell.fg, Color::Reset);
|
||||
}
|
||||
// border is black on magenta
|
||||
(1 | 31, _) | (1..=31, 1 | 85) => {
|
||||
(1 | 32, _) | (1..=31, 1 | 85) => {
|
||||
assert_eq!(result_cell.bg, Color::Magenta);
|
||||
assert_eq!(result_cell.fg, Color::Black);
|
||||
}
|
||||
// oxker logo && description
|
||||
(2..=10, 2..=85) | (12, 19..=66)
|
||||
// button in the brackets
|
||||
// oxker logo && description
|
||||
(2..=10, 2..=85)
|
||||
| (12, 19..=66)
|
||||
| (14, 2..=10 | 13..=27)
|
||||
| (15, 2..=10 | 13..=21 | 24..=40 | 43..=56)
|
||||
| (16 | 23, 2..=12)
|
||||
| (17..=20 | 22 | 25, 2..=8)
|
||||
| (17..=20 | 22 | 25 | 27, 2..=8)
|
||||
| (21, 2..=9 | 12..=18)
|
||||
| (24, 2..=10) => {
|
||||
| (24 | 26, 2..=10) => {
|
||||
assert_eq!(result_cell.bg, Color::Magenta);
|
||||
assert_eq!(result_cell.fg, Color::White);
|
||||
}
|
||||
// The URL is white and underlined
|
||||
(28, 25..=60) => {
|
||||
(30, 25..=60) => {
|
||||
assert_eq!(result_cell.bg, Color::Magenta);
|
||||
assert_eq!(result_cell.fg, Color::White);
|
||||
assert_eq!(result_cell.modifier, Modifier::UNDERLINED);
|
||||
@@ -488,7 +499,7 @@ mod tests {
|
||||
#[test]
|
||||
/// Test that the help panel gets drawn with custom colors
|
||||
fn test_draw_blocks_help_custom_colors() {
|
||||
let mut setup = test_setup(87, 33, true, true);
|
||||
let mut setup = test_setup(87, 35, true, true);
|
||||
let mut colors = AppColors::new();
|
||||
let tz = setup.app_data.lock().config.timezone.clone();
|
||||
|
||||
@@ -515,29 +526,29 @@ mod tests {
|
||||
for (result_cell_index, result_cell) in result_row.iter().enumerate() {
|
||||
match (row_index, result_cell_index) {
|
||||
// first & last row, and first & last char on each row, is reset/reset, making sure that the help info is centered in the given area
|
||||
(0 | 32, _) | (0..=33, 0 | 86) => {
|
||||
(0 | 34, _) | (0..=33, 0 | 86) => {
|
||||
assert_eq!(result_cell.bg, Color::Reset);
|
||||
assert_eq!(result_cell.fg, Color::Reset);
|
||||
}
|
||||
// border is black on magenta
|
||||
(1 | 31, _) | (1..=31, 1 | 85) => {
|
||||
// border is red on black
|
||||
(1 | 32, _) | (1..=31, 1 | 85) => {
|
||||
assert_eq!(result_cell.bg, Color::Black);
|
||||
assert_eq!(result_cell.fg, Color::Red);
|
||||
}
|
||||
// oxker logo && description
|
||||
(2..=10, 2..=85) | (12, 19..=66)
|
||||
// button in the brackets
|
||||
// oxker logo && description
|
||||
(2..=10, 2..=85)
|
||||
| (12, 19..=66)
|
||||
| (14, 2..=10 | 13..=27)
|
||||
| (15, 2..=10 | 13..=21 | 24..=40 | 43..=56)
|
||||
| (16 | 23, 2..=12)
|
||||
| (17..=20 | 22 | 25, 2..=8)
|
||||
| (17..=20 | 22 | 25 | 27, 2..=8)
|
||||
| (21, 2..=9 | 12..=18)
|
||||
| (24, 2..=10) => {
|
||||
| (24 | 26, 2..=10) => {
|
||||
assert_eq!(result_cell.bg, Color::Black);
|
||||
assert_eq!(result_cell.fg, Color::Yellow);
|
||||
}
|
||||
// The URL is yellow and underlined
|
||||
(28, 25..=60) => {
|
||||
(30, 25..=60) => {
|
||||
assert_eq!(result_cell.bg, Color::Black);
|
||||
assert_eq!(result_cell.fg, Color::Yellow);
|
||||
assert_eq!(result_cell.modifier, Modifier::UNDERLINED);
|
||||
@@ -562,6 +573,9 @@ mod tests {
|
||||
delete_deny: (KeyCode::Char('c'), None),
|
||||
delete_confirm: (KeyCode::Char('e'), None),
|
||||
exec: (KeyCode::Char('g'), None),
|
||||
log_section_height_decrease: (KeyCode::Char('z'), None),
|
||||
log_section_height_increase: (KeyCode::Char('x'), None),
|
||||
log_section_toggle: (KeyCode::Char('W'), None),
|
||||
filter_mode: (KeyCode::Char('i'), None),
|
||||
quit: (KeyCode::Char('k'), None),
|
||||
save_logs: (KeyCode::Char('m'), None),
|
||||
@@ -607,6 +621,9 @@ mod tests {
|
||||
delete_deny: (KeyCode::Char('c'), Some(KeyCode::Char('d'))),
|
||||
delete_confirm: (KeyCode::Char('e'), Some(KeyCode::Char('f'))),
|
||||
exec: (KeyCode::Char('g'), Some(KeyCode::Char('h'))),
|
||||
log_section_height_decrease: (KeyCode::Char('A'), Some(KeyCode::Char('Z'))),
|
||||
log_section_height_increase: (KeyCode::Char('B'), Some(KeyCode::Char('X'))),
|
||||
log_section_toggle: (KeyCode::Char('C'), Some(KeyCode::Char('W'))),
|
||||
filter_mode: (KeyCode::Char('i'), Some(KeyCode::Char('j'))),
|
||||
quit: (KeyCode::Char('k'), Some(KeyCode::Char('l'))),
|
||||
save_logs: (KeyCode::Char('m'), Some(KeyCode::Char('n'))),
|
||||
@@ -653,6 +670,9 @@ mod tests {
|
||||
delete_confirm: (KeyCode::Char('e'), Some(KeyCode::Char('f'))),
|
||||
exec: (KeyCode::Char('g'), None),
|
||||
filter_mode: (KeyCode::Char('i'), Some(KeyCode::Char('j'))),
|
||||
log_section_height_decrease: (KeyCode::Char('A'), Some(KeyCode::Char('Z'))),
|
||||
log_section_height_increase: (KeyCode::Char('B'), Some(KeyCode::Char('X'))),
|
||||
log_section_toggle: (KeyCode::Char('C'), Some(KeyCode::Char('W'))),
|
||||
quit: (KeyCode::Char('k'), None),
|
||||
save_logs: (KeyCode::Char('m'), Some(KeyCode::Char('n'))),
|
||||
scroll_down_many: (KeyCode::Char('o'), None),
|
||||
@@ -691,7 +711,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_draw_blocks_help_show_timezone() {
|
||||
let mut setup = test_setup(87, 35, true, true);
|
||||
let mut setup = test_setup(87, 37, true, true);
|
||||
|
||||
setup
|
||||
.terminal
|
||||
|
||||
@@ -124,8 +124,14 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
setup.gui_state.lock().next_panel();
|
||||
setup.gui_state.lock().next_panel();
|
||||
setup
|
||||
.gui_state
|
||||
.lock()
|
||||
.selectable_panel_next(&setup.app_data);
|
||||
setup
|
||||
.gui_state
|
||||
.lock()
|
||||
.selectable_panel_next(&setup.app_data);
|
||||
let fd = FrameData::from((&setup.app_data, &setup.gui_state));
|
||||
|
||||
// When selected, has a blue border
|
||||
|
||||
+76
-14
@@ -128,7 +128,7 @@ pub mod tests {
|
||||
use crate::{
|
||||
app_data::{AppData, ContainerId, ContainerImage, ContainerName, ContainerPorts},
|
||||
tests::{gen_appdata, gen_containers},
|
||||
ui::{GuiState, Redraw, draw_frame},
|
||||
ui::{GuiState, Rerender, draw_frame},
|
||||
};
|
||||
|
||||
use super::FrameData;
|
||||
@@ -152,32 +152,33 @@ pub mod tests {
|
||||
fn from(data: (&Arc<Mutex<AppData>>, &Arc<Mutex<GuiState>>)) -> Self {
|
||||
let (app_data, gui_data) = (data.0.lock(), data.1.lock());
|
||||
|
||||
// set max height for container section, needs +5 to deal with docker commands list and borders
|
||||
let height = app_data.get_container_len();
|
||||
let height = if height < 12 {
|
||||
u16::try_from(height + 5).unwrap_or_default()
|
||||
} else {
|
||||
12
|
||||
};
|
||||
// let container_section_height = app_data.get_container_len();
|
||||
// let container_section_height = if container_section_height < 12 {
|
||||
// u16::try_from(container_section_height + 5).unwrap_or_default()
|
||||
// } else {
|
||||
// 12
|
||||
// };
|
||||
|
||||
let (filter_by, filter_term) = app_data.get_filter();
|
||||
Self {
|
||||
chart_data: app_data.get_chart_data(),
|
||||
columns: app_data.get_width(),
|
||||
color_logs: app_data.config.color_logs,
|
||||
columns: app_data.get_width(),
|
||||
// container_section_height,
|
||||
container_title: app_data.get_container_title(),
|
||||
delete_confirm: gui_data.get_delete_container(),
|
||||
filter_by,
|
||||
filter_term: filter_term.cloned(),
|
||||
has_containers: app_data.get_container_len() > 0,
|
||||
has_error: app_data.get_error(),
|
||||
height,
|
||||
ports: app_data.get_selected_ports(),
|
||||
port_max_lens: app_data.get_longest_port(),
|
||||
show_logs: gui_data.get_show_logs(),
|
||||
info_text: gui_data.info_box_text.clone(),
|
||||
is_loading: gui_data.is_loading(),
|
||||
loading_icon: gui_data.get_loading().to_string(),
|
||||
log_height: gui_data.get_log_height(),
|
||||
log_title: app_data.get_log_title(),
|
||||
port_max_lens: app_data.get_longest_port(),
|
||||
ports: app_data.get_selected_ports(),
|
||||
selected_panel: gui_data.get_selected_panel(),
|
||||
sorted_by: app_data.get_sorted(),
|
||||
status: gui_data.get_status(),
|
||||
@@ -199,8 +200,8 @@ pub mod tests {
|
||||
app_data.containers_start();
|
||||
}
|
||||
|
||||
let redraw = Arc::new(Redraw::new());
|
||||
let gui_state = GuiState::new(&redraw);
|
||||
let redraw = Arc::new(Rerender::new());
|
||||
let gui_state = GuiState::new(&redraw, app_data.config.show_logs);
|
||||
|
||||
let app_data = Arc::new(Mutex::new(app_data));
|
||||
let gui_state = Arc::new(Mutex::new(gui_state));
|
||||
@@ -360,4 +361,65 @@ pub mod tests {
|
||||
|
||||
assert_snapshot!(setup.terminal.backend());
|
||||
}
|
||||
|
||||
#[test]
|
||||
/// Check that the whole layout is drawn correctly when the logs panel is removed
|
||||
fn test_draw_blocks_whole_layout_no_logs() {
|
||||
let mut setup = test_setup(160, 30, true, true);
|
||||
|
||||
insert_chart_data(&setup);
|
||||
insert_logs(&setup);
|
||||
setup.app_data.lock().containers.items[0]
|
||||
.ports
|
||||
.push(ContainerPorts {
|
||||
ip: Some(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1))),
|
||||
private: 8003,
|
||||
public: Some(8003),
|
||||
});
|
||||
let colors = setup.app_data.lock().config.app_colors;
|
||||
let keymap = setup.app_data.lock().config.keymap.clone();
|
||||
setup.gui_state.lock().log_height_zero();
|
||||
|
||||
let fd = FrameData::from((&setup.app_data, &setup.gui_state));
|
||||
setup
|
||||
.terminal
|
||||
.draw(|f| {
|
||||
draw_frame(&setup.app_data, colors, &keymap, f, &fd, &setup.gui_state);
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
assert_snapshot!(setup.terminal.backend());
|
||||
}
|
||||
|
||||
#[test]
|
||||
/// Check that the whole layout is drawn correctly when the logs panel height is ~4
|
||||
fn test_draw_blocks_whole_layout_short_height_logs() {
|
||||
let mut setup = test_setup(160, 30, true, true);
|
||||
|
||||
insert_chart_data(&setup);
|
||||
insert_logs(&setup);
|
||||
setup.app_data.lock().containers.items[0]
|
||||
.ports
|
||||
.push(ContainerPorts {
|
||||
ip: Some(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1))),
|
||||
private: 8003,
|
||||
public: Some(8003),
|
||||
});
|
||||
let colors = setup.app_data.lock().config.app_colors;
|
||||
let keymap = setup.app_data.lock().config.keymap.clone();
|
||||
setup.gui_state.lock().log_height_zero();
|
||||
|
||||
for _ in 0..=3 {
|
||||
setup.gui_state.lock().log_height_increase();
|
||||
}
|
||||
let fd = FrameData::from((&setup.app_data, &setup.gui_state));
|
||||
setup
|
||||
.terminal
|
||||
.draw(|f| {
|
||||
draw_frame(&setup.app_data, colors, &keymap, f, &fd, &setup.gui_state);
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
assert_snapshot!(setup.terminal.backend());
|
||||
}
|
||||
}
|
||||
|
||||
+3
@@ -1,5 +1,6 @@
|
||||
---
|
||||
source: src/ui/draw_blocks/help.rs
|
||||
assertion_line: 456
|
||||
expression: setup.terminal.backend()
|
||||
---
|
||||
" "
|
||||
@@ -26,6 +27,8 @@ expression: setup.terminal.backend()
|
||||
" │ ( F1 ) or ( / ) enter filter mode │ "
|
||||
" │ ( 0 ) stop sort │ "
|
||||
" │ ( 1 - 9 ) sort by header - or click header │ "
|
||||
" │ ( - = ) change log section height │ "
|
||||
" │ ( \ ) toggle log section visibility │ "
|
||||
" │ ( esc ) close dialog │ "
|
||||
" │ ( q ) quit at any time │ "
|
||||
" │ │ "
|
||||
|
||||
+2
@@ -26,6 +26,8 @@ expression: setup.terminal.backend()
|
||||
" │ ( F1 ) or ( / ) enter filter mode │ "
|
||||
" │ ( 0 ) stop sort │ "
|
||||
" │ ( 1 - 9 ) sort by header - or click header │ "
|
||||
" │ ( - = ) change log section height │ "
|
||||
" │ ( \ ) toggle log section visibility │ "
|
||||
" │ ( esc ) close dialog │ "
|
||||
" │ ( q ) quit at any time │ "
|
||||
" │ │ "
|
||||
|
||||
+3
-3
@@ -2,7 +2,6 @@
|
||||
source: src/ui/draw_blocks/help.rs
|
||||
expression: setup.terminal.backend()
|
||||
---
|
||||
" "
|
||||
" ╭ 0.00.000 ──────────────────────────────────────────────────────────────────────────────────╮ "
|
||||
" │ │ "
|
||||
" │ 88 │ "
|
||||
@@ -40,12 +39,13 @@ expression: setup.terminal.backend()
|
||||
" │ ( , ) sort containers by image │ "
|
||||
" │ ( . ) sort containers by rx │ "
|
||||
" │ ( Insert ) sort containers by tx │ "
|
||||
" │ ( z ) decrease log section height │ "
|
||||
" │ ( x ) increase log section height │ "
|
||||
" │ ( W ) toggle log section visibility │ "
|
||||
" │ ( a ) close dialog │ "
|
||||
" │ ( k ) quit at any time │ "
|
||||
" │ │ "
|
||||
" │ currently an early work in progress, all and any input appreciated │ "
|
||||
" │ https://github.com/mrjackwills/oxker │ "
|
||||
" │ │ "
|
||||
" │ │ "
|
||||
" ╰────────────────────────────────────────────────────────────────────────────────────────────╯ "
|
||||
" "
|
||||
|
||||
+3
-3
@@ -2,7 +2,6 @@
|
||||
source: src/ui/draw_blocks/help.rs
|
||||
expression: setup.terminal.backend()
|
||||
---
|
||||
" "
|
||||
" ╭ 0.00.000 ────────────────────────────────────────────────────────────────────────────────────────────────╮ "
|
||||
" │ │ "
|
||||
" │ 88 │ "
|
||||
@@ -40,12 +39,13 @@ expression: setup.terminal.backend()
|
||||
" │ ( , ) or ( \ ) sort containers by image │ "
|
||||
" │ ( . ) or ( ] ) sort containers by rx │ "
|
||||
" │ ( Insert ) or ( Back Tab ) sort containers by tx │ "
|
||||
" │ ( A ) or ( Z ) decrease log section height │ "
|
||||
" │ ( B ) or ( X ) increase log section height │ "
|
||||
" │ ( C ) or ( W ) toggle log section visibility │ "
|
||||
" │ ( a ) or ( b ) close dialog │ "
|
||||
" │ ( k ) or ( l ) quit at any time │ "
|
||||
" │ │ "
|
||||
" │ currently an early work in progress, all and any input appreciated │ "
|
||||
" │ https://github.com/mrjackwills/oxker │ "
|
||||
" │ │ "
|
||||
" │ │ "
|
||||
" ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────╯ "
|
||||
" "
|
||||
|
||||
+3
-3
@@ -2,7 +2,6 @@
|
||||
source: src/ui/draw_blocks/help.rs
|
||||
expression: setup.terminal.backend()
|
||||
---
|
||||
" "
|
||||
" ╭ 0.00.000 ────────────────────────────────────────────────────────────────────────────────────────────────╮ "
|
||||
" │ │ "
|
||||
" │ 88 │ "
|
||||
@@ -40,12 +39,13 @@ expression: setup.terminal.backend()
|
||||
" │ ( , ) sort containers by image │ "
|
||||
" │ ( . ) or ( ] ) sort containers by rx │ "
|
||||
" │ ( Insert ) sort containers by tx │ "
|
||||
" │ ( A ) or ( Z ) decrease log section height │ "
|
||||
" │ ( B ) or ( X ) increase log section height │ "
|
||||
" │ ( C ) or ( W ) toggle log section visibility │ "
|
||||
" │ ( a ) or ( b ) close dialog │ "
|
||||
" │ ( k ) quit at any time │ "
|
||||
" │ │ "
|
||||
" │ currently an early work in progress, all and any input appreciated │ "
|
||||
" │ https://github.com/mrjackwills/oxker │ "
|
||||
" │ │ "
|
||||
" │ │ "
|
||||
" ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────╯ "
|
||||
" "
|
||||
|
||||
+2
@@ -28,6 +28,8 @@ expression: setup.terminal.backend()
|
||||
" │ ( F1 ) or ( / ) enter filter mode │ "
|
||||
" │ ( 0 ) stop sort │ "
|
||||
" │ ( 1 - 9 ) sort by header - or click header │ "
|
||||
" │ ( - = ) change log section height │ "
|
||||
" │ ( \ ) toggle log section visibility │ "
|
||||
" │ ( esc ) close dialog │ "
|
||||
" │ ( q ) quit at any time │ "
|
||||
" │ │ "
|
||||
|
||||
+5
-5
@@ -8,8 +8,6 @@ expression: setup.terminal.backend()
|
||||
"│ container_2 ✓ running Up 2 hour 00.00% 0.00 kB / 0.00 kB 2 image_2 0.00 kB 0.00 kB ││ restart │"
|
||||
"│ container_3 ✓ running Up 3 hour 00.00% 0.00 kB / 0.00 kB 3 image_3 0.00 kB 0.00 kB ││ stop │"
|
||||
"│ ││ delete │"
|
||||
"│ ││ │"
|
||||
"│ ││ │"
|
||||
"╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯╰──────────────╯"
|
||||
"╭ Logs 3/3 - container_1 - image_1 ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮"
|
||||
"│ line 1 │"
|
||||
@@ -25,10 +23,12 @@ expression: setup.terminal.backend()
|
||||
"│ │"
|
||||
"│ │"
|
||||
"│ │"
|
||||
"│ │"
|
||||
"╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯"
|
||||
"╭───────────────────────── cpu 03.00% ──────────────────────────╮╭─────────────────────── memory 30.00 kB ───────────────────────╮╭────────── ports ───────────╮"
|
||||
"│10.00%│ •••• ││100.00 kB│ ••• ││ ip private public│"
|
||||
"│ │ ••• • ││ │ ••• • ││ 8001 │"
|
||||
"│ │•• ••• ││ │•• ••• ││127.0.0.1 8003 8003│"
|
||||
"│10.00%│ ••• ││100.00 kB│ •• ││ ip private public│"
|
||||
"│ │ •• • ││ │ •• • ││ 8001 │"
|
||||
"│ │ ••• • • ││ │ ••• • • ││127.0.0.1 8003 8003│"
|
||||
"│ │• •• ││ │• •• ││ │"
|
||||
"│ │ ││ │ ││ │"
|
||||
"╰───────────────────────────────────────────────────────────────╯╰───────────────────────────────────────────────────────────────╯╰────────────────────────────╯"
|
||||
|
||||
+5
-5
@@ -8,8 +8,6 @@ expression: setup.terminal.backend()
|
||||
"│ container_2 ✓ running Up 2 hour 00.00% 0.00 kB / 0.00 kB 2 image_2 0.00 kB 0.00 kB ││ restart │"
|
||||
"│ container_3 ✓ running Up 3 hour 00.00% 0.00 kB / 0.00 kB 3 image_3 0.00 kB 0.00 kB ││ stop │"
|
||||
"│ ││ delete │"
|
||||
"│ ││ │"
|
||||
"│ ││ │"
|
||||
"╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯╰─────────────────╯"
|
||||
"╭ Logs 3/3 - a_long_container_name_for_the_purposes_of_this_test - a_long_image_name_for_the_purposes_of_this_test ──────────────────────────────────────────────────────────────────────────╮"
|
||||
"│ line 1 │"
|
||||
@@ -25,10 +23,12 @@ expression: setup.terminal.backend()
|
||||
"│ │"
|
||||
"│ │"
|
||||
"│ │"
|
||||
"│ │"
|
||||
"╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯"
|
||||
"╭───────────────────────────────── cpu 03.00% ─────────────────────────────────╮╭────────────────────────────── memory 30.00 kB ───────────────────────────────╮╭────────── ports ───────────╮"
|
||||
"│10.00%│ •••• ││100.00 kB│ ••••• ││ ip private public│"
|
||||
"│ │ •••• • ││ │ ••• • ││ 8001 │"
|
||||
"│ │••• •••• ││ │••• ••• ││127.0.0.1 8003 8003│"
|
||||
"│10.00%│ ••• ││100.00 kB│ •••• ││ ip private public│"
|
||||
"│ │ ••• • ││ │ •• • ││ 8001 │"
|
||||
"│ │ ••• • • ││ │ ••• • • ││127.0.0.1 8003 8003│"
|
||||
"│ │•• ••• ││ │•• •• ││ │"
|
||||
"│ │ ││ │ ││ │"
|
||||
"╰──────────────────────────────────────────────────────────────────────────────╯╰──────────────────────────────────────────────────────────────────────────────╯╰────────────────────────────╯"
|
||||
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
---
|
||||
source: src/ui/draw_blocks/mod.rs
|
||||
expression: setup.terminal.backend()
|
||||
---
|
||||
" name state status cpu memory/limit id image ↓ rx ↑ tx ( h ) show help "
|
||||
"╭ Containers 1/3 ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮╭──────────────╮"
|
||||
"│⚪ container_1 ✓ running Up 1 hour 03.00% 30.00 kB / 30.00 kB 1 image_1 0.00 kB 0.00 kB ││▶ pause │" Hidden by multi-width symbols: [(2, " ")]
|
||||
"│ container_2 ✓ running Up 2 hour 00.00% 0.00 kB / 0.00 kB 2 image_2 0.00 kB 0.00 kB ││ restart │"
|
||||
"│ container_3 ✓ running Up 3 hour 00.00% 0.00 kB / 0.00 kB 3 image_3 0.00 kB 0.00 kB ││ stop │"
|
||||
"│ ││ delete │"
|
||||
"│ ││ │"
|
||||
"│ ││ │"
|
||||
"│ ││ │"
|
||||
"│ ││ │"
|
||||
"│ ││ │"
|
||||
"│ ││ │"
|
||||
"│ ││ │"
|
||||
"│ ││ │"
|
||||
"│ ││ │"
|
||||
"│ ││ │"
|
||||
"│ ││ │"
|
||||
"│ ││ │"
|
||||
"│ ││ │"
|
||||
"│ ││ │"
|
||||
"│ ││ │"
|
||||
"│ ││ │"
|
||||
"╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯╰──────────────╯"
|
||||
"╭───────────────────────── cpu 03.00% ──────────────────────────╮╭─────────────────────── memory 30.00 kB ───────────────────────╮╭────────── ports ───────────╮"
|
||||
"│10.00%│ ••• ││100.00 kB│ •• ││ ip private public│"
|
||||
"│ │ •• • ││ │ •• • ││ 8001 │"
|
||||
"│ │ ••• • • ││ │ ••• • • ││127.0.0.1 8003 8003│"
|
||||
"│ │• •• ││ │• •• ││ │"
|
||||
"│ │ ││ │ ││ │"
|
||||
"╰───────────────────────────────────────────────────────────────╯╰───────────────────────────────────────────────────────────────╯╰────────────────────────────╯"
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
---
|
||||
source: src/ui/draw_blocks/mod.rs
|
||||
expression: setup.terminal.backend()
|
||||
---
|
||||
" name state status cpu memory/limit id image ↓ rx ↑ tx ( h ) show help "
|
||||
"╭ Containers 1/3 ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮╭──────────────╮"
|
||||
"│⚪ container_1 ✓ running Up 1 hour 03.00% 30.00 kB / 30.00 kB 1 image_1 0.00 kB 0.00 kB ││▶ pause │" Hidden by multi-width symbols: [(2, " ")]
|
||||
"│ container_2 ✓ running Up 2 hour 00.00% 0.00 kB / 0.00 kB 2 image_2 0.00 kB 0.00 kB ││ restart │"
|
||||
"│ container_3 ✓ running Up 3 hour 00.00% 0.00 kB / 0.00 kB 3 image_3 0.00 kB 0.00 kB ││ stop │"
|
||||
"│ ││ delete │"
|
||||
"│ ││ │"
|
||||
"│ ││ │"
|
||||
"│ ││ │"
|
||||
"│ ││ │"
|
||||
"│ ││ │"
|
||||
"│ ││ │"
|
||||
"│ ││ │"
|
||||
"│ ││ │"
|
||||
"│ ││ │"
|
||||
"│ ││ │"
|
||||
"│ ││ │"
|
||||
"│ ││ │"
|
||||
"╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯╰──────────────╯"
|
||||
"╭ Logs 3/3 - container_1 - image_1 ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮"
|
||||
"│ line 2 │"
|
||||
"│▶ line 3 │"
|
||||
"╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯"
|
||||
"╭───────────────────────── cpu 03.00% ──────────────────────────╮╭─────────────────────── memory 30.00 kB ───────────────────────╮╭────────── ports ───────────╮"
|
||||
"│10.00%│ ••• ││100.00 kB│ •• ││ ip private public│"
|
||||
"│ │ •• • ││ │ •• • ││ 8001 │"
|
||||
"│ │ ••• • • ││ │ ••• • • ││127.0.0.1 8003 8003│"
|
||||
"│ │• •• ││ │• •• ││ │"
|
||||
"│ │ ││ │ ││ │"
|
||||
"╰───────────────────────────────────────────────────────────────╯╰───────────────────────────────────────────────────────────────╯╰────────────────────────────╯"
|
||||
+82
-18
@@ -9,11 +9,11 @@ use tokio::task::JoinHandle;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::{
|
||||
app_data::{ContainerId, Header},
|
||||
app_data::{AppData, ContainerId, Header},
|
||||
exec::ExecMode,
|
||||
};
|
||||
|
||||
use super::Redraw;
|
||||
use super::Rerender;
|
||||
|
||||
#[derive(Debug, Default, Clone, Copy, Eq, Hash, PartialEq)]
|
||||
pub enum SelectablePanel {
|
||||
@@ -184,13 +184,15 @@ pub struct GuiState {
|
||||
loading_handle: Option<JoinHandle<()>>,
|
||||
loading_index: u8,
|
||||
loading_set: HashSet<Uuid>,
|
||||
redraw: Arc<Redraw>,
|
||||
log_height: u16,
|
||||
rerender: Arc<Rerender>,
|
||||
selected_panel: SelectablePanel,
|
||||
show_logs: bool,
|
||||
status: HashSet<Status>,
|
||||
pub info_box_text: Option<(String, Instant)>,
|
||||
}
|
||||
impl GuiState {
|
||||
pub fn new(redraw: &Arc<Redraw>) -> Self {
|
||||
pub fn new(redraw: &Arc<Rerender>, show_logs: bool) -> Self {
|
||||
Self {
|
||||
delete_container: None,
|
||||
exec_mode: None,
|
||||
@@ -202,11 +204,61 @@ impl GuiState {
|
||||
loading_handle: None,
|
||||
loading_index: 0,
|
||||
loading_set: HashSet::new(),
|
||||
redraw: Arc::clone(redraw),
|
||||
log_height: 75,
|
||||
rerender: Arc::clone(redraw),
|
||||
selected_panel: SelectablePanel::default(),
|
||||
show_logs,
|
||||
status: HashSet::new(),
|
||||
}
|
||||
}
|
||||
/// Increase the height of the log panel, then rerender
|
||||
pub fn log_height_increase(&mut self) {
|
||||
if self.show_logs {
|
||||
if self.log_height <= 75 {
|
||||
self.log_height = self.log_height.saturating_add(5);
|
||||
}
|
||||
} else {
|
||||
self.log_height = 5;
|
||||
}
|
||||
self.show_logs = true;
|
||||
self.rerender.update();
|
||||
}
|
||||
|
||||
/// Reduce the height of the logs panel, then rerender
|
||||
/// Unselect logs panel if currently selected
|
||||
pub fn log_height_decrease(&mut self) {
|
||||
if self.show_logs {
|
||||
self.log_height = self.log_height.saturating_sub(5);
|
||||
if self.log_height == 0 && self.selected_panel == SelectablePanel::Logs {
|
||||
self.show_logs = false;
|
||||
self.selected_panel = SelectablePanel::Containers;
|
||||
}
|
||||
self.rerender.update();
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn get_show_logs(&self) -> bool {
|
||||
self.show_logs
|
||||
}
|
||||
|
||||
pub fn toggle_show_logs(&mut self) {
|
||||
self.show_logs = !self.show_logs;
|
||||
if !self.show_logs && self.selected_panel == SelectablePanel::Logs {
|
||||
self.selected_panel = SelectablePanel::Containers;
|
||||
}
|
||||
self.rerender.update();
|
||||
}
|
||||
|
||||
/// Set the log_height to zero, used if show_logs=false in the config file
|
||||
pub const fn log_height_zero(&mut self) {
|
||||
self.log_height = 0;
|
||||
}
|
||||
|
||||
/// Get the log height, *should* be a u8 between 0 and 80, essentially a percentage
|
||||
pub const fn get_log_height(&self) -> u16 {
|
||||
self.log_height
|
||||
}
|
||||
|
||||
/// Clear panels hash map, so on resize can fix the sizes for mouse clicks
|
||||
pub fn clear_area_map(&mut self) {
|
||||
self.intersect_panel.clear();
|
||||
@@ -227,7 +279,7 @@ impl GuiState {
|
||||
.first()
|
||||
{
|
||||
self.selected_panel = *data.0;
|
||||
self.redraw.set_true();
|
||||
self.rerender.update();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -300,7 +352,7 @@ impl GuiState {
|
||||
self.status_del(Status::DeleteConfirm);
|
||||
}
|
||||
self.delete_container = id;
|
||||
self.redraw.set_true();
|
||||
self.rerender.update();
|
||||
}
|
||||
|
||||
/// Return a copy of the Status HashSet
|
||||
@@ -321,7 +373,7 @@ impl GuiState {
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
self.redraw.set_true();
|
||||
self.rerender.update();
|
||||
}
|
||||
|
||||
/// Inset the ExecMode into self, and set the Status as exec
|
||||
@@ -330,7 +382,7 @@ impl GuiState {
|
||||
pub fn set_exec_mode(&mut self, mode: ExecMode) {
|
||||
self.exec_mode = Some(mode);
|
||||
self.status.insert(Status::Exec);
|
||||
self.redraw.set_true();
|
||||
self.rerender.update();
|
||||
}
|
||||
|
||||
pub fn get_exec_mode(&self) -> Option<ExecMode> {
|
||||
@@ -342,20 +394,32 @@ impl GuiState {
|
||||
pub fn status_push(&mut self, status: Status) {
|
||||
if status != Status::Exec {
|
||||
self.status.insert(status);
|
||||
self.redraw.set_true();
|
||||
self.rerender.update();
|
||||
}
|
||||
}
|
||||
|
||||
/// Change to next selectable panel
|
||||
pub fn next_panel(&mut self) {
|
||||
pub fn selectable_panel_next(&mut self, app_data: &Arc<Mutex<AppData>>) {
|
||||
self.selected_panel = self.selected_panel.next();
|
||||
self.redraw.set_true();
|
||||
if (app_data.lock().get_container_len() == 0
|
||||
&& self.get_selected_panel() == SelectablePanel::Commands)
|
||||
|| (self.log_height == 0 && self.get_selected_panel() == SelectablePanel::Logs)
|
||||
{
|
||||
self.selected_panel = self.selected_panel.next();
|
||||
}
|
||||
self.rerender.update();
|
||||
}
|
||||
|
||||
/// Change to previous selectable panel
|
||||
pub fn previous_panel(&mut self) {
|
||||
pub fn selectable_panel_previous(&mut self, app_data: &Arc<Mutex<AppData>>) {
|
||||
self.selected_panel = self.selected_panel.prev();
|
||||
self.redraw.set_true();
|
||||
if (app_data.lock().get_container_len() == 0
|
||||
&& self.get_selected_panel() == SelectablePanel::Commands)
|
||||
|| (self.log_height == 0 && self.get_selected_panel() == SelectablePanel::Logs)
|
||||
{
|
||||
self.selected_panel = self.selected_panel.prev();
|
||||
}
|
||||
self.rerender.update();
|
||||
}
|
||||
|
||||
/// Insert a new loading_uuid into HashSet, and advance the loading_index by one frame, or reset to 0 if at end of array
|
||||
@@ -366,7 +430,7 @@ impl GuiState {
|
||||
self.loading_index += 1;
|
||||
}
|
||||
self.loading_set.insert(uuid);
|
||||
self.redraw.set_true();
|
||||
self.rerender.update();
|
||||
}
|
||||
|
||||
pub fn is_loading(&self) -> bool {
|
||||
@@ -399,7 +463,7 @@ impl GuiState {
|
||||
/// Stop the loading_spin function, and reset gui loading status
|
||||
pub fn stop_loading_animation(&mut self, loading_uuid: Uuid) {
|
||||
self.loading_set.remove(&loading_uuid);
|
||||
self.redraw.set_true();
|
||||
self.rerender.update();
|
||||
if self.loading_set.is_empty() {
|
||||
self.loading_index = 0;
|
||||
if let Some(h) = &self.loading_handle {
|
||||
@@ -412,12 +476,12 @@ impl GuiState {
|
||||
/// Set info box content
|
||||
pub fn set_info_box(&mut self, text: &str) {
|
||||
self.info_box_text = Some((text.to_owned(), std::time::Instant::now()));
|
||||
self.redraw.set_true();
|
||||
self.rerender.update();
|
||||
}
|
||||
|
||||
/// Remove info box content
|
||||
pub fn reset_info_box(&mut self) {
|
||||
self.info_box_text = None;
|
||||
self.redraw.set_true();
|
||||
self.rerender.update();
|
||||
}
|
||||
}
|
||||
|
||||
+72
-39
@@ -24,7 +24,7 @@ mod color_match;
|
||||
mod draw_blocks;
|
||||
mod gui_state;
|
||||
mod redraw;
|
||||
pub use redraw::Redraw;
|
||||
pub use redraw::Rerender;
|
||||
|
||||
pub use self::color_match::*;
|
||||
pub use self::gui_state::{DeleteButton, GuiState, SelectablePanel, Status};
|
||||
@@ -50,7 +50,7 @@ pub struct Ui {
|
||||
input_tx: Sender<InputMessages>,
|
||||
is_running: Arc<AtomicBool>,
|
||||
now: Instant,
|
||||
redraw: Arc<Redraw>,
|
||||
redraw: Arc<Rerender>,
|
||||
terminal: Terminal<CrosstermBackend<Stdout>>,
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ impl Ui {
|
||||
gui_state: Arc<Mutex<GuiState>>,
|
||||
input_tx: Sender<InputMessages>,
|
||||
is_running: Arc<AtomicBool>,
|
||||
redraw: Arc<Redraw>,
|
||||
redraw: Arc<Rerender>,
|
||||
) {
|
||||
match Self::setup_terminal() {
|
||||
Ok(mut terminal) => {
|
||||
@@ -205,6 +205,10 @@ impl Ui {
|
||||
let docker_interval_ms = u128::from(self.app_data.lock().config.docker_interval_ms);
|
||||
let mut drawn_at = std::time::Instant::now();
|
||||
|
||||
if !self.app_data.lock().config.show_logs {
|
||||
self.gui_state.lock().log_height_zero();
|
||||
}
|
||||
|
||||
while self.is_running.load(Ordering::SeqCst) {
|
||||
if self.should_redraw(&mut drawn_at, docker_interval_ms) {
|
||||
let fd = FrameData::from(&*self);
|
||||
@@ -245,6 +249,8 @@ impl Ui {
|
||||
}
|
||||
} else if let Event::Resize(_, _) = event {
|
||||
self.gui_state.lock().clear_area_map();
|
||||
// self.gui_state.lock().set_window_height(row);
|
||||
|
||||
self.terminal.autoresize().ok();
|
||||
}
|
||||
}
|
||||
@@ -267,6 +273,7 @@ impl Ui {
|
||||
|
||||
/// Frequent data required by multiple frame drawing functions, can reduce mutex reads by placing it all in here
|
||||
#[derive(Debug, Clone)]
|
||||
#[allow(clippy::struct_excessive_bools)]
|
||||
pub struct FrameData {
|
||||
chart_data: Option<(CpuTuple, MemTuple)>,
|
||||
color_logs: bool,
|
||||
@@ -276,8 +283,10 @@ pub struct FrameData {
|
||||
filter_by: FilterBy,
|
||||
filter_term: Option<String>,
|
||||
has_containers: bool,
|
||||
// container_section_height: u16,
|
||||
log_height: u16,
|
||||
show_logs: bool,
|
||||
has_error: Option<AppError>,
|
||||
height: u16,
|
||||
info_text: Option<(String, Instant)>,
|
||||
is_loading: bool,
|
||||
loading_icon: String,
|
||||
@@ -293,29 +302,36 @@ impl From<&Ui> for FrameData {
|
||||
fn from(ui: &Ui) -> Self {
|
||||
let (app_data, gui_data) = (ui.app_data.lock(), ui.gui_state.lock());
|
||||
|
||||
// set a flag if the - or = button has been pressed, and if so use that calc, else use this calc
|
||||
// set max height for container section, needs +5 to deal with docker commands list and borders
|
||||
let height = app_data.get_container_len();
|
||||
let height = if height < 12 {
|
||||
u16::try_from(height + 5).unwrap_or_default()
|
||||
} else {
|
||||
12
|
||||
};
|
||||
// TODO fix this
|
||||
// let container_len = app_data.get_container_len();
|
||||
// let container_section_height = if container_len < 12 {
|
||||
// // u16::try_from(container_len + 5).unwrap_or_default()
|
||||
// 8
|
||||
// } else {
|
||||
// 12
|
||||
// };
|
||||
// TODO work out what to do with this
|
||||
// container_section_height = 8;
|
||||
|
||||
let (filter_by, filter_term) = app_data.get_filter();
|
||||
Self {
|
||||
chart_data: app_data.get_chart_data(),
|
||||
color_logs: app_data.config.color_logs,
|
||||
columns: app_data.get_width(),
|
||||
// container_section_height,
|
||||
container_title: app_data.get_container_title(),
|
||||
delete_confirm: gui_data.get_delete_container(),
|
||||
filter_by,
|
||||
filter_term: filter_term.cloned(),
|
||||
has_containers: app_data.get_container_len() > 0,
|
||||
has_error: app_data.get_error(),
|
||||
height,
|
||||
info_text: gui_data.info_box_text.clone(),
|
||||
is_loading: gui_data.is_loading(),
|
||||
show_logs: gui_data.get_show_logs(),
|
||||
loading_icon: gui_data.get_loading().to_string(),
|
||||
log_height: gui_data.get_log_height(),
|
||||
log_title: app_data.get_log_title(),
|
||||
port_max_lens: app_data.get_longest_port(),
|
||||
ports: app_data.get_selected_ports(),
|
||||
@@ -346,44 +362,61 @@ fn draw_frame(
|
||||
.constraints(whole_constraints)
|
||||
.split(f.area());
|
||||
|
||||
// Split into 3, containers+controls, logs, then graphs
|
||||
draw_blocks::headers::draw(whole_layout[0], colors, f, fd, gui_state, keymap);
|
||||
|
||||
// If required, draw filter bar
|
||||
if let Some(rect) = whole_layout.get(2) {
|
||||
draw_blocks::filter::draw(*rect, colors, f, fd);
|
||||
}
|
||||
|
||||
// What we should do is work out the container+logs size, and then set the percentage to height - 6
|
||||
|
||||
let container_logs_section_constraints = if fd.show_logs {
|
||||
vec![Constraint::Min(6), Constraint::Percentage(fd.log_height)]
|
||||
} else {
|
||||
vec![Constraint::Percentage(100)]
|
||||
};
|
||||
|
||||
let upper_main_constraints = if fd.has_containers {
|
||||
vec![Constraint::Percentage(75), Constraint::Percentage(25)]
|
||||
} else {
|
||||
vec![Constraint::Percentage(100), Constraint::Percentage(0)]
|
||||
};
|
||||
let upper_main = Layout::default()
|
||||
.direction(Direction::Vertical)
|
||||
.constraints([Constraint::Max(fd.height), Constraint::Min(1)].as_ref())
|
||||
.constraints(upper_main_constraints)
|
||||
.split(whole_layout[1]);
|
||||
|
||||
let top_split = if fd.has_containers {
|
||||
let containers_logs_section = Layout::default()
|
||||
.direction(Direction::Vertical)
|
||||
.constraints(container_logs_section_constraints)
|
||||
.split(upper_main[0]);
|
||||
|
||||
// Containers & Command Horizontal split
|
||||
let container_command_constraints = if fd.has_containers {
|
||||
vec![Constraint::Percentage(90), Constraint::Percentage(10)]
|
||||
} else {
|
||||
vec![Constraint::Percentage(100)]
|
||||
};
|
||||
|
||||
// Containers + docker commands
|
||||
let top_panel = Layout::default()
|
||||
let containers_commands = Layout::default()
|
||||
.direction(Direction::Horizontal)
|
||||
.constraints(top_split)
|
||||
.split(upper_main[0]);
|
||||
.constraints(container_command_constraints)
|
||||
.split(containers_logs_section[0]);
|
||||
|
||||
let lower_split = if fd.has_containers {
|
||||
vec![Constraint::Percentage(70), Constraint::Percentage(30)]
|
||||
} else {
|
||||
vec![Constraint::Percentage(100)]
|
||||
};
|
||||
draw_blocks::containers::draw(app_data, containers_commands[0], colors, f, fd, gui_state);
|
||||
|
||||
// Split into 2, logs and charts
|
||||
let lower_main = Layout::default()
|
||||
.direction(Direction::Vertical)
|
||||
.constraints(lower_split)
|
||||
.split(upper_main[1]);
|
||||
|
||||
draw_blocks::containers::draw(app_data, top_panel[0], colors, f, fd, gui_state);
|
||||
|
||||
draw_blocks::logs::draw(app_data, lower_main[0], colors, f, fd, gui_state);
|
||||
|
||||
draw_blocks::headers::draw(whole_layout[0], colors, f, fd, gui_state, keymap);
|
||||
|
||||
// Draw filter bar
|
||||
if let Some(rect) = whole_layout.get(2) {
|
||||
draw_blocks::filter::draw(*rect, colors, f, fd);
|
||||
// TODO redraw logs
|
||||
if fd.show_logs {
|
||||
draw_blocks::logs::draw(
|
||||
app_data,
|
||||
containers_logs_section[1],
|
||||
colors,
|
||||
f,
|
||||
fd,
|
||||
gui_state,
|
||||
);
|
||||
}
|
||||
|
||||
if let Some(id) = fd.delete_confirm.as_ref() {
|
||||
@@ -400,7 +433,7 @@ fn draw_frame(
|
||||
}
|
||||
|
||||
// only draw commands + charts if there are containers
|
||||
if let Some(rect) = top_panel.get(1) {
|
||||
if let Some(rect) = containers_commands.get(1) {
|
||||
draw_blocks::commands::draw(app_data, *rect, colors, f, fd, gui_state);
|
||||
|
||||
// Can calculate the max string length here, and then use that to keep the ports section as small as possible (+4 for some padding + border)
|
||||
@@ -411,7 +444,7 @@ fn draw_frame(
|
||||
let lower = Layout::default()
|
||||
.direction(Direction::Horizontal)
|
||||
.constraints([Constraint::Min(1), Constraint::Max(ports_len)])
|
||||
.split(lower_main[1]);
|
||||
.split(upper_main[1]);
|
||||
|
||||
draw_blocks::charts::draw(lower[0], colors, f, fd);
|
||||
draw_blocks::ports::draw(lower[1], colors, f, fd);
|
||||
|
||||
+3
-3
@@ -1,14 +1,14 @@
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Redraw(AtomicBool);
|
||||
pub struct Rerender(AtomicBool);
|
||||
|
||||
impl Redraw {
|
||||
impl Rerender {
|
||||
pub const fn new() -> Self {
|
||||
Self(AtomicBool::new(true))
|
||||
}
|
||||
|
||||
pub fn set_true(&self) {
|
||||
pub fn update(&self) {
|
||||
self.0.store(true, Ordering::SeqCst);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user