feature: add battery flag

This commit is contained in:
ClementTsang 2020-04-27 15:52:39 -04:00
parent 8534d42f1b
commit 8e4f6a3a02
8 changed files with 301 additions and 145 deletions

View File

@ -143,20 +143,21 @@ Run using `btm`.
-s, --show_disabled_data Shows disabled CPU entries in the CPU legend
-b, --basic Enables basic mode, removing charts and condensing data
--autohide_time Automatically hide the time scaling in graphs after being shown for a brief moment when
zoomed in/out. If time is disabled via --hide_time then this will have no effect.
zoomed in/out. If time is disabled via --hide_time then this will have no effect
--use_old_network_legend Use the older (pre-0.4) network legend which is separate from the network chart
--hide_table_gap Hides the spacing between table headers and data
--battery Displays the battery widget for default and basic layouts
```
### Options
```
-r, --rate <MS> Set the refresh rate in milliseconds [default: 1000]
-C, --config <PATH> Use the specified config file; if it does not exist it is automatically created
-C, --config <PATH> Use the specified config file; if it does not exist it is automatically created [default: see section on config files]
-t, --default_time_value <MS> Sets the default time interval for charts in milliseconds [default: 60000]
-d, --time_delta <MS> Sets the default amount each zoom in/out action changes by in milliseconds [default: 15000]
--default_widget_count <COUNT> Which number of the selected widget type to select, from left to right, top to bottom. Defaults to 1.
--default_widget_type <TYPE> The default widget type to select by default.
--default_widget_count <COUNT> Which number of the selected widget type to select, from left to right, top to bottom [default: 1]
--default_widget_type <TYPE> The default widget type to select by default [default: "process"]
```
### Keybindings

View File

@ -1213,6 +1213,7 @@ impl App {
| BottomWidgetType::Proc
| BottomWidgetType::ProcSearch
| BottomWidgetType::Disk
| BottomWidgetType::Battery
if self.basic_table_widget_state.is_some() =>
{
if let Some(basic_table_widget_state) =
@ -1311,6 +1312,7 @@ impl App {
| BottomWidgetType::Proc
| BottomWidgetType::ProcSearch
| BottomWidgetType::Disk
| BottomWidgetType::Battery
if self.basic_table_widget_state.is_some() =>
{
if let Some(basic_table_widget_state) =

View File

@ -510,7 +510,141 @@ impl BottomLayout {
}
}
pub fn init_basic_default() -> Self {
pub fn init_basic_default(use_battery: bool) -> Self {
let table_widgets = if use_battery {
vec![
BottomCol::builder()
.canvas_handle_width(true)
.children(vec![BottomColRow::builder()
.canvas_handle_height(true)
.children(vec![BottomWidget::builder()
.canvas_handle_width(true)
.widget_type(BottomWidgetType::Disk)
.widget_id(4)
.up_neighbour(Some(100))
.left_neighbour(Some(8))
.right_neighbour(Some(DEFAULT_WIDGET_ID))
.build()])
.build()])
.build(),
BottomCol::builder()
.canvas_handle_width(true)
.children(vec![
BottomColRow::builder()
.canvas_handle_height(true)
.children(vec![BottomWidget::builder()
.canvas_handle_width(true)
.widget_type(BottomWidgetType::Proc)
.widget_id(DEFAULT_WIDGET_ID)
.up_neighbour(Some(100))
.down_neighbour(Some(DEFAULT_WIDGET_ID + 1))
.left_neighbour(Some(4))
.right_neighbour(Some(8))
.build()])
.build(),
BottomColRow::builder()
.canvas_handle_height(true)
.children(vec![BottomWidget::builder()
.canvas_handle_width(true)
.widget_type(BottomWidgetType::ProcSearch)
.widget_id(DEFAULT_WIDGET_ID + 1)
.up_neighbour(Some(DEFAULT_WIDGET_ID))
.left_neighbour(Some(4))
.right_neighbour(Some(7))
.build()])
.build(),
])
.build(),
BottomCol::builder()
.canvas_handle_width(true)
.children(vec![BottomColRow::builder()
.canvas_handle_height(true)
.children(vec![BottomWidget::builder()
.canvas_handle_width(true)
.widget_type(BottomWidgetType::Temp)
.widget_id(7)
.up_neighbour(Some(100))
.left_neighbour(Some(DEFAULT_WIDGET_ID))
.right_neighbour(Some(8))
.build()])
.build()])
.build(),
BottomCol::builder()
.canvas_handle_width(true)
.children(vec![BottomColRow::builder()
.canvas_handle_height(true)
.children(vec![BottomWidget::builder()
.canvas_handle_width(true)
.widget_type(BottomWidgetType::Battery)
.widget_id(8)
.up_neighbour(Some(100))
.left_neighbour(Some(7))
.right_neighbour(Some(4))
.build()])
.build()])
.build(),
]
} else {
vec![
BottomCol::builder()
.canvas_handle_width(true)
.children(vec![BottomColRow::builder()
.canvas_handle_height(true)
.children(vec![BottomWidget::builder()
.canvas_handle_width(true)
.widget_type(BottomWidgetType::Disk)
.widget_id(4)
.up_neighbour(Some(100))
.left_neighbour(Some(7))
.right_neighbour(Some(DEFAULT_WIDGET_ID))
.build()])
.build()])
.build(),
BottomCol::builder()
.canvas_handle_width(true)
.children(vec![
BottomColRow::builder()
.canvas_handle_height(true)
.children(vec![BottomWidget::builder()
.canvas_handle_width(true)
.widget_type(BottomWidgetType::Proc)
.widget_id(DEFAULT_WIDGET_ID)
.up_neighbour(Some(100))
.down_neighbour(Some(DEFAULT_WIDGET_ID + 1))
.left_neighbour(Some(4))
.right_neighbour(Some(7))
.build()])
.build(),
BottomColRow::builder()
.canvas_handle_height(true)
.children(vec![BottomWidget::builder()
.canvas_handle_width(true)
.widget_type(BottomWidgetType::ProcSearch)
.widget_id(DEFAULT_WIDGET_ID + 1)
.up_neighbour(Some(DEFAULT_WIDGET_ID))
.left_neighbour(Some(4))
.right_neighbour(Some(7))
.build()])
.build(),
])
.build(),
BottomCol::builder()
.canvas_handle_width(true)
.children(vec![BottomColRow::builder()
.canvas_handle_height(true)
.children(vec![BottomWidget::builder()
.canvas_handle_width(true)
.widget_type(BottomWidgetType::Temp)
.widget_id(7)
.up_neighbour(Some(100))
.left_neighbour(Some(DEFAULT_WIDGET_ID))
.right_neighbour(Some(4))
.build()])
.build()])
.build(),
]
};
BottomLayout {
total_row_height_ratio: 3,
rows: vec![
@ -573,119 +707,93 @@ impl BottomLayout {
.build(),
BottomRow::builder()
.canvas_handle_height(true)
.children(vec![
BottomCol::builder()
.canvas_handle_width(true)
.children(vec![BottomColRow::builder()
.canvas_handle_height(true)
.children(vec![BottomWidget::builder()
.canvas_handle_width(true)
.widget_type(BottomWidgetType::Disk)
.widget_id(4)
.up_neighbour(Some(100))
.left_neighbour(Some(7))
.right_neighbour(Some(DEFAULT_WIDGET_ID))
.build()])
.build()])
.build(),
BottomCol::builder()
.canvas_handle_width(true)
.children(vec![
BottomColRow::builder()
.canvas_handle_height(true)
.children(vec![BottomWidget::builder()
.canvas_handle_width(true)
.widget_type(BottomWidgetType::Proc)
.widget_id(DEFAULT_WIDGET_ID)
.up_neighbour(Some(100))
.down_neighbour(Some(DEFAULT_WIDGET_ID + 1))
.left_neighbour(Some(4))
.right_neighbour(Some(7))
.build()])
.build(),
BottomColRow::builder()
.canvas_handle_height(true)
.children(vec![BottomWidget::builder()
.canvas_handle_width(true)
.widget_type(BottomWidgetType::ProcSearch)
.widget_id(DEFAULT_WIDGET_ID + 1)
.up_neighbour(Some(DEFAULT_WIDGET_ID))
.left_neighbour(Some(4))
.right_neighbour(Some(7))
.build()])
.build(),
])
.build(),
BottomCol::builder()
.canvas_handle_width(true)
.children(vec![BottomColRow::builder()
.canvas_handle_height(true)
.children(vec![BottomWidget::builder()
.canvas_handle_width(true)
.widget_type(BottomWidgetType::Temp)
.widget_id(7)
.up_neighbour(Some(100))
.left_neighbour(Some(DEFAULT_WIDGET_ID))
.right_neighbour(Some(4))
.build()])
.build()])
.build(),
])
.children(table_widgets)
.build(),
],
}
}
pub fn init_default(left_legend: bool) -> Self {
pub fn init_default(left_legend: bool, use_battery: bool) -> Self {
let cpu_layout = if left_legend {
vec![
BottomWidget::builder()
.width_ratio(3)
.widget_type(BottomWidgetType::CpuLegend)
.widget_id(2)
.down_neighbour(Some(11))
.right_neighbour(Some(1))
.canvas_handle_width(true)
.build(),
BottomWidget::builder()
.width_ratio(17)
.widget_type(BottomWidgetType::Cpu)
.widget_id(1)
.down_neighbour(Some(12))
.left_neighbour(Some(2))
.right_neighbour(if use_battery { Some(99) } else { None })
.flex_grow(true)
.build(),
]
} else {
vec![
BottomWidget::builder()
.width_ratio(17)
.widget_type(BottomWidgetType::Cpu)
.widget_id(1)
.down_neighbour(Some(11))
.right_neighbour(Some(2))
.flex_grow(true)
.build(),
BottomWidget::builder()
.width_ratio(3)
.widget_type(BottomWidgetType::CpuLegend)
.widget_id(2)
.down_neighbour(Some(12))
.left_neighbour(Some(1))
.right_neighbour(if use_battery { Some(99) } else { None })
.canvas_handle_width(true)
.build(),
]
};
let first_row_layout = if use_battery {
vec![
BottomCol::builder()
.col_width_ratio(2)
.children(vec![BottomColRow::builder()
.total_widget_ratio(20)
.children(cpu_layout)
.build()])
.build(),
BottomCol::builder()
.col_width_ratio(1)
.children(vec![BottomColRow::builder()
.children(vec![BottomWidget::builder()
.widget_type(BottomWidgetType::Battery)
.widget_id(99)
.down_neighbour(Some(12))
.left_neighbour(Some(if left_legend { 1 } else { 2 }))
.canvas_handle_width(true)
.build()])
.build()])
.build(),
]
} else {
vec![BottomCol::builder()
.children(vec![BottomColRow::builder()
.total_widget_ratio(20)
.children(cpu_layout)
.build()])
.build()]
};
BottomLayout {
total_row_height_ratio: 100,
rows: vec![
BottomRow::builder()
.row_height_ratio(30)
.children(vec![BottomCol::builder()
.children(vec![BottomColRow::builder()
.total_widget_ratio(20)
.children(if left_legend {
vec![
BottomWidget::builder()
.width_ratio(3)
.widget_type(BottomWidgetType::CpuLegend)
.widget_id(2)
.down_neighbour(Some(11))
.right_neighbour(Some(1))
.canvas_handle_width(true)
.build(),
BottomWidget::builder()
.width_ratio(17)
.widget_type(BottomWidgetType::Cpu)
.widget_id(1)
.down_neighbour(Some(12))
.left_neighbour(Some(2))
.flex_grow(true)
.build(),
]
} else {
vec![
BottomWidget::builder()
.width_ratio(17)
.widget_type(BottomWidgetType::Cpu)
.widget_id(1)
.down_neighbour(Some(11))
.right_neighbour(Some(2))
.flex_grow(true)
.build(),
BottomWidget::builder()
.width_ratio(3)
.widget_type(BottomWidgetType::CpuLegend)
.widget_id(2)
.down_neighbour(Some(12))
.left_neighbour(Some(1))
.canvas_handle_width(true)
.build(),
]
})
.build()])
.build()])
.total_col_ratio(if use_battery { 3 } else { 1 })
.children(first_row_layout)
.build(),
BottomRow::builder()
.total_col_ratio(7)
@ -907,6 +1015,7 @@ impl BottomWidgetType {
Proc => "Processes",
Temp => "Temperature",
Disk => "Disks",
Battery => "Battery",
_ => "",
}
}

View File

@ -350,6 +350,7 @@ impl Painter {
&mut f,
app_state,
rect[0],
true,
app_state.current_widget.widget_id,
),
_ => {}
@ -410,6 +411,13 @@ impl Painter {
false,
widget_id,
),
Battery => self.draw_battery_display(
&mut f,
app_state,
vertical_chunks[4],
false,
widget_id,
),
_ => {}
}
}
@ -541,9 +549,13 @@ impl Painter {
true,
widget.widget_id,
),
Battery => {
self.draw_battery_display(f, app_state, *widget_draw_loc, widget.widget_id)
}
Battery => self.draw_battery_display(
f,
app_state,
*widget_draw_loc,
true,
widget.widget_id,
),
_ => {}
}
}

View File

@ -23,19 +23,38 @@ impl BasicTableArrows for Painter {
&self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect,
) {
// Effectively a paragraph with a ton of spacing
let (left_table, right_table) =
if let Some(basic_table_widget_state) = &app_state.basic_table_widget_state {
match basic_table_widget_state.currently_displayed_widget_type {
BottomWidgetType::Proc | BottomWidgetType::ProcSearch => {
(BottomWidgetType::Temp, BottomWidgetType::Disk)
}
BottomWidgetType::Disk => (BottomWidgetType::Proc, BottomWidgetType::Temp),
BottomWidgetType::Temp => (BottomWidgetType::Disk, BottomWidgetType::Proc),
_ => (BottomWidgetType::Disk, BottomWidgetType::Temp),
}
} else {
(BottomWidgetType::Disk, BottomWidgetType::Temp)
};
let (left_table, right_table) = (
{
app_state
.current_widget
.left_neighbour
.and_then(|left_widget_id| {
Some(
app_state
.widget_map
.get(&left_widget_id)
.and_then(|left_widget| Some(&left_widget.widget_type))
.unwrap_or_else(|| &BottomWidgetType::Temp),
)
})
.unwrap_or_else(|| &BottomWidgetType::Temp)
},
{
app_state
.current_widget
.right_neighbour
.and_then(|right_widget_id| {
Some(
app_state
.widget_map
.get(&right_widget_id)
.and_then(|right_widget| Some(&right_widget.widget_type))
.unwrap_or_else(|| &BottomWidgetType::Disk),
)
})
.unwrap_or_else(|| &BottomWidgetType::Disk)
},
);
let left_name = left_table.get_pretty_name();
let right_name = right_table.get_pretty_name();
@ -46,12 +65,9 @@ impl BasicTableArrows for Painter {
) as usize;
let arrow_text = vec![
Text::Styled(
format!("\n{}", right_name).into(),
self.colours.text_style,
),
Text::Styled(format!("\n{}", left_name).into(), self.colours.text_style),
Text::Raw(" ".repeat(num_spaces).into()),
Text::Styled(format!("{}", left_name).into(), self.colours.text_style),
Text::Styled(format!("{}", right_name).into(), self.colours.text_style),
];
let margined_draw_loc = Layout::default()

View File

@ -3,6 +3,7 @@ use std::cmp::max;
use crate::{
app::App,
canvas::{drawing_utils::calculate_basic_use_bars, Painter},
constants::*,
};
use tui::{
@ -14,17 +15,20 @@ use tui::{
pub trait BatteryDisplayWidget {
fn draw_battery_display<B: Backend>(
&self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect, widget_id: u64,
&self, f: &mut Frame<'_, B>, app_state: &mut App, 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 App, draw_loc: Rect, widget_id: u64,
&self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect, draw_border: bool,
widget_id: u64,
) {
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 title = if app_state.is_expanded {
const TITLE_BASE: &str = " Battery ── Esc to go back ";
let repeat_num = max(
@ -40,21 +44,29 @@ impl BatteryDisplayWidget for Painter {
" Battery ".to_string()
};
let border_and_title_style = if app_state.current_widget.widget_id == widget_id {
let border_and_title_style = if is_on_widget {
self.colours.highlighted_border_style
} else {
self.colours.border_style
};
let battery_block = Block::default()
.title(&title)
.title_style(if app_state.is_expanded {
border_and_title_style
} else {
self.colours.widget_title_style
})
.borders(Borders::ALL)
.border_style(border_and_title_style);
let battery_block = if draw_border {
Block::default()
.title(&title)
.title_style(if app_state.is_expanded {
border_and_title_style
} else {
self.colours.widget_title_style
})
.borders(Borders::ALL)
.border_style(border_and_title_style)
} else if is_on_widget {
Block::default()
.borders(*SIDE_BORDERS)
.border_style(self.colours.highlighted_border_style)
} else {
Block::default().borders(Borders::NONE)
};
if let Some(battery_details) = app_state
.canvas_data

View File

@ -94,7 +94,11 @@ impl TempTableWidget for Painter {
let temp_block = if draw_border {
Block::default()
.title(&title)
.title_style(border_and_title_style)
.title_style(if app_state.is_expanded {
border_and_title_style
} else {
self.colours.widget_title_style
})
.borders(Borders::ALL)
.border_style(border_and_title_style)
} else if is_on_widget {

View File

@ -262,7 +262,7 @@ pub fn get_widget_layout(
let bottom_layout = if get_use_basic_mode(matches, config) {
default_widget_id = DEFAULT_WIDGET_ID;
BottomLayout::init_basic_default()
BottomLayout::init_basic_default(get_use_battery(matches, config))
} else if let Some(rows) = &config.row {
let mut iter_id = 0; // A lazy way of forcing unique IDs *shrugs*
let mut total_height_ratio = 0;
@ -284,7 +284,7 @@ pub fn get_widget_layout(
total_row_height_ratio: total_height_ratio,
};
// Confirm that we have at least ONE widget - if we don't, go back to default!
// Confirm that we have at least ONE widget - if not, error out!
if iter_id > 0 {
ret_bottom_layout.get_movement_mappings();
ret_bottom_layout
@ -295,7 +295,7 @@ pub fn get_widget_layout(
}
} else {
default_widget_id = DEFAULT_WIDGET_ID;
BottomLayout::init_default(left_legend)
BottomLayout::init_default(left_legend, get_use_battery(matches, config))
};
Ok((bottom_layout, default_widget_id))