summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClementTsang <cjhtsang@uwaterloo.ca>2021-08-24 22:34:25 -0400
committerClementTsang <cjhtsang@uwaterloo.ca>2021-08-24 22:49:06 -0400
commitdd7e183ec8a152d5fda84c49a7f79141171e1448 (patch)
treeca3d44f3878ebb9181adef1d2fc969e361009f3a
parent189be96622431ece680e4fbf98eda8d07c63e9fe (diff)
refactor: rip out trait system for drawing widgets
This rips out this weird trait system I previously used for drawing widgets, where I implemented a trait onto the Painter struct that did the drawing. I have no idea what I was thinking back then.
-rw-r--r--src/app.rs4
-rw-r--r--src/bin/main.rs6
-rw-r--r--src/canvas.rs93
-rw-r--r--src/canvas/widgets.rs22
-rw-r--r--src/canvas/widgets/basic_table_arrows.rs264
-rw-r--r--src/canvas/widgets/battery_display.rs354
-rw-r--r--src/canvas/widgets/cpu_basic.rs335
-rw-r--r--src/canvas/widgets/cpu_graph.rs856
-rw-r--r--src/canvas/widgets/disk_table.rs414
-rw-r--r--src/canvas/widgets/mem_basic.rs191
-rw-r--r--src/canvas/widgets/mem_graph.rs403
-rw-r--r--src/canvas/widgets/network_basic.rs105
-rw-r--r--src/canvas/widgets/network_graph.rs1318
-rw-r--r--src/canvas/widgets/process_table.rs1387
-rw-r--r--src/canvas/widgets/temp_table.rs390
-rw-r--r--src/lib.rs7
16 files changed, 2999 insertions, 3150 deletions
diff --git a/src/app.rs b/src/app.rs
index d0237d94..fe4e44da 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -270,6 +270,10 @@ impl AppState {
EventResult::NoRedraw
}
}
+ BottomEvent::Resize {
+ width: _,
+ height: _,
+ } => EventResult::Redraw,
BottomEvent::Clean => {
self.data_collection
.clean_data(constants::STALE_MAX_MILLISECONDS);
diff --git a/src/bin/main.rs b/src/bin/main.rs
index 075ea051..37431389 100644
--- a/src/bin/main.rs
+++ b/src/bin/main.rs
@@ -233,6 +233,12 @@ fn main() -> Result<()> {
try_drawing(&mut terminal, &mut app, &mut painter)?;
}
}
+ BottomEvent::Resize {
+ width: _,
+ height: _,
+ } => {
+ try_drawing(&mut terminal, &mut app, &mut painter)?;
+ }
BottomEvent::Clean => {
app.data_collection
.clean_data(constants::STALE_MAX_MILLISECONDS);
diff --git a/src/canvas.rs b/src/canvas.rs
index 55bbe968..5d9fe89f 100644
--- a/src/canvas.rs
+++ b/src/canvas.rs
@@ -95,8 +95,6 @@ impl FromStr for ColourScheme {
/// Handles the canvas' state. TODO: [OPT] implement this.
pub struct Painter {
pub colours: CanvasColours,
- height: u16,
- width: u16,
styled_help_text: Vec<Spans<'static>>,
is_mac_os: bool, // FIXME: This feels out of place...
row_constraints: Vec<Constraint>,
@@ -182,8 +180,6 @@ impl Painter {
let mut painter = Painter {
colours: CanvasColours::default(),
- height: 0,
- width: 0,
styled_help_text: Vec::default(),
is_mac_os: cfg!(target_os = "macos"),
row_constraints,
@@ -313,36 +309,6 @@ impl Painter {
let terminal_height = terminal_size.height;
let terminal_width = terminal_size.width;
- if (self.height == 0 && self.width == 0)
- || (self.height != terminal_height || self.width != terminal_width)
- {
- app_state.is_force_redraw = true;
- self.height = terminal_height;
- self.width = terminal_width;
- }
-
- if app_state.should_get_widget_bounds() {
- // If we're force drawing, reset ALL mouse boundaries.
- for widget in app_state.widget_map.values_mut() {
- widget.top_left_corner = None;
- widget.bottom_right_corner = None;
- }
-
- // Reset dd_dialog...
- app_state.delete_dialog_state.button_positions = vec![];
-
- // Reset battery dialog...
- for battery_widget in app_state.battery_state.widget_states.values_mut() {
- battery_widget.tab_click_locs = None;
- }
-
- // Reset column headers for sorting in process widget...
- for proc_widget in app_state.proc_state.widget_states.values_mut() {
- proc_widget.columns.column_header_y_loc = None;
- proc_widget.columns.column_header_x_locs = None;
- }
- }
-
if app_state.help_dialog_state.is_showing_help {
let gen_help_len = GENERAL_HELP_TEXT.len() as u16 + 3;
let border_len = terminal_height.saturating_sub(gen_help_len) / 2;
@@ -461,39 +427,45 @@ impl Painter {
.constraints([Constraint::Percentage(100)])
.split(terminal_size);
match &app_state.current_widget.widget_type {
- Cpu => self.draw_cpu(
+ Cpu => draw_cpu(
+ self,
&mut f,
app_state,
rect[0],
app_state.current_widget.widget_id,
),
- CpuLegend => self.draw_cpu(
+ CpuLegend => draw_cpu(
+ self,
&mut f,
app_state,
rect[0],
app_state.current_widget.widget_id - 1,
),
- Mem | BasicMem => self.draw_memory_graph(
+ Mem | BasicMem => draw_memory_graph(
+ self,
&mut f,
app_state,
rect[0],
app_state.current_widget.widget_id,
),
- Disk => self.draw_disk_table(
+ Disk => draw_disk_table(
+ self,
&mut f,
app_state,
rect[0],
true,
app_state.current_widget.widget_id,
),
- Temp => self.draw_temp_table(
+ Temp => draw_temp_table(
+ self,
&mut f,
app_state,
rect[0],
true,
app_state.current_widget.widget_id,
),
- Net => self.draw_network_graph(
+ Net => draw_network_graph(
+ self,
&mut f,
app_state,
rect[0],
@@ -508,9 +480,10 @@ impl Painter {
_ => 0,
};
- self.draw_process_features(&mut f, app_state, rect[0], true, widget_id);
+ draw_process_features(self, &mut f, app_state, rect[0], true, widget_id);
}
- Battery => self.draw_battery_display(
+ Battery => draw_battery_display(
+ self,
&mut f,
app_state,
rect[0],
@@ -555,16 +528,17 @@ impl Painter {
.direction(Direction::Horizontal)
.constraints([Constraint::Percentage(50), Constraint::Percentage(50)])
.split(vertical_chunks[1]);
- self.draw_basic_cpu(&mut f, app_state, vertical_chunks[0], 1);
- self.draw_basic_memory(&mut f, app_state, middle_chunks[0], 2);
- self.draw_basic_network(&mut f, app_state, middle_chunks[1], 3);
+ draw_basic_cpu(self, &mut f, app_state, vertical_chunks[0], 1);
+ draw_basic_memory(self, &mut f, app_state, middle_chunks[0], 2);
+ draw_basic_network(self, &mut f, app_state, middle_chunks[1], 3);
let mut later_widget_id: Option<u64> = None;
if let Some(basic_table_widget_state) = &app_state.basic_table_widget_state {
let widget_id = basic_table_widget_state.currently_displayed_widget_id;
later_widget_id = Some(widget_id);
match basic_table_widget_state.currently_displayed_widget_type {
- Disk => self.draw_disk_table(
+ Disk => draw_disk_table(
+ self,
&mut f,
app_state,
vertical_chunks[3],
@@ -578,7 +552,8 @@ impl Painter {
ProcSort => 2,
_ => 0,
};
- self.draw_process_features(
+ draw_process_features(
+ self,
&mut f,
app_state,
vertical_chunks[3],
@@ -586,14 +561,16 @@ impl Painter {
wid,
);
}
- Temp => self.draw_temp_table(
+ Temp => draw_temp_table(
+ self,
&mut f,
app_state,
vertical_chunks[3],
false,
widget_id,
),
- Battery => self.draw_battery_display(
+ Battery => draw_battery_display(
+ self,
&mut f,
app_state,
vertical_chunks[3],
@@ -605,7 +582,7 @@ impl Painter {
}
if let Some(widget_id) = later_widget_id {
- self.draw_basic_table_arrows(&mut f, app_state, vertical_chunks[2], widget_id);
+ draw_basic_table_arrows(self, &mut f, app_state, vertical_chunks[2], widget_id);
}
} else {
// Draws using the passed in (or default) layout.
@@ -713,23 +690,25 @@ impl Painter {
for (widget, widget_draw_loc) in widgets.children.iter().zip(widget_draw_locs) {
match &widget.widget_type {
Empty => {}
- Cpu => self.draw_cpu(f, app_state, *widget_draw_loc, widget.widget_id),
- Mem => self.draw_memory_graph(f, app_state, *widget_draw_loc, widget.widget_id),
- Net => self.draw_network(f, app_state, *widget_draw_loc, widget.widget_id),
+ Cpu => draw_cpu(self, f, app_state, *widget_draw_loc, widget.widget_id),
+ Mem => draw_memory_graph(self, f, app_state, *widget_draw_loc, widget.widget_id),
+ Net => draw_network(self, f, app_state, *widget_draw_loc, widget.widget_id),
Temp => {
- self.draw_temp_table(f, app_state, *widget_draw_loc, true, widget.widget_id)
+ draw_temp_table(self, f, app_state, *widget_draw_loc, true, widget.widget_id)
}
Disk => {
- self.draw_disk_table(f, app_state, *widget_draw_loc, true, widget.widget_id)
+ draw_disk_table(self, f, app_state, *widget_draw_loc, true, widget.widget_id)
}
- Proc => self.draw_process_features(
+ Proc => draw_process_features(
+ self,
f,
app_state,
*widget_draw_loc,
true,
widget.widget_id,
),
- Battery => self.draw_battery_display(
+ Battery => draw_battery_display(
+ self,
f,
app_state,
*widget_draw_loc,
diff --git a/src/canvas/widgets.rs b/src/canvas/widgets.rs
index a76b4591..c2f5f91e 100644
--- a/src/canvas/widgets.rs
+++ b/src/canvas/widgets.rs
@@ -10,14 +10,14 @@ pub mod network_graph;
pub mod process_table;
pub mod temp_table;
-pub use basic_table_arrows::BasicTableArrows;
-pub use battery_display::BatteryDisplayWidget;
-pub use cpu_basic::CpuBasicWidget;
-pub use cpu_graph::CpuGraphWidget;
-pub use disk_table::DiskTableWidget;
-pub use mem_basic::MemBasicWidget;
-pub use mem_graph::MemGraphWidget;
-pub use network_basic::NetworkBasicWidget;
-pub use network_graph::NetworkGraphWidget;
-pub use process_table::ProcessTableWidget;
-pub use temp_table::TempTableWidget;
+pub use basic_table_arrows::*;
+pub use battery_display::*;
+pub use cpu_basic::*;
+pub use cpu_graph::*;
+pub use disk_table::*;
+pub use mem_basic::*;
+pub use mem_graph::*;
+pub use network_basic::*;
+pub use network_graph::*;
+pub use process_table::*;
+pub use temp_table::*;
diff --git a/src/canvas/widgets/basic_table_arrows.rs b/src/canvas/widgets/basic_table_arrows.rs
index 82c23245..8e1f476e 100644
--- a/src/canvas/widgets/basic_table_arrows.rs
+++ b/src/canvas/widgets/basic_table_arrows.rs
@@ -12,154 +12,142 @@ use tui::{
widgets::{Block, Paragraph},
};
-pub trait BasicTableArrows {
- fn draw_basic_table_arrows<B: Backend>(
- &self, f: &mut Frame<'_, B>, app_state: &mut AppState, draw_loc: Rect, widget_id: u64,
- );
-}
+pub fn draw_basic_table_arrows<B: Backend>(
+ painter: &Painter, f: &mut Frame<'_, B>, app_state: &mut AppState, draw_loc: Rect,
+ widget_id: u64,
+) {
+ if let Some(current_table) = app_state.widget_map.get(&widget_id) {
+ let current_table = if let BottomWidgetType::ProcSort = current_table.widget_type {
+ current_table
+ .right_neighbour
+ .map(|id| app_state.widget_map.get(&id).unwrap())
+ .unwrap()
+ } else {
+ current_table
+ };
-impl BasicTableArrows for Painter {
- fn draw_basic_table_arrows<B: Backend>(
- &self, f: &mut Frame<'_, B>, app_state: &mut AppState, draw_loc: Rect, widget_id: u64,
- ) {
- if let Some(current_table) = app_state.widget_map.get(&widget_id) {
- let current_table = if let BottomWidgetType::ProcSort = current_table.widget_type {
+ let (left_table, right_table) = (
+ {
current_table
- .right_neighbour
- .map(|id| app_state.widget_map.get(&id).unwrap())
- .unwrap()
- } else {
+ .left_neighbour
+ .map(|left_widget_id| {
+ app_state
+ .widget_map
+ .get(&left_widget_id)
+ .map(|left_widget| {
+ if left_widget.widget_type == BottomWidgetType::ProcSort {
+ left_widget
+ .left_neighbour
+ .map(|left_left_widget_id| {
+ app_state.widget_map.get(&left_left_widget_id).map(
+ |left_left_widget| &left_left_widget.widget_type,
+ )
+ })
+ .unwrap_or(Some(&BottomWidgetType::Temp))
+ .unwrap_or(&BottomWidgetType::Temp)
+ } else {
+ &left_widget.widget_type
+ }
+ })
+ .unwrap_or(&BottomWidgetType::Temp)
+ })
+ .unwrap_or(&BottomWidgetType::Temp)
+ },
+ {
current_table
- };
-
- let (left_table, right_table) = (
- {
- current_table
- .left_neighbour
- .map(|left_widget_id| {
- app_state
- .widget_map
- .get(&left_widget_id)
- .map(|left_widget| {
- if left_widget.widget_type == BottomWidgetType::ProcSort {
- left_widget
- .left_neighbour
- .map(|left_left_widget_id| {
- app_state.widget_map.get(&left_left_widget_id).map(
- |left_left_widget| {
- &left_left_widget.widget_type
- },
- )
- })
- .unwrap_or(Some(&BottomWidgetType::Temp))
- .unwrap_or(&BottomWidgetType::Temp)
- } else {
- &left_widget.widget_type
- }
- })
- .unwrap_or(&BottomWidgetType::Temp)
- })
- .unwrap_or(&BottomWidgetType::Temp)
- },
- {
- current_table
- .right_neighbour
- .map(|right_widget_id| {
- app_state
- .widget_map
- .get(&right_widget_id)
- .map(|right_widget| {
- if right_widget.widget_type == BottomWidgetType::ProcSort {
- right_widget
- .right_neighbour
- .map(|right_right_widget_id| {
- app_state
- .widget_map
- .get(&right_right_widget_id)
- .map(|right_right_widget| {
- &right_right_widget.widget_type
- })
- })
- .unwrap_or(Some(&BottomWidgetType::Disk))
- .unwrap_or(&BottomWidgetType::Disk)
- } else {
- &right_widget.widget_type
- }
- })
- .unwrap_or(&BottomWidgetType::Disk)
- })
- .unwrap_or(&BottomWidgetType::Disk)
- },
- );
+ .right_neighbour
+ .map(|right_widget_id| {
+ app_state
+ .widget_map
+ .get(&right_widget_id)
+ .map(|right_widget| {
+ if right_widget.widget_type == BottomWidgetType::ProcSort {
+ right_widget
+ .right_neighbour
+ .map(|right_right_widget_id| {
+ app_state.widget_map.get(&right_right_widget_id).map(
+ |right_right_widget| {
+ &right_right_widget.widget_type
+ },
+ )
+ })
+ .unwrap_or(Some(&BottomWidgetType::Disk))
+ .unwrap_or(&BottomWidgetType::Disk)
+ } else {
+ &right_widget.widget_type
+ }
+ })
+ .unwrap_or(&BottomWidgetType::Disk)
+ })
+ .unwrap_or(&BottomWidgetType::Disk)
+ },
+ );
- let left_name = left_table.get_pretty_name();
- let right_name = right_table.get_pretty_name();
+ let left_name = left_table.get_pretty_name();
+ let right_name = right_table.get_pretty_name();
- let num_spaces =
- usize::from(draw_loc.width).saturating_sub(6 + left_name.len() + right_name.len());
+ let num_spaces =
+ usize::from(draw_loc.width).saturating_sub(6 + left_name.len() + right_name.len());
- let left_arrow_text = vec![
- Spans::default(),
- Spans::from(Span::styled(
- format!("◄ {}", left_name),
- self.colours.text_style,
- )),
- ];
+ let left_arrow_text = vec![
+ Spans::default(),
+ Spans::from(Span::styled(
+ format!("◄ {}", left_name),
+ painter.colours.text_style,
+ )),
+ ];
- let right_arrow_text = vec![
- Spans::default(),
- Spans::from(Span::styled(
- format!("{} ►", right_name),
- self.colours.text_style,
- )),
- ];
+ let right_arrow_text = vec![
+ Spans::default(),
+ Spans::from(Span::styled(
+ format!("{} ►", right_name),
+ painter.colours.text_style,
+ )),
+ ];
- let margined_draw_loc = Layout::default()
- .direction(Direction::Horizontal)
- .constraints([
- Constraint::Length(2 + left_name.len() as u16),
- Constraint::Length(num_spaces as u16),
- Constraint::Length(2 + right_name.len() as u16),
- ])
- .horizontal_margin(1)
- .split(draw_loc);
+ let margined_draw_loc = Layout::default()
+ .direction(Direction::Horizontal)
+ .constraints([
+ Constraint::Length(2 + left_name.len() as u16),
+ Constraint::Length(num_spaces as u16),
+ Constraint::Length(2 + right_name.len() as u16),
+ ])
+ .horizontal_margin(1)
+ .split(draw_loc);
- f.render_widget(
- Paragraph::new(left_arrow_text).block(Block::default()),
- margined_draw_loc[0],
- );
- f.render_widget(
- Paragraph::new(right_arrow_text)
- .block(Block::default())
- .alignment(Alignment::Right),
- margined_draw_loc[2],
- );
+ f.render_widget(
+ Paragraph::new(left_arrow_text).block(Block::default()),
+ margined_draw_loc[0],
+ );
+ f.render_widget(
+ Paragraph::new(right_arrow_text)
+ .block(Block::default())
+ .alignment(Alignment::Right),
+ margined_draw_loc[2],
+ );
- if app_state.should_get_widget_bounds() {
- // Some explanations for future readers:
- // - The "height" as of writing of this entire widget is 2. If it's 1, it occasionally doesn't draw.
- // - As such, the buttons are only on the lower part of this 2-high widget.
- // - So, we want to only check at one location, the `draw_loc.y + 1`, and that's it.
- // - But why is it "+2" then? Well, it's because I have a REALLY ugly hack
- // for mouse button checking, since most button checks are of the form `(draw_loc.y + draw_loc.height)`,
- // and the same for the x and width. Unfortunately, if you check using >= and <=, the outer bound is
- // actually too large - so, we assume all of them are one too big and check via < (see
- // https://github.com/ClementTsang/bottom/pull/459 for details).
- // - So in other words, to make it simple, we keep this to a standard and overshoot by one here.
- if let Some(basic_table) = &mut app_state.basic_table_widget_state {
- basic_table.left_tlc =
- Some((margined_draw_loc[0].x, margined_draw_loc[0].y + 1));
- basic_table.left_brc = Some((
- margined_draw_loc[0].x + margined_draw_loc[0].width,
- margined_draw_loc[0].y + 2,
- ));
- basic_table.right_tlc =
- Some((margined_draw_loc[2].x, margined_draw_loc[2].y + 1));
- basic_table.right_brc = Some((
- margined_draw_loc[2].x + margined_draw_loc[2].width,
- margined_draw_loc[2].y + 2,
- ));
- }
+ if app_state.should_get_widget_bounds() {
+ // Some explanations for future readers:
+ // - The "height" as of writing of this entire widget is 2. If it's 1, it occasionally doesn't draw.
+ // - As such, the buttons are only on the lower part of this 2-high widget.
+ // - So, we want to only check at one location, the `draw_loc.y + 1`, and that's it.
+ // - But why is it "+2" then? Well, it's because I have a REALLY ugly hack
+ // for mouse button checking, since most button checks are of the form `(draw_loc.y + draw_loc.height)`,
+ // and the same for the x and width. Unfortunately, if you check using >= and <=, the outer bound is
+ // actually too large - so, we assume all of them are one too big and check via < (see
+ // https://github.com/ClementTsang/bottom/pull/459 for details).
+ // - So in other words, to make it simple, we keep this to a standard and overshoot by one here.
+ if let Some(basic_table) = &mut app_state.basic_table_widget_state {
+ basic_table.left_tlc = Some((margined_draw_loc[0].x, margined_draw_loc[0].y + 1));
+ basic_table.left_brc = Some((
+ margined_draw_loc[0].x + margined_draw_loc[0].width,
+ margined_draw_loc[0].y + 2,
+ ));
+ basic_table.right_tlc = Some((margined_draw_loc[2].x, margined_draw_loc[2].y + 1));
+ basic_table.right_brc = Some((
+ margined_draw_loc[2].x + margined_draw_loc[2].width,
+ margined_draw_loc[2].y + 2,
+ ));
}
}
}
diff --git a/src/canvas/widgets/battery_display.rs b/src/canvas/widgets/battery_display.rs
index 34d9783c..2b9fe5f5 100644
--- a/src/canvas/widgets/battery_display.rs
+++ b/src/canvas/widgets/battery_display.rs
@@ -13,198 +13,184 @@ use tui::{
};
use unicode_segmentation::UnicodeSegmentation;
-pub trait BatteryDisplayWidget {
- fn draw_battery_display<B: Backend>(
- &self, f: &mut Frame<'_, B>, app_state: &mut AppState, draw_loc: Rect, draw_border: bool,
- widget_id: u64,
- );
-}
-
-impl BatteryDisplayWidget for Painter {
- fn draw_battery_display<B: Backend>(
- &self, f: &mut Frame<'_, B>, app_state: &mut AppState, draw_loc: Rect, draw_border: bool,
- widget_id: u64,
- ) {
- let should_get_widget_bounds = app_state.should_get_widget_bounds();
- if let Some(battery_widget_state) =
- app_state.battery_state.widget_states.get_mut(&widget_id)
- {
- let is_on_widget = widget_id == app_state.current_widget.widget_id;
- let border_style = if is_on_widget {
- self.colours.highlighted_border_style
- } else {
- self.colours.border_style
- };
- let table_gap = if draw_loc.height < TABLE_GAP_HEIGHT_LIMIT {
- 0
- } else {
- app_state.app_config_fields.table_gap
- };
-
- let title = if app_state.is_expanded {
- const TITLE_BASE: &str = " Battery ── Esc to go back ";
- Spans::from(vec![
- Span::styled(" Battery ".to_string(), self.colours.widget_title_style),
- Span::styled(
- format!(
- "─{}─ Esc to go back ",
- "─".repeat(usize::from(draw_loc.width).saturating_sub(
- UnicodeSegmentation::graphemes(TITLE_BASE, true).count() + 2
- ))
- ),
- border_style,
+pub fn draw_battery_display<B: Backend>(
+ painter: &Painter, f: &mut Frame<'_, B>, app_state: &mut AppState, draw_loc: Rect,
+ draw_border: bool, widget_id: u64,
+) {
+ let should_get_widget_bounds = app_state.should_get_widget_bounds();
+ if let Some(battery_widget_state) = app_state.battery_state.widget_states.get_mut(&widget_id) {
+ let is_on_widget = widget_id == app_state.current_widget.widget_id;
+ let border_style = if is_on_widget {
+ painter.colours.highlighted_border_style
+ } else {
+ painter.colours.border_style
+ };
+ let table_gap = if draw_loc.height < TABLE_GAP_HEIGHT_LIMIT {
+ 0
+ } else {
+ app_state.app_config_fields.table_gap
+ };
+
+ let title = if app_state.is_expanded {
+ const TITLE_BASE: &str = " Battery ── Esc to go back ";
+ Spans::from(vec![
+ Span::styled(" Battery ".to_string(), painter.colours.widget_title_style),
+ Span::styled(
+ format!(
+ "─{}─ Esc to go back ",
+ "─".repeat(usize::from(draw_loc.width).saturating_sub(
+ UnicodeSegmentation::graphemes(TITLE_BASE, true).count() + 2
+ ))
),
- ])
- } else {
- Spans::from(Span::styled(
- " Battery ".to_string(),
- self.colours.widget_title_style,
- ))
- };
-
- let battery_block = if draw_border {
- Block::default()
- .title(title)
- .borders(Borders::ALL)
- .border_style(border_style)
- } else if is_on_widget {
- Block::default()
- .borders(*SIDE_BORDERS)
- .border_style(self.colours.highlighted_border_style)
- } else {
- Block::default().borders(Borders::NONE)
- };
-
- let battery_names = app_state
- .canvas_data
- .battery_data
- .iter()
- .map(|battery| &battery.battery_name)
- .collect::<Vec<_>>();
-
- let tab_draw_loc = Layout::default()
- .constraints([
- Constraint::Length(1),
- Constraint::Length(2),
- Constraint::Min(0),
- ])
- .direction(Direction::Vertical)
- .split(draw_loc)[1];
+ border_style,
+ ),
+ ])
+ } else {
+ Spans::from(Span::styled(
+ " Battery ".to_string(),
+ painter.colours.widget_title_style,
+ ))
+ };
+
+ let battery_block = if draw_border {
+ Block::default()
+ .title(title)
+ .borders(Borders::ALL)
+ .border_style(border_style)
+ } else if is_on_widget {
+ Block::default()
+ .borders(*SIDE_BORDERS)
+ .border_style(painter.colours.highlighted_border_style)
+ } else {
+ Block::default().borders(Borders::NONE)
+ };
+
+ let battery_names = app_state
+ .canvas_data
+ .battery_data
+ .iter()
+ .map(|battery| &battery.battery_name)
+ .collect::<Vec<_>>();
+
+ let tab_draw_loc = Layout::default()
+ .constraints([
+ Constraint::Length(1),
+ Constraint::Length(2),
+ Constraint::Min(0),
+ ])
+ .direction(Direction::Vertical)
+ .split(draw_loc)[1];
+
+ f.render_widget(
+ Tabs::new(
+ battery_names
+ .iter()
+ .map(|name| Spans::from((*name).clone()))
+ .collect::<Vec<_>>(),
+ )
+ .block(Block::default())
+ .divider(tui::symbols::line::VERTICAL)
+ .style(painter.colours.text_style)
+ .highlight_style(painter.colours.currently_selected_text_style)
+ .select(battery_widget_state.currently_selected_battery_index),
+ tab_draw_loc,
+ );
+
+ let margined_draw_loc = Layout::default()
+ .constraints([Constraint::Percentage(100)])
+ .horizontal_margin(if is_on_widget || draw_border { 0 } else { 1 })
+ .direction(Direction::Horizontal)
+ .split(draw_loc)[0];
+
+ if let Some(battery_details) = app_state
+ .canvas_data
+ .battery_data
+ .get(battery_widget_state.currently_selected_battery_index)
+ {
+ // Assuming a 50/50 split in width
+ let bar_length = usize::from((draw_loc.width.saturating_sub(2) / 2).saturating_sub(8));
+ let charge_percentage = battery_details.charge_percentage;
+ let num_bars = calculate_basic_use_bars(charge_percentage, bar_length);
+ let bars = format!(
+ "[{}{}{:3.0}%]",
+ "|".repeat(num_bars),
+ " ".repeat(bar_length - num_bars),
+ charge_percentage,
+ );
+ let battery_rows = vec![
+ Row::new(vec![