From 1017850a6cc91328abc1127bdb117495f5e909d8 Mon Sep 17 00:00:00 2001
From: Jack Wills <32690432+mrjackwills@users.noreply.github.com>
Date: Thu, 28 Apr 2022 21:25:27 +0000
Subject: [PATCH 01/13] feat: refactored centered box to diplay in any of 9
areas
---
README.md | 13 +++--
src/app_error.rs | 25 +++------
src/input_handler/mod.rs | 35 ++++++++++++-
src/main.rs | 2 +
src/ui/draw_blocks.rs | 68 ++++++++++++++++++-------
src/ui/gui_state.rs | 106 +++++++++++++++++++++++++++++++++------
src/ui/mod.rs | 10 +++-
7 files changed, 202 insertions(+), 57 deletions(-)
diff --git a/README.md b/README.md
index ae524e6..4610130 100644
--- a/README.md
+++ b/README.md
@@ -21,14 +21,21 @@
-## Download
+## Download & install
See releases
+install
+```bash
+INSTALL_DIR="${HOME}/.local/bin"
+tar xzvf oxker_linux_x86_64.tar.gz oxker
+install -Dm 755 oxker -t "$INSTALL_DIR"
+rm oxker_linux_x86_64.tar.gz oxker
+```
## Run
-```./oxker```
+```oxker```
available command line arguments
| argument|result|
@@ -56,7 +63,7 @@ requires docker & error!("Unable to access docker daemon"),
- Self::DockerInterval => error!("Docker update interval needs to be greater than 0"),
- Self::InputPoll => error!("Unable to poll user input"),
- Self::Terminal => error!("Unable to draw to terminal"),
- Self::DockerCommand(s) => {
- let error = format!("Unable to {} container", s);
- error!(%error);
- }
- }
- }
-}
-
/// Convert errors into strings to display
impl fmt::Display for AppError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -39,6 +22,10 @@ impl fmt::Display for AppError {
Self::InputPoll => "Unable to poll user input".to_owned(),
Self::Terminal => "Unable to draw to terminal".to_owned(),
Self::DockerCommand(s) => format!("Unable to {} container", s),
+ Self::MouseCapture(x) => {
+ let reason = if *x { "en" } else { "dis" };
+ format!("Unable to {}able mouse capture", reason)
+ }
};
write!(f, "{}", disp)
}
diff --git a/src/input_handler/mod.rs b/src/input_handler/mod.rs
index 3e14fb5..610c0f5 100644
--- a/src/input_handler/mod.rs
+++ b/src/input_handler/mod.rs
@@ -4,7 +4,12 @@ use std::sync::{
};
use bollard::{container::StartContainerOptions, Docker};
-use crossterm::event::{KeyCode, MouseButton, MouseEvent, MouseEventKind};
+use crossterm::{
+ event::{
+ DisableMouseCapture, EnableMouseCapture, KeyCode, MouseButton, MouseEvent, MouseEventKind,
+ },
+ execute,
+};
use parking_lot::Mutex;
use tokio::sync::broadcast::Receiver;
use tui::layout::Rect;
@@ -25,6 +30,7 @@ pub struct InputHandler {
gui_state: Arc>,
is_running: Arc,
rec: Receiver,
+ mouse_capture: bool,
}
impl InputHandler {
@@ -42,6 +48,7 @@ impl InputHandler {
gui_state,
is_running,
rec,
+ mouse_capture: true,
};
inner.start().await;
}
@@ -69,6 +76,7 @@ impl InputHandler {
async fn button_press(&mut self, key_code: KeyCode) {
let show_error = self.app_data.lock().show_error;
let show_info = self.gui_state.lock().show_help;
+
if show_error {
match key_code {
KeyCode::Char('q') => {
@@ -98,6 +106,31 @@ impl InputHandler {
KeyCode::Char('h') => {
self.gui_state.lock().show_help = true;
}
+ KeyCode::Char('m') => {
+ if self.mouse_capture {
+ match execute!(std::io::stdout(), DisableMouseCapture) {
+ Ok(_) => self
+ .gui_state
+ .lock()
+ .set_info_box("Mouse capture disabled".to_owned()),
+ Err(_) => self
+ .app_data
+ .lock()
+ .set_error(AppError::MouseCapture(false)),
+ }
+ } else {
+ match execute!(std::io::stdout(), EnableMouseCapture) {
+ Ok(_) => self
+ .gui_state
+ .lock()
+ .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();
+ };
+ self.mouse_capture = !self.mouse_capture;
+ }
KeyCode::Tab => self.gui_state.lock().next_panel(),
KeyCode::BackTab => self.gui_state.lock().previous_panel(),
KeyCode::Home => {
diff --git a/src/main.rs b/src/main.rs
index 97a3e50..112118a 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,3 +1,5 @@
+#![allow(unused)]
+
use app_data::AppData;
use app_error::AppError;
use bollard::Docker;
diff --git a/src/ui/draw_blocks.rs b/src/ui/draw_blocks.rs
index f3ac6c9..28830b0 100644
--- a/src/ui/draw_blocks.rs
+++ b/src/ui/draw_blocks.rs
@@ -19,6 +19,7 @@ use crate::{
app_error::AppError,
};
+use super::gui_state::BoxLocation;
use super::{GuiState, SelectablePanel};
const NAME_TEXT: &str = r#"
@@ -497,7 +498,7 @@ pub fn draw_help_box(f: &mut Frame<'_, B>) {
.border_type(BorderType::Rounded)
.border_style(Style::default().fg(Color::Black));
- let area = centered_info(lines as u16, max_line_width as u16, f.size());
+ let area = draw_popup(lines as u16, max_line_width as u16, f.size(), BoxLocation::MiddleCentre);
let split_popup = Layout::default()
.direction(Direction::Vertical)
@@ -560,38 +561,67 @@ pub fn draw_error(f: &mut Frame<'_, B>, error: AppError, seconds: Op
.block(block)
.alignment(Alignment::Center);
- let area = centered_info(lines as u16, max_line_width as u16, f.size());
+ 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);
+}
+
+/// Show info box in bottom right corner
+pub fn draw_info(f: &mut Frame<'_, B>, text: String) {
+ let block = Block::default()
+ .title("")
+ .title_alignment(Alignment::Center)
+ .borders(Borders::NONE);
+
+ // Add a blank line, so that the text is verticall centered
+ let text = format!("\n{}", text);
+
+ let mut max_line_width = 0;
+ text.lines().into_iter().for_each(|line| {
+ let width = line.chars().count();
+ if width > max_line_width {
+ max_line_width = width;
+ }
+ });
+
+ let mut lines = text.lines().count();
+
+ // Add some horizontal & vertical margins
+ max_line_width += 8;
+ lines += 3;
+
+ let paragraph = Paragraph::new(text)
+ .style(Style::default().bg(Color::Blue).fg(Color::White))
+ .block(block)
+ .alignment(Alignment::Center);
+
+ 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 centered_info(number_lines: u16, max_line_width: u16, r: Rect) -> 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 - number_lines) / 2;
- let blank_horizontal = (r.width - max_line_width) / 2;
+ 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 indexes = box_location.get_indexes();
let popup_layout = Layout::default()
.direction(Direction::Vertical)
.constraints(
- [
- Constraint::Max(blank_vertical),
- Constraint::Max(number_lines),
- Constraint::Max(blank_vertical),
- ]
- .as_ref(),
+ vertical_constraints
)
.split(r);
Layout::default()
.direction(Direction::Horizontal)
.constraints(
- [
- Constraint::Max(blank_horizontal),
- Constraint::Max(max_line_width),
- Constraint::Max(blank_horizontal),
- ]
- .as_ref(),
+ horizontal_constraints
)
- .split(popup_layout[1])[1]
-}
+ .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 eb53924..7ee205e 100644
--- a/src/ui/gui_state.rs
+++ b/src/ui/gui_state.rs
@@ -1,5 +1,5 @@
use std::{collections::HashMap, fmt};
-use tui::layout::Rect;
+use tui::layout::{Constraint, Rect};
#[derive(Debug, PartialEq, std::hash::Hash, std::cmp::Eq, Clone, Copy)]
pub enum SelectablePanel {
@@ -7,7 +7,78 @@ pub enum SelectablePanel {
Commands,
Logs,
}
-#[derive(Debug)]
+
+#[derive(Debug, Clone, Copy)]
+pub enum BoxLocation {
+ TopLeft,
+ TopCentre,
+ TopRight,
+ MiddleLeft,
+ MiddleCentre,
+ MiddleRight,
+ BottomLeft,
+ BottomCentre,
+ BottomRight,
+}
+
+impl BoxLocation {
+ pub fn get_indexes(&self) -> (usize, usize) {
+ match self {
+ Self::TopLeft => (0, 0),
+ Self::TopCentre => (0, 1),
+ Self::TopRight => (0, 2),
+ Self::MiddleLeft => (1, 0),
+ Self::MiddleCentre => (1, 1),
+ Self::MiddleRight => (1, 2),
+ Self::BottomLeft => (2, 0),
+ Self::BottomCentre => (2, 1),
+ Self::BottomRight => (2, 2),
+ }
+ }
+
+ // 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),
+ Constraint::Max(blank_vertical),
+ Constraint::Max(blank_vertical),
+ ],
+ Self::TopCentre | Self::MiddleCentre | Self::BottomCentre => [
+ Constraint::Max(blank_vertical),
+ Constraint::Max(text_width),
+ Constraint::Max(blank_vertical),
+ ],
+ Self::TopRight | Self::MiddleRight | Self::BottomRight => [
+ Constraint::Max(blank_vertical),
+ Constraint::Max(blank_vertical),
+ Constraint::Max(text_width),
+ ],
+ }
+ }
+ 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),
+ Constraint::Max(blank_vertical),
+ Constraint::Max(blank_vertical),
+ ],
+ Self::MiddleLeft | Self::MiddleCentre | Self::MiddleRight => [
+ Constraint::Max(blank_vertical),
+ Constraint::Max(number_lines),
+ Constraint::Max(blank_vertical),
+ ],
+ Self::BottomLeft | Self::BottomCentre | Self::BottomRight => [
+ Constraint::Max(blank_vertical),
+ Constraint::Max(blank_vertical),
+ Constraint::Max(number_lines),
+ ],
+ }
+ }
+
+}
+
+#[derive(Debug, Clone)]
pub enum Loading {
One,
Two,
@@ -34,20 +105,9 @@ impl Loading {
Self::Eight => Self::Nine,
Self::Nine => Self::Ten,
Self::Ten => Self::One,
- // Self::Five => Self::One
}
}
}
-// "⠋",
-// "⠙",
-// "⠹",
-// "⠸",
-// "⠼",
-// "⠴",
-// "⠦",
-// "⠧",
-// "⠇",
-// "⠏"
impl fmt::Display for Loading {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -92,7 +152,7 @@ impl SelectablePanel {
}
/// Global gui_state, stored in an Arc
-#[derive(Debug)]
+#[derive(Debug, Clone)]
pub struct GuiState {
// Think this should be a BMapTree, so can define order when iterating over potential intersects
// Is an issue if two panels are in the same space, sush as a smaller panel embedded, yet infront of, a larger panel
@@ -101,6 +161,8 @@ pub struct GuiState {
loading: Loading,
pub selected_panel: SelectablePanel,
pub show_help: bool,
+ // show_info_panel: bool,
+ pub info_box_text: Option,
}
impl GuiState {
@@ -111,6 +173,8 @@ impl GuiState {
loading: Loading::One,
selected_panel: SelectablePanel::Containers,
show_help: false,
+ // show_info_panel: false,
+ info_box_text: None,
}
}
@@ -158,4 +222,18 @@ impl GuiState {
pub fn reset_loading(&mut self) {
self.loading = Loading::One;
}
+
+ pub fn set_info_box(&mut self, text: String) {
+ self.info_box_text = Some(text);
+ // self.show_info_panel = true;
+
+ // Should spawn and after 10 seconds close?
+ // Need to copy whatever we're doing with parsing logs icon
+ }
+
+ pub fn reset_info_box(&mut self) {
+ // self.loading = Loading::One;
+ self.info_box_text = None;
+ // self.show_info_panel = false;
+ }
}
diff --git a/src/ui/mod.rs b/src/ui/mod.rs
index 002175a..65f3291 100644
--- a/src/ui/mod.rs
+++ b/src/ui/mod.rs
@@ -11,6 +11,7 @@ use std::{
sync::{atomic::Ordering, Arc},
};
use tokio::sync::broadcast::Sender;
+use tracing::error;
use tui::{
backend::{Backend, CrosstermBackend},
layout::{Constraint, Direction, Layout},
@@ -50,7 +51,7 @@ pub async fn create_ui(
terminal.show_cursor().unwrap();
if let Err(err) = res {
- err.disp()
+ error!(%err);
}
Ok(())
}
@@ -126,6 +127,7 @@ fn ui(
let log_index = app_data.lock().get_selected_log_index();
let selected_panel = gui_state.lock().selected_panel;
let show_help = gui_state.lock().show_help;
+ let info_text = gui_state.lock().info_box_text.clone();
let whole_layout = Layout::default()
.direction(Direction::Vertical)
@@ -198,11 +200,17 @@ 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 {
+ draw_info(f, info);
+ }
+
// Check if error, and show popup if so
if show_help {
draw_help_box(f);
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 02/13] 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);
}
From 421aa82ebde080ee62411675f5efa1a1857a2b32 Mon Sep 17 00:00:00 2001
From: Jack Wills <32690432+mrjackwills@users.noreply.github.com>
Date: Fri, 29 Apr 2022 01:11:20 +0000
Subject: [PATCH 03/13] feat: help box "m" explanation
---
Cargo.toml | 2 +-
src/ui/draw_blocks.rs | 1 +
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/Cargo.toml b/Cargo.toml
index 59fce02..a26aed7 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -19,7 +19,7 @@ parking_lot = {version= "0.12.0"}
tokio = {version = "1.17.0", features=["full"]}
tracing = "0.1.32"
tracing-subscriber = "0.3.9"
-tui = "0.17"
+tui = "0.18"
[dev-dependencies]
diff --git a/src/ui/draw_blocks.rs b/src/ui/draw_blocks.rs
index 1a0b2bb..3d492b2 100644
--- a/src/ui/draw_blocks.rs
+++ b/src/ui/draw_blocks.rs
@@ -476,6 +476,7 @@ pub fn draw_help_box(f: &mut Frame<'_, B>) {
description_text.push_str("\n Tab or Alt+Tab to change panels, arrows to change lines, enter to send docker container commands.");
description_text.push_str("\n Mouse input also available.");
description_text.push_str("\n ( q ) to quit at any time.");
+ description_text.push_str("\n ( m ) to toggle mouse capture. When disabled, text on screen can be selected & copied, but mouse clicks get disabled");
description_text
.push_str("\n\n currenty an early work in progress, all and any input appreciated");
description_text.push_str(format!("\n {}", REPO.trim()).as_str());
From 01e000169dab710ea78cc38b0c58b648f190f6b6 Mon Sep 17 00:00:00 2001
From: Jack Wills <32690432+mrjackwills@users.noreply.github.com>
Date: Fri, 29 Apr 2022 01:12:44 +0000
Subject: [PATCH 04/13] feat: help box "m" explanation
---
src/ui/draw_blocks.rs | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/src/ui/draw_blocks.rs b/src/ui/draw_blocks.rs
index 3d492b2..362735e 100644
--- a/src/ui/draw_blocks.rs
+++ b/src/ui/draw_blocks.rs
@@ -634,8 +634,20 @@ pub fn draw_info(f: &mut Frame<'_, B>, text: String) {
/// 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 {
// 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 blank_vertical = if r.height > text_lines {
+ (r.height - text_lines) / 2
+ } else {
+ r.height / 2
+ };
+ let blank_horizontal = if r.width > text_width {
+ (r.width - text_width) / 2
+ }else {
+ r.width / 2
+
+ };
let vertical_constraints = box_location.get_vertical_constraints(blank_vertical, text_lines);
let horizontal_constraints =
From 12b5cfce6ce46a9225f00121a905245759fa2244 Mon Sep 17 00:00:00 2001
From: Jack Wills <32690432+mrjackwills@users.noreply.github.com>
Date: Fri, 29 Apr 2022 01:16:26 +0000
Subject: [PATCH 05/13] fix: make sure popup blank sapce can't be negative
---
src/ui/draw_blocks.rs | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/src/ui/draw_blocks.rs b/src/ui/draw_blocks.rs
index 362735e..e55f3a0 100644
--- a/src/ui/draw_blocks.rs
+++ b/src/ui/draw_blocks.rs
@@ -633,20 +633,17 @@ pub fn draw_info(f: &mut Frame<'_, B>, text: String) {
/// 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 {
- // This can panic if number_lines or max_line_width is larger than r.height or r.width
-
-
+ // Make sure blank_space can't be an negative, as will crash
let blank_vertical = if r.height > text_lines {
(r.height - text_lines) / 2
} else {
- r.height / 2
+ 1
};
let blank_horizontal = if r.width > text_width {
(r.width - text_width) / 2
}else {
- r.width / 2
-
+ 1
};
let vertical_constraints = box_location.get_vertical_constraints(blank_vertical, text_lines);
From 00dfacfe13ccd7562b622d15e923a831fca1fd69 Mon Sep 17 00:00:00 2001
From: Jack Wills <32690432+mrjackwills@users.noreply.github.com>
Date: Fri, 29 Apr 2022 01:30:31 +0000
Subject: [PATCH 06/13] refactor: m_button, help box text
---
src/input_handler/mod.rs | 87 +++++++++++++++++++---------------------
src/ui/draw_blocks.rs | 15 ++++---
2 files changed, 50 insertions(+), 52 deletions(-)
diff --git a/src/input_handler/mod.rs b/src/input_handler/mod.rs
index 68728b8..af2f63c 100644
--- a/src/input_handler/mod.rs
+++ b/src/input_handler/mod.rs
@@ -74,6 +74,41 @@ impl InputHandler {
}
}
+ fn m_button(&mut self) {
+ if self.mouse_capture {
+ match execute!(std::io::stdout(), DisableMouseCapture) {
+ Ok(_) => self
+ .gui_state
+ .lock()
+ .set_info_box("✖ mouse capture disabled".to_owned()),
+ Err(_) => self
+ .app_data
+ .lock()
+ .set_error(AppError::MouseCapture(false)),
+ }
+ } else {
+ match execute!(std::io::stdout(), EnableMouseCapture) {
+ Ok(_) => self
+ .gui_state
+ .lock()
+ .set_info_box("✓ mouse capture enabled".to_owned()),
+ Err(_) => self.app_data.lock().set_error(AppError::MouseCapture(true)),
+ }
+ };
+
+ 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;
+ }
+
/// Handle any keyboard button events
async fn button_press(&mut self, key_code: KeyCode) {
let show_error = self.app_data.lock().show_error;
@@ -92,56 +127,16 @@ impl InputHandler {
}
} else if show_info {
match key_code {
- KeyCode::Char('q') => {
- self.is_running.store(false, Ordering::SeqCst);
- }
- KeyCode::Char('h') => {
- self.gui_state.lock().show_help = false;
- }
+ KeyCode::Char('q') => self.is_running.store(false, Ordering::SeqCst),
+ KeyCode::Char('h') => self.gui_state.lock().show_help = false,
+ KeyCode::Char('m') => self.m_button(),
_ => (),
}
} else {
match key_code {
- KeyCode::Char('q') => {
- self.is_running.store(false, Ordering::SeqCst);
- }
- KeyCode::Char('h') => {
- self.gui_state.lock().show_help = true;
- }
- KeyCode::Char('m') => {
- if self.mouse_capture {
- match execute!(std::io::stdout(), DisableMouseCapture) {
- Ok(_) => self
- .gui_state
- .lock()
- .set_info_box("✖ mouse capture disabled".to_owned()),
- Err(_) => self
- .app_data
- .lock()
- .set_error(AppError::MouseCapture(false)),
- }
- } else {
- match execute!(std::io::stdout(), EnableMouseCapture) {
- Ok(_) => self
- .gui_state
- .lock()
- .set_info_box("✓ mouse capture enabled".to_owned()),
- Err(_) => self.app_data.lock().set_error(AppError::MouseCapture(true)),
- }
- };
-
- 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::Char('q') => self.is_running.store(false, Ordering::SeqCst),
+ KeyCode::Char('h') => self.gui_state.lock().show_help = true,
+ KeyCode::Char('m') => self.m_button(),
KeyCode::Tab => self.gui_state.lock().next_panel(),
KeyCode::BackTab => self.gui_state.lock().previous_panel(),
KeyCode::Home => {
diff --git a/src/ui/draw_blocks.rs b/src/ui/draw_blocks.rs
index e55f3a0..b6bb42d 100644
--- a/src/ui/draw_blocks.rs
+++ b/src/ui/draw_blocks.rs
@@ -471,12 +471,15 @@ pub fn draw_heading_bar(
pub fn draw_help_box(f: &mut Frame<'_, B>) {
let title = format!(" {} ", VERSION);
- let mut description_text =
- String::from("\n A basic docker container information viewer and controller.");
- description_text.push_str("\n Tab or Alt+Tab to change panels, arrows to change lines, enter to send docker container commands.");
- description_text.push_str("\n Mouse input also available.");
- description_text.push_str("\n ( q ) to quit at any time.");
- description_text.push_str("\n ( m ) to toggle mouse capture. When disabled, text on screen can be selected & copied, but mouse clicks get disabled");
+ let mut description_text = String::new();
+ // String::from("\n A basic docker container information viewer and controller.");
+ description_text.push_str("\n ( tab ) or ( alt+tab ) to change panels");
+ description_text.push_str("\n ( ↑ ↓ ← → ) mto change selected line");
+ description_text.push_str("\n ( enter ) to send docker container commands");
+ description_text.push_str("\n ( m ) to toggle mouse capture - if disabled, text on screen can be selected & copied, but mouse clicks get disabled");
+ description_text.push_str("\n ( h ) to toggle this help information");
+ description_text.push_str("\n ( q ) to quit at any time");
+ description_text.push_str("\n mouse scrolling & clicking also available");
description_text
.push_str("\n\n currenty an early work in progress, all and any input appreciated");
description_text.push_str(format!("\n {}", REPO.trim()).as_str());
From db99e61a3718d41a2c464373550bafdd58ceaa28 Mon Sep 17 00:00:00 2001
From: Jack Wills <32690432+mrjackwills@users.noreply.github.com>
Date: Fri, 29 Apr 2022 01:36:20 +0000
Subject: [PATCH 07/13] refactor: help box text
---
src/ui/draw_blocks.rs | 40 +++++++++++++++++++++++++---------------
1 file changed, 25 insertions(+), 15 deletions(-)
diff --git a/src/ui/draw_blocks.rs b/src/ui/draw_blocks.rs
index b6bb42d..3e85ab7 100644
--- a/src/ui/draw_blocks.rs
+++ b/src/ui/draw_blocks.rs
@@ -471,22 +471,24 @@ pub fn draw_heading_bar(
pub fn draw_help_box(f: &mut Frame<'_, B>) {
let title = format!(" {} ", VERSION);
- let mut description_text = String::new();
- // String::from("\n A basic docker container information viewer and controller.");
- description_text.push_str("\n ( tab ) or ( alt+tab ) to change panels");
- description_text.push_str("\n ( ↑ ↓ ← → ) mto change selected line");
- description_text.push_str("\n ( enter ) to send docker container commands");
- description_text.push_str("\n ( m ) to toggle mouse capture - if disabled, text on screen can be selected & copied, but mouse clicks get disabled");
- description_text.push_str("\n ( h ) to toggle this help information");
- description_text.push_str("\n ( q ) to quit at any time");
- description_text.push_str("\n mouse scrolling & clicking also available");
- description_text
+ let description_text = String::from("\n A basic docker container information viewer and controller");
+
+ let mut help_text = String::from("\n ( tab ) or ( alt+tab ) to change panels");
+ help_text.push_str("\n ( ↑ ↓ ← → ) mto change selected line");
+ help_text.push_str("\n ( enter ) to send docker container commands");
+ help_text.push_str("\n ( h ) to toggle this help information");
+ help_text.push_str("\n ( m ) to toggle mouse capture - if disabled, text on screen can be selected & copied, but mouse clicks get disabled");
+ help_text.push_str("\n ( q ) to quit at any time");
+ help_text.push_str("\n mouse scrolling & clicking also available");
+ help_text
.push_str("\n\n currenty an early work in progress, all and any input appreciated");
- description_text.push_str(format!("\n {}", REPO.trim()).as_str());
+ help_text.push_str(format!("\n {}", REPO.trim()).as_str());
let mut max_line_width = 0;
- let all_text = format!("{}{}", NAME_TEXT, description_text);
+
+
+ let all_text = format!("{}{}{}", NAME_TEXT, description_text, help_text);
all_text.lines().into_iter().for_each(|line| {
let width = line.chars().count();
@@ -506,7 +508,13 @@ pub fn draw_help_box(f: &mut Frame<'_, B>) {
.block(Block::default())
.alignment(Alignment::Center);
- let description_paragraph = Paragraph::new(description_text.as_str())
+
+ let description_paragrpah = Paragraph::new(description_text.as_str())
+ .style(Style::default().bg(Color::Magenta).fg(Color::Black))
+ .block(Block::default())
+ .alignment(Alignment::Center);
+
+ let help_paragraph = Paragraph::new(help_text.as_str())
.style(Style::default().bg(Color::Magenta).fg(Color::Black))
.block(Block::default())
.alignment(Alignment::Left);
@@ -529,7 +537,8 @@ pub fn draw_help_box(f: &mut Frame<'_, B>) {
.constraints(
[
Constraint::Max(NAME_TEXT.lines().count() as u16),
- Constraint::Max(description_text.lines().count() as u16),
+ Constraint::Max(description_text.lines().count() as u16),
+ Constraint::Max(help_text.lines().count() as u16),
]
.as_ref(),
)
@@ -538,7 +547,8 @@ pub fn draw_help_box(f: &mut Frame<'_, B>) {
// Order is important here
f.render_widget(Clear, area);
f.render_widget(name_paragraph, split_popup[0]);
- f.render_widget(description_paragraph, split_popup[1]);
+ f.render_widget(description_paragrpah, split_popup[1]);
+ f.render_widget(help_paragraph, split_popup[2]);
f.render_widget(block, area);
}
From 757103c54fe05afcd6e3cfeba09da2a8806e8086 Mon Sep 17 00:00:00 2001
From: Jack Wills <32690432+mrjackwills@users.noreply.github.com>
Date: Fri, 29 Apr 2022 01:39:21 +0000
Subject: [PATCH 08/13] refactor: help box description from TOML
---
src/app_data/container_state.rs | 4 +-
src/input_handler/mod.rs | 64 +++++++++++++--------------
src/ui/draw_blocks.rs | 77 +++++++++++++++------------------
3 files changed, 70 insertions(+), 75 deletions(-)
diff --git a/src/app_data/container_state.rs b/src/app_data/container_state.rs
index 3852e4c..aca3744 100644
--- a/src/app_data/container_state.rs
+++ b/src/app_data/container_state.rs
@@ -402,7 +402,7 @@ pub struct Columns {
pub status: (String, usize),
pub cpu: (String, usize),
pub mem: (String, usize),
- pub id: (String, usize),
+ pub id: (String, usize),
pub name: (String, usize),
pub image: (String, usize),
pub net_rx: (String, usize),
@@ -417,7 +417,7 @@ impl Columns {
// 7 to allow for "100.00%"
cpu: (String::from("cpu"), 7),
mem: (String::from("memory/limit"), 12),
- id: (String::from("id"), 8),
+ id: (String::from("id"), 8),
name: (String::from("name"), 4),
image: (String::from("image"), 5),
net_rx: (String::from("↓ rx"), 5),
diff --git a/src/input_handler/mod.rs b/src/input_handler/mod.rs
index af2f63c..9baadc7 100644
--- a/src/input_handler/mod.rs
+++ b/src/input_handler/mod.rs
@@ -74,40 +74,40 @@ impl InputHandler {
}
}
- fn m_button(&mut self) {
- if self.mouse_capture {
- match execute!(std::io::stdout(), DisableMouseCapture) {
- Ok(_) => self
- .gui_state
- .lock()
- .set_info_box("✖ mouse capture disabled".to_owned()),
- Err(_) => self
- .app_data
- .lock()
- .set_error(AppError::MouseCapture(false)),
- }
- } else {
- match execute!(std::io::stdout(), EnableMouseCapture) {
- Ok(_) => self
- .gui_state
- .lock()
- .set_info_box("✓ mouse capture enabled".to_owned()),
- Err(_) => self.app_data.lock().set_error(AppError::MouseCapture(true)),
- }
- };
+ fn m_button(&mut self) {
+ if self.mouse_capture {
+ match execute!(std::io::stdout(), DisableMouseCapture) {
+ Ok(_) => self
+ .gui_state
+ .lock()
+ .set_info_box("✖ mouse capture disabled".to_owned()),
+ Err(_) => self
+ .app_data
+ .lock()
+ .set_error(AppError::MouseCapture(false)),
+ }
+ } else {
+ match execute!(std::io::stdout(), EnableMouseCapture) {
+ Ok(_) => self
+ .gui_state
+ .lock()
+ .set_info_box("✓ mouse capture enabled".to_owned()),
+ Err(_) => self.app_data.lock().set_error(AppError::MouseCapture(true)),
+ }
+ };
- let gui_state = Arc::clone(&self.gui_state);
+ 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()
- }));
+ 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;
- }
+ self.mouse_capture = !self.mouse_capture;
+ }
/// Handle any keyboard button events
async fn button_press(&mut self, key_code: KeyCode) {
@@ -129,7 +129,7 @@ impl InputHandler {
match key_code {
KeyCode::Char('q') => self.is_running.store(false, Ordering::SeqCst),
KeyCode::Char('h') => self.gui_state.lock().show_help = false,
- KeyCode::Char('m') => self.m_button(),
+ KeyCode::Char('m') => self.m_button(),
_ => (),
}
} else {
diff --git a/src/ui/draw_blocks.rs b/src/ui/draw_blocks.rs
index 3e85ab7..9f97085 100644
--- a/src/ui/draw_blocks.rs
+++ b/src/ui/draw_blocks.rs
@@ -35,6 +35,7 @@ a8" "8a `Y8, ,8P' 88 ,a8" a8P_____88 88P' "Y8
const NAME: &str = env!("CARGO_PKG_NAME");
const VERSION: &str = env!("CARGO_PKG_VERSION");
const REPO: &str = env!("CARGO_PKG_REPOSITORY");
+const DESCRIPTION: &str = env!("CARGO_PKG_DESCRIPTION");
const ORANGE: Color = Color::Rgb(255, 178, 36);
const MARGIN: &str = " ";
@@ -45,7 +46,9 @@ fn generate_block<'a>(
app_data: &Arc>,
selected_panel: &SelectablePanel,
) -> Block<'a> {
- let mut block = Block::default().borders(Borders::ALL).border_type(BorderType::Rounded);
+ let mut block = Block::default()
+ .borders(Borders::ALL)
+ .border_type(BorderType::Rounded);
if let Some(panel) = selectable_panel {
let title = match panel {
@@ -65,10 +68,9 @@ fn generate_block<'a>(
if selected_panel == &panel {
// let selected_style = Style::default().fg(Color::LightCyan);
// let selected_border = BorderType::Plain;
- // let selected_border = BorderType::Rounded;
- block = block
- .border_style(Style::default().fg(Color::LightCyan));
- // .border_type(BorderType::Rounded);
+ // let selected_border = BorderType::Rounded;
+ block = block.border_style(Style::default().fg(Color::LightCyan));
+ // .border_type(BorderType::Rounded);
}
}
block
@@ -172,8 +174,13 @@ pub fn draw_containers(
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),
+ Span::styled(
+ format!(
+ "{}{:>width$}",
+ MARGIN,
+ i.id.chars().take(8).collect::(),
+ width = widths.id.1
+ ),
blue,
),
Span::styled(
@@ -337,7 +344,7 @@ fn make_chart(
))
.borders(Borders::ALL)
// .border_type(BorderType::Plain),
- .border_type(BorderType::Rounded),
+ .border_type(BorderType::Rounded),
)
.x_axis(
Axis::default()
@@ -386,15 +393,8 @@ pub fn draw_heading_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$}", MARGIN, columns.id.0, width = columns.id.1).as_str());
column_headings.push_str(
format!(
"{}{:>width$}",
@@ -471,23 +471,20 @@ pub fn draw_heading_bar(
pub fn draw_help_box(f: &mut Frame<'_, B>) {
let title = format!(" {} ", VERSION);
- let description_text = String::from("\n A basic docker container information viewer and controller");
+ let description_text = format!("\n{}", DESCRIPTION);
let mut help_text = String::from("\n ( tab ) or ( alt+tab ) to change panels");
- help_text.push_str("\n ( ↑ ↓ ← → ) mto change selected line");
- help_text.push_str("\n ( enter ) to send docker container commands");
+ help_text.push_str("\n ( ↑ ↓ ← → ) mto change selected line");
+ help_text.push_str("\n ( enter ) to send docker container commands");
help_text.push_str("\n ( h ) to toggle this help information");
- help_text.push_str("\n ( m ) to toggle mouse capture - if disabled, text on screen can be selected & copied, but mouse clicks get disabled");
- help_text.push_str("\n ( q ) to quit at any time");
+ help_text.push_str("\n ( m ) to toggle mouse capture - if disabled, text on screen can be selected & copied, but mouse clicks get disabled");
+ help_text.push_str("\n ( q ) to quit at any time");
help_text.push_str("\n mouse scrolling & clicking also available");
- help_text
- .push_str("\n\n currenty an early work in progress, all and any input appreciated");
+ help_text.push_str("\n\n currenty an early work in progress, all and any input appreciated");
help_text.push_str(format!("\n {}", REPO.trim()).as_str());
let mut max_line_width = 0;
-
-
let all_text = format!("{}{}{}", NAME_TEXT, description_text, help_text);
all_text.lines().into_iter().for_each(|line| {
@@ -508,8 +505,7 @@ pub fn draw_help_box(f: &mut Frame<'_, B>) {
.block(Block::default())
.alignment(Alignment::Center);
-
- let description_paragrpah = Paragraph::new(description_text.as_str())
+ let description_paragrpah = Paragraph::new(description_text.as_str())
.style(Style::default().bg(Color::Magenta).fg(Color::Black))
.block(Block::default())
.alignment(Alignment::Center);
@@ -537,7 +533,7 @@ pub fn draw_help_box(f: &mut Frame<'_, B>) {
.constraints(
[
Constraint::Max(NAME_TEXT.lines().count() as u16),
- Constraint::Max(description_text.lines().count() as u16),
+ Constraint::Max(description_text.lines().count() as u16),
Constraint::Max(help_text.lines().count() as u16),
]
.as_ref(),
@@ -547,7 +543,7 @@ pub fn draw_help_box(f: &mut Frame<'_, B>) {
// Order is important here
f.render_widget(Clear, area);
f.render_widget(name_paragraph, split_popup[0]);
- f.render_widget(description_paragrpah, split_popup[1]);
+ f.render_widget(description_paragrpah, split_popup[1]);
f.render_widget(help_paragraph, split_popup[2]);
f.render_widget(block, area);
}
@@ -646,18 +642,17 @@ pub fn draw_info(f: &mut Frame<'_, B>, text: String) {
/// 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 {
-
- // Make sure blank_space can't be an negative, as will crash
+ // Make sure blank_space can't be an negative, as will crash
let blank_vertical = if r.height > text_lines {
- (r.height - text_lines) / 2
- } else {
- 1
- };
- let blank_horizontal = if r.width > text_width {
- (r.width - text_width) / 2
- }else {
- 1
- };
+ (r.height - text_lines) / 2
+ } else {
+ 1
+ };
+ let blank_horizontal = if r.width > text_width {
+ (r.width - text_width) / 2
+ } else {
+ 1
+ };
let vertical_constraints = box_location.get_vertical_constraints(blank_vertical, text_lines);
let horizontal_constraints =
From 836df247c45667e61be9478fd39a9ad36c32ef58 Mon Sep 17 00:00:00 2001
From: Jack Wills <32690432+mrjackwills@users.noreply.github.com>
Date: Fri, 29 Apr 2022 02:28:58 +0000
Subject: [PATCH 09/13] fix: cli arg DOCKER > ms
---
src/docker_data/mod.rs | 2 +-
src/parse_args/mod.rs | 13 +++++++++----
2 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/src/docker_data/mod.rs b/src/docker_data/mod.rs
index 0ab2a94..e6364c3 100644
--- a/src/docker_data/mod.rs
+++ b/src/docker_data/mod.rs
@@ -220,7 +220,7 @@ impl DockerData {
docker,
gui_state,
initialised: false,
- sleep_duration: Duration::from_millis(args.docker as u64),
+ sleep_duration: Duration::from_millis(args.docker_interval as u64),
timestamps: args.timestamp,
};
inner.initialise_container_data().await;
diff --git a/src/parse_args/mod.rs b/src/parse_args/mod.rs
index 351917a..6133465 100644
--- a/src/parse_args/mod.rs
+++ b/src/parse_args/mod.rs
@@ -8,13 +8,17 @@ use tracing::error;
pub struct CliArgs {
/// Docker update interval in ms, minimum 1, reccomended 500+
- #[clap(short = 'd', default_value_t = 1000)]
- pub docker: u32,
+ #[clap(short = 'd', value_name = "ms", default_value_t = 1000)]
+ pub docker_interval: u32,
/// Don't draw gui - for debugging - mostly pointless
#[clap(short = 'g')]
pub gui: bool,
+ /// Install to ./local/bin
+ #[clap(short = 'i')]
+ pub install: bool,
+
/// Remove timestamps from Docker logs
#[clap(short = 't')]
pub timestamp: bool,
@@ -35,15 +39,16 @@ impl CliArgs {
// Quit the program if the docker update argument is 0
// Should maybe change it to check if less than 100
- if args.docker == 0 {
+ if args.docker_interval == 0 {
error!("docker args needs to be greater than 0");
process::exit(1)
}
Self {
color: args.color,
- docker: args.docker,
+ docker_interval: args.docker_interval,
gui: !args.gui,
raw: args.raw,
+ install: args.install,
timestamp: !args.timestamp,
}
}
From 3542f65e61543df8dbcb9bbb6ac3714ed1d5c6c7 Mon Sep 17 00:00:00 2001
From: Jack Wills <32690432+mrjackwills@users.noreply.github.com>
Date: Fri, 29 Apr 2022 03:10:41 +0000
Subject: [PATCH 10/13] refactor: dead space removed
---
src/parse_args/mod.rs | 9 ++++-----
src/ui/draw_blocks.rs | 2 +-
2 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/src/parse_args/mod.rs b/src/parse_args/mod.rs
index 6133465..524da85 100644
--- a/src/parse_args/mod.rs
+++ b/src/parse_args/mod.rs
@@ -15,10 +15,9 @@ pub struct CliArgs {
#[clap(short = 'g')]
pub gui: bool,
- /// Install to ./local/bin
- #[clap(short = 'i')]
- pub install: bool,
-
+ // /// Install to ./local/bin
+ // #[clap(short = 'i')]
+ // pub install: bool,
/// Remove timestamps from Docker logs
#[clap(short = 't')]
pub timestamp: bool,
@@ -48,7 +47,7 @@ impl CliArgs {
docker_interval: args.docker_interval,
gui: !args.gui,
raw: args.raw,
- install: args.install,
+ // install: args.install,
timestamp: !args.timestamp,
}
}
diff --git a/src/ui/draw_blocks.rs b/src/ui/draw_blocks.rs
index 9f97085..20dfc50 100644
--- a/src/ui/draw_blocks.rs
+++ b/src/ui/draw_blocks.rs
@@ -471,7 +471,7 @@ pub fn draw_heading_bar(
pub fn draw_help_box(f: &mut Frame<'_, B>) {
let title = format!(" {} ", VERSION);
- let description_text = format!("\n{}", DESCRIPTION);
+ let description_text = format!("\n{}", DESCRIPTION);
let mut help_text = String::from("\n ( tab ) or ( alt+tab ) to change panels");
help_text.push_str("\n ( ↑ ↓ ← → ) mto change selected line");
From 1daf1c177d90e98916865409e9b932a3d933411c Mon Sep 17 00:00:00 2001
From: Jack Wills <32690432+mrjackwills@users.noreply.github.com>
Date: Fri, 29 Apr 2022 03:14:35 +0000
Subject: [PATCH 11/13] fix: info box lines
---
src/ui/draw_blocks.rs | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/src/ui/draw_blocks.rs b/src/ui/draw_blocks.rs
index 20dfc50..451a3ac 100644
--- a/src/ui/draw_blocks.rs
+++ b/src/ui/draw_blocks.rs
@@ -608,8 +608,6 @@ 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
- let text = format!("\n{}", text);
let mut max_line_width = 0;
text.lines().into_iter().for_each(|line| {
@@ -623,7 +621,7 @@ pub fn draw_info(f: &mut Frame<'_, B>, text: String) {
// Add some horizontal & vertical margins
max_line_width += 8;
- lines += 3;
+ lines += 2;
let paragraph = Paragraph::new(text)
.style(Style::default().bg(Color::Blue).fg(Color::White))
From bfd5ab87733d8c54e5edcf3ec86ef888654c5f8b Mon Sep 17 00:00:00 2001
From: Jack Wills <32690432+mrjackwills@users.noreply.github.com>
Date: Fri, 29 Apr 2022 14:24:34 +0000
Subject: [PATCH 12/13] fix: help box typos
---
src/ui/draw_blocks.rs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/ui/draw_blocks.rs b/src/ui/draw_blocks.rs
index 451a3ac..a04628f 100644
--- a/src/ui/draw_blocks.rs
+++ b/src/ui/draw_blocks.rs
@@ -474,10 +474,10 @@ pub fn draw_help_box(f: &mut Frame<'_, B>) {
let description_text = format!("\n{}", DESCRIPTION);
let mut help_text = String::from("\n ( tab ) or ( alt+tab ) to change panels");
- help_text.push_str("\n ( ↑ ↓ ← → ) mto change selected line");
+ help_text.push_str("\n ( ↑ ↓ ← → ) to change selected line");
help_text.push_str("\n ( enter ) to send docker container commands");
help_text.push_str("\n ( h ) to toggle this help information");
- help_text.push_str("\n ( m ) to toggle mouse capture - if disabled, text on screen can be selected & copied, but mouse clicks get disabled");
+ help_text.push_str("\n ( m ) to toggle mouse capture - if disabled, text on screen can be selected & copied");
help_text.push_str("\n ( q ) to quit at any time");
help_text.push_str("\n mouse scrolling & clicking also available");
help_text.push_str("\n\n currenty an early work in progress, all and any input appreciated");
From 4b46efe89d737c64f0169deaac6ac4ea1987d199 Mon Sep 17 00:00:00 2001
From: Jack Wills <32690432+mrjackwills@users.noreply.github.com>
Date: Fri, 29 Apr 2022 14:28:29 +0000
Subject: [PATCH 13/13] fix: gui typo
---
src/ui/draw_blocks.rs | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)
diff --git a/src/ui/draw_blocks.rs b/src/ui/draw_blocks.rs
index a04628f..4d71af0 100644
--- a/src/ui/draw_blocks.rs
+++ b/src/ui/draw_blocks.rs
@@ -39,7 +39,7 @@ const DESCRIPTION: &str = env!("CARGO_PKG_DESCRIPTION");
const ORANGE: Color = Color::Rgb(255, 178, 36);
const MARGIN: &str = " ";
-/// Generate block, add a bored if is the selected panel,
+/// Generate block, add a border if is the selected panel,
/// add custom title based on state of each panel
fn generate_block<'a>(
selectable_panel: Option,
@@ -66,11 +66,7 @@ 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_border = BorderType::Rounded;
block = block.border_style(Style::default().fg(Color::LightCyan));
- // .border_type(BorderType::Rounded);
}
}
block
@@ -343,7 +339,6 @@ fn make_chart(
.add_modifier(Modifier::BOLD),
))
.borders(Borders::ALL)
- // .border_type(BorderType::Plain),
.border_type(BorderType::Rounded),
)
.x_axis(
@@ -362,7 +357,6 @@ fn make_chart(
.fg(label_color),
),
])
- // add 0.01, for cases when the value is 0
.bounds([0.0, max.get_value() + 0.01]),
)
}