From 08327d2ec04d64991ac353dd667f38f5bd634253 Mon Sep 17 00:00:00 2001 From: unspeaker Date: Fri, 23 Aug 2024 00:09:13 +0300 Subject: [PATCH] wip: arranger: colors --- crates/tek_core/src/render_theme.rs | 7 + crates/tek_sequencer/src/arranger_handle.rs | 20 ++- crates/tek_sequencer/src/arranger_main.rs | 3 + crates/tek_sequencer/src/arranger_view_v.rs | 176 ++++++++++---------- crates/tek_sequencer/src/scene.rs | 13 +- 5 files changed, 120 insertions(+), 99 deletions(-) diff --git a/crates/tek_core/src/render_theme.rs b/crates/tek_core/src/render_theme.rs index 6e8184a9..50e3cb77 100644 --- a/crates/tek_core/src/render_theme.rs +++ b/crates/tek_core/src/render_theme.rs @@ -1,6 +1,13 @@ use crate::*; use ratatui::style::Modifier; +pub const COLOR_BG0: Color = Color::Rgb(30, 33, 36); +pub const COLOR_BG1: Color = Color::Rgb(41, 46, 57); +pub const COLOR_BG2: Color = Color::Rgb(46, 52, 64); +pub const COLOR_BG3: Color = Color::Rgb(59, 66, 82); +pub const COLOR_BG4: Color = Color::Rgb(67, 76, 94); +pub const COLOR_BG5: Color = Color::Rgb(76, 86, 106); + pub trait Theme { const BG0: Color; const BG1: Color; diff --git a/crates/tek_sequencer/src/arranger_handle.rs b/crates/tek_sequencer/src/arranger_handle.rs index b2e0552f..5c0fad00 100644 --- a/crates/tek_sequencer/src/arranger_handle.rs +++ b/crates/tek_sequencer/src/arranger_handle.rs @@ -15,11 +15,11 @@ handle!(Arranger |self, e| { /// Key bindings for arranger section. pub const KEYMAP_ARRANGER: &'static [KeyBinding] = keymap!(Arranger { - [Char('`'), NONE, "arranger_mode_switch", "switch the display mode", |arranger: &mut Arranger| { + [Char('`'), NONE, "mode_switch", "switch the display mode", |arranger: &mut Arranger| { arranger.mode.to_next(); Ok(true) }], - [Up, NONE, "arranger_cursor_up", "move cursor up", |arranger: &mut Arranger| { + [Up, NONE, "cursor_up", "move cursor up", |arranger: &mut Arranger| { match arranger.mode { ArrangerViewMode::Horizontal => arranger.track_prev(), _ => arranger.scene_prev(), @@ -27,7 +27,7 @@ pub const KEYMAP_ARRANGER: &'static [KeyBinding] = keymap!(Arranger { arranger.show_phrase()?; Ok(true) }], - [Down, NONE, "arranger_cursor_down", "move cursor down", |arranger: &mut Arranger| { + [Down, NONE, "cursor_down", "move cursor down", |arranger: &mut Arranger| { match arranger.mode { ArrangerViewMode::Horizontal => arranger.track_next(), _ => arranger.scene_next(), @@ -35,7 +35,7 @@ pub const KEYMAP_ARRANGER: &'static [KeyBinding] = keymap!(Arranger { arranger.show_phrase()?; Ok(true) }], - [Left, NONE, "arranger_cursor_left", "move cursor left", |arranger: &mut Arranger| { + [Left, NONE, "cursor_left", "move cursor left", |arranger: &mut Arranger| { match arranger.mode { ArrangerViewMode::Horizontal => arranger.scene_prev(), _ => arranger.track_prev(), @@ -43,7 +43,7 @@ pub const KEYMAP_ARRANGER: &'static [KeyBinding] = keymap!(Arranger { arranger.show_phrase()?; Ok(true) }], - [Right, NONE, "arranger_cursor_right", "move cursor right", |arranger: &mut Arranger| { + [Right, NONE, "cursor_right", "move cursor right", |arranger: &mut Arranger| { match arranger.mode { ArrangerViewMode::Horizontal => arranger.scene_next(), _ => arranger.track_next(), @@ -51,15 +51,15 @@ pub const KEYMAP_ARRANGER: &'static [KeyBinding] = keymap!(Arranger { arranger.show_phrase()?; Ok(true) }], - [Char('.'), NONE, "arranger_increment", "set next clip at cursor", |arranger: &mut Arranger| { + [Char('.'), NONE, "increment", "set next clip at cursor", |arranger: &mut Arranger| { arranger.phrase_next(); Ok(true) }], - [Char(','), NONE, "arranger_decrement", "set previous clip at cursor", |arranger: &mut Arranger| { + [Char(','), NONE, "decrement", "set previous clip at cursor", |arranger: &mut Arranger| { arranger.phrase_prev(); Ok(true) }], - [Enter, NONE, "arranger_activate", "activate item at cursor", |arranger: &mut Arranger| { + [Enter, NONE, "activate", "activate item at cursor", |arranger: &mut Arranger| { arranger.activate(); Ok(true) }], @@ -78,5 +78,9 @@ pub const KEYMAP_ARRANGER: &'static [KeyBinding] = keymap!(Arranger { [Char('l'), NONE, "length", "set length of item at cursor", |arranger: &mut Arranger| { todo!(); Ok(true) + }], + [Char('c'), NONE, "color", "set color of item at cursor", |arranger: &mut Arranger| { + todo!(); + Ok(true) }] }); diff --git a/crates/tek_sequencer/src/arranger_main.rs b/crates/tek_sequencer/src/arranger_main.rs index cffb6fed..7f745e9f 100644 --- a/crates/tek_sequencer/src/arranger_main.rs +++ b/crates/tek_sequencer/src/arranger_main.rs @@ -52,6 +52,9 @@ impl ArrangerStandalone { } for _ in 0..args.scenes { let scene = app.arranger.scene_add(None)?; + for i in 0..args.tracks { + scene.clips[i] = Some(i); + } } Ok(app) } diff --git a/crates/tek_sequencer/src/arranger_view_v.rs b/crates/tek_sequencer/src/arranger_view_v.rs index 596a7a3b..25705cfd 100644 --- a/crates/tek_sequencer/src/arranger_view_v.rs +++ b/crates/tek_sequencer/src/arranger_view_v.rs @@ -34,13 +34,13 @@ pub fn draw ( let tracks = state.tracks.as_ref(); let scenes = state.scenes.as_ref(); Layered::new() - .add(FillBg(Nord::bg_lo(state.focused, state.entered))) - .add(ColumnSeparators(offset, cols)) - .add(CursorFocus(focus_sequencer, focused, entered, selected, offset, cols, rows)) - .add(Split::down() - .add(TracksHeader(offset, cols, tracks)) - .add(SceneRows(offset, cols, rows, tracks, scenes))) - .add(RowSeparators(rows)) + //.add_ref(&FillBg(Color::Rgb(30, 33, 36)))//COLOR_BG1))//bg_lo(state.focused, state.entered))) + .add_ref(&ColumnSeparators(offset, cols)) + .add_ref(&Split::down() + .add_ref(&TracksHeader(offset, cols, tracks)) + .add_ref(&SceneRows(offset, cols, rows, tracks, scenes))) + .add_ref(&CursorFocus(focus_sequencer, focused, entered, selected, offset, cols, rows)) + .add_ref(&RowSeparators(rows)) .render(buf, area) } @@ -87,60 +87,43 @@ struct CursorFocus<'a>( impl<'a> Render for CursorFocus<'a> { fn render (&self, buf: &mut Buffer, area: Rect) -> Usually { let Self(focus_sequencer, focused, entered, selected, offset, cols, rows) = *self; + let track_area = |t: usize| Rect { + x: offset + area.x + cols[t].1 as u16 - 1, + y: area.y, + width: cols[t].0 as u16, + height: area.height + }; + let scene_area = |s: usize| Rect { + x: area.x, + y: 2 + area.y + (rows[s].1 / 96) as u16, + width: area.width, + height: (rows[s].0 / 96) as u16 + }; + let clip_area = |t: usize, s: usize| Rect { + x: offset + area.x + cols[t].1 as u16 - 1, + y: 2 + area.y + (rows[s].1 / 96) as u16, + width: cols[t].0 as u16, + height: (rows[s].0 / 96) as u16 + }; let area = match selected { - ArrangerFocus::Mix => if focused - && entered - && selected == ArrangerFocus::Mix - { - fill_bg(buf, area, Nord::bg_hi(focused, entered)); + ArrangerFocus::Mix => if focused && entered && selected == ArrangerFocus::Mix { + fill_bg(buf, area, COLOR_BG3); area } else { area }, ArrangerFocus::Track(t) => { - let area = Rect { - x: offset + area.x + cols[t].1 as u16 - 1, - y: area.y, - width: cols[t].0 as u16, - height: area.height - }; - fill_bg(buf, area, Nord::bg_hi(focused, entered)); + fill_bg(buf, track_area(t), COLOR_BG3); area }, ArrangerFocus::Scene(s) => { - let area = Rect { - x: area.x, - y: 2 + area.y + (rows[s].1 / 96) as u16, - width: area.width, - height: (rows[s].0 / 96) as u16 - }; - fill_bg(buf, area, Nord::bg_hi(focused, entered)); + fill_bg(buf, scene_area(s), COLOR_BG3); area }, ArrangerFocus::Clip(t, s) => { - let track_area = Rect { - x: offset + area.x + cols[t].1 as u16 - 1, - y: area.y, - width: cols[t].0 as u16, - height: area.height - }; - let scene_area = Rect { - x: area.x, - y: 2 + area.y + (rows[s].1 / 96) as u16, - width: area.width, - height: (rows[s].0 / 96) as u16 - }; - let area = Rect { - x: offset + area.x + cols[t].1 as u16 - 1, - y: 2 + area.y + (rows[s].1 / 96) as u16, - width: cols[t].0 as u16, - height: (rows[s].0 / 96) as u16 - }; - let lo = Nord::bg_hi(focused, entered); - let hi = Nord::bg_hier(focused, entered); - fill_bg(buf, track_area, lo); - fill_bg(buf, scene_area, lo); - fill_bg(buf, area, hi); + fill_bg(buf, track_area(t), COLOR_BG2); + fill_bg(buf, scene_area(s), COLOR_BG2); + fill_bg(buf, clip_area(t, s), COLOR_BG3); area }, }; @@ -157,12 +140,14 @@ impl<'a> Render for TracksHeader<'a> { fn render (&self, buf: &mut Buffer, area: Rect) -> Usually { let Self(offset, track_cols, tracks) = *self; let Rect { y, width, .. } = area; - for (track, (_, x)) in tracks.iter().zip(track_cols) { + for (track, (w, x)) in tracks.iter().zip(track_cols) { let x = *x as u16; if x > width { break } - track.name.read().unwrap().blit(buf, offset + x + 1, y, Some(Style::default()))?; + let name = track.name.read().unwrap(); + fill_bg(buf, Rect { x: offset + x, y, width: *w as u16, height: 2 }, COLOR_BG1); + name.blit(buf, offset + x + 1, y, Some(Style::default().white()))?; } Ok(Rect { x: area.x, y, width, height: 2 }) } @@ -184,56 +169,69 @@ impl<'a> Render for SceneRows<'a> { } } for (scene, (pulses, _)) in scenes.iter().zip(scene_rows) { - if y > height { - break - } + //if y > height { + //break + //} let h = 1.max((pulses / 96) as u16); - scene_row(tracks, buf, Rect { + SceneRow(tracks, scene, track_cols, offset).render(buf, Rect { x: area.x, y, width: area.width, height: h,//.min(area.height - y) - }, scene, track_cols, offset)?; + })?; y = y + h } Ok(area) } } -fn scene_row <'a> ( - tracks: &'a[Sequencer], - buf: &mut Buffer, - area: Rect, - scene: &Scene, - track_cols: &[(usize, usize)], - offset: u16 -) -> Usually { - let Rect { y, width, .. } = area; - let playing = scene.is_playing(tracks); - (if playing { "▶" } else { " " }).blit(buf, area.x, y, None)?; - scene.name.read().unwrap().blit(buf, area.x + 1, y, None)?; - let style = Some(Style::default().white()); - for (track, (w, x)) in track_cols.iter().enumerate() { - let x = *x as u16 + offset; - if x > width { - break - } - if let (Some(track), Some(Some(clip))) = ( - tracks.get(track), scene.clips.get(track) - ) { - if let Some(phrase) = track.phrases.get(*clip) { - let phrase = phrase.read().unwrap(); - phrase.name.read().unwrap().blit(buf, x + 1, y, style)?; - if track.sequence == Some(*clip) { - fill_bg(buf, Rect { - x: x - 1, - y, - width: *w as u16, - height: area.height, - }, Nord::PLAYING); - } +struct SceneRow<'a>(&'a[Sequencer], &'a Scene, &'a[(usize, usize)], u16); + +impl<'a> Render for SceneRow<'a> { + fn render (&self, buf: &mut Buffer, area: Rect) -> Usually { + let Self(tracks, scene, track_cols, offset) = self; + let Rect { x, y, width, .. } = area; + let playing = scene.is_playing(tracks); + (if playing { "▶" } else { " " }).blit(buf, x, y, None)?; + scene.name.read().unwrap().blit(buf, x + 1, y, Some(Style::default().white()))?; + fill_bg(buf, Rect { x: x, y, width: offset.saturating_sub(1), height: 2 }, COLOR_BG1); + + for (track, (w, x)) in track_cols.iter().enumerate() { + let x = *x as u16 + offset; + if x > width { + break + } + + if let (Some(track), Some(Some(clip))) = ( + tracks.get(track), scene.clips.get(track) + ) { + let area = Rect { x, y, width: *w as u16, height: area.height, }; + SceneClip(track, *clip).render(buf, area)?; } } + + Ok(area) + } +} + +struct SceneClip<'a>(&'a Sequencer, usize); + +impl<'a> Render for SceneClip<'a> { + fn render (&self, buf: &mut Buffer, area: Rect) -> Usually { + let Self(track, clip) = self; + let style = Some(Style::default().white()); + if let Some(phrase) = track.phrases.get(*clip) { + let phrase = phrase.read().unwrap(); + let name = phrase.name.read().unwrap(); + name.blit(buf, area.x + 1, area.y, style)?; + fill_bg(buf, area, if track.sequence == Some(*clip) { + Nord::PLAYING + } else { + COLOR_BG1 + }); + } else { + fill_bg(buf, area, COLOR_BG0) + } + Ok(area) } - Ok((scene.pulses(tracks) / 96) as u16) } diff --git a/crates/tek_sequencer/src/scene.rs b/crates/tek_sequencer/src/scene.rs index 747ad78b..556369bf 100644 --- a/crates/tek_sequencer/src/scene.rs +++ b/crates/tek_sequencer/src/scene.rs @@ -39,7 +39,13 @@ impl Scene { /// Returns the pulse length of the longest phrase in the scene pub fn pulses (&self, tracks: &[Sequencer]) -> usize { self.clips.iter().enumerate() - .filter_map(|(i, c)|c.map(|c|tracks[i].phrases.get(c))) + .filter_map(|(i, c)|c + .map(|c|tracks + .get(i) + .map(|track|track + .phrases + .get(c)))) + .filter_map(|p|p) .filter_map(|p|p) .fold(0, |a, p|a.max(p.read().unwrap().length)) } @@ -47,7 +53,10 @@ impl Scene { pub fn is_playing (&self, tracks: &[Sequencer]) -> bool { self.clips.iter().enumerate() .all(|(track_index, phrase_index)|match phrase_index { - Some(i) => tracks[track_index].sequence == Some(*i), + Some(i) => tracks + .get(track_index) + .map(|track|track.sequence == Some(*i)) + .unwrap_or(false), None => true }) }