From 33600e890f4a898f22b63783da2ad7530d117b27 Mon Sep 17 00:00:00 2001 From: unspeaker Date: Sat, 2 Nov 2024 14:43:13 +0200 Subject: [PATCH] move color handling to core --- Cargo.lock | 4 +- crates/tek_core/Cargo.toml | 2 + crates/tek_core/src/color.rs | 90 +++++++++++++++++++++++++++++++++ crates/tek_core/src/lib.rs | 1 + crates/tek_sequencer/Cargo.toml | 2 - crates/tek_sequencer/src/lib.rs | 48 ------------------ 6 files changed, 95 insertions(+), 52 deletions(-) create mode 100644 crates/tek_core/src/color.rs diff --git a/Cargo.lock b/Cargo.lock index 802b42b3..6cf29f30 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2670,6 +2670,8 @@ dependencies = [ "jack", "midly", "once_cell", + "palette", + "rand", "ratatui", "tek_mixer", "tek_sequencer", @@ -2693,8 +2695,6 @@ dependencies = [ name = "tek_sequencer" version = "0.1.0" dependencies = [ - "palette", - "rand", "tek_core", "uuid", ] diff --git a/crates/tek_core/Cargo.toml b/crates/tek_core/Cargo.toml index 5770eb02..a80ef13f 100644 --- a/crates/tek_core/Cargo.toml +++ b/crates/tek_core/Cargo.toml @@ -13,6 +13,8 @@ crossterm = "0.27" jack = "0.13" midly = "0.5" once_cell = "1.19.0" +palette = { version = "0.7.6", features = [ "random" ] } +rand = "0.8.5" ratatui = { version = "0.26.3", features = [ "unstable-widget-ref", "underline-color" ] } toml = "0.8.12" #no_deadlocks = "1.3.2" diff --git a/crates/tek_core/src/color.rs b/crates/tek_core/src/color.rs new file mode 100644 index 00000000..11680b03 --- /dev/null +++ b/crates/tek_core/src/color.rs @@ -0,0 +1,90 @@ +use crate::*; +use rand::{thread_rng, distributions::uniform::UniformSampler}; +pub use palette::{*, convert::*, okhsl::*}; + +#[derive(Debug, Copy, Clone)] +pub struct ItemColor { + pub okhsl: Okhsl, + pub rgb: Color, +} +#[derive(Debug, Copy, Clone)] +pub struct ItemColorTriplet { + pub base: ItemColor, + pub light: ItemColor, + pub dark: ItemColor, +} +impl From> for ItemColor { + fn from (okhsl: Okhsl) -> Self { + Self { okhsl, rgb: okhsl_to_rgb(okhsl) } + } +} +impl ItemColor { + pub fn random () -> Self { + random_okhsl().into() + } + pub fn random_dark () -> Self { + random_okhsl_dark().into() + } + pub fn random_near (other: Self, distance: f32) -> Self { + if distance > 1.0 { + panic!("random_color_near requires distance between 0.0 and 1.0"); + } + other.okhsl.mix(random_okhsl(), distance).into() + } +} +impl From for ItemColorTriplet { + fn from (base: ItemColor) -> Self { + let mut light = base.okhsl.clone(); + light.saturation = (light.saturation * 0.9).max(Okhsl::::min_saturation()); + light.lightness = (light.lightness * 1.1).min(Okhsl::::max_saturation()); + let mut dark = base.okhsl.clone(); + dark.saturation = (dark.saturation * 1.1).min(Okhsl::::max_saturation()); + dark.lightness = (dark.lightness * 0.9).max(Okhsl::::min_saturation()); + Self { base, light: light.into(), dark: dark.into() } + } +} + +pub fn random_okhsl () -> Okhsl { + let mut rng = thread_rng(); + UniformOkhsl::new( + Okhsl::new(-180.0, 0.01, 0.2), + Okhsl::new( 180.0, 0.9, 0.5), + ).sample(&mut rng) +} + +pub fn random_okhsl_dark () -> Okhsl { + let mut rng = thread_rng(); + UniformOkhsl::new( + Okhsl::new(-180.0, 0.01, 0.05), + Okhsl::new( 180.0, 0.5, 0.2), + ).sample(&mut rng) +} + +pub fn okhsl_to_rgb (color: Okhsl) -> Color { + let Srgb { red, green, blue, .. }: Srgb = Srgb::from_color_unclamped(color); + Color::Rgb((red * 255.0) as u8, (green * 255.0) as u8, (blue * 255.0) as u8,) +} + +pub fn random_color () -> Color { + okhsl_to_rgb(random_okhsl()) +} + +pub fn random_color_dark () -> Color { + okhsl_to_rgb(random_okhsl_dark()) +} + +pub fn random_color_near (color: Color, distance: f32) -> Color { + let (r, g, b) = if let Color::Rgb(r, g, b) = color { + (r, g, b) + } else { + panic!("random_color_near works only with Color::Rgb") + }; + if distance > 1.0 { + panic!("random_color_near requires distance between 0.0 and 1.0"); + } + okhsl_to_rgb(Okhsl::from_color(Srgb::new( + r as f32 / 255.0, + g as f32 / 255.0, + b as f32 / 255.0, + )).mix(random_okhsl(), distance)) +} diff --git a/crates/tek_core/src/lib.rs b/crates/tek_core/src/lib.rs index 76fc8f55..8f132bf8 100644 --- a/crates/tek_core/src/lib.rs +++ b/crates/tek_core/src/lib.rs @@ -37,6 +37,7 @@ use std::fmt::{Debug, Display}; submod! { audio + color edn engine focus diff --git a/crates/tek_sequencer/Cargo.toml b/crates/tek_sequencer/Cargo.toml index c33a160f..461b18bc 100644 --- a/crates/tek_sequencer/Cargo.toml +++ b/crates/tek_sequencer/Cargo.toml @@ -6,8 +6,6 @@ version = "0.1.0" [dependencies] tek_core = { path = "../tek_core" } uuid = { version = "1.10.0", features = [ "v4" ] } -palette = { version = "0.7.6", features = [ "random" ] } -rand = "0.8.5" [lib] path = "src/lib.rs" diff --git a/crates/tek_sequencer/src/lib.rs b/crates/tek_sequencer/src/lib.rs index ec393a45..d8681f02 100644 --- a/crates/tek_sequencer/src/lib.rs +++ b/crates/tek_sequencer/src/lib.rs @@ -5,9 +5,6 @@ pub(crate) use tek_core::crossterm::event::KeyCode; pub(crate) use tek_core::midly::{num::u7, live::LiveEvent, MidiMessage}; pub(crate) use tek_core::jack::*; pub(crate) use std::sync::{Arc, RwLock}; -pub(crate) use rand::thread_rng; -pub(crate) use palette::{*, convert::*, okhsl::*}; -use rand::distributions::uniform::UniformSampler; submod! { arranger arranger_cmd arranger_tui arranger_snd @@ -26,48 +23,3 @@ tui_style!(CORNERS_STYLE = pub const NTH_OCTAVE: [&'static str;11] = [ "-1", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" ]; - -pub fn random_okhsl () -> Okhsl { - let mut rng = thread_rng(); - UniformOkhsl::new( - Okhsl::new(-180.0, 0.01, 0.2), - Okhsl::new( 180.0, 0.9, 0.5), - ).sample(&mut rng) -} - -pub fn random_okhsl_dark () -> Okhsl { - let mut rng = thread_rng(); - UniformOkhsl::new( - Okhsl::new(-180.0, 0.01, 0.05), - Okhsl::new( 180.0, 0.5, 0.2), - ).sample(&mut rng) -} - -pub fn okhsl_to_rgb (color: Okhsl) -> Color { - let Srgb { red, green, blue, .. }: Srgb = Srgb::from_color_unclamped(color); - Color::Rgb((red * 255.0) as u8, (green * 255.0) as u8, (blue * 255.0) as u8,) -} - -pub fn random_color () -> Color { - okhsl_to_rgb(random_okhsl()) -} - -pub fn random_color_dark () -> Color { - okhsl_to_rgb(random_okhsl_dark()) -} - -pub fn random_color_near (color: Color, distance: f32) -> Color { - let (r, g, b) = if let Color::Rgb(r, g, b) = color { - (r, g, b) - } else { - panic!("random_color_near works only with Color::Rgb") - }; - if distance > 1.0 { - panic!("random_color_near requires distance between 0.0 and 1.0"); - } - okhsl_to_rgb(Okhsl::from_color(Srgb::new( - r as f32 / 255.0, - g as f32 / 255.0, - b as f32 / 255.0, - )).mix(random_okhsl(), distance)) -}