From b10f927481c9e38a48c1d4b94e744ec48e8b6ba6 Mon Sep 17 00:00:00 2001 From: Jack Wills <32690432+mrjackwills@users.noreply.github.com> Date: Fri, 29 Apr 2022 01:03:06 +0000 Subject: [PATCH] feat: show id column --- src/app_data/container_state.rs | 16 ++++---- src/input_handler/mod.rs | 21 +++++++--- src/ui/draw_blocks.rs | 71 +++++++++++++++++++++++---------- src/ui/gui_state.rs | 15 +++++-- src/ui/mod.rs | 6 +-- 5 files changed, 87 insertions(+), 42 deletions(-) diff --git a/src/app_data/container_state.rs b/src/app_data/container_state.rs index 0c0243c..3852e4c 100644 --- a/src/app_data/container_state.rs +++ b/src/app_data/container_state.rs @@ -398,12 +398,13 @@ impl ContainerItem { /// Container information panel headings + widths, for nice pretty formatting #[derive(Debug)] pub struct Columns { - pub cpu: (String, usize), - pub image: (String, usize), - pub name: (String, usize), pub state: (String, usize), pub status: (String, usize), + pub cpu: (String, usize), pub mem: (String, usize), + pub id: (String, usize), + pub name: (String, usize), + pub image: (String, usize), pub net_rx: (String, usize), pub net_tx: (String, usize), } @@ -411,13 +412,14 @@ pub struct Columns { impl Columns { pub fn new() -> Self { Self { - // 7 to allow for 100.00% - cpu: (String::from("cpu"), 7), - image: (String::from("image"), 5), - name: (String::from("name"), 4), state: (String::from("state"), 11), status: (String::from("status"), 16), + // 7 to allow for "100.00%" + cpu: (String::from("cpu"), 7), mem: (String::from("memory/limit"), 12), + id: (String::from("id"), 8), + name: (String::from("name"), 4), + image: (String::from("image"), 5), net_rx: (String::from("↓ rx"), 5), net_tx: (String::from("↑ tx"), 5), } diff --git a/src/input_handler/mod.rs b/src/input_handler/mod.rs index 610c0f5..68728b8 100644 --- a/src/input_handler/mod.rs +++ b/src/input_handler/mod.rs @@ -11,7 +11,7 @@ use crossterm::{ execute, }; use parking_lot::Mutex; -use tokio::sync::broadcast::Receiver; +use tokio::{sync::broadcast::Receiver, task::JoinHandle}; use tui::layout::Rect; mod message; @@ -31,6 +31,7 @@ pub struct InputHandler { is_running: Arc, rec: Receiver, mouse_capture: bool, + info_sleep: Option>, } impl InputHandler { @@ -49,6 +50,7 @@ impl InputHandler { is_running, rec, mouse_capture: true, + info_sleep: None, }; inner.start().await; } @@ -112,7 +114,7 @@ impl InputHandler { Ok(_) => self .gui_state .lock() - .set_info_box("Mouse capture disabled".to_owned()), + .set_info_box("✖ mouse capture disabled".to_owned()), Err(_) => self .app_data .lock() @@ -123,12 +125,21 @@ impl InputHandler { Ok(_) => self .gui_state .lock() - .set_info_box("Mouse capture enabled".to_owned()), + .set_info_box("✓ mouse capture enabled".to_owned()), Err(_) => self.app_data.lock().set_error(AppError::MouseCapture(true)), } - todo!("tokio spawn for x seconds and then reset, probably need to take in an arc clone for self.gui_state") - // execute!(stdout, EnableMouseCapture).unwrap(); }; + + let gui_state = Arc::clone(&self.gui_state); + + if self.info_sleep.is_some() { + self.info_sleep.as_ref().unwrap().abort() + } + self.info_sleep = Some(tokio::spawn(async move { + tokio::time::sleep(std::time::Duration::from_millis(4000)).await; + gui_state.lock().reset_info_box() + })); + self.mouse_capture = !self.mouse_capture; } KeyCode::Tab => self.gui_state.lock().next_panel(), diff --git a/src/ui/draw_blocks.rs b/src/ui/draw_blocks.rs index 28830b0..1a0b2bb 100644 --- a/src/ui/draw_blocks.rs +++ b/src/ui/draw_blocks.rs @@ -45,7 +45,7 @@ fn generate_block<'a>( app_data: &Arc>, selected_panel: &SelectablePanel, ) -> Block<'a> { - let mut block = Block::default().borders(Borders::ALL); + let mut block = Block::default().borders(Borders::ALL).border_type(BorderType::Rounded); if let Some(panel) = selectable_panel { let title = match panel { @@ -63,11 +63,12 @@ fn generate_block<'a>( }; block = block.title(title); if selected_panel == &panel { - let selected_style = Style::default().fg(Color::LightCyan); - let selected_border = BorderType::Plain; + // let selected_style = Style::default().fg(Color::LightCyan); + // let selected_border = BorderType::Plain; + // let selected_border = BorderType::Rounded; block = block - .border_style(selected_style) - .border_type(selected_border); + .border_style(Style::default().fg(Color::LightCyan)); + // .border_type(BorderType::Rounded); } } block @@ -170,6 +171,10 @@ pub fn draw_containers( Span::styled( format!("{}{:>width$}", MARGIN, mems, width = widths.mem.1), state_style, + ), + Span::styled( + format!("{}{:>width$}", MARGIN, i.id.chars().take(8).collect::(), width = widths.id.1), + blue, ), Span::styled( format!("{}{:>width$}", MARGIN, i.name, width = widths.name.1), @@ -331,7 +336,8 @@ fn make_chart( .add_modifier(Modifier::BOLD), )) .borders(Borders::ALL) - .border_type(BorderType::Plain), + // .border_type(BorderType::Plain), + .border_type(BorderType::Rounded), ) .x_axis( Axis::default() @@ -355,7 +361,7 @@ fn make_chart( } /// Show error popup over whole screen -pub fn draw_info_bar( +pub fn draw_heading_bar( area: Rect, columns: &Columns, f: &mut Frame<'_, B>, @@ -380,6 +386,15 @@ pub fn draw_info_bar( .push_str(format!("{}{:>width$}", MARGIN, columns.cpu.0, width = columns.cpu.1).as_str()); column_headings .push_str(format!("{}{:>width$}", MARGIN, columns.mem.0, width = columns.mem.1).as_str()); + column_headings.push_str( + format!( + "{}{:>width$}", + MARGIN, + columns.id.0, + width = columns.id.1 + ) + .as_str(), + ); column_headings.push_str( format!( "{}{:>width$}", @@ -498,7 +513,12 @@ pub fn draw_help_box(f: &mut Frame<'_, B>) { .border_type(BorderType::Rounded) .border_style(Style::default().fg(Color::Black)); - let area = draw_popup(lines as u16, max_line_width as u16, f.size(), BoxLocation::MiddleCentre); + let area = draw_popup( + lines as u16, + max_line_width as u16, + f.size(), + BoxLocation::MiddleCentre, + ); let split_popup = Layout::default() .direction(Direction::Vertical) @@ -561,7 +581,12 @@ pub fn draw_error(f: &mut Frame<'_, B>, error: AppError, seconds: Op .block(block) .alignment(Alignment::Center); - let area = draw_popup(lines as u16, max_line_width as u16, f.size(), BoxLocation::MiddleCentre); + let area = draw_popup( + lines as u16, + max_line_width as u16, + f.size(), + BoxLocation::MiddleCentre, + ); f.render_widget(Clear, area); f.render_widget(paragraph, area); } @@ -573,7 +598,7 @@ pub fn draw_info(f: &mut Frame<'_, B>, text: String) { .title_alignment(Alignment::Center) .borders(Borders::NONE); - // Add a blank line, so that the text is verticall centered + // Add a blank line, so that the text is verticall centered let text = format!("\n{}", text); let mut max_line_width = 0; @@ -595,33 +620,35 @@ pub fn draw_info(f: &mut Frame<'_, B>, text: String) { .block(block) .alignment(Alignment::Center); - let area = draw_popup(lines as u16, max_line_width as u16, f.size(), BoxLocation::BottomRight); + let area = draw_popup( + lines as u16, + max_line_width as u16, + f.size(), + BoxLocation::BottomRight, + ); f.render_widget(Clear, area); f.render_widget(paragraph, area); } /// draw a box in the center of the screen, based on max line width + number of lines -fn draw_popup(text_lines: u16, text_width: u16, r: Rect, box_location:BoxLocation) -> Rect { +fn draw_popup(text_lines: u16, text_width: u16, r: Rect, box_location: BoxLocation) -> Rect { // This can panic if number_lines or max_line_width is larger than r.height or r.width let blank_vertical = (r.height - text_lines) / 2; let blank_horizontal = (r.width - text_width) / 2; - let vertical_constraints = box_location.get_vertical_constraints(blank_vertical, text_lines); - let horizontal_constraints = box_location.get_horizontal_constraints(blank_horizontal, text_width); + let vertical_constraints = box_location.get_vertical_constraints(blank_vertical, text_lines); + let horizontal_constraints = + box_location.get_horizontal_constraints(blank_horizontal, text_width); - let indexes = box_location.get_indexes(); + let indexes = box_location.get_indexes(); let popup_layout = Layout::default() .direction(Direction::Vertical) - .constraints( - vertical_constraints - ) + .constraints(vertical_constraints) .split(r); Layout::default() .direction(Direction::Horizontal) - .constraints( - horizontal_constraints - ) + .constraints(horizontal_constraints) .split(popup_layout[indexes.0])[indexes.1] -} \ No newline at end of file +} diff --git a/src/ui/gui_state.rs b/src/ui/gui_state.rs index 7ee205e..72ef238 100644 --- a/src/ui/gui_state.rs +++ b/src/ui/gui_state.rs @@ -36,8 +36,12 @@ impl BoxLocation { } } - // Should combine and just return a tupple? - pub fn get_horizontal_constraints(&self, blank_vertical: u16, text_width: u16) -> [Constraint; 3] { + // Should combine and just return a tupple? + pub fn get_horizontal_constraints( + &self, + blank_vertical: u16, + text_width: u16, + ) -> [Constraint; 3] { match self { Self::TopLeft | Self::MiddleLeft | Self::BottomLeft => [ Constraint::Max(text_width), @@ -56,7 +60,11 @@ impl BoxLocation { ], } } - pub fn get_vertical_constraints(&self, blank_vertical: u16, number_lines: u16) -> [Constraint; 3] { + pub fn get_vertical_constraints( + &self, + blank_vertical: u16, + number_lines: u16, + ) -> [Constraint; 3] { match self { Self::TopLeft | Self::TopCentre | Self::TopRight => [ Constraint::Max(number_lines), @@ -75,7 +83,6 @@ impl BoxLocation { ], } } - } #[derive(Debug, Clone)] diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 65f3291..7027a5a 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -192,7 +192,7 @@ fn ui( &selected_panel, ); - draw_info_bar( + draw_heading_bar( whole_layout[0], &column_widths, f, @@ -200,14 +200,12 @@ fn ui( show_help, ); - - // only draw charts if there are containers if has_containers { draw_chart(f, lower_main[1], app_data, log_index); } - if let Some(info) = info_text { + if let Some(info) = info_text { draw_info(f, info); }