piano roll full block cursor (1 off)

This commit is contained in:
🪞👃🪞 2024-12-04 16:30:19 +01:00
parent d2a9e0b722
commit aef0213a2b

View file

@ -34,7 +34,7 @@ impl<'a, T: HasEditor> From<&'a T> for PhraseView<'a> {
editor.note_lo.store(note_lo, Ordering::Relaxed); editor.note_lo.store(note_lo, Ordering::Relaxed);
} }
let mut note_hi = 127.min(note_lo + height * 2 + 1); let mut note_hi = 127.min(note_lo + height + 1);
if note_point > note_hi { if note_point > note_hi {
note_lo += note_point - note_hi; note_lo += note_point - note_hi;
note_hi = note_point; note_hi = note_point;
@ -84,34 +84,43 @@ impl<'a> Content for PhraseView<'a> {
now, now,
.. ..
} = self; } = self;
let border_color = if *focused{Color::Rgb(100, 110, 40)}else{Color::Rgb(70, 80, 50)};
let title_color = if *focused{Color::Rgb(150, 160, 90)}else{Color::Rgb(120, 130, 100)}; let upper_left = format!(
let border = Lozenge(Style::default().bg(Color::Rgb(40, 50, 30)).fg(border_color)); "{note_hi} {note_hi_name} {}",
let playhead_inactive = Style::default().fg(Color::Rgb(255,255,255)).bg(Color::Rgb(40,50,30)); phrase.as_ref().map(|p|p.read().unwrap().name.clone()).unwrap_or(String::new())
let playhead_active = playhead_inactive.clone().yellow().bold().not_dim(); );
let mut name = "".to_string();
if let Some(phrase) = phrase { let lower_left = format!(
name = phrase.read().unwrap().name.clone(); "{note_lo} {note_lo_name}"
}
let upper_left = format!("{note_hi} {note_hi_name} {name}"); );
let lower_left = format!("{note_lo} {note_lo_name}");
let mut lower_right = format!("{}", size.format()); let mut lower_right = format!(
"┤{}├", size.format()
);
if *focused && *entered { if *focused && *entered {
lower_right = format!("┤Note: {} ({}) {}├─{lower_right}", lower_right = format!("┤Note: {} ({}) {}├─{lower_right}",
note_point, to_note_name(*note_point), pulses_to_name(*note_len) note_point, to_note_name(*note_point), pulses_to_name(*note_len)
); );
} }
let mut upper_right = format!("[{}]", if *entered {""} else {" "});
let mut upper_right = format!(
"[{}]",
if *entered {""} else {" "}
);
if let Some(phrase) = phrase { if let Some(phrase) = phrase {
upper_right = format!("┤Time: {}/{} {}{upper_right}", upper_right = format!("┤Time: {}/{} {}{upper_right}",
time_point, phrase.read().unwrap().length, pulses_to_name(*time_scale), time_point, phrase.read().unwrap().length, pulses_to_name(*time_scale),
) )
}; };
let title_color = if *focused{Color::Rgb(150, 160, 90)}else{Color::Rgb(120, 130, 100)};
lay!( lay!(
row!( row!(
CustomWidget::new(|to:[u16;2]|Ok(Some(to.clip_w(2))), move|to: &mut TuiOutput|{ CustomWidget::new(|to:[u16;2]|Ok(Some(to.clip_w(2))), move|to: &mut TuiOutput|{
Ok(if to.area().h() >= 2 { Ok(if to.area().h() >= 2 {
view_mode.blit_keys(to, *note_hi) view_mode.blit_keys(to, *note_hi, *note_lo)
}) })
}).fill_y(), }).fill_y(),
lay!( lay!(
@ -128,14 +137,20 @@ impl<'a> Content for PhraseView<'a> {
Ok(if *focused && *entered { Ok(if *focused && *entered {
view_mode.blit_cursor( view_mode.blit_cursor(
to, to,
*time_point, *time_scale, *time_point, *time_start, *time_scale,
*note_len, *note_hi, *note_lo, *note_point *note_point, *note_len, *note_hi, *note_lo,
) )
}) })
}) })
).fill_x() ).fill_x()
).fill_x().bg(Color::Rgb(40, 50, 30)).border(border), ).fill_x().bg(Color::Rgb(40, 50, 30)).border(Lozenge(Style::default().bg(Color::Rgb(40, 50, 30)).fg(if *focused{
Color::Rgb(100, 110, 40)
} else {
Color::Rgb(70, 80, 50)
}))),
CustomWidget::new(|to:[u16;2]|Ok(Some(to.clip_h(1))), move|to: &mut TuiOutput|{ CustomWidget::new(|to:[u16;2]|Ok(Some(to.clip_h(1))), move|to: &mut TuiOutput|{
let playhead_inactive = Style::default().fg(Color::Rgb(255,255,255)).bg(Color::Rgb(40,50,30));
let playhead_active = playhead_inactive.clone().yellow().bold().not_dim();
if let Some(_) = phrase { if let Some(_) = phrase {
let now = now.get() as usize; // TODO FIXME: self.now % phrase.read().unwrap().length; let now = now.get() as usize; // TODO FIXME: self.now % phrase.read().unwrap().length;
let time_clamp = time_clamp; let time_clamp = time_clamp;
@ -226,59 +241,61 @@ impl PhraseViewMode {
_ => unimplemented!() _ => unimplemented!()
} }
} }
fn blit_keys (&self, to: &mut TuiOutput, note_hi: usize) { fn blit_keys (&self, to: &mut TuiOutput, note_hi: usize, note_lo: usize) {
for y in to.area.y()..to.area.y2() { let style = Some(Style::default().fg(Color::White).bg(Color::Rgb(0, 0, 0)));
let n = y - to.area.y(); match self {
let m = note_hi.saturating_sub(n as usize*2); Self::PianoHorizontal { .. } => {
//let c = format!("{m:>03} {n}"); let [x0, y0, _, h] = to.area().xywh();
//to.blit(&c, to.area.x(), y, None); for (y, note) in (note_lo..note_hi).rev().enumerate() {
let x = to.area.x(); to.blit(&match note % 12 {
let s = Some(Style::default().fg(Color::Rgb(255,255,255)).bg(Color::Rgb(0,0,0))); 11 => "██",
match m % 2 { 10 => " ",
1 => match (m / 2) % 6 { 9 => "██",
5 => to.blit(&"", x, y, s), 8 => " ",
4 => to.blit(&"", x, y, s), 7 => "██",
3 => to.blit(&"", x, y, s), 6 => " ",
2 => to.blit(&"", x, y, s), 5 => "██",
1 => to.blit(&"", x, y, s), 4 => "██",
0 => to.blit(&"", x, y, s), 3 => " ",
2 => "██",
1 => " ",
0 => "██",
_ => unreachable!(), _ => unreachable!(),
}, }, x0, y0 + y as u16, style)
0 => match (m / 2) % 6 {
5 => to.blit(&"", x, y, s),
4 => to.blit(&"", x, y, s),
3 => to.blit(&"", x, y, s),
2 => to.blit(&"", x, y, s),
1 => to.blit(&"", x, y, s),
0 => to.blit(&"", x, y, s),
_ => unreachable!(),
},
_ => unreachable!()
} }
},
_ => unimplemented!()
} }
} }
fn blit_cursor ( fn blit_cursor (
&self, &self,
to: &mut TuiOutput, to: &mut TuiOutput,
time_point: usize, time_point: usize,
time_start: usize,
time_scale: usize, time_scale: usize,
note_point: usize,
note_len: usize, note_len: usize,
note_hi: usize, note_hi: usize,
note_lo: usize, note_lo: usize,
note_point: usize,
) { ) {
let area = to.area(); match self {
let x1 = area.x() + (time_point / time_scale) as u16; Self::PianoHorizontal { .. } => {
let x2 = x1 + (note_len / time_scale) as u16; let [x0, y0, w, h] = to.area().xywh();
let y = area.y() + (note_hi - note_point) as u16 / 2; for (y, note) in (note_lo..note_hi).rev().enumerate() {
let c = if note_lo % 2 == 0 { if note == note_point {
if note_point % 2 == 0 { "" } else { "" } for x in 0..w {
} else { let time_1 = time_start + x as usize * time_scale;
if note_point % 2 == 0 { "" } else { "" } let time_2 = time_1 + time_scale;
}; if time_1 <= time_point && time_point < time_2 {
let style = Some(Style::default().fg(Color::Rgb(0,255,0))); to.blit(&"", x0 + x as u16, y0 + y as u16, None);
for x in x1..x2 { break
to.blit(&c, x, y, style); }
}
break
}
}
},
_ => unimplemented!()
} }
} }
/// Determine the required width to render the phrase. /// Determine the required width to render the phrase.