More cleaning up of new colour feature

This commit is contained in:
ClementTsang 2020-02-08 18:00:50 -05:00
parent 7000a2720d
commit b593a29e9c
3 changed files with 195 additions and 185 deletions

View file

@ -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,

View 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(())
}
}

View 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))
}