diff --git a/crates/tek_core/src/color.rs b/crates/tek_core/src/color.rs index d08d8fcc..edf8a176 100644 --- a/crates/tek_core/src/color.rs +++ b/crates/tek_core/src/color.rs @@ -36,8 +36,8 @@ impl ItemColor { let hi = Okhsl::new( 180.0, 0.5, 0.2); UniformOkhsl::new(lo, hi).sample(&mut rng).into() } - pub fn random_near (base: Self, distance: f32) -> Self { - base.mix(Self::random(), distance) + 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"); } @@ -55,6 +55,14 @@ impl From for ItemColorTriplet { Self { base, light: light.into(), dark: dark.into() } } } +impl ItemColorTriplet { + pub fn random () -> Self { + ItemColor::random().into() + } + pub fn random_near (color: Self, distance: f32) -> Self { + color.base.mix(ItemColor::random(), distance).into() + } +} 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,) diff --git a/crates/tek_sequencer/src/arranger.rs b/crates/tek_sequencer/src/arranger.rs index 51f947cf..b02e2265 100644 --- a/crates/tek_sequencer/src/arranger.rs +++ b/crates/tek_sequencer/src/arranger.rs @@ -378,7 +378,7 @@ impl Arrangement { ArrangementFocus::Track(t) => { self.tracks[t].color = ItemColor::random() }, ArrangementFocus::Scene(s) => { self.scenes[s].color = ItemColor::random() }, ArrangementFocus::Clip(t, s) => if let Some(phrase) = &self.scenes[s].clips[t] { - phrase.write().unwrap().color = ItemColor::random(); + phrase.write().unwrap().color = ItemColorTriplet::random(); } } } diff --git a/crates/tek_sequencer/src/arranger_tui.rs b/crates/tek_sequencer/src/arranger_tui.rs index 11ccef69..a7cbdba4 100644 --- a/crates/tek_sequencer/src/arranger_tui.rs +++ b/crates/tek_sequencer/src/arranger_tui.rs @@ -236,7 +236,7 @@ impl<'a> Content for VerticalArranger<'a, Tui> { let name = format!("{}", name); let max_w = name.len().min((w as usize).saturating_sub(2)); add(&name.as_str()[0..max_w].push_x(1).fixed_x(w))?; - color = (phrase as &Arc>).read().unwrap().color.rgb; + color = (phrase as &Arc>).read().unwrap().color.base.rgb; }, _ => {} }; diff --git a/crates/tek_sequencer/src/sequencer.rs b/crates/tek_sequencer/src/sequencer.rs index 08387609..02a64839 100644 --- a/crates/tek_sequencer/src/sequencer.rs +++ b/crates/tek_sequencer/src/sequencer.rs @@ -79,7 +79,7 @@ pub enum PhrasePoolMode { /// All notes are displayed with minimum length pub percussive: bool, /// Identifying color of phrase - pub color: ItemColor, + pub color: ItemColorTriplet, } /// Contains state for viewing and editing a phrase pub struct PhraseEditor { @@ -205,7 +205,7 @@ impl PhrasePool { } return None } - fn new_phrase (name: Option<&str>, color: Option) -> Arc> { + fn new_phrase (name: Option<&str>, color: Option) -> Arc> { Arc::new(RwLock::new(Phrase::new( String::from(name.unwrap_or("(new)")), true, 4 * PPQ, None, color ))) @@ -216,23 +216,23 @@ impl PhrasePool { self.phrase = self.phrase.min(self.phrases.len().saturating_sub(1)); } } - pub fn append_new (&mut self, name: Option<&str>, color: Option) { + pub fn append_new (&mut self, name: Option<&str>, color: Option) { self.phrases.push(Self::new_phrase(name, color)); self.phrase = self.phrases.len() - 1; } - pub fn insert_new (&mut self, name: Option<&str>, color: Option) { + pub fn insert_new (&mut self, name: Option<&str>, color: Option) { self.phrases.insert(self.phrase + 1, Self::new_phrase(name, color)); self.phrase += 1; } pub fn insert_dup (&mut self) { let mut phrase = self.phrases[self.phrase].read().unwrap().duplicate(); - phrase.color = ItemColor::random_near(phrase.color, 0.25); + phrase.color = ItemColorTriplet::random_near(phrase.color, 0.25); self.phrases.insert(self.phrase + 1, Arc::new(RwLock::new(phrase))); self.phrase += 1; } pub fn randomize_color (&mut self) { let mut phrase = self.phrases[self.phrase].write().unwrap(); - phrase.color = ItemColor::random(); + phrase.color = ItemColorTriplet::random(); } pub fn begin_rename (&mut self) { self.mode = Some(PhrasePoolMode::Rename( @@ -347,7 +347,7 @@ impl Phrase { loop_on: bool, length: usize, notes: Option, - color: Option, + color: Option, ) -> Self { Self { uuid: uuid::Uuid::new_v4(), @@ -359,7 +359,7 @@ impl Phrase { loop_start: 0, loop_length: length, percussive: true, - color: color.unwrap_or_else(ItemColor::random) + color: color.unwrap_or_else(ItemColorTriplet::random) } } pub fn duplicate (&self) -> Self { @@ -384,7 +384,9 @@ impl Phrase { } } impl Default for Phrase { - fn default () -> Self { Self::new("(empty)", false, 0, None, Some(Color::Rgb(0, 0, 0).into())) } + fn default () -> Self { + Self::new("(empty)", false, 0, None, Some(ItemColor::from(Color::Rgb(0, 0, 0)).into())) + } } impl PartialEq for Phrase { fn eq (&self, other: &Self) -> bool { self.uuid == other.uuid } } impl Eq for Phrase {} diff --git a/crates/tek_sequencer/src/sequencer_tui.rs b/crates/tek_sequencer/src/sequencer_tui.rs index f606f73d..9edbc9ce 100644 --- a/crates/tek_sequencer/src/sequencer_tui.rs +++ b/crates/tek_sequencer/src/sequencer_tui.rs @@ -32,7 +32,7 @@ impl Content for PhrasePool { if *focused && i == *phrase { row2 = format!("{row2}▄"); } }; let row2 = TuiStyle::bold(row2, true); - let bg = if i == self.phrase { color } else { color }; + let bg = if i == self.phrase { color.base } else { color.light }; add(&col!(row1, row2).fill_x().bg(bg.rgb))?; Ok(if *focused && i == self.phrase { add(&CORNERS)?; }) }) @@ -57,7 +57,7 @@ impl Content for PhraseEditor { start: time_start, point: time_point, clamp: time_clamp, scale: time_scale } = *self.time_axis.read().unwrap(); let color = Color::Rgb(0,255,0); - let color = phrase.as_ref().map(|p|p.read().unwrap().color.rgb).unwrap_or(color); + let color = phrase.as_ref().map(|p|p.read().unwrap().color.base.rgb).unwrap_or(color); let keys = CustomWidget::new(|to:[u16;2]|Ok(Some(to.clip_w(5))), move|to: &mut TuiOutput|{ Ok(if to.area().h() >= 2 { to.buffer_update(to.area().set_w(5), &|cell, x, y|{