feature: support simple colour settings for text fields too (#1511)

* feature: support simple colour settings for text fields too

* also add 'color' back to some options

* tests
This commit is contained in:
Clement Tsang 2024-07-30 07:15:23 +00:00 committed by GitHub
parent 95905d7a2b
commit f091ebdc6a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 442 additions and 189 deletions

View file

@ -83,6 +83,14 @@ field = { color = "black", bg_color = "blue", bold = false }
All fields are optional; by default if `bg_color` is not set then there will be no background color.
If you _just_ want to style text by setting the foreground colour, for brevity, then you can also just set the field
to be the colour itself. For example:
```toml
[styles.widgets]
selected_text = "#fff"
```
### Configuration
#### CPU
@ -100,33 +108,33 @@ These can be set under `[styles.cpu]`:
These can be set under `[styles.memory]`:
| Config field | Details | Examples |
| ------------ | ------------------------------------------------------------------------------ | --------------------------------- |
| `ram` | The colour of the RAM label and graph line | `ram = "Red"` |
| `cache` | The colour of the cache label and graph line. Does not do anything on Windows. | `cache = "#ffffff"` |
| `swap` | The colour of the swap label and graph line | `swap = "255, 0, 255"` |
| `arc` | The colour of the ARC label and graph line | `arc = "Blue"` |
| `gpus` | Colour of each GPU's memory label and graph line. Read in order. | `gpus = ["Red", "Blue", "Green"]` |
| ------------- | ------------------------------------------------------------------------------ | --------------------------------------- |
| `ram_color` | The colour of the RAM label and graph line | `ram_color = "Red"` |
| `cache_color` | The colour of the cache label and graph line. Does not do anything on Windows. | `cache_color = "#ffffff"` |
| `swap_color` | The colour of the swap label and graph line | `swap_color = "255, 0, 255"` |
| `arc_color` | The colour of the ARC label and graph line | `arc_color = "Blue"` |
| `gpu_colors` | Colour of each GPU's memory label and graph line. Read in order. | `gpu_colors = ["Red", "Blue", "Green"]` |
#### Network
These can be set under `[styles.network]`:
| Config field | Details | Examples |
| ------------ | --------------------------------------------------------- | ---------------------- |
| `rx` | The colour of the RX (download) label and graph line | `rx = "Red"` |
| `tx` | The colour of the TX (upload) label and graph line. | `tx = "#ffffff"` |
| `rx_total` | The colour of the total RX (download) label in basic mode | `rx_total = "0, 0, 0"` |
| `tx_total` | The colour of the total TX (upload) label in basic mode | `tx_total = "#000"` |
| ---------------- | --------------------------------------------------------- | ---------------------------- |
| `rx_color` | The colour of the RX (download) label and graph line | `rx_color = "Red"` |
| `tx_color` | The colour of the TX (upload) label and graph line | `tx_color = "#ffffff"` |
| `rx_total_color` | The colour of the total RX (download) label in basic mode | `rx_total_color = "0, 0, 0"` |
| `tx_total_color` | The colour of the total TX (upload) label in basic mode | `tx_total_color = "#000"` |
#### Battery
These can be set under `[styles.battery]`:
| Config field | Details | Examples |
| ---------------- | ------------------------------------------------------------------------ | ---------------------------- |
| `high_battery` | The colour of the battery widget bar when the battery is over 50% | `high_battery = "Red"` |
| `medium_battery` | The colour of the battery widget bar when the battery between 10% to 50% | `medium_battery = "#ffffff"` |
| `low_battery` | The colour of the battery widget bar when the battery is under 10% | `low_battery = "0, 0, 0"` |
| ---------------------- | ------------------------------------------------------------------------ | ---------------------------------- |
| `high_battery_color` | The colour of the battery widget bar when the battery is over 50% | `high_battery_color = "Red"` |
| `medium_battery_color` | The colour of the battery widget bar when the battery between 10% to 50% | `medium_battery_color = "#ffffff"` |
| `low_battery_color` | The colour of the battery widget bar when the battery is under 10% | `low_battery_color = "0, 0, 0"` |
#### Tables
@ -150,10 +158,10 @@ These can be set under `[styles.graphs]`:
These can be set under `[styles.widgets]`:
| Config field | Details | Examples |
| ----------------- | ------------------------------------------------------------ | --------------------------------------------------------------------- |
| `border` | The colour of the widgets' borders | `border = "white"` |
| `selected_border` | The colour of a widget's borders when the widget is selected | `selected_border = "white"` |
| ----------------------- | ------------------------------------------------------------ | --------------------------------------------------------------------- |
| `border_color` | The colour of the widgets' borders | `border_color = "white"` |
| `selected_border_color` | The colour of a widget's borders when the widget is selected | `selected_border_color = "white"` |
| `widget_title` | Text styling for a widget's title | `widget_title = { color = "black", bg_color = "blue", bold = true }` |
| `text` | Text styling for text in general | `text = { color = "black", bg_color = "blue", bold = true }` |
| `selected_text` | Text styling for text when representing something selected | `selected_text = { color = "black", bg_color = "blue", bold = true }` |
| `disabled_text` | Text styling for text when representing something disabled | `disabled_text = { color = "black", bg_color = "blue", bold = true }` |
| `selected_text` | Text styling for text when representing something that is selected | `selected_text = { color = "black", bg_color = "blue", bold = true }` |
| `disabled_text` | Text styling for text when representing something that is disabled | `disabled_text = { color = "black", bg_color = "blue", bold = true }` |

View file

@ -147,22 +147,22 @@
#cpu_core_colors = ["light magenta", "light yellow", "light cyan", "light green", "light blue", "cyan", "green", "blue"]
#[styles.memory]
#ram = "light magenta"
#cache = "light red"
#swap = "light yellow"
#arc = "light cyan"
#gpus = ["light blue", "light red", "cyan", "green", "blue", "red"]
#ram_color = "light magenta"
#cache_color = "light red"
#swap_color = "light yellow"
#arc_color = "light cyan"
#gpu_colors = ["light blue", "light red", "cyan", "green", "blue", "red"]
#[styles.network]
#rx = "light magenta"
#tx = "light yellow"
#rx_total = "light cyan"
#tx_total = "light green"
#rx_color = "light magenta"
#tx_color = "light yellow"
#rx_total_color = "light cyan"
#tx_total_color = "light green"
#[styles.battery]
#high_battery = "green"
#medium_battery = "yellow"
#low_battery = "red"
#high_battery_color = "green"
#medium_battery_color = "yellow"
#low_battery_color = "red"
#[styles.tables]
#headers = {color = "light blue"}
@ -172,8 +172,8 @@
#legend_text = {color = "gray"}
#[styles.widgets]
#border = "gray"
#selected_border = "light blue"
#border_color = "gray"
#selected_border_color = "light blue"
#widget_title = {color = "gray"}
#text = {color = "gray"}
#selected_text = {color = "black", bg_color = "light blue"}

View file

@ -90,7 +90,8 @@
"description": "Styling specific to the battery widget.",
"type": "object",
"properties": {
"high_battery": {
"high_battery_color": {
"description": "The colour of the battery widget bar when the battery is over 50%.",
"anyOf": [
{
"$ref": "#/definitions/ColorStr"
@ -100,7 +101,8 @@
}
]
},
"low_battery": {
"low_battery_color": {
"description": "The colour of the battery widget bar when the battery is under 10%.",
"anyOf": [
{
"$ref": "#/definitions/ColorStr"
@ -110,7 +112,8 @@
}
]
},
"medium_battery": {
"medium_battery_color": {
"description": "The colour of the battery widget bar when the battery between 10% to 50%.",
"anyOf": [
{
"$ref": "#/definitions/ColorStr"
@ -147,6 +150,7 @@
"type": "object",
"properties": {
"all_entry_color": {
"description": "The colour of the \"All\" CPU label.",
"anyOf": [
{
"$ref": "#/definitions/ColorStr"
@ -157,6 +161,7 @@
]
},
"avg_entry_color": {
"description": "The colour of the average CPU label and graph line.",
"anyOf": [
{
"$ref": "#/definitions/ColorStr"
@ -167,6 +172,7 @@
]
},
"cpu_core_colors": {
"description": "Colour of each CPU threads' label and graph line. Read in order.",
"type": [
"array",
"null"
@ -481,6 +487,7 @@
"type": "object",
"properties": {
"graph_color": {
"description": "The general colour of the parts of the graph.",
"anyOf": [
{
"$ref": "#/definitions/ColorStr"
@ -491,6 +498,7 @@
]
},
"legend_text": {
"description": "Text styling for graph's legend text.",
"anyOf": [
{
"$ref": "#/definitions/TextStyleConfig"
@ -536,7 +544,8 @@
"description": "Styling specific to the memory widget.",
"type": "object",
"properties": {
"arc": {
"arc_color": {
"description": "The colour of the ARC label and graph line.",
"anyOf": [
{
"$ref": "#/definitions/ColorStr"
@ -546,7 +555,8 @@
}
]
},
"cache": {
"cache_color": {
"description": "The colour of the cache label and graph line. Does not do anything on Windows.",
"anyOf": [
{
"$ref": "#/definitions/ColorStr"
@ -556,7 +566,8 @@
}
]
},
"gpus": {
"gpu_colors": {
"description": "Colour of each GPU's memory label and graph line. Read in order.",
"type": [
"array",
"null"
@ -565,7 +576,8 @@
"$ref": "#/definitions/ColorStr"
}
},
"ram": {
"ram_color": {
"description": "The colour of the RAM label and graph line.",
"anyOf": [
{
"$ref": "#/definitions/ColorStr"
@ -575,7 +587,8 @@
}
]
},
"swap": {
"swap_color": {
"description": "The colour of the swap label and graph line.",
"anyOf": [
{
"$ref": "#/definitions/ColorStr"
@ -608,7 +621,8 @@
"description": "Styling specific to the network widget.",
"type": "object",
"properties": {
"rx": {
"rx_color": {
"description": "The colour of the RX (download) label and graph line.",
"anyOf": [
{
"$ref": "#/definitions/ColorStr"
@ -618,8 +632,8 @@
}
]
},
"rx_total": {
"description": "Set the colour of the \"rx total\" text. This only affects basic mode.",
"rx_total_color": {
"description": "he colour of the total RX (download) label in basic mode.",
"anyOf": [
{
"$ref": "#/definitions/ColorStr"
@ -629,7 +643,8 @@
}
]
},
"tx": {
"tx_color": {
"description": "The colour of the TX (upload) label and graph line.",
"anyOf": [
{
"$ref": "#/definitions/ColorStr"
@ -639,8 +654,8 @@
}
]
},
"tx_total": {
"description": "Set the colour of the \"tx total\" text. This only affects basic mode.",
"tx_total_color": {
"description": "The colour of the total TX (upload) label in basic mode.",
"anyOf": [
{
"$ref": "#/definitions/ColorStr"
@ -831,6 +846,7 @@
"type": "object",
"properties": {
"headers": {
"description": "Text styling for table headers.",
"anyOf": [
{
"$ref": "#/definitions/TextStyleConfig"
@ -861,6 +877,11 @@
},
"TextStyleConfig": {
"description": "A style for text.",
"anyOf": [
{
"$ref": "#/definitions/ColorStr"
},
{
"type": "object",
"properties": {
"bg_color": {
@ -893,12 +914,15 @@
]
}
}
}
]
},
"WidgetStyle": {
"description": "General styling for generic widgets.",
"type": "object",
"properties": {
"border": {
"border_color": {
"description": "The colour of the widgets' borders.",
"anyOf": [
{
"$ref": "#/definitions/ColorStr"
@ -909,6 +933,7 @@
]
},
"disabled_text": {
"description": "Text styling for text when representing something that is disabled.",
"anyOf": [
{
"$ref": "#/definitions/TextStyleConfig"
@ -918,7 +943,8 @@
}
]
},
"selected_border": {
"selected_border_color": {
"description": "The colour of a widget's borders when the widget is selected.",
"anyOf": [
{
"$ref": "#/definitions/ColorStr"
@ -929,6 +955,7 @@
]
},
"selected_text": {
"description": "Text styling for text when representing something that is selected.",
"anyOf": [
{
"$ref": "#/definitions/TextStyleConfig"
@ -939,6 +966,7 @@
]
},
"text": {
"description": "Text styling for text in general.",
"anyOf": [
{
"$ref": "#/definitions/TextStyleConfig"
@ -949,6 +977,7 @@
]
},
"widget_title": {
"description": "Text styling for a widget's title.",
"anyOf": [
{
"$ref": "#/definitions/TextStyleConfig"

View file

@ -411,22 +411,22 @@ pub const CONFIG_TEXT: &str = r#"# This is a default config file for bottom. Al
#cpu_core_colors = ["light magenta", "light yellow", "light cyan", "light green", "light blue", "cyan", "green", "blue"]
#[styles.memory]
#ram = "light magenta"
#cache = "light red"
#swap = "light yellow"
#arc = "light cyan"
#gpus = ["light blue", "light red", "cyan", "green", "blue", "red"]
#ram_color = "light magenta"
#cache_color = "light red"
#swap_color = "light yellow"
#arc_color = "light cyan"
#gpu_colors = ["light blue", "light red", "cyan", "green", "blue", "red"]
#[styles.network]
#rx = "light magenta"
#tx = "light yellow"
#rx_total = "light cyan"
#tx_total = "light green"
#rx_color = "light magenta"
#tx_color = "light yellow"
#rx_total_color = "light cyan"
#tx_total_color = "light green"
#[styles.battery]
#high_battery = "green"
#medium_battery = "yellow"
#low_battery = "red"
#high_battery_color = "green"
#medium_battery_color = "yellow"
#low_battery_color = "red"
#[styles.tables]
#headers = {color = "light blue"}
@ -436,8 +436,8 @@ pub const CONFIG_TEXT: &str = r#"# This is a default config file for bottom. Al
#legend_text = {color = "gray"}
#[styles.widgets]
#border = "gray"
#selected_border = "light blue"
#border_color = "gray"
#selected_border_color = "light blue"
#widget_title = {color = "gray"}
#text = {color = "gray"}
#selected_text = {color = "black", bg_color = "light blue"}

View file

@ -32,20 +32,24 @@ use super::Config;
pub(crate) struct ColorStr(Cow<'static, str>);
/// A style for text.
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(untagged)]
#[cfg_attr(feature = "generate_schema", derive(schemars::JsonSchema))]
pub(crate) struct TextStyleConfig {
pub(crate) enum TextStyleConfig {
Colour(ColorStr),
TextStyle {
/// A built-in ANSI colour, RGB hex, or RGB colour code.
#[serde(alias = "colour")]
pub(crate) color: Option<ColorStr>,
color: Option<ColorStr>,
/// A built-in ANSI colour, RGB hex, or RGB colour code.
#[serde(alias = "bg_colour")]
pub(crate) bg_color: Option<ColorStr>,
bg_color: Option<ColorStr>,
/// Whether to make this text bolded or not. If not set,
/// will default to built-in defaults.
pub(crate) bold: Option<bool>,
bold: Option<bool>,
},
}
/// Style-related configs.
@ -161,28 +165,28 @@ impl ColourPalette {
set_colour_list!(self.cpu_colour_styles, config.cpu, cpu_core_colors);
// Memory
set_colour!(self.ram_style, config.memory, ram);
set_colour!(self.swap_style, config.memory, swap);
set_colour!(self.ram_style, config.memory, ram_color);
set_colour!(self.swap_style, config.memory, swap_color);
#[cfg(not(target_os = "windows"))]
set_colour!(self.cache_style, config.memory, cache);
set_colour!(self.cache_style, config.memory, cache_color);
#[cfg(feature = "zfs")]
set_colour!(self.arc_style, config.memory, arc);
set_colour!(self.arc_style, config.memory, arc_color);
#[cfg(feature = "gpu")]
set_colour_list!(self.gpu_colours, config.memory, gpus);
set_colour_list!(self.gpu_colours, config.memory, gpu_colors);
// Network
set_colour!(self.rx_style, config.network, rx);
set_colour!(self.tx_style, config.network, tx);
set_colour!(self.total_rx_style, config.network, rx_total);
set_colour!(self.total_tx_style, config.network, tx_total);
set_colour!(self.rx_style, config.network, rx_color);
set_colour!(self.tx_style, config.network, tx_color);
set_colour!(self.total_rx_style, config.network, rx_total_color);
set_colour!(self.total_tx_style, config.network, tx_total_color);
// Battery
set_colour!(self.high_battery, config.battery, high_battery);
set_colour!(self.medium_battery, config.battery, medium_battery);
set_colour!(self.low_battery, config.battery, low_battery);
set_colour!(self.high_battery, config.battery, high_battery_color);
set_colour!(self.medium_battery, config.battery, medium_battery_color);
set_colour!(self.low_battery, config.battery, low_battery_color);
// Tables
set_style!(self.table_header_style, config.tables, headers);
@ -198,11 +202,11 @@ impl ColourPalette {
set_style!(self.disabled_text_style, config.widgets, disabled_text);
// Widget borders
set_colour!(self.border_style, config.widgets, border);
set_colour!(self.border_style, config.widgets, border_color);
set_colour!(
self.highlighted_border_style,
config.widgets,
selected_border
selected_border_color
);
Ok(())

View file

@ -6,7 +6,15 @@ use super::ColorStr;
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
#[cfg_attr(feature = "generate_schema", derive(schemars::JsonSchema))]
pub(crate) struct BatteryStyle {
pub(crate) high_battery: Option<ColorStr>,
pub(crate) medium_battery: Option<ColorStr>,
pub(crate) low_battery: Option<ColorStr>,
/// The colour of the battery widget bar when the battery is over 50%.
#[serde(alias = "high_battery_colour")]
pub(crate) high_battery_color: Option<ColorStr>,
/// The colour of the battery widget bar when the battery between 10% to 50%.
#[serde(alias = "medium_battery_colour")]
pub(crate) medium_battery_color: Option<ColorStr>,
/// The colour of the battery widget bar when the battery is under 10%.
#[serde(alias = "low_battery_colour")]
pub(crate) low_battery_color: Option<ColorStr>,
}

View file

@ -6,13 +6,15 @@ use super::ColorStr;
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
#[cfg_attr(feature = "generate_schema", derive(schemars::JsonSchema))]
pub(crate) struct CpuStyle {
// TODO: Should I change the name of these?
/// The colour of the "All" CPU label.
#[serde(alias = "all_entry_colour")]
pub(crate) all_entry_color: Option<ColorStr>,
/// The colour of the average CPU label and graph line.
#[serde(alias = "avg_entry_colour")]
pub(crate) avg_entry_color: Option<ColorStr>,
/// Colour of each CPU threads' label and graph line. Read in order.
#[serde(alias = "cpu_core_colours")]
pub(crate) cpu_core_colors: Option<Vec<ColorStr>>,
}

View file

@ -6,8 +6,10 @@ use super::{ColorStr, TextStyleConfig};
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
#[cfg_attr(feature = "generate_schema", derive(schemars::JsonSchema))]
pub(crate) struct GraphStyle {
/// The general colour of the parts of the graph.
#[serde(alias = "graph_colour")]
pub(crate) graph_color: Option<ColorStr>,
/// Text styling for graph's legend text.
pub(crate) legend_text: Option<TextStyleConfig>,
}

View file

@ -1,15 +1,30 @@
use serde::{Deserialize, Serialize};
use super::ColorStr;
// TODO: Maybe I should swap the alias and the field name since internally I use u.
/// Styling specific to the memory widget.
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
#[cfg_attr(feature = "generate_schema", derive(schemars::JsonSchema))]
pub(crate) struct MemoryStyle {
pub(crate) ram: Option<ColorStr>,
/// The colour of the RAM label and graph line.
#[serde(alias = "ram_colour")]
pub(crate) ram_color: Option<ColorStr>,
/// The colour of the cache label and graph line. Does not do anything on Windows.
#[cfg(not(target_os = "windows"))]
pub(crate) cache: Option<ColorStr>,
pub(crate) swap: Option<ColorStr>,
pub(crate) arc: Option<ColorStr>,
pub(crate) gpus: Option<Vec<ColorStr>>,
#[serde(alias = "cache_colour")]
pub(crate) cache_color: Option<ColorStr>,
/// The colour of the swap label and graph line.
#[serde(alias = "swap_colour")]
pub(crate) swap_color: Option<ColorStr>,
/// The colour of the ARC label and graph line.
#[serde(alias = "arc_colour")]
pub(crate) arc_color: Option<ColorStr>,
/// Colour of each GPU's memory label and graph line. Read in order.
#[serde(alias = "gpu_colours")]
pub(crate) gpu_colors: Option<Vec<ColorStr>>,
}

View file

@ -6,14 +6,19 @@ use super::ColorStr;
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
#[cfg_attr(feature = "generate_schema", derive(schemars::JsonSchema))]
pub(crate) struct NetworkStyle {
pub(crate) rx: Option<ColorStr>,
pub(crate) tx: Option<ColorStr>,
/// The colour of the RX (download) label and graph line.
#[serde(alias = "rx_colour")]
pub(crate) rx_color: Option<ColorStr>,
/// Set the colour of the "rx total" text. This only affects
/// basic mode.
pub(crate) rx_total: Option<ColorStr>,
/// The colour of the TX (upload) label and graph line.
#[serde(alias = "tx_colour")]
pub(crate) tx_color: Option<ColorStr>,
/// Set the colour of the "tx total" text. This only affects
/// basic mode.
pub(crate) tx_total: Option<ColorStr>,
/// he colour of the total RX (download) label in basic mode.
#[serde(alias = "rx_total_colour")]
pub(crate) rx_total_color: Option<ColorStr>,
/// The colour of the total TX (upload) label in basic mode.
#[serde(alias = "tx_total_colour")]
pub(crate) tx_total_color: Option<ColorStr>,
}

View file

@ -6,5 +6,6 @@ use super::TextStyleConfig;
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
#[cfg_attr(feature = "generate_schema", derive(schemars::JsonSchema))]
pub(crate) struct TableStyle {
/// Text styling for table headers.
pub(crate) headers: Option<TextStyleConfig>,
}

View file

@ -1,5 +1,5 @@
use concat_string::concat_string;
use tui::style::{Color, Style};
use tui::style::Color;
use unicode_segmentation::UnicodeSegmentation;
/// Convert a hex string to a colour.
@ -53,10 +53,6 @@ pub fn str_to_colour(input_val: &str) -> Result<Color, String> {
}
}
pub(super) fn str_to_fg(input_val: &str) -> Result<Style, String> {
Ok(Style::default().fg(str_to_colour(input_val)?))
}
fn convert_rgb_to_color(rgb_str: &str) -> Result<Color, String> {
let rgb_list = rgb_str.split(',').collect::<Vec<&str>>();
if rgb_list.len() != 3 {
@ -136,18 +132,55 @@ macro_rules! opt {
macro_rules! set_style {
($palette_field:expr, $config_location:expr, $field:tt) => {
if let Some(style) = &(opt!($config_location.as_ref()?.$field.as_ref())) {
if let Some(colour) = &style.color {
$palette_field = crate::options::config::style::utils::str_to_fg(&colour.0)
match &style {
TextStyleConfig::Colour(colour) => {
$palette_field = $palette_field.fg(
crate::options::config::style::utils::str_to_colour(&colour.0)
.map_err(|err| match stringify!($config_location).split_once(".") {
Some((_, loc)) => OptionError::config(format!(
Some((_, loc)) => crate::options::OptionError::config(format!(
"Please update 'styles.{loc}.{}' in your config file. {err}",
stringify!($field)
)),
None => OptionError::config(format!(
None => crate::options::OptionError::config(format!(
"Please update 'styles.{}' in your config file. {err}",
stringify!($field)
)),
})?;
})?
);
}
TextStyleConfig::TextStyle {color, bg_color, bold: _} => {
if let Some(fg) = &color {
$palette_field = $palette_field.fg(
crate::options::config::style::utils::str_to_colour(&fg.0)
.map_err(|err| match stringify!($config_location).split_once(".") {
Some((_, loc)) => crate::options::OptionError::config(format!(
"Please update 'styles.{loc}.{}' in your config file. {err}",
stringify!($field)
)),
None => crate::options::OptionError::config(format!(
"Please update 'styles.{}' in your config file. {err}",
stringify!($field)
)),
})?
);
}
if let Some(bg) = &bg_color {
$palette_field = $palette_field.bg(
crate::options::config::style::utils::str_to_colour(&bg.0)
.map_err(|err| match stringify!($config_location).split_once(".") {
Some((_, loc)) => crate::options::OptionError::config(format!(
"Please update 'styles.{loc}.{}' in your config file. {err}",
stringify!($field)
)),
None => crate::options::OptionError::config(format!(
"Please update 'styles.{}' in your config file. {err}",
stringify!($field)
)),
})?
);
}
}
}
}
};
@ -156,19 +189,20 @@ macro_rules! set_style {
macro_rules! set_colour {
($palette_field:expr, $config_location:expr, $field:tt) => {
if let Some(colour) = &(opt!($config_location.as_ref()?.$field.as_ref())) {
$palette_field =
crate::options::config::style::utils::str_to_fg(&colour.0).map_err(|err| {
$palette_field = $palette_field.fg(
crate::options::config::style::utils::str_to_colour(&colour.0).map_err(|err| {
match stringify!($config_location).split_once(".") {
Some((_, loc)) => OptionError::config(format!(
Some((_, loc)) => crate::options::OptionError::config(format!(
"Please update 'styles.{loc}.{}' in your config file. {err}",
stringify!($field)
)),
None => OptionError::config(format!(
None => crate::options::OptionError::config(format!(
"Please update 'styles.{}' in your config file. {err}",
stringify!($field)
)),
}
})?;
})?,
);
}
};
}
@ -178,14 +212,17 @@ macro_rules! set_colour_list {
if let Some(colour_list) = &(opt!($config_location.as_ref()?.$field.as_ref())) {
$palette_field = colour_list
.iter()
.map(|s| crate::options::config::style::utils::str_to_fg(&s.0))
.map(|s| {
Ok(Style::default()
.fg(crate::options::config::style::utils::str_to_colour(&s.0)?))
})
.collect::<Result<Vec<Style>, String>>()
.map_err(|err| match stringify!($config_location).split_once(".") {
Some((_, loc)) => OptionError::config(format!(
Some((_, loc)) => crate::options::OptionError::config(format!(
"Please update 'styles.{loc}.{}' in your config file. {err}",
stringify!($field)
)),
None => OptionError::config(format!(
None => crate::options::OptionError::config(format!(
"Please update 'styles.{}' in your config file. {err}",
stringify!($field)
)),
@ -199,6 +236,10 @@ pub(super) use {opt, set_colour, set_colour_list, set_style};
#[cfg(test)]
mod test {
use tui::style::Style;
use crate::options::config::style::{ColorStr, TextStyleConfig};
use super::*;
#[test]
@ -351,4 +392,124 @@ mod test {
assert!(convert_rgb_to_color("1, -100000, 1").is_err());
assert!(convert_rgb_to_color("1, -100000, 100000").is_err());
}
struct DummyConfig {
inner: Option<InnerDummyConfig>,
}
struct InnerDummyConfig {
color_a: Option<ColorStr>,
color_b: Option<ColorStr>,
color_c: Option<ColorStr>,
color_d: Option<ColorStr>,
many_colors: Option<Vec<ColorStr>>,
text_a: Option<TextStyleConfig>,
text_b: Option<TextStyleConfig>,
text_c: Option<TextStyleConfig>,
text_d: Option<TextStyleConfig>,
text_e: Option<TextStyleConfig>,
}
impl Default for InnerDummyConfig {
fn default() -> Self {
Self {
color_a: None,
color_b: Some(ColorStr("red".into())),
color_c: Some(ColorStr("255, 255, 255".into())),
color_d: Some(ColorStr("#000000".into())),
many_colors: Some(vec![ColorStr("red".into()), ColorStr("blue".into())]),
text_a: Some(TextStyleConfig::Colour(ColorStr("green".into()))),
text_b: Some(TextStyleConfig::TextStyle {
color: None,
bg_color: None,
bold: None,
}),
text_c: Some(TextStyleConfig::TextStyle {
color: Some(ColorStr("magenta".into())),
bg_color: Some(ColorStr("255, 255, 255".into())),
bold: Some(false),
}),
text_d: Some(TextStyleConfig::TextStyle {
color: Some(ColorStr("#fff".into())),
bg_color: Some(ColorStr("1, 1, 1".into())),
bold: Some(true),
}),
text_e: None,
}
}
}
#[test]
fn test_set_colour() -> anyhow::Result<()> {
let mut s = Style::default().fg(Color::Black);
let dummy = DummyConfig {
inner: Some(InnerDummyConfig::default()),
};
set_colour!(s, &dummy.inner, color_a);
assert_eq!(s.fg.unwrap(), Color::Black);
assert_eq!(s.bg, None);
set_colour!(s, &dummy.inner, color_b);
assert_eq!(s.fg.unwrap(), Color::Red);
assert_eq!(s.bg, None);
set_colour!(s, &dummy.inner, color_c);
assert_eq!(s.fg.unwrap(), Color::Rgb(255, 255, 255));
assert_eq!(s.bg, None);
set_colour!(s, &dummy.inner, color_d);
assert_eq!(s.fg.unwrap(), Color::Rgb(0, 0, 0));
assert_eq!(s.bg, None);
Ok(())
}
#[test]
fn test_set_multi_colours() -> anyhow::Result<()> {
let mut s: Vec<Style> = vec![];
let dummy = DummyConfig {
inner: Some(InnerDummyConfig::default()),
};
set_colour_list!(s, &dummy.inner, many_colors);
assert_eq!(s.len(), 2);
assert_eq!(s[0].fg, Some(Color::Red));
assert_eq!(s[1].fg, Some(Color::Blue));
Ok(())
}
#[test]
fn test_set_style() -> anyhow::Result<()> {
let mut s = Style::default().fg(Color::Black);
let dummy = DummyConfig {
inner: Some(InnerDummyConfig::default()),
};
set_style!(s, &dummy.inner, text_e);
assert_eq!(s.fg.unwrap(), Color::Black);
assert_eq!(s.bg, None);
assert!(s.add_modifier.is_empty());
set_style!(s, &dummy.inner, text_a);
assert_eq!(s.fg.unwrap(), Color::Green);
assert_eq!(s.bg, None);
set_style!(s, &dummy.inner, text_b);
assert_eq!(s.fg.unwrap(), Color::Green);
assert_eq!(s.bg, None);
set_style!(s, &dummy.inner, text_c);
assert_eq!(s.fg.unwrap(), Color::Magenta);
assert_eq!(s.bg.unwrap(), Color::Rgb(255, 255, 255));
set_style!(s, &dummy.inner, text_d);
assert_eq!(s.fg.unwrap(), Color::Rgb(255, 255, 255));
assert_eq!(s.bg.unwrap(), Color::Rgb(1, 1, 1));
// TODO: Add this
// assert!(s.add_modifier.contains(Modifier::BOLD));
Ok(())
}
}

View file

@ -6,11 +6,23 @@ use super::{ColorStr, TextStyleConfig};
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
#[cfg_attr(feature = "generate_schema", derive(schemars::JsonSchema))]
pub(crate) struct WidgetStyle {
pub(crate) border: Option<ColorStr>,
pub(crate) selected_border: Option<ColorStr>,
/// The colour of the widgets' borders.
#[serde(alias = "border_colour")]
pub(crate) border_color: Option<ColorStr>,
/// The colour of a widget's borders when the widget is selected.
#[serde(alias = "selected_border_colour")]
pub(crate) selected_border_color: Option<ColorStr>,
/// Text styling for a widget's title.
pub(crate) widget_title: Option<TextStyleConfig>,
/// Text styling for text in general.
pub(crate) text: Option<TextStyleConfig>,
/// Text styling for text when representing something that is selected.
pub(crate) selected_text: Option<TextStyleConfig>,
/// Text styling for text when representing something that is disabled.
pub(crate) disabled_text: Option<TextStyleConfig>,
}

View file

@ -1,6 +1,6 @@
# Test basic colours
[styles.cpu]
all_entry_color="255, 50, 50"
all_entry_color = "255, 50, 50"
# Test tables
[styles.graphs.legend_text]
@ -10,4 +10,10 @@ bold = false
# Test inline tables
[styles.tables]
headers = { color = "red", bg_color = "reset", bold = true }
headers = { color = "red", bg_color = "black", bold = true }
# Test using normal colour where inline table can also work
[styles.widgets]
selected_text = "#fff"
disabled_text = "blue"
text = "255, 0, 255"

View file

@ -20,34 +20,34 @@ avg_entry_color = "red"
cpu_core_colors = ["light magenta", "light yellow", "light cyan", "light green", "light blue", "cyan", "green", "blue"]
[styles.memory]
ram = "light magenta"
cache = "light red"
swap = "light yellow"
arc = "light cyan"
gpus = ["light blue", "light red", "cyan", "green", "blue", "red"]
ram_color = "light magenta"
cache_color = "light red"
swap_color = "light yellow"
arc_color = "light cyan"
gpu_colors = ["light blue", "light red", "cyan", "green", "blue", "red"]
[styles.network]
rx = "light magenta"
tx = "light yellow"
rx_total = "light cyan"
tx_total = "light green"
rx_color = "light magenta"
tx_color = "light yellow"
rx_total_color = "light cyan"
tx_total_color = "light green"
[styles.battery]
high_battery = "green"
medium_battery = "yellow"
low_battery = "red"
high_battery_color = "green"
medium_battery_color = "yellow"
low_battery_color = "red"
[styles.tables]
headers = {color = "light blue"}
headers = { color = "light blue" }
[styles.graphs]
graph_color = "gray"
legend_text = {color = "gray"}
legend_text = { color = "gray" }
[styles.widgets]
border = "gray"
selected_border = "light blue"
widget_title = {color = "gray"}
text = {color = "gray"}
selected_text = {color = "black", bg_color = "light blue"}
disabled_text = {color = "dark gray"}
border_color = "gray"
selected_border_color = "light blue"
widget_title = { color = "gray" }
text = { color = "gray" }
selected_text = { color = "black", bg_color = "light blue" }
disabled_text = { color = "dark gray" }