summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClement Tsang <34804052+ClementTsang@users.noreply.github.com>2023-12-10 15:21:35 -0500
committerGitHub <noreply@github.com>2023-12-10 15:21:35 -0500
commitb6f92c2f3d4773870a6cde224fb2844d291989d2 (patch)
tree048c5dfd759ca3fa0ff8ea46ec49fe2c130addef
parent300f66700e41d9ff5adb5f100c4455683ebaa6d5 (diff)
feature: support default selection of average CPU graph (#1353)
* feature: support default selection of average CPU graph * test
-rw-r--r--.cargo/config.toml12
-rw-r--r--docs/content/configuration/config-file/cpu.md11
-rw-r--r--sample_configs/default_config.toml4
-rw-r--r--src/app.rs22
-rw-r--r--src/components/data_table.rs16
-rw-r--r--src/components/data_table/draw.rs9
-rw-r--r--src/components/data_table/sortable.rs1
-rw-r--r--src/constants.rs4
-rw-r--r--src/options.rs13
-rw-r--r--src/options/cpu.rs79
-rw-r--r--src/widgets/cpu_graph.rs15
11 files changed, 152 insertions, 34 deletions
diff --git a/.cargo/config.toml b/.cargo/config.toml
index 4d45f24b..7e766c36 100644
--- a/.cargo/config.toml
+++ b/.cargo/config.toml
@@ -3,15 +3,3 @@ rustflags = ["-C", "target-feature=+crt-static"]
[target.i686-pc-windows-msvc]
rustflags = ["-C", "target-feature=+crt-static"]
-
-# [target.arm-unknown-linux-gnueabihf]
-# linker = "arm-linux-gnueabihf-gcc"
-
-# [target.armv7-unknown-linux-gnueabihf]
-# linker = "arm-linux-gnueabihf-gcc"
-
-# [target.aarch64-unknown-linux-gnu]
-# linker = "aarch64-linux-gnu-gcc"
-
-# [target.aarch64-unknown-linux-musl]
-# linker = "aarch64-linux-musl-gcc" \ No newline at end of file
diff --git a/docs/content/configuration/config-file/cpu.md b/docs/content/configuration/config-file/cpu.md
new file mode 100644
index 00000000..77d8fe30
--- /dev/null
+++ b/docs/content/configuration/config-file/cpu.md
@@ -0,0 +1,11 @@
+# CPU
+
+## Default CPU Graph Selection
+
+You can configure which CPU graph is shown by default when starting up bottom by setting `cpu.default`.
+
+```toml
+[cpu]
+# One of "all" (default), "average"/"avg"
+default = "average"
+```
diff --git a/sample_configs/default_config.toml b/sample_configs/default_config.toml
index 7d6a9f28..a7731dd6 100644
--- a/sample_configs/default_config.toml
+++ b/sample_configs/default_config.toml
@@ -85,6 +85,10 @@
#[processes]
#columns = ["PID", "Name", "CPU%", "Mem%", "R/s", "W/s", "T.Read", "T.Write", "User", "State", "GMEM%", "GPU%"]
+# [cpu]
+# One of "all" (default), "average"/"avg"
+# default = "average"
+
# These are all the components that support custom theming. Note that colour support
# will depend on terminal support.
diff --git a/src/app.rs b/src/app.rs
index 32f0af06..005a743b 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -49,7 +49,7 @@ pub struct AppConfigFields {
pub temperature_type: temperature::TemperatureType,
pub use_dot: bool,
pub left_legend: bool,
- pub show_average_cpu: bool,
+ pub show_average_cpu: bool, // TODO: Unify this in CPU options
pub use_current_cpu_total: bool,
pub unnormalized_cpu: bool,
pub use_basic_mode: bool,
@@ -1910,7 +1910,7 @@ impl App {
.proc_state
.get_mut_widget_state(self.current_widget.widget_id)
{
- proc_widget_state.table.set_first();
+ proc_widget_state.table.to_first();
}
}
BottomWidgetType::ProcSort => {
@@ -1919,7 +1919,7 @@ impl App {
.proc_state
.get_mut_widget_state(self.current_widget.widget_id - 2)
{
- proc_widget_state.sort_table.set_first();
+ proc_widget_state.sort_table.to_first();
}
}
BottomWidgetType::Temp => {
@@ -1928,7 +1928,7 @@ impl App {
.temp_state
.get_mut_widget_state(self.current_widget.widget_id)
{
- temp_widget_state.table.set_first();
+ temp_widget_state.table.to_first();
}
}
BottomWidgetType::Disk => {
@@ -1937,7 +1937,7 @@ impl App {
.disk_state
.get_mut_widget_state(self.current_widget.widget_id)
{
- disk_widget_state.table.set_first();
+ disk_widget_state.table.to_first();
}
}
BottomWidgetType::CpuLegend => {
@@ -1946,7 +1946,7 @@ impl App {
.cpu_state
.get_mut_widget_state(self.current_widget.widget_id - 1)
{
- cpu_widget_state.table.set_first();
+ cpu_widget_state.table.to_first();
}
}
@@ -1969,7 +1969,7 @@ impl App {
.proc_state
.get_mut_widget_state(self.current_widget.widget_id)
{
- proc_widget_state.table.set_last();
+ proc_widget_state.table.to_last();
}
}
BottomWidgetType::ProcSort => {
@@ -1978,7 +1978,7 @@ impl App {
.proc_state
.get_mut_widget_state(self.current_widget.widget_id - 2)
{
- proc_widget_state.sort_table.set_last();
+ proc_widget_state.sort_table.to_last();
}
}
BottomWidgetType::Temp => {
@@ -1987,7 +1987,7 @@ impl App {
.temp_state
.get_mut_widget_state(self.current_widget.widget_id)
{
- temp_widget_state.table.set_last();
+ temp_widget_state.table.to_last();
}
}
BottomWidgetType::Disk => {
@@ -1997,7 +1997,7 @@ impl App {
.get_mut_widget_state(self.current_widget.widget_id)
{
if !self.converted_data.disk_data.is_empty() {
- disk_widget_state.table.set_last();
+ disk_widget_state.table.to_last();
}
}
}
@@ -2007,7 +2007,7 @@ impl App {
.cpu_state
.get_mut_widget_state(self.current_widget.widget_id - 1)
{
- cpu_widget_state.table.set_last();
+ cpu_widget_state.table.to_last();
}
}
_ => {}
diff --git a/src/components/data_table.rs b/src/components/data_table.rs
index ed79961a..4ae23d1d 100644
--- a/src/components/data_table.rs
+++ b/src/components/data_table.rs
@@ -40,6 +40,7 @@ pub struct DataTable<DataType, Header, S = Unsortable, C = Column<Header>> {
data: Vec<DataType>,
sort_type: S,
first_draw: bool,
+ first_index: Option<usize>,
_pd: PhantomData<(DataType, S, Header)>,
}
@@ -55,6 +56,7 @@ impl<DataType: DataToCell<H>, H: ColumnHeader> DataTable<DataType, H, Unsortable
data: vec![],
sort_type: Unsortable,
first_draw: true,
+ first_index: None,
_pd: PhantomData,
}
}
@@ -63,14 +65,20 @@ impl<DataType: DataToCell<H>, H: ColumnHeader> DataTable<DataType, H, Unsortable
impl<DataType: DataToCell<H>, H: ColumnHeader, S: SortType, C: DataTableColumn<H>>
DataTable<DataType, H, S, C>
{
+ /// Sets the default value selected on first initialization, if possible.
+ pub fn first_draw_index(mut self, first_index: usize) -> Self {
+ self.first_index = Some(first_index);
+ self
+ }
+
/// Sets the scroll position to the first value.
- pub fn set_first(&mut self) {
+ pub fn to_first(&mut self) {
self.state.current_index = 0;
self.state.scroll_direction = ScrollDirection::Up;
}
/// Sets the scroll position to the last value.
- pub fn set_last(&mut self) {
+ pub fn to_last(&mut self) {
self.state.current_index = self.data.len().saturating_sub(1);
self.state.scroll_direction = ScrollDirection::Down;
}
@@ -189,11 +197,11 @@ mod test {
let mut table = DataTable::new(columns, props, styling);
table.set_data((0..=4).map(|index| TestType { index }).collect::<Vec<_>>());
- table.set_last();
+ table.to_last();
assert_eq!(table.current_index(), 4);
assert_eq!(table.state.scroll_direction, ScrollDirection::Down);
- table.set_first();
+ table.to_first();
assert_eq!(table.current_index(), 0);
assert_eq!(table.state.scroll_direction, ScrollDirection::Up);
diff --git a/src/components/data_table/draw.rs b/src/components/data_table/draw.rs
index 3903f381..91fef6ba 100644
--- a/src/components/data_table/draw.rs
+++ b/src/components/data_table/draw.rs
@@ -200,10 +200,15 @@ where
self.props.table_gap
};
- let columns = &self.columns;
if !self.data.is_empty() || !self.first_draw {
- self.first_draw = false; // TODO: Doing it this way is fine, but it could be done better (e.g. showing custom no results/entries message)
+ if self.first_draw {
+ self.first_draw = false; // TODO: Doing it this way is fine, but it could be done better (e.g. showing custom no results/entries message)
+ if let Some(first_index) = self.first_index {
+ self.set_position(first_index);
+ }
+ }
+ let columns = &self.columns;
let rows = {
let num_rows =
usize::from(inner_height.saturating_sub(table_gap + header_height));
diff --git a/src/components/data_table/sortable.rs b/src/components/data_table/sortable.rs
index b44906a4..3a3de1fc 100644
--- a/src/components/data_table/sortable.rs
+++ b/src/components/data_table/sortable.rs
@@ -260,6 +260,7 @@ where
order: props.order,
},
first_draw: true,
+ first_index: None,
data: vec![],
_pd: PhantomData,
}
diff --git a/src/constants.rs b/src/constants.rs
index f511313e..3ad60f82 100644
--- a/src/constants.rs
+++ b/src/constants.rs
@@ -598,6 +598,10 @@ pub const CONFIG_TEXT: &str = r#"# This is a default config file for bottom. Al
# PID, Name, CPU%, Mem%, R/s, W/s, T.Read, T.Write, User, State, Time, GMem%, GPU%
#columns = ["PID", "Name", "CPU%", "Mem%", "R/s", "W/s", "T.Read", "T.Write", "User", "State", "GMEM%", "GPU%"]
+# [cpu]
+# One of "all" (default), "average"/"avg"
+# default = "average"
+
# These are all the components that support custom theming. Note that colour support
# will depend on terminal support.
#[colors] # Uncomment if you want to use custom colors
diff --git a/src/options.rs b/src/options.rs
index 152db131..08c96e34 100644
--- a/src/options.rs
+++ b/src/options.rs
@@ -28,8 +28,11 @@ use crate::{
pub mod layout_options;
-pub mod process_columns;
-use self::process_columns::ProcessConfig;
+mod process_columns;
+pub use process_columns::ProcessConfig;
+
+mod cpu;
+pub use cpu::{CpuConfig, CpuDefault};
use anyhow::{Context, Result};
@@ -43,6 +46,7 @@ pub struct Config {
pub temp_filter: Option<IgnoreList>,
pub net_filter: Option<IgnoreList>,
pub processes: Option<ProcessConfig>,
+ pub cpu: Option<CpuConfig>,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
@@ -340,6 +344,11 @@ pub fn build_app(
widget.widget_id,
CpuWidgetState::new(
&app_config_fields,
+ config
+ .cpu
+ .as_ref()
+ .map(|cfg| cfg.default)
+ .unwrap_or_default(),
default_time_value,
autohide_timer,
styling,
diff --git a/src/options/cpu.rs b/src/options/cpu.rs
new file mode 100644
index 00000000..ce027305
--- /dev/null
+++ b/src/options/cpu.rs
@@ -0,0 +1,79 @@
+use serde::Deserialize;
+
+/// The default selection of the CPU widget. If the given selection is invalid, we will fall back to all.
+#[derive(Clone, Copy, Debug, Default, Deserialize)]
+#[serde(rename_all = "lowercase")]
+pub enum CpuDefault {
+ #[default]
+ All,
+ #[serde(alias = "avg")]
+ Average,
+}
+
+/// Process column settings.
+#[derive(Clone, Debug, Default, Deserialize)]
+pub struct CpuConfig {
+ #[serde(default)]
+ pub default: CpuDefault,
+}
+
+#[cfg(test)]
+mod test {
+ use super::*;
+
+ #[test]
+ fn default_cpu_default() {
+ let config = "";
+ let generated: CpuConfig = toml_edit::de::from_str(config).unwrap();
+ match generated.default {
+ CpuDefault::All => {}
+ CpuDefault::Average => {
+ panic!("the default should be all")
+ }
+ }
+ }
+
+ #[test]
+ fn all_cpu_default() {
+ let config = r#"
+ default = "all"
+ "#;
+ let generated: CpuConfig = toml_edit::de::from_str(config).unwrap();
+ match generated.default {
+ CpuDefault::All => {}
+ CpuDefault::Average => {
+ panic!("the default should be all")
+ }
+ }
+ }
+
+ #[test]
+ fn avg_cpu_default() {
+ let config = r#"
+ default = "avg"
+ "#;
+
+ let generated: CpuConfig = toml_edit::de::from_str(config).unwrap();
+ match generated.default {
+ CpuDefault::All => {
+ panic!("the avg should be set")
+ }
+ CpuDefault::Average => {}
+ }
+ }
+
+ #[test]
+ fn average_cpu_default() {
+ let config = r#"
+ default = "average"
+ "#;
+
+ let generated: CpuConfig = toml_edit::de::from_str(config).unwrap();
+ match generated.default {
+ CpuDefault::All => {
+ panic!("the avg should be set")
+ }
+ CpuDefault::Average => {}
+ }
+ }
+}
diff --git a/src/widgets/cpu_graph.rs b/src/widgets/cpu_graph.rs
index 2b555c10..3d3e6df1 100644
--- a/src/widgets/cpu_graph.rs
+++ b/src/widgets/cpu_graph.rs
@@ -11,6 +11,7 @@ use crate::{
DataToCell,
},
data_conversion::CpuWidgetData,
+ options::CpuDefault,
utils::gen_util::truncate_to_text,
};
@@ -165,8 +166,8 @@ pub struct CpuWidgetState {
impl CpuWidgetState {
pub fn new(
- config: &AppConfigFields, current_display_time: u64, autohide_timer: Option<Instant>,
- colours: &CanvasStyling,
+ config: &AppConfigFields, default_selection: CpuDefault, current_display_time: u64,
+ autohide_timer: Option<Instant>, colours: &CanvasStyling,
) -> Self {
const COLUMNS: [Column<CpuWidgetColumn>; 2] = [
Column::soft(CpuWidgetColumn::CPU, Some(0.5)),
@@ -183,13 +184,21 @@ impl CpuWidgetState {
};
let styling = DataTableStyling::from_colours(colours);
+ let mut table = DataTable::new(COLUMNS, props, styling);
+ match default_selection {
+ CpuDefault::All => {}
+ CpuDefault::Average if !config.show_average_cpu => {}
+ CpuDefault::Average => {
+ table = table.first_draw_index(1);
+ }
+ }
CpuWidgetState {
current_display_time,
is_legend_hidden: false,
show_avg: config.show_average_cpu,
autohide_timer,
- table: DataTable::new(COLUMNS, props, styling),
+ table,
styling: CpuWidgetStyling::from_colours(colours),
}
}