mirror of
https://github.com/ClementTsang/bottom
synced 2024-11-21 19:53:05 +00:00
Added named colour support + rgb colour support in config files.
This commit is contained in:
parent
6ffe14707d
commit
59238c2687
4 changed files with 157 additions and 51 deletions
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -9,8 +9,11 @@ Cargo.lock
|
|||
# These are backup files generated by rustfmt
|
||||
**/*.rs.bk
|
||||
|
||||
# Stuff to really ignore
|
||||
*.log
|
||||
.vscode
|
||||
rust-unmangle
|
||||
*.svg
|
||||
*.data
|
||||
*.data
|
||||
|
||||
sample_configs/testing.toml
|
||||
|
|
|
@ -12,26 +12,27 @@ One use of a config file is to set boot flags to execute without having to state
|
|||
|
||||
## Colours
|
||||
|
||||
Another use is to set colours, under the `[colors]`. The following labels are customizable with hex colour code strings:
|
||||
Another use is to set colours, under the `[colors]`. The following labels are customizable with strings that are hex colours, RGB colours, or specific named colours.
|
||||
|
||||
| Labels | Details | Example |
|
||||
| ------------------------------- | ---------------------------------------------- | --------------------------------------------------- |
|
||||
| Table header colours | Colour of table headers | `table_header_color="#ffffff"` |
|
||||
| CPU colour per core | Colour of each core. Read in order. | `cpu_core_colors=["#ffffff", "#000000", "#111111"]` |
|
||||
| | Looks at 256 colours at most. |
|
||||
| Average CPU colour | The average CPU color | `avg_cpu_color="#d3869b"` |
|
||||
| RAM | The colour RAM will use | `ram_color="#ffffff"` |
|
||||
| SWAP | The colour SWAP will use | `swap_color="#111111"` |
|
||||
| RX | The colour rx will use | `rx_color="#ffffff"` |
|
||||
| TX | The colour tx will use | `tx_color="#111111"` |
|
||||
| Widget title colour | The colour of the label each widget has | `widget_title_color="#ffffff"` |
|
||||
| Border colour | The colour of the border of unselected widgets | `border_color="#ffffff"` |
|
||||
| Selected border colour | The colour of the border of selected widgets | `highlighted_border_color="#ffffff"` |
|
||||
| Text colour | The colour of most text | `text_color="#ffffff"` |
|
||||
| Graph colour | The colour of the lines and text of the graph | `graph_color="#ffffff"` |
|
||||
| Cursor colour | The cursor's colour | `cursor_color="#ffffff"` |
|
||||
| Selected text colour | The colour of text that is selected | `scroll_entry_text_color="#282828"` |
|
||||
| Selected text background colour | The background colour of text that is selected | `scroll_entry_bg_color="#458588"` |
|
||||
Supported named colours are one of the following: `Reset, Black, Red, Green, Yellow, Blue, Magenta, Cyan, Gray, DarkGray, LightRed, LightGreen, LightYellow, LightBlue, LightMagenta, LightCyan, White`
|
||||
|
||||
| Labels | Details | Example |
|
||||
| ------------------------------- | ---------------------------------------------- | ------------------------------------------------------ |
|
||||
| Table header colours | Colour of table headers | `table_header_color="256, 256, 256"` |
|
||||
| CPU colour per core | Colour of each core. Read in order. | `cpu_core_colors=["#ffffff", "blue", "122, 122, 122"]` |
|
||||
| Average CPU colour | The average CPU color | `avg_cpu_color="Red"` |
|
||||
| RAM | The colour RAM will use | `ram_color="#ffffff"` |
|
||||
| SWAP | The colour SWAP will use | `swap_color="#111111"` |
|
||||
| RX | The colour rx will use | `rx_color="#ffffff"` |
|
||||
| TX | The colour tx will use | `tx_color="#111111"` |
|
||||
| Widget title colour | The colour of the label each widget has | `widget_title_color="#ffffff"` |
|
||||
| Border colour | The colour of the border of unselected widgets | `border_color="#ffffff"` |
|
||||
| Selected border colour | The colour of the border of selected widgets | `highlighted_border_color="#ffffff"` |
|
||||
| Text colour | The colour of most text | `text_color="#ffffff"` |
|
||||
| Graph colour | The colour of the lines and text of the graph | `graph_color="#ffffff"` |
|
||||
| Cursor colour | The cursor's colour | `cursor_color="#ffffff"` |
|
||||
| Selected text colour | The colour of text that is selected | `scroll_entry_text_color="#282828"` |
|
||||
| Selected text background colour | The background colour of text that is selected | `scroll_entry_bg_color="#458588"` |
|
||||
|
||||
Note some colours may not be compatible with the terminal you are using. For example, macOS's default Terminal does not play nice with many colours.
|
||||
|
||||
|
|
|
@ -49,50 +49,49 @@ impl Default for CanvasColours {
|
|||
}
|
||||
|
||||
impl CanvasColours {
|
||||
pub fn set_text_colour(&mut self, hex: &str) -> error::Result<()> {
|
||||
self.text_style = get_style_from_hex(hex)?;
|
||||
pub fn set_text_colour(&mut self, colour: &str) -> error::Result<()> {
|
||||
self.text_style = get_style_from_config(colour)?;
|
||||
Ok(())
|
||||
}
|
||||
pub fn set_border_colour(&mut self, hex: &str) -> error::Result<()> {
|
||||
self.border_style = get_style_from_hex(hex)?;
|
||||
pub fn set_border_colour(&mut self, colour: &str) -> error::Result<()> {
|
||||
self.border_style = get_style_from_config(colour)?;
|
||||
Ok(())
|
||||
}
|
||||
pub fn set_highlighted_border_colour(&mut self, hex: &str) -> error::Result<()> {
|
||||
self.highlighted_border_style = get_style_from_hex(hex)?;
|
||||
pub fn set_highlighted_border_colour(&mut self, colour: &str) -> error::Result<()> {
|
||||
self.highlighted_border_style = get_style_from_config(colour)?;
|
||||
Ok(())
|
||||
}
|
||||
pub fn set_table_header_colour(&mut self, hex: &str) -> error::Result<()> {
|
||||
self.table_header_style = get_style_from_hex(hex)?.modifier(Modifier::BOLD);
|
||||
pub fn set_table_header_colour(&mut self, colour: &str) -> error::Result<()> {
|
||||
self.table_header_style = get_style_from_config(colour)?.modifier(Modifier::BOLD);
|
||||
Ok(())
|
||||
}
|
||||
pub fn set_ram_colour(&mut self, hex: &str) -> error::Result<()> {
|
||||
self.ram_style = get_style_from_hex(hex)?;
|
||||
pub fn set_ram_colour(&mut self, colour: &str) -> error::Result<()> {
|
||||
self.ram_style = get_style_from_config(colour)?;
|
||||
Ok(())
|
||||
}
|
||||
pub fn set_swap_colour(&mut self, hex: &str) -> error::Result<()> {
|
||||
self.swap_style = get_style_from_hex(hex)?;
|
||||
pub fn set_swap_colour(&mut self, colour: &str) -> error::Result<()> {
|
||||
self.swap_style = get_style_from_config(colour)?;
|
||||
Ok(())
|
||||
}
|
||||
pub fn set_rx_colour(&mut self, hex: &str) -> error::Result<()> {
|
||||
self.rx_style = get_style_from_hex(hex)?;
|
||||
pub fn set_rx_colour(&mut self, colour: &str) -> error::Result<()> {
|
||||
self.rx_style = get_style_from_config(colour)?;
|
||||
Ok(())
|
||||
}
|
||||
pub fn set_tx_colour(&mut self, hex: &str) -> error::Result<()> {
|
||||
self.tx_style = get_style_from_hex(hex)?;
|
||||
pub fn set_tx_colour(&mut self, colour: &str) -> error::Result<()> {
|
||||
self.tx_style = get_style_from_config(colour)?;
|
||||
Ok(())
|
||||
}
|
||||
pub fn set_avg_cpu_colour(&mut self, hex: &str) -> error::Result<()> {
|
||||
self.avg_colour_style = get_style_from_hex(hex)?;
|
||||
pub fn set_avg_cpu_colour(&mut self, colour: &str) -> error::Result<()> {
|
||||
self.avg_colour_style = get_style_from_config(colour)?;
|
||||
Ok(())
|
||||
}
|
||||
pub fn set_cpu_colours(&mut self, hex_colours: &[String]) -> error::Result<()> {
|
||||
let max_amount = std::cmp::min(hex_colours.len(), NUM_COLOURS as usize);
|
||||
for (itx, hex_colour) in hex_colours.iter().enumerate() {
|
||||
pub fn set_cpu_colours(&mut self, colours: &[String]) -> error::Result<()> {
|
||||
let max_amount = std::cmp::min(colours.len(), NUM_COLOURS as usize);
|
||||
for (itx, colour) in colours.iter().enumerate() {
|
||||
if itx >= max_amount {
|
||||
break;
|
||||
}
|
||||
self.cpu_colour_styles
|
||||
.push(Style::default().fg(convert_hex_to_color(hex_colour)?));
|
||||
self.cpu_colour_styles.push(get_style_from_config(colour)?);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -102,28 +101,28 @@ impl CanvasColours {
|
|||
.extend(gen_n_styles(remaining_num_colours));
|
||||
}
|
||||
|
||||
pub fn set_scroll_entry_text_color(&mut self, hex: &str) -> error::Result<()> {
|
||||
self.currently_selected_text_colour = convert_hex_to_color(hex)?;
|
||||
pub fn set_scroll_entry_text_color(&mut self, colour: &str) -> error::Result<()> {
|
||||
self.currently_selected_text_colour = get_colour_from_config(colour)?;
|
||||
self.currently_selected_text_style = Style::default()
|
||||
.fg(self.currently_selected_text_colour)
|
||||
.bg(self.currently_selected_bg_colour);
|
||||
Ok(())
|
||||
}
|
||||
pub fn set_scroll_entry_bg_color(&mut self, hex: &str) -> error::Result<()> {
|
||||
self.currently_selected_bg_colour = convert_hex_to_color(hex)?;
|
||||
pub fn set_scroll_entry_bg_color(&mut self, colour: &str) -> error::Result<()> {
|
||||
self.currently_selected_bg_colour = get_colour_from_config(colour)?;
|
||||
self.currently_selected_text_style = Style::default()
|
||||
.fg(self.currently_selected_text_colour)
|
||||
.bg(self.currently_selected_bg_colour);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn set_widget_title_colour(&mut self, hex: &str) -> error::Result<()> {
|
||||
self.widget_title_style = get_style_from_hex(hex)?;
|
||||
pub fn set_widget_title_colour(&mut self, colour: &str) -> error::Result<()> {
|
||||
self.widget_title_style = get_style_from_config(colour)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn set_graph_colour(&mut self, hex: &str) -> error::Result<()> {
|
||||
self.graph_style = get_style_from_hex(hex)?;
|
||||
pub fn set_graph_colour(&mut self, colour: &str) -> error::Result<()> {
|
||||
self.graph_style = get_style_from_config(colour)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use crate::utils::{error, gen_util::*};
|
||||
use std::collections::HashMap;
|
||||
use tui::style::{Color, Style};
|
||||
|
||||
const GOLDEN_RATIO: f32 = 0.618_034; // Approx, good enough for use (also Clippy gets mad if it's too long)
|
||||
|
@ -6,6 +7,31 @@ pub const STANDARD_FIRST_COLOUR: Color = Color::LightMagenta;
|
|||
pub const STANDARD_SECOND_COLOUR: Color = Color::LightYellow;
|
||||
pub const AVG_COLOUR: Color = Color::Red;
|
||||
|
||||
lazy_static! {
|
||||
static ref COLOR_NAME_LOOKUP_TABLE: HashMap<&'static str, Color> = [
|
||||
("reset", Color::Reset),
|
||||
("black", Color::Black),
|
||||
("red", Color::Red),
|
||||
("green", Color::Green),
|
||||
("yellow", Color::Yellow),
|
||||
("blue", Color::Blue),
|
||||
("magenta", Color::Magenta),
|
||||
("cyan", Color::Cyan),
|
||||
("gray", Color::Gray),
|
||||
("darkgray", Color::DarkGray),
|
||||
("lightred", Color::LightRed),
|
||||
("lightgreen", Color::LightGreen),
|
||||
("lightyellow", Color::LightYellow),
|
||||
("lightblue", Color::LightBlue),
|
||||
("lightmagenta", Color::LightMagenta),
|
||||
("lightcyan", Color::LightCyan),
|
||||
("white", Color::White)
|
||||
]
|
||||
.iter()
|
||||
.copied()
|
||||
.collect();
|
||||
}
|
||||
|
||||
/// Generates random colours. Strategy found from
|
||||
/// https://martin.ankerl.com/2009/12/09/how-to-create-random-colors-programmatically/
|
||||
pub fn gen_n_styles(num_to_gen: i32) -> Vec<Style> {
|
||||
|
@ -80,6 +106,83 @@ pub fn convert_hex_to_color(hex: &str) -> error::Result<Color> {
|
|||
Ok(Color::Rgb(rgb.0, rgb.1, rgb.2))
|
||||
}
|
||||
|
||||
pub fn get_style_from_config(input_val: &str) -> error::Result<Style> {
|
||||
if input_val.len() > 1 {
|
||||
if &input_val[0..1] == "#" {
|
||||
get_style_from_hex(input_val)
|
||||
} else if input_val.contains(',') {
|
||||
get_style_from_rgb(input_val)
|
||||
} else {
|
||||
get_style_from_color_name(input_val)
|
||||
}
|
||||
} else {
|
||||
Err(error::BottomError::GenericError(format!(
|
||||
"Colour input {} is not valid.",
|
||||
input_val
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_colour_from_config(input_val: &str) -> error::Result<Color> {
|
||||
if input_val.len() > 1 {
|
||||
if &input_val[0..1] == "#" {
|
||||
convert_hex_to_color(input_val)
|
||||
} else if input_val.contains(',') {
|
||||
convert_rgb_to_color(input_val)
|
||||
} else {
|
||||
convert_name_to_color(input_val)
|
||||
}
|
||||
} else {
|
||||
Err(error::BottomError::GenericError(format!(
|
||||
"Colour input {} is not valid.",
|
||||
input_val
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_style_from_hex(hex: &str) -> error::Result<Style> {
|
||||
Ok(Style::default().fg(convert_hex_to_color(hex)?))
|
||||
}
|
||||
|
||||
fn convert_rgb_to_color(rgb_str: &str) -> error::Result<Color> {
|
||||
let rgb_list = rgb_str.split(',');
|
||||
let rgb = rgb_list
|
||||
.filter_map(|val| {
|
||||
if let Ok(res) = val.to_string().trim().parse::<u8>() {
|
||||
Some(res)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
if rgb.len() == 3 {
|
||||
Ok(Color::Rgb(rgb[0], rgb[1], rgb[2]))
|
||||
} else {
|
||||
Err(error::BottomError::GenericError(format!(
|
||||
"RGB colour {} is not of valid length. It must be a comma separated value with 3 integers from 0 to 255, like \"255, 0, 155\".",
|
||||
rgb_str
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_style_from_rgb(rgb_str: &str) -> error::Result<Style> {
|
||||
Ok(Style::default().fg(convert_rgb_to_color(rgb_str)?))
|
||||
}
|
||||
|
||||
fn convert_name_to_color(color_name: &str) -> error::Result<Color> {
|
||||
let color = COLOR_NAME_LOOKUP_TABLE.get(color_name.to_lowercase().as_str());
|
||||
if let Some(color) = color {
|
||||
return Ok(*color);
|
||||
}
|
||||
|
||||
Err(error::BottomError::GenericError(format!(
|
||||
"Color {} is not a supported config colour. bottom supports the following named colours as strings: \
|
||||
Reset, Black, Red, Green, Yellow, Blue, Magenta, Cyan, Gray, DarkGray, LightRed, LightGreen, \
|
||||
LightYellow, LightBlue, LightMagenta, LightCyan, White",
|
||||
color_name
|
||||
)))
|
||||
}
|
||||
|
||||
pub fn get_style_from_color_name(color_name: &str) -> error::Result<Style> {
|
||||
Ok(Style::default().fg(convert_name_to_color(color_name)?))
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue