wip: launcher scenes

This commit is contained in:
🪞👃🪞 2024-06-25 00:18:15 +03:00
parent 90998b1c6e
commit 143da7f1b8

View file

@ -5,7 +5,7 @@ pub struct Launcher {
cursor: (usize, usize),
tracks: Vec<DynamicDevice<Sequencer>>,
chains: Vec<DynamicDevice<Chain>>,
rows: usize,
scenes: Vec<Scene>,
show_help: bool,
view: LauncherView,
}
@ -14,6 +14,18 @@ pub enum LauncherView {
Sequencer,
Chains
}
pub struct Scene {
name: String,
clips: Vec<Option<usize>>,
}
impl Scene {
pub fn new (name: impl AsRef<str>, clips: impl AsRef<[Option<usize>]>) -> Self {
Self {
name: name.as_ref().into(),
clips: clips.as_ref().iter().map(|x|x.clone()).collect()
}
}
}
impl Launcher {
pub fn new (
name: &str,
@ -23,8 +35,17 @@ impl Launcher {
name: name.into(),
view: LauncherView::Tracks,
timebase: timebase.clone(),
cursor: (0, 0),
rows: 8,
cursor: (1, 2),
scenes: vec![
Scene::new(&"Scene#01", &[Some(0), None, None, None]),
Scene::new(&"Scene#02", &[None, None, None, None]),
Scene::new(&"Scene#03", &[None, None, None, None]),
Scene::new(&"Scene#04", &[None, None, None, None]),
Scene::new(&"Scene#05", &[None, None, None, None]),
Scene::new(&"Scene#06", &[None, None, None, None]),
Scene::new(&"Scene#07", &[None, None, None, None]),
Scene::new(&"Scene#08", &[None, None, None, None]),
],
tracks: vec![
Sequencer::new("Drum", timebase)?,
Sequencer::new("Bass", timebase)?,
@ -69,7 +90,7 @@ impl Launcher {
}
}
fn rows (&self) -> usize {
(self.rows + 2) as usize
(self.scenes.len() + 2) as usize
}
fn row (&self) -> usize {
self.cursor.1 as usize
@ -137,28 +158,26 @@ pub fn render (state: &Launcher, buf: &mut Buffer, area: Rect) -> Usually<Rect>
}
Ok(area)
}
fn draw_scenes (
state: &Launcher, buf: &mut Buffer, x: u16, y: u16,
) -> Rect {
let style = Style::default().not_dim().bold();
let row = state.row() as u16;
let col = state.col() as u16;
let green = |r: u16, c: u16| if row == r && col == c {
Style::default().green()
} else {
Style::default()
};
let mut width = 8u16;
let mut height = 6u16;
format!("{} | ", state.name).blit(buf, x+2, y+1, Some(
if row == 0 && col == 0 { Style::default().green() } else { Style::default() }
));
format!("Sync 1/1").blit(buf, x+2, y+3, Some(
if row == 1 && col == 0 { Style::default().green() } else { Style::default() }
));
for j in 0..=7 {
let y = y + 5 + j as u16 * 2;
let label = format!("▶ Scene {j}");
width = width.max(label.len() as u16 + 3);
label.blit(buf, x + 2, y, Some(
if row == j + 2 && col == 0 { Style::default().green() } else { Style::default() }
));
format!("{} | ", state.name).blit(buf, x+2, y+1, Some(green(0, 0)));
format!("Sync 1/1").blit(buf, x+2, y+3, Some(green(1, 0)));
for (scene_index, scene) in state.scenes.iter().enumerate() {
let y = y + 5 + scene_index as u16 * 2;
let label = format!("{}", &scene.name);
width = width.max(label.len() as u16 + 2);
label.blit(buf, x + 2, y, Some(green(scene_index as u16 + 2, 0)));
height = height + 2;
}
Rect { x, y, width, height }
@ -182,45 +201,52 @@ fn draw_tracks (
fn draw_track (
state: &Launcher, buf: &mut Buffer, x: u16, y: u16, i: u16, track: &Sequencer
) -> u16 {
let mut width = track.name.len() as u16 + 3;
let mut width = 11.max(track.name.len() as u16 + 3);
let row = state.row() as u16;
let col = state.col() as u16;
track.name.blit(buf, x, y + 1, Some(
if row == 0 && col == i + 1 { Style::default().green() } else { Style::default() }
));
"(global)".blit(buf, x, y + 3, Some(
if row == 1 && col == i + 1 { Style::default().green() } else { Style::default().dim() }
));
"".blit(buf, x - 2, y + 3, Some(
Style::default().dim()
));
for j in 0..=7 {
let y = y + 5 + j as u16 * 2;
if let Some(sequence) = track.sequences.get(j) {
let label = format!("{}", &sequence.name);
width = width.max(label.len() as u16 + 1);
let style = if j + 2 == row as usize && i + 1 == col {
Style::default().green().bold()
} else {
Style::default()
};
buf.set_string(x - 0, y + 0, &label, style);
buf.set_string(x - 2, y + 0, &"", style.dim());
buf.set_string(x - 2, y + 1, &"", style.dim());
buf.set_string(x + width - 2, y + 0, &"", style.dim());
buf.set_string(x + width - 2, y + 1, &"", style.dim());
let green = |r: u16, c: u16| if row == r && col == c {
Style::default().green()
} else {
Style::default()
};
for (scene_index, scene) in state.scenes.iter().enumerate() {
let y = y + 5 + scene_index as u16 * 2;
//let label = format!("▶ {}", &scene.name);
//width = width.max(label.len() as u16 + 2);
//label.blit(buf, x + 2, y, Some(green(scene_index as u16 + 2, 0)));
//height = height + 2;
let style = if scene_index + 2 == row as usize && i + 1 == col {
Style::default().green().bold()
} else {
buf.set_string(x - 2, y as u16,
format!("{}", &"·".repeat(track.name.len())),
Style::default().dim()
);
Style::default().dim()
};
if let Some(Some(sequence_index)) = scene.clips.get(i as usize) {
if let Some(sequence) = track.sequences.get(*sequence_index) {
let label = format!("{}", &sequence.name);
width = width.max(label.len() as u16 + 1);
label.blit(buf, x, y, Some(style));
} else {
format!("{}", &"?".repeat(track.name.len()))
.blit(buf, x - 2, y as u16, Some(Style::default().dim()));
}
} else {
"····".blit(buf, x, y, Some(style.dim()));
}
let style = Some(style.dim());
"".blit(buf, x - 2, y + 0, style);
"".blit(buf, x - 2, y + 1, style);
"".blit(buf, x + width - 2, y + 0, style);
"".blit(buf, x + width - 2, y + 1, style);
}
width
}
fn draw_crossings (state: &Launcher, buf: &mut Buffer, x: u16, y: u16) {
@ -282,10 +308,12 @@ pub const KEYMAP: &'static [KeyBinding<Launcher>] = keymap!(Launcher {
[Tab, NONE, "focus_next", "focus next area", focus_next],
});
pub const KEYMAP_TRACKS: &'static [KeyBinding<Launcher>] = keymap!(Launcher {
[Up, NONE, "cursor_up", "move cursor up", cursor_up],
[Down, NONE, "cursor_down", "move cursor down", cursor_down],
[Left, NONE, "cursor_left", "move cursor left", cursor_left],
[Right, NONE, "cursor_right", "move cursor right", cursor_right],
[Up, NONE, "cursor_up", "move cursor up", cursor_up],
[Down, NONE, "cursor_down", "move cursor down", cursor_down],
[Left, NONE, "cursor_left", "move cursor left", cursor_left],
[Right, NONE, "cursor_right", "move cursor right", cursor_right],
[Char('.'), NONE, "clip_next", "set clip to next phrase", clip_next],
[Char(','), NONE, "clip_next", "set clip to last phrase", clip_prev],
});
fn rename (_: &mut Launcher) -> Usually<bool> {
Ok(true)
@ -326,3 +354,35 @@ fn focus_prev (state: &mut Launcher) -> Usually<bool> {
};
Ok(true)
}
fn clip_next (state: &mut Launcher) -> Usually<bool> {
if state.cursor.0 >= 1 && state.cursor.1 >= 2 {
let scene_id = state.cursor.1 - 2;
let clip_id = state.cursor.0 - 1;
let scene = &mut state.scenes[scene_id];
scene.clips[clip_id] = match scene.clips[clip_id] {
None => Some(0),
Some(i) => if i >= state.tracks[clip_id].state().sequences.len().saturating_sub(1) {
None
} else {
Some(i + 1)
}
};
}
Ok(true)
}
fn clip_prev (state: &mut Launcher) -> Usually<bool> {
if state.cursor.0 >= 1 && state.cursor.1 >= 2 {
let scene_id = state.cursor.1 - 2;
let clip_id = state.cursor.0 - 1;
let scene = &mut state.scenes[scene_id];
scene.clips[clip_id] = match scene.clips[clip_id] {
None => Some(state.tracks[clip_id].state().sequences.len().saturating_sub(1)),
Some(i) => if i == 0 {
None
} else {
Some(i - 1)
}
};
}
Ok(true)
}