mirror of
https://github.com/ClementTsang/bottom
synced 2024-11-22 12:13:06 +00:00
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:
parent
3f53818c54
commit
df3088e80e
4 changed files with 73 additions and 64 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in a new issue