mirror of
https://github.com/ClementTsang/bottom
synced 2024-11-23 04:33:10 +00:00
More cleaning up of new colour feature
This commit is contained in:
parent
7000a2720d
commit
b593a29e9c
3 changed files with 195 additions and 185 deletions
188
src/canvas.rs
188
src/canvas.rs
|
@ -2,7 +2,7 @@ use crate::{
|
|||
app::{self, data_harvester::processes::ProcessHarvest},
|
||||
constants::*,
|
||||
data_conversion::{ConvertedCpuData, ConvertedProcessData},
|
||||
utils::{error, gen_util::*},
|
||||
utils::error,
|
||||
};
|
||||
use std::cmp::max;
|
||||
use std::collections::HashMap;
|
||||
|
@ -15,10 +15,8 @@ use tui::{
|
|||
Terminal,
|
||||
};
|
||||
|
||||
const STANDARD_FIRST_COLOUR: Color = Color::Rgb(150, 106, 253);
|
||||
const STANDARD_SECOND_COLOUR: Color = Color::LightYellow;
|
||||
const GOLDEN_RATIO: f32 = 0.618_034; // Approx, good enough for use (also Clippy gets mad if it's too long)
|
||||
|
||||
mod canvas_colours;
|
||||
use canvas_colours::*;
|
||||
// Headers
|
||||
const CPU_LEGEND_HEADER: [&str; 2] = ["CPU", "Use%"];
|
||||
const DISK_HEADERS: [&str; 7] = ["Disk", "Mount", "Used", "Free", "Total", "R/s", "W/s"];
|
||||
|
@ -101,75 +99,6 @@ pub struct DisplayableData {
|
|||
pub cpu_data: Vec<ConvertedCpuData>,
|
||||
}
|
||||
|
||||
/// Generates random colours. Strategy found from
|
||||
/// https://martin.ankerl.com/2009/12/09/how-to-create-random-colors-programmatically/
|
||||
fn gen_n_styles(num_to_gen: i32) -> Vec<Style> {
|
||||
fn gen_hsv(h: f32) -> f32 {
|
||||
let new_val = h + GOLDEN_RATIO;
|
||||
if new_val > 1.0 {
|
||||
new_val.fract()
|
||||
} else {
|
||||
new_val
|
||||
}
|
||||
}
|
||||
/// This takes in an h, s, and v value of range [0, 1]
|
||||
/// For explanation of what this does, see
|
||||
/// https://en.wikipedia.org/wiki/HSL_and_HSV#HSV_to_RGB_alternative
|
||||
fn hsv_to_rgb(hue: f32, saturation: f32, value: f32) -> (u8, u8, u8) {
|
||||
fn hsv_helper(num: u32, hu: f32, sat: f32, val: f32) -> f32 {
|
||||
let k = (num as f32 + hu * 6.0) % 6.0;
|
||||
val - val * sat * float_max(float_min(k, float_min(4.1 - k, 1.1)), 0.0)
|
||||
}
|
||||
|
||||
(
|
||||
(hsv_helper(5, hue, saturation, value) * 255.0) as u8,
|
||||
(hsv_helper(3, hue, saturation, value) * 255.0) as u8,
|
||||
(hsv_helper(1, hue, saturation, value) * 255.0) as u8,
|
||||
)
|
||||
}
|
||||
|
||||
// Generate colours
|
||||
let mut colour_vec: Vec<Style> = vec![
|
||||
Style::default().fg(Color::Rgb(150, 106, 253)),
|
||||
Style::default().fg(Color::LightYellow),
|
||||
Style::default().fg(Color::LightMagenta),
|
||||
Style::default().fg(Color::LightCyan),
|
||||
Style::default().fg(Color::Green),
|
||||
Style::default().fg(Color::Red),
|
||||
];
|
||||
|
||||
let mut h: f32 = 0.4; // We don't need random colours... right?
|
||||
for _i in 0..(num_to_gen - 6) {
|
||||
h = gen_hsv(h);
|
||||
let result = hsv_to_rgb(h, 0.5, 0.95);
|
||||
colour_vec.push(Style::default().fg(Color::Rgb(result.0, result.1, result.2)));
|
||||
}
|
||||
|
||||
colour_vec
|
||||
}
|
||||
|
||||
fn convert_hex_to_color(hex: &str) -> error::Result<Color> {
|
||||
fn convert_hex_to_rgb(hex: &str) -> error::Result<(u8, u8, u8)> {
|
||||
if hex.len() == 7 && &hex[0..1] == "#" {
|
||||
let r = u8::from_str_radix(&hex[1..3], 16)?;
|
||||
let g = u8::from_str_radix(&hex[3..5], 16)?;
|
||||
let b = u8::from_str_radix(&hex[5..7], 16)?;
|
||||
|
||||
return Ok((r, g, b));
|
||||
}
|
||||
|
||||
Err(error::BottomError::GenericError {
|
||||
message: format!(
|
||||
"Colour hex {} is not of valid length. It must be a 7 character string of the form \"#112233\".",
|
||||
hex
|
||||
),
|
||||
})
|
||||
}
|
||||
|
||||
let rgb = convert_hex_to_rgb(hex)?;
|
||||
Ok(Color::Rgb(rgb.0, rgb.1, rgb.2))
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Default)]
|
||||
/// Handles the canvas' state. TODO: [OPT] implement this.
|
||||
|
@ -187,117 +116,6 @@ pub struct Painter {
|
|||
pub colours: CanvasColours,
|
||||
}
|
||||
|
||||
pub struct CanvasColours {
|
||||
currently_selected_text_colour: Color,
|
||||
currently_selected_bg_colour: Color,
|
||||
currently_selected_text_style: Style,
|
||||
table_header_style: Style,
|
||||
ram_style: Style,
|
||||
swap_style: Style,
|
||||
rx_style: Style,
|
||||
tx_style: Style,
|
||||
cpu_colour_styles: Vec<Style>,
|
||||
border_style: Style,
|
||||
highlighted_border_style: Style,
|
||||
text_style: Style,
|
||||
widget_title_style: Style,
|
||||
graph_style: Style,
|
||||
}
|
||||
|
||||
impl Default for CanvasColours {
|
||||
fn default() -> Self {
|
||||
CanvasColours {
|
||||
currently_selected_text_colour: Color::Black,
|
||||
currently_selected_bg_colour: Color::Cyan,
|
||||
currently_selected_text_style: Style::default().fg(Color::Black).bg(Color::Cyan),
|
||||
table_header_style: Style::default().fg(Color::LightBlue),
|
||||
ram_style: Style::default().fg(STANDARD_FIRST_COLOUR),
|
||||
swap_style: Style::default().fg(STANDARD_SECOND_COLOUR),
|
||||
rx_style: Style::default().fg(STANDARD_FIRST_COLOUR),
|
||||
tx_style: Style::default().fg(STANDARD_SECOND_COLOUR),
|
||||
cpu_colour_styles: Vec::new(),
|
||||
border_style: Style::default().fg(Color::Gray),
|
||||
highlighted_border_style: Style::default().fg(Color::LightBlue),
|
||||
text_style: Style::default().fg(Color::Gray),
|
||||
widget_title_style: Style::default().fg(Color::Gray),
|
||||
graph_style: Style::default().fg(Color::Gray),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl CanvasColours {
|
||||
pub fn set_text_colour(&mut self, hex: &str) -> error::Result<()> {
|
||||
self.text_style = Style::default().fg(convert_hex_to_color(hex)?);
|
||||
Ok(())
|
||||
}
|
||||
pub fn set_border_colour(&mut self, hex: &str) -> error::Result<()> {
|
||||
self.border_style = Style::default().fg(convert_hex_to_color(hex)?);
|
||||
Ok(())
|
||||
}
|
||||
pub fn set_highlighted_border_colour(&mut self, hex: &str) -> error::Result<()> {
|
||||
self.highlighted_border_style = Style::default().fg(convert_hex_to_color(hex)?);
|
||||
Ok(())
|
||||
}
|
||||
pub fn set_table_header_colour(&mut self, hex: &str) -> error::Result<()> {
|
||||
self.table_header_style = Style::default().fg(convert_hex_to_color(hex)?);
|
||||
Ok(())
|
||||
}
|
||||
pub fn set_ram_colour(&mut self, hex: &str) -> error::Result<()> {
|
||||
self.ram_style = Style::default().fg(convert_hex_to_color(hex)?);
|
||||
Ok(())
|
||||
}
|
||||
pub fn set_swap_colour(&mut self, hex: &str) -> error::Result<()> {
|
||||
self.swap_style = Style::default().fg(convert_hex_to_color(hex)?);
|
||||
Ok(())
|
||||
}
|
||||
pub fn set_rx_colour(&mut self, hex: &str) -> error::Result<()> {
|
||||
self.rx_style = Style::default().fg(convert_hex_to_color(hex)?);
|
||||
Ok(())
|
||||
}
|
||||
pub fn set_tx_colour(&mut self, hex: &str) -> error::Result<()> {
|
||||
self.tx_style = Style::default().fg(convert_hex_to_color(hex)?);
|
||||
Ok(())
|
||||
}
|
||||
pub fn set_cpu_colours(&mut self, hex_colours: &Vec<String>) -> error::Result<()> {
|
||||
let max_amount = std::cmp::min(hex_colours.len(), NUM_COLOURS as usize);
|
||||
for i in 0..max_amount {
|
||||
self.cpu_colour_styles
|
||||
.push(Style::default().fg(convert_hex_to_color(&hex_colours[i])?));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
pub fn generate_remaining_cpu_colours(&mut self) {
|
||||
let remaining_num_colours = NUM_COLOURS - self.cpu_colour_styles.len() as i32;
|
||||
self.cpu_colour_styles
|
||||
.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)?;
|
||||
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)?;
|
||||
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 = Style::default().fg(convert_hex_to_color(hex)?);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn set_graph_colour(&mut self, hex: &str) -> error::Result<()> {
|
||||
self.graph_style = Style::default().fg(convert_hex_to_color(hex)?);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Painter {
|
||||
pub fn draw_data<B: backend::Backend>(
|
||||
&mut self, terminal: &mut Terminal<B>, app_state: &mut app::App,
|
||||
|
|
119
src/canvas/canvas_colours.rs
Normal file
119
src/canvas/canvas_colours.rs
Normal file
|
@ -0,0 +1,119 @@
|
|||
mod drawing_utils;
|
||||
use drawing_utils::*;
|
||||
use tui::style::{Color, Style};
|
||||
|
||||
use crate::{constants::*, utils::error};
|
||||
|
||||
const STANDARD_FIRST_COLOUR: Color = Color::Rgb(150, 106, 253);
|
||||
const STANDARD_SECOND_COLOUR: Color = Color::LightYellow;
|
||||
|
||||
pub struct CanvasColours {
|
||||
pub currently_selected_text_colour: Color,
|
||||
pub currently_selected_bg_colour: Color,
|
||||
pub currently_selected_text_style: Style,
|
||||
pub table_header_style: Style,
|
||||
pub ram_style: Style,
|
||||
pub swap_style: Style,
|
||||
pub rx_style: Style,
|
||||
pub tx_style: Style,
|
||||
pub cpu_colour_styles: Vec<Style>,
|
||||
pub border_style: Style,
|
||||
pub highlighted_border_style: Style,
|
||||
pub text_style: Style,
|
||||
pub widget_title_style: Style,
|
||||
pub graph_style: Style,
|
||||
}
|
||||
|
||||
impl Default for CanvasColours {
|
||||
fn default() -> Self {
|
||||
CanvasColours {
|
||||
currently_selected_text_colour: Color::Black,
|
||||
currently_selected_bg_colour: Color::Cyan,
|
||||
currently_selected_text_style: Style::default().fg(Color::Black).bg(Color::Cyan),
|
||||
table_header_style: Style::default().fg(Color::LightBlue),
|
||||
ram_style: Style::default().fg(STANDARD_FIRST_COLOUR),
|
||||
swap_style: Style::default().fg(STANDARD_SECOND_COLOUR),
|
||||
rx_style: Style::default().fg(STANDARD_FIRST_COLOUR),
|
||||
tx_style: Style::default().fg(STANDARD_SECOND_COLOUR),
|
||||
cpu_colour_styles: Vec::new(),
|
||||
border_style: Style::default().fg(Color::Gray),
|
||||
highlighted_border_style: Style::default().fg(Color::LightBlue),
|
||||
text_style: Style::default().fg(Color::Gray),
|
||||
widget_title_style: Style::default().fg(Color::Gray),
|
||||
graph_style: Style::default().fg(Color::Gray),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl CanvasColours {
|
||||
pub fn set_text_colour(&mut self, hex: &str) -> error::Result<()> {
|
||||
self.text_style = Style::default().fg(convert_hex_to_color(hex)?);
|
||||
Ok(())
|
||||
}
|
||||
pub fn set_border_colour(&mut self, hex: &str) -> error::Result<()> {
|
||||
self.border_style = Style::default().fg(convert_hex_to_color(hex)?);
|
||||
Ok(())
|
||||
}
|
||||
pub fn set_highlighted_border_colour(&mut self, hex: &str) -> error::Result<()> {
|
||||
self.highlighted_border_style = Style::default().fg(convert_hex_to_color(hex)?);
|
||||
Ok(())
|
||||
}
|
||||
pub fn set_table_header_colour(&mut self, hex: &str) -> error::Result<()> {
|
||||
self.table_header_style = Style::default().fg(convert_hex_to_color(hex)?);
|
||||
Ok(())
|
||||
}
|
||||
pub fn set_ram_colour(&mut self, hex: &str) -> error::Result<()> {
|
||||
self.ram_style = Style::default().fg(convert_hex_to_color(hex)?);
|
||||
Ok(())
|
||||
}
|
||||
pub fn set_swap_colour(&mut self, hex: &str) -> error::Result<()> {
|
||||
self.swap_style = Style::default().fg(convert_hex_to_color(hex)?);
|
||||
Ok(())
|
||||
}
|
||||
pub fn set_rx_colour(&mut self, hex: &str) -> error::Result<()> {
|
||||
self.rx_style = Style::default().fg(convert_hex_to_color(hex)?);
|
||||
Ok(())
|
||||
}
|
||||
pub fn set_tx_colour(&mut self, hex: &str) -> error::Result<()> {
|
||||
self.tx_style = Style::default().fg(convert_hex_to_color(hex)?);
|
||||
Ok(())
|
||||
}
|
||||
pub fn set_cpu_colours(&mut self, hex_colours: &Vec<String>) -> error::Result<()> {
|
||||
let max_amount = std::cmp::min(hex_colours.len(), NUM_COLOURS as usize);
|
||||
for i in 0..max_amount {
|
||||
self.cpu_colour_styles
|
||||
.push(Style::default().fg(convert_hex_to_color(&hex_colours[i])?));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
pub fn generate_remaining_cpu_colours(&mut self) {
|
||||
let remaining_num_colours = NUM_COLOURS - self.cpu_colour_styles.len() as i32;
|
||||
self.cpu_colour_styles
|
||||
.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)?;
|
||||
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)?;
|
||||
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 = Style::default().fg(convert_hex_to_color(hex)?);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn set_graph_colour(&mut self, hex: &str) -> error::Result<()> {
|
||||
self.graph_style = Style::default().fg(convert_hex_to_color(hex)?);
|
||||
Ok(())
|
||||
}
|
||||
}
|
73
src/canvas/canvas_colours/drawing_utils.rs
Normal file
73
src/canvas/canvas_colours/drawing_utils.rs
Normal file
|
@ -0,0 +1,73 @@
|
|||
use crate::utils::{error, gen_util::*};
|
||||
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)
|
||||
|
||||
/// 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> {
|
||||
fn gen_hsv(h: f32) -> f32 {
|
||||
let new_val = h + GOLDEN_RATIO;
|
||||
if new_val > 1.0 {
|
||||
new_val.fract()
|
||||
} else {
|
||||
new_val
|
||||
}
|
||||
}
|
||||
/// This takes in an h, s, and v value of range [0, 1]
|
||||
/// For explanation of what this does, see
|
||||
/// https://en.wikipedia.org/wiki/HSL_and_HSV#HSV_to_RGB_alternative
|
||||
fn hsv_to_rgb(hue: f32, saturation: f32, value: f32) -> (u8, u8, u8) {
|
||||
fn hsv_helper(num: u32, hu: f32, sat: f32, val: f32) -> f32 {
|
||||
let k = (num as f32 + hu * 6.0) % 6.0;
|
||||
val - val * sat * float_max(float_min(k, float_min(4.1 - k, 1.1)), 0.0)
|
||||
}
|
||||
|
||||
(
|
||||
(hsv_helper(5, hue, saturation, value) * 255.0) as u8,
|
||||
(hsv_helper(3, hue, saturation, value) * 255.0) as u8,
|
||||
(hsv_helper(1, hue, saturation, value) * 255.0) as u8,
|
||||
)
|
||||
}
|
||||
|
||||
// Generate colours
|
||||
let mut colour_vec: Vec<Style> = vec![
|
||||
Style::default().fg(Color::Rgb(150, 106, 253)),
|
||||
Style::default().fg(Color::LightYellow),
|
||||
Style::default().fg(Color::LightMagenta),
|
||||
Style::default().fg(Color::LightCyan),
|
||||
Style::default().fg(Color::Green),
|
||||
Style::default().fg(Color::Red),
|
||||
];
|
||||
|
||||
let mut h: f32 = 0.4; // We don't need random colours... right?
|
||||
for _i in 0..(num_to_gen - 6) {
|
||||
h = gen_hsv(h);
|
||||
let result = hsv_to_rgb(h, 0.5, 0.95);
|
||||
colour_vec.push(Style::default().fg(Color::Rgb(result.0, result.1, result.2)));
|
||||
}
|
||||
|
||||
colour_vec
|
||||
}
|
||||
|
||||
pub fn convert_hex_to_color(hex: &str) -> error::Result<Color> {
|
||||
fn convert_hex_to_rgb(hex: &str) -> error::Result<(u8, u8, u8)> {
|
||||
if hex.len() == 7 && &hex[0..1] == "#" {
|
||||
let r = u8::from_str_radix(&hex[1..3], 16)?;
|
||||
let g = u8::from_str_radix(&hex[3..5], 16)?;
|
||||
let b = u8::from_str_radix(&hex[5..7], 16)?;
|
||||
|
||||
return Ok((r, g, b));
|
||||
}
|
||||
|
||||
Err(error::BottomError::GenericError {
|
||||
message: format!(
|
||||
"Colour hex {} is not of valid length. It must be a 7 character string of the form \"#112233\".",
|
||||
hex
|
||||
),
|
||||
})
|
||||
}
|
||||
|
||||
let rgb = convert_hex_to_rgb(hex)?;
|
||||
Ok(Color::Rgb(rgb.0, rgb.1, rgb.2))
|
||||
}
|
Loading…
Reference in a new issue