summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLee Wonjoon <lyuha@users.noreply.github.com>2024-04-02 05:06:01 +0000
committerGitHub <noreply@github.com>2024-04-02 01:06:01 -0400
commita083ec00dd4e74c29bb96bd7c9b0e9cec1cd22b3 (patch)
tree43299d972046f64d8ea4afb8e9d7157ad7cd6d28 /src
parent2ee0df1502925e1a5cae75f543110233006ef743 (diff)
feature: Add option to set a position of legend (#1430)
* Add option to set a position of legend * some small changes --------- Co-authored-by: ClementTsang <34804052+ClementTsang@users.noreply.github.com>
Diffstat (limited to 'src')
-rw-r--r--src/app.rs3
-rw-r--r--src/canvas/components/time_graph.rs9
-rw-r--r--src/canvas/components/tui_widget/time_chart.rs23
-rw-r--r--src/canvas/widgets/cpu_graph.rs1
-rw-r--r--src/canvas/widgets/mem_graph.rs1
-rw-r--r--src/canvas/widgets/network_graph.rs1
-rw-r--r--src/constants.rs6
-rw-r--r--src/options.rs49
-rw-r--r--src/options/args.rs41
-rw-r--r--src/options/config.rs2
10 files changed, 130 insertions, 6 deletions
diff --git a/src/app.rs b/src/app.rs
index a149869f..60ad35b8 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -21,6 +21,7 @@ pub use states::*;
use unicode_segmentation::{GraphemeCursor, UnicodeSegmentation};
use crate::{
+ canvas::components::time_chart::LegendPosition,
constants,
data_collection::temperature,
data_conversion::ConvertedData,
@@ -62,8 +63,10 @@ pub struct AppConfigFields {
pub enable_cache_memory: bool,
pub show_table_scroll_position: bool,
pub is_advanced_kill: bool,
+ pub memory_legend_position: Option<LegendPosition>,
// TODO: Remove these, move network details state-side.
pub network_unit_type: DataUnit,
+ pub network_legend_position: Option<LegendPosition>,
pub network_scale_type: AxisScaling,
pub network_use_binary_prefix: bool,
pub retention_ms: u64,
diff --git a/src/canvas/components/time_graph.rs b/src/canvas/components/time_graph.rs
index 3f438349..361b502e 100644
--- a/src/canvas/components/time_graph.rs
+++ b/src/canvas/components/time_graph.rs
@@ -11,7 +11,9 @@ use tui::{
};
use unicode_segmentation::UnicodeSegmentation;
-use super::time_chart::{Axis, Dataset, Point, TimeChart, DEFAULT_LEGEND_CONSTRAINTS};
+use super::time_chart::{
+ Axis, Dataset, LegendPosition, Point, TimeChart, DEFAULT_LEGEND_CONSTRAINTS,
+};
/// Represents the data required by the [`TimeGraph`].
pub struct GraphData<'a> {
@@ -48,6 +50,9 @@ pub struct TimeGraph<'a> {
/// The title style.
pub title_style: Style,
+ /// The legend position.
+ pub legend_position: Option<LegendPosition>,
+
/// Any legend constraints.
pub legend_constraints: Option<(Constraint, Constraint)>,
@@ -142,6 +147,7 @@ impl<'a> TimeGraph<'a> {
.y_axis(y_axis)
.marker(self.marker)
.legend_style(self.graph_style)
+ .legend_position(self.legend_position)
.hidden_legend_constraints(
self.legend_constraints
.unwrap_or(DEFAULT_LEGEND_CONSTRAINTS),
@@ -202,6 +208,7 @@ mod test {
border_style: Style::default().fg(Color::Blue),
is_expanded: false,
title_style: Style::default().fg(Color::Cyan),
+ legend_position: None,
legend_constraints: None,
marker: Marker::Braille,
}
diff --git a/src/canvas/components/tui_widget/time_chart.rs b/src/canvas/components/tui_widget/time_chart.rs
index 60c797bc..04f491bc 100644
--- a/src/canvas/components/tui_widget/time_chart.rs
+++ b/src/canvas/components/tui_widget/time_chart.rs
@@ -7,7 +7,7 @@
mod canvas;
mod points;
-use std::cmp::max;
+use std::{cmp::max, str::FromStr};
use canvas::*;
use tui::{
@@ -213,6 +213,27 @@ impl LegendPosition {
}
}
+#[derive(Debug, PartialEq)]
+pub struct ParseLegendPositionError;
+
+impl FromStr for LegendPosition {
+ type Err = ParseLegendPositionError;
+
+ fn from_str(s: &str) -> Result<Self, Self::Err> {
+ match s.to_ascii_lowercase().as_str() {
+ "top" => Ok(Self::Top),
+ "top-left" => Ok(Self::TopLeft),
+ "top-right" => Ok(Self::TopRight),
+ "left" => Ok(Self::Left),
+ "right" => Ok(Self::Right),
+ "bottom-left" => Ok(Self::BottomLeft),
+ "bottom" => Ok(Self::Bottom),
+ "bottom-right" => Ok(Self::BottomRight),
+ _ => Err(ParseLegendPositionError),
+ }
+ }
+}
+
/// A group of data points
///
/// This is the main element composing a [`TimeChart`].
diff --git a/src/canvas/widgets/cpu_graph.rs b/src/canvas/widgets/cpu_graph.rs
index b5027bc6..f882b210 100644
--- a/src/canvas/widgets/cpu_graph.rs
+++ b/src/canvas/widgets/cpu_graph.rs
@@ -233,6 +233,7 @@ impl Painter {
title,
is_expanded: app_state.is_expanded,
title_style: self.colours.widget_title_style,
+ legend_position: None,
legend_constraints: None,
marker,
}
diff --git a/src/canvas/widgets/mem_graph.rs b/src/canvas/widgets/mem_graph.rs
index b9782e5a..5c814f51 100644
--- a/src/canvas/widgets/mem_graph.rs
+++ b/src/canvas/widgets/mem_graph.rs
@@ -133,6 +133,7 @@ impl Painter {
title: " Memory ".into(),
is_expanded: app_state.is_expanded,
title_style: self.colours.widget_title_style,
+ legend_position: app_state.app_config_fields.memory_legend_position,
legend_constraints: Some((Constraint::Ratio(3, 4), Constraint::Ratio(3, 4))),
marker,
}
diff --git a/src/canvas/widgets/network_graph.rs b/src/canvas/widgets/network_graph.rs
index 35ab9373..ec7e5fbd 100644
--- a/src/canvas/widgets/network_graph.rs
+++ b/src/canvas/widgets/network_graph.rs
@@ -162,6 +162,7 @@ impl Painter {
title: " Network ".into(),
is_expanded: app_state.is_expanded,
title_style: self.colours.widget_title_style,
+ legend_position: app_state.app_config_fields.network_legend_position,
legend_constraints: Some(legend_constraints),
marker,
}
diff --git a/src/constants.rs b/src/constants.rs
index eb185779..1c3aa097 100644
--- a/src/constants.rs
+++ b/src/constants.rs
@@ -573,7 +573,7 @@ pub const CONFIG_TEXT: &str = r#"# This is a default config file for bottom. Al
#battery = false
# Disable mouse clicks
#disable_click = false
-# Built-in themes. Valid values are "default", "default-light", "gruvbox", "gruvbox-light", "nord", "nord-light"
+# Built-in themes. Valid values are "default", "default-light", "gruvbox", "gruvbox-light", "nord", "nord-light"
#color = "default"
# Show memory values in the processes widget as values by default
#mem_as_value = false
@@ -597,6 +597,10 @@ pub const CONFIG_TEXT: &str = r#"# This is a default config file for bottom. Al
#enable_cache_memory = false
# How much data is stored at once in terms of time.
#retention = "10m"
+# Where to place the legend for the memory widget. One of "none", "top-left", "top", "top-right", "left", "right", "bottom-left", "bottom", "bottom-right".
+#memory_legend = "TopRight".
+# Where to place the legend for the network widget. One of "none", "top-left", "top", "top-right", "left", "right", "bottom-left", "bottom", "bottom-right".
+#network_legend = "TopRight".
# These are flags around the process widget.
#[processes]
diff --git a/src/options.rs b/src/options.rs
index 902c5c87..e36685ea 100644
--- a/src/options.rs
+++ b/src/options.rs
@@ -24,7 +24,7 @@ use starship_battery::Manager;
use self::config::{layout::Row, IgnoreList, StringOrNum};
use crate::{
app::{filter::Filter, layout_manager::*, *},
- canvas::{styling::CanvasStyling, ColourScheme},
+ canvas::{components::time_chart::LegendPosition, styling::CanvasStyling, ColourScheme},
constants::*,
data_collection::temperature::TemperatureType,
utils::{
@@ -126,6 +126,9 @@ pub fn init_app(
}
};
+ let network_legend_position = get_network_legend(matches, config)?;
+ let memory_legend_position = get_memory_legend(matches, config)?;
+
// TODO: Can probably just reuse the options struct.
let app_config_fields = AppConfigFields {
update_rate: get_update_rate(matches, config)
@@ -150,6 +153,8 @@ pub fn init_app(
enable_cache_memory: get_enable_cache_memory(matches, config),
show_table_scroll_position: is_flag_enabled!(show_table_scroll_position, matches, config),
is_advanced_kill,
+ memory_legend_position,
+ network_legend_position,
network_scale_type,
network_unit_type,
network_use_binary_prefix,
@@ -772,6 +777,48 @@ fn get_retention(matches: &ArgMatches, config: &Config) -> error::Result<u64> {
}
}
+fn get_network_legend(
+ matches: &ArgMatches, config: &Config,
+) -> error::Result<Option<LegendPosition>> {
+ let error =
+ |_| BottomError::ConfigError("network_legend is set to an invalid value".to_string());
+ if let Some(s) = matches.get_one::<String>("network_legend") {
+ match s.to_ascii_lowercase().trim() {
+ "none" => Ok(None),
+ position => Ok(Some(position.parse::<LegendPosition>().map_err(error)?)),
+ }
+ } else if let Some(flags) = &config.flags {
+ if let Some(legend) = &flags.network_legend {
+ Ok(Some(legend.parse::<LegendPosition>().map_err(error)?))
+ } else {
+ Ok(Some(LegendPosition::default()))
+ }
+ } else {
+ Ok(Some(LegendPosition::default()))
+ }
+}
+
+fn get_memory_legend(
+ matches: &ArgMatches, config: &Config,
+) -> error::Result<Option<LegendPosition>> {
+ let error =
+ |_| BottomError::ConfigError("memory_legend is set to an invalid value".to_string());
+ if let Some(s) = matches.get_one::<String>("memory_legend") {
+ match s.to_ascii_lowercase().trim() {
+ "none" => Ok(None),
+ position => Ok(Some(position.parse::<LegendPosition>().map_err(error)?)),
+ }
+ } else if let Some(flags) = &config.flags {
+ if let Some(legend) = &flags.memory_legend {
+ Ok(Some(legend.parse::<LegendPosition>().map_err(error)?))
+ } else {
+ Ok(Some(LegendPosition::default()))
+ }
+ } else {
+ Ok(Some(LegendPosition::default()))
+ }
+}
+
#[cfg(test)]
mod test {
use clap::ArgMatches;
diff --git a/src/options/args.rs b/src/options/args.rs
index b410eba4..c8fe35320 100644
--- a/src/options/args.rs
+++ b/src/options/args.rs
@@ -436,6 +436,24 @@ fn mem_args(cmd: Command) -> Command {
to showing it by percentage.",
);
+ let memory_legend = Arg::new("memory_legend")
+ .long("memory_legend")
+ .action(ArgAction::Set)
+ .value_name("POSITION")
+ .ignore_case(true)
+ .help("Where to place the legend for the memory widget.")
+ .value_parser([
+ "none",
+ "top-left",
+ "top",
+ "top-right",
+ "left",
+ "right",
+ "bottom-left",
+ "bottom",
+ "bottom-right",
+ ]);
+
#[cfg(not(target_os = "windows"))]
{
let enable_cache_memory = Arg::new("enable_cache_memory")
@@ -443,11 +461,11 @@ fn mem_args(cmd: Command) -> Command {
.action(ArgAction::SetTrue)
.help("Enable collecting and displaying cache and buffer memory.");
- cmd.args(args![mem_as_value, enable_cache_memory])
+ cmd.args(args![mem_as_value, memory_legend, enable_cache_memory])
}
#[cfg(target_os = "windows")]
{
- cmd.arg(mem_as_value)
+ cmd.args(args![mem_as_value, memory_legend])
}
}
@@ -464,6 +482,24 @@ fn network_args(cmd: Command) -> Command {
display is not tested anymore and may be broken.",
);
+ let network_legend = Arg::new("network_legend")
+ .long("network_legend")
+ .action(ArgAction::Set)
+ .value_name("POSITION")
+ .ignore_case(true)
+ .help("Where to place the legend for the network widget.")
+ .value_parser([
+ "none",
+ "top-left",
+ "top",
+ "top-right",
+ "left",
+ "right",
+ "bottom-left",
+ "bottom",
+ "bottom-right",
+ ]);
+
let network_use_bytes = Arg::new("network_use_bytes")
.long("network_use_bytes")
.action(ArgAction::SetTrue)
@@ -487,6 +523,7 @@ fn network_args(cmd: Command) -> Command {
cmd.args(args![
use_old_network_legend,
+ network_legend,
network_use_bytes,
network_use_log,
network_use_binary_prefix,
diff --git a/src/options/config.rs b/src/options/config.rs
index 23c2f956..6b3643f0 100644
--- a/src/options/config.rs
+++ b/src/options/config.rs
@@ -68,6 +68,8 @@ pub(crate) struct ConfigFlags {
pub(crate) battery: Option<bool>,
pub(crate) disable_click: Option<bool>,
pub(crate) no_write: Option<bool>,
+ pub(crate) network_legend: Option<String>,
+ pub(crate) memory_legend: Option<String>,
/// For built-in colour palettes.
pub(crate) color: Option<String>,
pub(crate) mem_as_value: Option<bool>,