wip: unearth the backlog severely
Some checks failed
/ build (push) Has been cancelled

This commit is contained in:
same mf who else 2026-03-20 02:49:10 +02:00
parent b0fbe3c173
commit 9dbf4fcab5
9 changed files with 1101 additions and 1169 deletions

View file

@ -1,11 +1,23 @@
pub(crate) use ::palette::Okhsl;
use ::ratatui::style::Color;
use crate::lang::impl_from;
pub(crate) use ::palette::{Okhsl, Srgb, OklabHue, okhsl::UniformOkhsl};
pub fn rgb (r: u8, g: u8, b: u8) -> ItemColor { todo!(); }
pub fn okhsl_to_rgb (color: Okhsl<f32>) -> Color {
let Srgb { red, green, blue, .. }: Srgb<f32> = Srgb::from_color_unclamped(color);
Color::Rgb((red * 255.0) as u8, (green * 255.0) as u8, (blue * 255.0) as u8,)
}
pub fn rgb_to_okhsl (color: Color) -> Okhsl<f32> {
if let Color::Rgb(r, g, b) = color {
Okhsl::from_color(Srgb::new(r as f32 / 255.0, g as f32 / 255.0, b as f32 / 255.0))
} else {
unreachable!("only Color::Rgb is supported")
}
}
pub trait HasColor { fn color (&self) -> ItemColor; }
pub struct ItemColor {}
pub struct ItemTheme {}
#[macro_export] macro_rules! has_color {
(|$self:ident:$Struct:ident$(<$($L:lifetime),*$($T:ident$(:$U:path)?),*>)?|$cb:expr) => {
impl $(<$($L),*$($T $(: $U)?),*>)? HasColor for $Struct $(<$($L),*$($T),*>)? {
@ -14,6 +26,107 @@ pub struct ItemTheme {}
}
}
pub fn rgb (r: u8, g: u8, b: u8) -> ItemColor {
todo!();
pub struct ItemColor {}
impl_from!(ItemColor: |rgb: Color| Self { rgb, okhsl: rgb_to_okhsl(rgb) });
impl_from!(ItemColor: |okhsl: Okhsl<f32>| Self { okhsl, rgb: okhsl_to_rgb(okhsl) });
// A single color within item theme parameters, in OKHSL and RGB representations.
impl ItemColor {
#[cfg(feature = "tui")] pub const fn from_tui (rgb: Color) -> Self {
Self { rgb, okhsl: Okhsl::new_const(OklabHue::new(0.0), 0.0, 0.0) }
}
pub fn random () -> Self {
let mut rng = ::rand::thread_rng();
let lo = Okhsl::new(-180.0, 0.01, 0.25);
let hi = Okhsl::new( 180.0, 0.9, 0.5);
UniformOkhsl::new(lo, hi).sample(&mut rng).into()
}
pub fn random_dark () -> Self {
let mut rng = ::rand::thread_rng();
let lo = Okhsl::new(-180.0, 0.025, 0.075);
let hi = Okhsl::new( 180.0, 0.5, 0.150);
UniformOkhsl::new(lo, hi).sample(&mut rng).into()
}
pub fn random_near (color: Self, distance: f32) -> Self {
color.mix(Self::random(), distance)
}
pub fn mix (&self, other: Self, distance: f32) -> Self {
if distance > 1.0 { panic!("color mixing takes distance between 0.0 and 1.0"); }
self.okhsl.mix(other.okhsl, distance).into()
}
}
pub struct ItemTheme {}
impl_from!(ItemTheme: |base: ItemColor| Self::from_item_color(base));
impl_from!(ItemTheme: |base: Color| Self::from_tui_color(base));
impl ItemTheme {
#[cfg(feature = "tui")] pub const G: [Self;256] = {
let mut builder = konst::array::ArrayBuilder::new();
while !builder.is_full() {
let index = builder.len() as u8;
let light = (index as f64 * 1.15) as u8;
let lighter = (index as f64 * 1.7) as u8;
let lightest = (index as f64 * 1.85) as u8;
let dark = (index as f64 * 0.9) as u8;
let darker = (index as f64 * 0.6) as u8;
let darkest = (index as f64 * 0.3) as u8;
builder.push(ItemTheme {
base: ItemColor::from_tui(Color::Rgb(index, index, index )),
light: ItemColor::from_tui(Color::Rgb(light, light, light, )),
lighter: ItemColor::from_tui(Color::Rgb(lighter, lighter, lighter, )),
lightest: ItemColor::from_tui(Color::Rgb(lightest, lightest, lightest, )),
dark: ItemColor::from_tui(Color::Rgb(dark, dark, dark, )),
darker: ItemColor::from_tui(Color::Rgb(darker, darker, darker, )),
darkest: ItemColor::from_tui(Color::Rgb(darkest, darkest, darkest, )),
});
}
builder.build()
};
pub fn random () -> Self { ItemColor::random().into() }
pub fn random_near (color: Self, distance: f32) -> Self {
color.base.mix(ItemColor::random(), distance).into()
}
pub const G00: Self = {
let color: ItemColor = ItemColor {
okhsl: Okhsl { hue: OklabHue::new(0.0), lightness: 0.0, saturation: 0.0 },
rgb: Color::Rgb(0, 0, 0)
};
Self {
base: color,
light: color,
lighter: color,
lightest: color,
dark: color,
darker: color,
darkest: color,
}
};
#[cfg(feature = "tui")] pub fn from_tui_color (base: Color) -> Self {
Self::from_item_color(ItemColor::from_tui(base))
}
pub fn from_item_color (base: ItemColor) -> Self {
let mut light = base.okhsl;
light.lightness = (light.lightness * 1.3).min(1.0);
let mut lighter = light;
lighter.lightness = (lighter.lightness * 1.3).min(1.0);
let mut lightest = base.okhsl;
lightest.lightness = 0.95;
let mut dark = base.okhsl;
dark.lightness = (dark.lightness * 0.75).max(0.0);
dark.saturation = (dark.saturation * 0.75).max(0.0);
let mut darker = dark;
darker.lightness = (darker.lightness * 0.66).max(0.0);
darker.saturation = (darker.saturation * 0.66).max(0.0);
let mut darkest = darker;
darkest.lightness = 0.1;
darkest.saturation = (darkest.saturation * 0.50).max(0.0);
Self {
base,
light: light.into(),
lighter: lighter.into(),
lightest: lightest.into(),
dark: dark.into(),
darker: darker.into(),
darkest: darkest.into(),
}
}
}