diff options
-rw-r--r-- | src/canvas.rs | 188 | ||||
-rw-r--r-- | src/canvas/canvas_colours.rs | 119 | ||||
-rw-r--r-- | src/canvas/canvas_colours/drawing_utils.rs | 73 |
3 files changed, 195 insertions, 185 deletions
diff --git a/src/canvas.rs b/src/canvas.rs index 9eaa29f9..c70ae720 100644 --- a/src/canvas.rs +++ b/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, diff --git a/src/canvas/canvas_colours.rs b/src/canvas/canvas_colours.rs new file mode 100644 index 00000000..322f6d0a --- /dev/null +++ b/src/canvas/canvas_colours.rs @@ -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(()) + } +} diff --git a/src/canvas/canvas_colours/drawing_utils.rs b/src/canvas/canvas_colours/drawing_utils.rs new file mode 100644 index 00000000..066e9f0d --- /dev/null +++ b/src/canvas/canvas_colours/drawing_utils.rs @@ -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)) +} |