use crate::model::Cmd;
pub type Color = rusty_x_ansi::color::RGBColor;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct RequestBackgroundColorMsg;
pub fn request_background_color() -> Cmd {
Some(Box::new(|| Some(Box::new(RequestBackgroundColorMsg))))
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct RequestForegroundColorMsg;
pub fn request_foreground_color() -> Cmd {
Some(Box::new(|| Some(Box::new(RequestForegroundColorMsg))))
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct RequestCursorColorMsg;
pub fn request_cursor_color() -> Cmd {
Some(Box::new(|| Some(Box::new(RequestCursorColorMsg))))
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ForegroundColorMsg(pub Color);
impl ForegroundColorMsg {
pub fn to_hex(&self) -> String {
self.0.hex()
}
pub fn is_dark(&self) -> bool {
is_dark_color(self.0)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct BackgroundColorMsg(pub Color);
impl BackgroundColorMsg {
pub fn to_hex(&self) -> String {
self.0.hex()
}
pub fn is_dark(&self) -> bool {
is_dark_color(self.0)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct CursorColorMsg(pub Color);
impl CursorColorMsg {
pub fn to_hex(&self) -> String {
self.0.hex()
}
pub fn is_dark(&self) -> bool {
is_dark_color(self.0)
}
}
fn is_dark_color(c: rusty_x_ansi::color::RGBColor) -> bool {
let (_, _, l) = rgb_to_hsl(c.r, c.g, c.b);
l < 0.5
}
fn rgb_to_hsl(r: u8, g: u8, b: u8) -> (f64, f64, f64) {
let rnot = f64::from(r) / 255.0;
let gnot = f64::from(g) / 255.0;
let bnot = f64::from(b) / 255.0;
let (cmax, cmin) = get_max_min(rnot, gnot, bnot);
let delta = cmax - cmin;
let l = (cmax + cmin) / 2.0;
let (h, s) = if delta == 0.0 {
(0.0, 0.0)
} else {
let h = if cmax == rnot {
60.0 * (((gnot - bnot) / delta).rem_euclid(6.0))
} else if cmax == gnot {
60.0 * (((bnot - rnot) / delta) + 2.0)
} else {
60.0 * (((rnot - gnot) / delta) + 4.0)
};
let h = if h < 0.0 { h + 360.0 } else { h };
let s = delta / (1.0 - (2.0 * l - 1.0).abs());
(h, s)
};
(h, round(s), round(l))
}
fn get_max_min(a: f64, b: f64, c: f64) -> (f64, f64) {
let (ma, mi) = if a > b { (a, b) } else { (b, a) };
if c > ma {
(c, mi)
} else if c < mi {
(ma, c)
} else {
(ma, mi)
}
}
fn round(x: f64) -> f64 {
(x * 1000.0).round() / 1000.0
}