compact launch grid

This commit is contained in:
🪞👃🪞 2024-06-29 20:46:57 +03:00
parent fad0caef88
commit 3886e34519
5 changed files with 75 additions and 90 deletions

View file

@ -15,8 +15,8 @@ impl<'a> LauncherGridView<'a> {
pub fn draw (&mut self) -> Usually<Rect> { pub fn draw (&mut self) -> Usually<Rect> {
//self.separator_h(0, false); //self.separator_h(0, false);
//self.separator_h(2, false); //self.separator_h(2, false);
self.separator_h((self.state.cursor.1 * 2) as u16, true); //self.separator_h((self.state.cursor.1 * 2) as u16, true);
self.separator_h(((self.state.cursor.1 + 1) * 2) as u16, true); //self.separator_h(((self.state.cursor.1 + 1) * 2) as u16, true);
draw_box_styled(self.buf, self.area, Some( draw_box_styled(self.buf, self.area, Some(
if self.focused { if self.focused {
Style::default().green().dim() Style::default().green().dim()
@ -26,7 +26,7 @@ impl<'a> LauncherGridView<'a> {
)); ));
let columns = self.column_names(); let columns = self.column_names();
let (mut x, y) = (self.area.x, self.area.y); let mut x = self.area.x;
for (i, w) in self.column_widths().iter().enumerate() { for (i, w) in self.column_widths().iter().enumerate() {
if x >= self.area.x + self.area.width { if x >= self.area.x + self.area.width {
break break
@ -42,18 +42,18 @@ impl<'a> LauncherGridView<'a> {
break break
} }
column.blit( column.blit(
self.buf, x + 2, y + 1, Some(self.highlight(i == self.state.cursor.0).bold()) self.buf, x + 2, y, Some(self.highlight(i == self.state.cursor.0).bold())
); );
if i == 0 { if i == 0 {
self.scenes(x + 2, y + 3); self.scenes(x + 2, y + 1);
} else if i < columns.len() { } else if i < columns.len() {
self.clips(x + 2, y + 3, i - 1); self.clips(x + 2, y + 1, i - 1);
} }
let w = (column.len() as u16).max(12) + 3; let w = (column.len() as u16).max(12) + 3;
x = x + w; x = x + w;
} }
"Add track…".blit(self.buf, x + 2, y + 1, Some(Style::default().dim())); "Add track…".blit(self.buf, x + 2, y, Some(Style::default().dim()));
Ok(self.area) Ok(self.area)
} }
@ -70,85 +70,70 @@ impl<'a> LauncherGridView<'a> {
} }
fn scenes (&mut self, x: u16, y: u16) { fn scenes (&mut self, x: u16, y: u16) {
let mut y2 = 0; let mut index = 0usize;
loop { loop {
if y2 >= self.area.height { if index >= self.state.scenes.len() {
break break
} }
if y2 % 2 == 0 { if y + index as u16 >= self.area.height {
let index = (y2 / 2) as usize; break
if let Some(scene) = self.state.scenes.get(index) {
format!("{}", scene.name).blit(
self.buf, x, y + y2,
Some(self.highlight(index + 1 == self.state.cursor.1))
)
} else {
break
}
} }
y2 = y2 + 1; if let Some(scene) = self.state.scenes.get(index) {
format!("{}", scene.name).blit(
self.buf, x, y + index as u16,
Some(self.highlight(
(0 == self.state.cursor.0) && (index + 1 == self.state.cursor.1)
).bold())
)
}
index = index + 1;
} }
"Add scene…".blit(self.buf, x, y + y2, Some(Style::default().dim())); let hi = (0 == self.state.cursor.0) &&
(self.state.scenes.len() + 1 == self.state.cursor.1);
"Add scene…".blit(self.buf, x, y + index as u16, Some(if hi {
self.highlight(true)
} else {
Style::default().dim()
}));
} }
fn clips (&mut self, x: u16, y: u16, track: usize) { fn clips (&mut self, x: u16, y: u16, track: usize) {
let mut y2 = 0; let mut index = 0;
loop { loop {
if y2 >= self.area.height { if index >= self.state.scenes.len() {
break break
} }
if y2 % 2 == 0 { if y + index as u16 >= self.area.height {
let index = (y2 / 2) as usize; break
if index >= self.state.scenes.len() {
break
}
if let Some(scene) = self.state.scenes.get(index) {
let hi = (track + 1 == self.state.cursor.0) &&
(index + 1 == self.state.cursor.1);
let style = Some(self.highlight(hi));
let clip = scene.clips.get(track);
if let Some(Some(clip)) = clip {
if let Some(phrase) = self.state.tracks[track].sequencer.state().sequences.get(*clip) {
format!("{}", phrase.name).blit(self.buf, x, y + y2, style);
} else {
"????".blit(self.buf, x, y + y2, Some(Style::default().dim()))
}
} else {
" ·········".blit(self.buf, x, y + y2, Some(Style::default().dim()))
}
if hi {
draw_box_styled(self.buf, Rect {
x: x - 2,
y: y + y2 - 1,
width: 16,
height: 3
}, style);
if self.focused {
let style = Some(self.highlight(hi).bold().yellow());
if let Some(Some(_)) = clip { } else {
"+ Add clip".blit(self.buf, x + 1, y + y2, Some(Style::default().dim()));
"+".blit(self.buf, x + 1, y + y2, style);
}
"".blit(self.buf, x + 6, y + y2 - 1, style);
"".blit(self.buf, x + 6, y + y2 + 1, style);
",".blit(self.buf, x - 1, y + y2, style);
"".blit(self.buf, x - 2, y + y2, style);
".".blit(self.buf, x + 12, y + y2, style);
"".blit(self.buf, x + 13, y + y2, style);
}
}
}
} }
y2 = y2 + 1; if let Some(scene) = self.state.scenes.get(index) {
let hi = (track + 1 == self.state.cursor.0) &&
(index + 1 == self.state.cursor.1);
let style = Some(self.highlight(hi));
let clip = scene.clips.get(track);
let index = index as u16;
let label = if let Some(Some(clip)) = clip {
let track = self.state.tracks[track].sequencer.state();
let phrase = track.sequences.get(*clip);
if let Some(phrase) = phrase {
format!("{}", phrase.name)
} else {
format!("????")
}
} else {
format!(" ·········")
};
label.blit(self.buf, x, y + index, style);
}
index = index + 1;
} }
let hi = (track + 1 == self.state.cursor.0) && let hi = (track + 1 == self.state.cursor.0) &&
(self.state.scenes.len() + 1 == self.state.cursor.1); (self.state.scenes.len() + 1 == self.state.cursor.1);
" + Add clip".blit(self.buf, x, y + y2, Some(Style::default().dim())); " + Add clip".blit(self.buf, x, y + index as u16, Some(if hi {
if hi { self.highlight(true)
draw_box_styled( } else {
self.buf, Rect { x: x - 2, y: y + y2 - 1, width: 16, height: 3 }, Some(Style::default().green()) Style::default().dim()
); }));
}
} }
fn highlight (&self, highlight: bool) -> Style { fn highlight (&self, highlight: bool) -> Style {
@ -170,15 +155,11 @@ impl<'a> LauncherGridView<'a> {
fn separator_v (&mut self, x: u16, highlight: bool) { fn separator_v (&mut self, x: u16, highlight: bool) {
let style = Some(self.highlight(highlight)); let style = Some(self.highlight(highlight));
"".blit(self.buf, x, self.area.y + 0, style); //"┬".blit(self.buf, x, self.area.y + 0, style);
"".blit(self.buf, x, self.area.y + 1, style); for y in self.area.y+1..self.area.y+self.area.height-1 {
"".blit(self.buf, x, self.area.y + 2, style);
"".blit(self.buf, x, self.area.y + 3, style);
"".blit(self.buf, x, self.area.y + 4, style);
for y in self.area.y+5..self.area.y+self.area.height-1 {
"".blit(self.buf, x, y, style); "".blit(self.buf, x, y, style);
} }
"".blit(self.buf, x, self.area.y+self.area.height-1, style); //"┴".blit(self.buf, x, self.area.y+self.area.height-1, style);
} }
} }

View file

@ -39,15 +39,19 @@ pub const KEYMAP: &'static [KeyBinding<Launcher>] = keymap!(Launcher {
//[Char(' '), SHIFT, "play_start", "play from start", play_start], //[Char(' '), SHIFT, "play_start", "play from start", play_start],
}); });
pub const KEYMAP_TRACKS: &'static [KeyBinding<Launcher>] = keymap!(Launcher { pub const KEYMAP_TRACKS: &'static [KeyBinding<Launcher>] = keymap!(Launcher {
[Up, NONE, "cursor_up", "move cursor up", cursor_up], [Up, NONE, "cursor_up", "move cursor up", cursor_up],
[Down, NONE, "cursor_down", "move cursor down", cursor_down], [Down, NONE, "cursor_down", "move cursor down", cursor_down],
[Left, NONE, "cursor_left", "move cursor left", cursor_left], [Left, NONE, "cursor_left", "move cursor left", cursor_left],
[Right, NONE, "cursor_right", "move cursor right", cursor_right], [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 next phrase", clip_next],
[Char(','), NONE, "clip_prev", "set clip to last phrase", clip_prev], [Char(','), NONE, "clip_prev", "set clip to last phrase", clip_prev],
[Delete, CONTROL, "delete_track", "delete track", delete_track], [Delete, CONTROL, "delete_track", "delete track", delete_track],
[Char('d'), CONTROL, "duplicate", "duplicate scene or track", duplicate],
[Enter, NONE, "clip_enter", "play or record clip or stop and advance", clip_enter], [Enter, NONE, "clip_enter", "play or record clip or stop and advance", clip_enter],
}); });
fn duplicate (_: &mut Launcher) -> Usually<bool> {
Ok(true)
}
fn clip_enter (_: &mut Launcher) -> Usually<bool> { fn clip_enter (_: &mut Launcher) -> Usually<bool> {
//let track = state.active_track().unwrap(); //let track = state.active_track().unwrap();
//let scene = state.active_scene(); //let scene = state.active_scene();

View file

@ -88,7 +88,7 @@ pub fn lanes (
format!("{}", step / time_zoom / 4 + 1) format!("{}", step / time_zoom / 4 + 1)
.blit(buf, x as u16, y - 1, Some(Style::default().bold().not_dim())); .blit(buf, x as u16, y - 1, Some(Style::default().bold().not_dim()));
} }
let h = (note1-note0)/2; let h = (note1-note0)/2 - y as u32;
for k in 0..h { for k in 0..h {
let (character, style) = match ( let (character, style) = match (
contains_note_on(phrase, u7::from_int_lossy((note0 + k * 2 + 0) as u8), a, b), contains_note_on(phrase, u7::from_int_lossy((note0 + k * 2 + 0) as u8), a, b),
@ -99,7 +99,7 @@ pub fn lanes (
(false, true) => ("", wh), (false, true) => ("", wh),
(false, false) => ("·", bw), (false, false) => ("·", bw),
}; };
let y = y as u32 + h + k; let y = y as u32 + k;
character.blit(buf, x as u16, y as u16, Some(style)); character.blit(buf, x as u16, y as u16, Some(style));
} }
} }

