From 32e547194a74d7ecf16c427ddadccff5f2da8597 Mon Sep 17 00:00:00 2001 From: unspeaker Date: Wed, 11 Dec 2024 19:29:11 +0100 Subject: [PATCH] more color degrees --- crates/tek/src/core/color.rs | 43 +++++++++++++---- crates/tek/src/tui/phrase_editor.rs | 75 ++++++----------------------- 2 files changed, 49 insertions(+), 69 deletions(-) diff --git a/crates/tek/src/core/color.rs b/crates/tek/src/core/color.rs index 8c245a85..a86ac49f 100644 --- a/crates/tek/src/core/color.rs +++ b/crates/tek/src/core/color.rs @@ -11,9 +11,13 @@ pub struct ItemColor { /// A color in OKHSL and RGB with lighter and darker variants. #[derive(Debug, Default, Copy, Clone, PartialEq)] pub struct ItemPalette { - pub base: ItemColor, - pub light: ItemColor, - pub dark: ItemColor, + pub base: ItemColor, + pub light: ItemColor, + pub lighter: ItemColor, + pub lightest: ItemColor, + pub dark: ItemColor, + pub darker: ItemColor, + pub darkest: ItemColor, } /// Adds TUI RGB representation to an OKHSL value. impl From> for ItemColor { @@ -45,13 +49,34 @@ impl ItemColor { } } impl From for ItemPalette { + fn from (base: ItemColor) -> Self { - let mut light = base.okhsl.clone(); - light.lightness = (light.lightness * 1.15).min(Okhsl::::max_lightness()); - let mut dark = base.okhsl.clone(); - dark.lightness = (dark.lightness * 0.85).max(Okhsl::::min_lightness()); - dark.saturation = (dark.saturation * 0.85).max(Okhsl::::min_saturation()); - Self { base, light: light.into(), dark: dark.into() } + let mut light = base.okhsl.clone(); + light.lightness = (light.lightness * 1.2).min(Okhsl::::max_lightness()); + let mut lighter = light.clone(); + lighter.lightness = (lighter.lightness * 1.2).min(Okhsl::::max_lightness()); + let mut lightest = lighter.clone(); + lightest.lightness = (lightest.lightness * 1.2).min(Okhsl::::max_lightness()); + + let mut dark = base.okhsl.clone(); + dark.lightness = (dark.lightness * 0.75).max(Okhsl::::min_lightness()); + dark.saturation = (dark.saturation * 0.75).max(Okhsl::::min_saturation()); + let mut darker = dark.clone(); + darker.lightness = (darker.lightness * 0.66).max(Okhsl::::min_lightness()); + darker.saturation = (darker.saturation * 0.66).max(Okhsl::::min_saturation()); + let mut darkest = darker.clone(); + darkest.lightness = (darkest.lightness * 0.50).max(Okhsl::::min_lightness()); + darkest.saturation = (darkest.saturation * 0.50).max(Okhsl::::min_saturation()); + + Self { + base, + light: light.into(), + lighter: lighter.into(), + lightest: lightest.into(), + dark: dark.into(), + darker: darker.into(), + darkest: darkest.into(), + } } } impl ItemPalette { diff --git a/crates/tek/src/tui/phrase_editor.rs b/crates/tek/src/tui/phrase_editor.rs index 88ddd669..669a43f1 100644 --- a/crates/tek/src/tui/phrase_editor.rs +++ b/crates/tek/src/tui/phrase_editor.rs @@ -202,7 +202,7 @@ struct PhraseViewKeys<'a>(&'a PhraseView<'a>, ItemPalette); render!(|self: PhraseViewKeys<'a>|{ let layout = |to:[u16;2]|Ok(Some(to.clip_w(5))); Tui::fill_xy(Widget::new(layout, |to: &mut TuiOutput|Ok( - self.0.view_mode.render_keys(to, self.1.dark.rgb, Some(self.0.note_point), self.0.note_range) + self.0.view_mode.render_keys(to, self.1.light.rgb, Some(self.0.note_point), self.0.note_range) ))) }); @@ -397,6 +397,17 @@ impl PhraseViewMode for PianoHorizontal { } } +/// Draw the piano roll using full blocks on note on and half blocks on legato: █▄ █▄ █▄ +fn draw_piano_horizontal ( + target: &mut BigBuffer, + phrase: &Phrase, + time_zoom: usize, + note_len: usize, +) { + draw_piano_horizontal_bg(target, phrase, time_zoom, note_len); + draw_piano_horizontal_fg(target, phrase, time_zoom); +} + fn draw_piano_horizontal_bg ( target: &mut BigBuffer, phrase: &Phrase, @@ -407,7 +418,8 @@ fn draw_piano_horizontal_bg ( for (x, time) in (0..target.width).map(|x|(x, x*time_zoom)) { let cell = target.get_mut(x, y).unwrap(); //cell.set_fg(Color::Rgb(48, 55, 45)); - cell.set_fg(phrase.color.dark.rgb); + cell.set_bg(phrase.color.darkest.rgb); + cell.set_fg(phrase.color.darker.rgb); cell.set_char(if time % 384 == 0 { '│' } else if time % 96 == 0 { @@ -428,7 +440,7 @@ fn draw_piano_horizontal_fg ( phrase: &Phrase, time_zoom: usize, ) { - let style = Style::default().fg(phrase.color.light.rgb);//.bg(Color::Rgb(0, 0, 0)); + let style = Style::default().fg(phrase.color.lightest.rgb);//.bg(Color::Rgb(0, 0, 0)); let mut notes_on = [false;128]; for (x, time_start) in (0..phrase.length).step_by(time_zoom).enumerate() { @@ -462,63 +474,6 @@ fn draw_piano_horizontal_fg ( } } -/// Draw the piano roll using full blocks on note on and half blocks on legato: █▄ █▄ █▄ -fn draw_piano_horizontal ( - target: &mut BigBuffer, - phrase: &Phrase, - time_zoom: usize, - note_len: usize, -) { - let color = phrase.color.light.rgb; - let style = Style::default().fg(color);//.bg(Color::Rgb(0, 0, 0)); - for (y, note) in (0..127).rev().enumerate() { - for (x, time) in (0..target.width).map(|x|(x, x*time_zoom)) { - let cell = target.get_mut(x, y).unwrap(); - //cell.set_fg(Color::Rgb(48, 55, 45)); - cell.set_fg(phrase.color.dark.rgb); - cell.set_char(if time % 384 == 0 { - '│' - } else if time % 96 == 0 { - '╎' - } else if time % note_len == 0 { - '┊' - } else if (127 - note) % 12 == 1 { - '=' - } else { - '·' - }); - } - } - let mut notes_on = [false;128]; - for (x, time_start) in (0..phrase.length).step_by(time_zoom).enumerate() { - let time_end = time_start + time_zoom; - for (y, note) in (0..127).rev().enumerate() { - let cell = target.get_mut(x, note).unwrap(); - if notes_on[note] { - cell.set_char('▄'); - cell.set_style(style); - } - } - for time in time_start..time_end { - for event in phrase.notes[time].iter() { - match event { - MidiMessage::NoteOn { key, .. } => { - let note = key.as_int() as usize; - let cell = target.get_mut(x, note).unwrap(); - cell.set_char('█'); - cell.set_style(style); - notes_on[note] = true - }, - MidiMessage::NoteOff { key, .. } => { - notes_on[key.as_int() as usize] = false - }, - _ => {} - } - } - } - } -} - #[derive(Clone, Debug)] pub enum PhraseCommand { // TODO: 1-9 seek markers that by default start every 8th of the phrase