other: hide battery tab selector if there is only one battery (#1236)

* other: hide battery tab selector if there is only one battery

* update changelog
This commit is contained in:
Clement Tsang 2023-07-02 00:38:40 -04:00 committed by GitHub
parent 3f53818c54
commit df3088e80e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 73 additions and 64 deletions

View file

@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- [#1230](https://github.com/ClementTsang/bottom/pull/1230): Fix core dump if the terminal is closed while bottom is open.
## Changes
- [#1236](https://github.com/ClementTsang/bottom/pull/1236): Hide the battery tab selector if there is only one battery detected.
## [0.9.3] - 2023-06-25
## Bug Fixes

View file

@ -693,7 +693,7 @@ impl App {
}
}
BottomWidgetType::Battery => {
if !self.converted_data.battery_data.is_empty() {
if self.converted_data.battery_data.len() > 1 {
if let Some(battery_widget_state) = self
.states
.battery_state
@ -754,7 +754,7 @@ impl App {
}
}
BottomWidgetType::Battery => {
if !self.converted_data.battery_data.is_empty() {
if self.converted_data.battery_data.len() > 1 {
let battery_count = self.converted_data.battery_data.len();
if let Some(battery_widget_state) = self
.states

View file

@ -6,6 +6,7 @@ use tui::{
widgets::{Block, Borders, Cell, Paragraph, Row, Table, Tabs},
};
use unicode_segmentation::UnicodeSegmentation;
use unicode_width::UnicodeWidthStr;
use crate::{
app::App,
@ -69,36 +70,55 @@ impl Painter {
Block::default().borders(Borders::NONE)
};
let battery_names = app_state
.converted_data
.battery_data
.iter()
.map(|battery| &battery.battery_name)
.collect::<Vec<_>>();
if app_state.converted_data.battery_data.len() > 1 {
let battery_names = app_state
.converted_data
.battery_data
.iter()
.enumerate()
.map(|(itx, _)| format!("Battery {itx}"))
.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];
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| Line::from((*name).clone()))
.collect::<Vec<_>>(),
)
.block(Block::default())
.divider(tui::symbols::line::VERTICAL)
.style(self.colours.text_style)
.highlight_style(self.colours.currently_selected_text_style)
.select(battery_widget_state.currently_selected_battery_index),
tab_draw_loc,
);
f.render_widget(
Tabs::new(
battery_names
.iter()
.map(|name| Line::from((*name).clone()))
.collect::<Vec<_>>(),
)
.divider(tui::symbols::line::VERTICAL)
.style(self.colours.text_style)
.highlight_style(self.colours.currently_selected_text_style)
.select(battery_widget_state.currently_selected_battery_index),
tab_draw_loc,
);
if should_get_widget_bounds {
let mut current_x = tab_draw_loc.x;
let current_y = tab_draw_loc.y;
let mut tab_click_locs: Vec<((u16, u16), (u16, u16))> = vec![];
for battery in battery_names {
// +1 because there's a space after the tab label.
let width = UnicodeWidthStr::width(battery.as_str()) as u16;
tab_click_locs
.push(((current_x, current_y), (current_x + width, current_y)));
// +4 because we want to go one space, then one space past to get to the '|', then 2 more
// to start at the blank space before the tab label.
current_x += width + 4;
}
battery_widget_state.tab_click_locs = Some(tab_click_locs);
}
}
let margined_draw_loc = Layout::default()
.constraints([Constraint::Percentage(100)])
@ -183,28 +203,28 @@ impl Painter {
Row::new(["State", &battery_details.state]).style(self.colours.text_style),
);
let mut s: String; // Keep string in scope.
let mut time: String; // Keep string lifetime in scope.
{
let style = self.colours.text_style;
match &battery_details.battery_duration {
BatteryDuration::ToEmpty(secs) => {
s = long_time(*secs);
time = long_time(*secs);
if half_width as usize > s.len() {
battery_rows.push(Row::new(["Time to empty", &s]).style(style));
if half_width as usize > time.len() {
battery_rows.push(Row::new(["Time to empty", &time]).style(style));
} else {
s = short_time(*secs);
battery_rows.push(Row::new(["To empty", &s]).style(style));
time = short_time(*secs);
battery_rows.push(Row::new(["To empty", &time]).style(style));
}
}
BatteryDuration::ToFull(secs) => {
s = long_time(*secs);
time = long_time(*secs);
if half_width as usize > s.len() {
battery_rows.push(Row::new(["Time to full", &s]).style(style));
if half_width as usize > time.len() {
battery_rows.push(Row::new(["Time to full", &time]).style(style));
} else {
s = short_time(*secs);
battery_rows.push(Row::new(["To full", &s]).style(style));
time = short_time(*secs);
battery_rows.push(Row::new(["To full", &time]).style(style));
}
}
BatteryDuration::Empty
@ -217,11 +237,17 @@ impl Painter {
Row::new(["Health %", &battery_details.health]).style(self.colours.text_style),
);
let header = if app_state.converted_data.battery_data.len() > 1 {
Row::new([""]).bottom_margin(table_gap)
} else {
Row::default()
};
// Draw
f.render_widget(
Table::new(battery_rows)
.block(battery_block)
.header(Row::new([""]).bottom_margin(table_gap))
.header(header)
.widths(&[Constraint::Percentage(50), Constraint::Percentage(50)]),
margined_draw_loc,
);
@ -240,24 +266,6 @@ impl Painter {
}
if should_get_widget_bounds {
// Tab wizardry
if !battery_names.is_empty() {
let mut current_x = tab_draw_loc.x;
let current_y = tab_draw_loc.y;
let mut tab_click_locs: Vec<((u16, u16), (u16, u16))> = vec![];
for battery in battery_names {
// +1 because there's a space after the tab label.
let width = unicode_width::UnicodeWidthStr::width(battery.as_str()) as u16;
tab_click_locs
.push(((current_x, current_y), (current_x + width, current_y)));
// +4 because we want to go one space, then one space past to get to the '|', then 2 more
// to start at the blank space before the tab label.
current_x += width + 4;
}
battery_widget_state.tab_click_locs = Some(tab_click_locs);
}
// Update draw loc in widget map
if let Some(widget) = app_state.widget_map.get_mut(&widget_id) {
widget.top_left_corner = Some((margined_draw_loc.x, margined_draw_loc.y));

View file

@ -26,7 +26,6 @@ pub enum BatteryDuration {
#[derive(Default, Debug)]
pub struct ConvertedBatteryData {
pub battery_name: String,
pub charge_percentage: f64,
pub watt_consumption: String,
pub battery_duration: BatteryDuration,
@ -520,9 +519,7 @@ pub fn convert_battery_harvest(current_data: &DataCollection) -> Vec<ConvertedBa
current_data
.battery_harvest
.iter()
.enumerate()
.map(|(itx, battery_harvest)| ConvertedBatteryData {
battery_name: format!("Battery {}", itx),
.map(|battery_harvest| ConvertedBatteryData {
charge_percentage: battery_harvest.charge_percent,
watt_consumption: format!("{:.2}W", battery_harvest.power_consumption_rate_watts),
battery_duration: if let Some(secs) = battery_harvest.secs_until_empty {