View file

@ -66,7 +66,7 @@ pub struct Sequencer {
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
enum SequencerView { pub enum SequencerView {
Tiny, Tiny,
Compact, Compact,
Horizontal, Horizontal,

View file

@ -35,7 +35,7 @@ fn main () -> Result<(), Box<dyn Error>> {
Track::new("Kick", &timebase, Some(vec![ Track::new("Kick", &timebase, Some(vec![
//Plugin::lv2("Kick/ChowKick", "file:///home/user/.lv2/ChowKick.lv2", &[1, 1, 0, 2])?.boxed(), //Plugin::lv2("Kick/ChowKick", "file:///home/user/.lv2/ChowKick.lv2", &[1, 1, 0, 2])?.boxed(),
Sampler::new("Sampler", Some(BTreeMap::from([ Sampler::new("Sampler", Some(BTreeMap::from([
(u7::from_int_lossy(35), Sample { (u7::from_int_lossy(35), Sample {
name: "Kick 1".into(), start: 0, end: 100000, channels: vec![], name: "Kick 1".into(), start: 0, end: 100000, channels: vec![],
}.into()), }.into()),
(u7::from_int_lossy(36).into(), Sample { (u7::from_int_lossy(36).into(), Sample {
@ -84,7 +84,7 @@ fn main () -> Result<(), Box<dyn Error>> {
]), ]),
Some(vec![ Some(vec![
Scene::new(&"Scene#01", &[Some(0), None, None, None]), Scene::new(&"Scene#01", &[Some(0), None, None, None]),
//Scene::new(&"Scene#02", &[Some(0), Some(0), None, None]), Scene::new(&"Scene#02", &[Some(0), Some(0), None, None]),
//Scene::new(&"Scene#03", &[None, Some(0), None, None]), //Scene::new(&"Scene#03", &[None, Some(0), None, None]),
//Scene::new(&"Scene#04", &[None, None, None, None]), //Scene::new(&"Scene#04", &[None, None, None, None]),
//Scene::new(&"Scene#05", &[None, None, None, None]), //Scene::new(&"Scene#05", &[None, None, None, None]),