More cleaning up of new colour feature
This commit is contained in:
parent
7000a2720d
commit
b593a29e9c
188
src/canvas.rs
188
src/canvas.rs
|
@ -2,7 +2,7 @@ use crate::{
|
||||||
app::{self, data_harvester::processes::ProcessHarvest},
|
app::{self, data_harvester::processes::ProcessHarvest},
|
||||||
constants::*,
|
constants::*,
|
||||||
data_conversion::{ConvertedCpuData, ConvertedProcessData},
|
data_conversion::{ConvertedCpuData, ConvertedProcessData},
|
||||||
utils::{error, gen_util::*},
|
utils::error,
|
||||||
};
|
};
|
||||||
use std::cmp::max;
|
use std::cmp::max;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
@ -15,10 +15,8 @@ use tui::{
|
||||||
Terminal,
|
Terminal,
|
||||||
};
|
};
|
||||||
|
|
||||||
const STANDARD_FIRST_COLOUR: Color = Color::Rgb(150, 106, 253);
|
mod canvas_colours;
|
||||||
const STANDARD_SECOND_COLOUR: Color = Color::LightYellow;
|
use canvas_colours::*;
|
||||||
const GOLDEN_RATIO: f32 = 0.618_034; // Approx, good enough for use (also Clippy gets mad if it's too long)
|
|
||||||
|
|
||||||
// Headers
|
// Headers
|
||||||
const CPU_LEGEND_HEADER: [&str; 2] = ["CPU", "Use%"];
|
const CPU_LEGEND_HEADER: [&str; 2] = ["CPU", "Use%"];
|
||||||
const DISK_HEADERS: [&str; 7] = ["Disk", "Mount", "Used", "Free", "Total", "R/s", "W/s"];
|
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>,
|
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)]
|
#[allow(dead_code)]
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
/// Handles the canvas' state. TODO: [OPT] implement this.
|
/// Handles the canvas' state. TODO: [OPT] implement this.
|
||||||
|
@ -187,117 +116,6 @@ pub struct Painter {
|
||||||
pub colours: CanvasColours,
|
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 {
|
impl Painter {
|
||||||
pub fn draw_data<B: backend::Backend>(
|
pub fn draw_data<B: backend::Backend>(
|
||||||
&mut self, terminal: &mut Terminal<B>, app_state: &mut app::App,
|
&mut self, terminal: &mut Terminal<B>, app_state: &mut app::App,
|
||||||
|
|
|
@ -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(())
|
||||||
|
}
|
||||||
|
}
|
|
@ -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 New Issue