full block piano roll: fix zooming

This commit is contained in:
🪞👃🪞 2024-12-04 18:32:29 +01:00
parent aef0213a2b
commit 59d4da1b22
3 changed files with 70 additions and 44 deletions

View file

@ -16,8 +16,6 @@ pub struct PhraseView<'a> {
time_start: usize,
time_point: usize,
time_clamp: usize,
time_scale: usize,
}
impl<'a, T: HasEditor> From<&'a T> for PhraseView<'a> {
@ -57,8 +55,6 @@ impl<'a, T: HasEditor> From<&'a T> for PhraseView<'a> {
time_start: editor.time_start.load(Ordering::Relaxed),
time_point: editor.time_point.load(Ordering::Relaxed),
time_clamp: editor.time_clamp.load(Ordering::Relaxed),
time_scale: editor.time_scale.load(Ordering::Relaxed),
}
}
}
@ -79,8 +75,6 @@ impl<'a> Content for PhraseView<'a> {
note_point,
time_start,
time_point,
time_clamp,
time_scale,
now,
..
} = self;
@ -110,7 +104,7 @@ impl<'a> Content for PhraseView<'a> {
);
if let Some(phrase) = phrase {
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(view_mode.time_zoom()),
)
};
@ -137,7 +131,7 @@ impl<'a> Content for PhraseView<'a> {
Ok(if *focused && *entered {
view_mode.blit_cursor(
to,
*time_point, *time_start, *time_scale,
*time_point, *time_start, view_mode.time_zoom(),
*note_point, *note_len, *note_hi, *note_lo,
)
})
@ -149,21 +143,21 @@ impl<'a> Content for PhraseView<'a> {
Color::Rgb(70, 80, 50)
}))),
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 {
let now = now.get() as usize; // TODO FIXME: self.now % phrase.read().unwrap().length;
let time_clamp = time_clamp;
for x in 0..(time_clamp/time_scale).saturating_sub(*time_start) {
let this_step = time_start + (x + 0) * time_scale;
let next_step = time_start + (x + 1) * time_scale;
let x = to.area().x() + x as u16;
let active = this_step <= now && now < next_step;
let character = if active { "|" } else { "·" };
let style = if active { playhead_active } else { playhead_inactive };
to.blit(&character, x, to.area.y(), Some(style));
}
}
//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 {
//let now = now.get() as usize; // TODO FIXME: self.now % phrase.read().unwrap().length;
//let time_clamp = time_clamp;
//for x in 0..(time_clamp/time_scale).saturating_sub(*time_start) {
//let this_step = time_start + (x + 0) * time_scale;
//let next_step = time_start + (x + 1) * time_scale;
//let x = to.area().x() + x as u16;
//let active = this_step <= now && now < next_step;
//let character = if active { "|" } else { "·" };
//let style = if active { playhead_active } else { playhead_inactive };
//to.blit(&character, x, to.area.y(), Some(style));
//}
//}
Ok(())
}).push_x(6).align_sw(),
TuiStyle::fg(upper_left.to_string(), title_color).push_x(1).align_nw(),
@ -194,6 +188,21 @@ pub enum PhraseViewNoteZoom {
}
impl PhraseViewMode {
pub fn time_zoom (&self) -> usize {
match self {
Self::PianoHorizontal { time_zoom, .. } => *time_zoom,
_ => unimplemented!()
}
}
pub fn set_time_zoom (&mut self, time_zoom: usize) {
*self = match self {
Self::PianoHorizontal { note_zoom, .. } => Self::PianoHorizontal {
note_zoom: *note_zoom,
time_zoom,
},
_ => unimplemented!()
}
}
/// Return a new [BigBuffer] containing a render of the phrase.
pub fn draw (&self, phrase: &Phrase) -> BigBuffer {
let mut buffer = BigBuffer::new(self.buffer_width(phrase), self.buffer_height(phrase));
@ -328,15 +337,36 @@ impl PhraseViewMode {
fn draw_piano_horizontal (
target: &mut BigBuffer, phrase: &Phrase, time_zoom: usize, _: usize
) {
//cell.set_char(if ppq == 0 {
//'·'
//} else if x % (4 * ppq) == 0 {
//'│'
//} else if x % ppq == 0 {
//'╎'
//} else {
//'·'
//});
//cell.set_fg(Color::Rgb(48, 64, 56));
let mut notes_on = [false;128];
for (y, _) in (127..0).enumerate() {
for (x, _) in (0..phrase.length).step_by(time_zoom).enumerate() {
let cell = target.get_mut(x, y).unwrap();
cell.set_fg(Color::Rgb(28, 35, 25));
cell.set_char('·');
}
}
for (x, time_start) in (0..phrase.length).step_by(time_zoom).enumerate() {
let time_end = time_start + time_zoom;
for time in time_start..time_end {
for (y, note) in (127..0).enumerate() {
let cell = target.get_mut(x, y).unwrap();
cell.set_fg(Color::Rgb(255, 255, 255));
cell.set_bg(Color::Rgb(28, 35, 25));
cell.set_char(if notes_on[note] { '▄' } else { '?' });
if notes_on[note] {
cell.set_fg(Color::Rgb(255, 255, 255));
cell.set_bg(Color::Rgb(0, 0, 0));
cell.set_char('▄');
} else {
cell.set_char('x');
}
}
for event in phrase.notes[time].iter() {
match event {