enable interior mutability for time/note axis

this will allow to adapt the cursor position
during render, always keeping it visible
This commit is contained in:
🪞👃🪞 2024-10-24 22:47:15 +03:00
parent 03e2e20258
commit dd21f73e9d
4 changed files with 83 additions and 60 deletions

View file

@ -52,12 +52,18 @@ impl Content for PhraseEditor<Tui> {
let Self {
focused, entered, time_axis, note_axis, keys, phrase, buffer, note_len, ..
} = self;
let FixedAxis {
start: note_start, point: note_point, clamp: note_clamp
} = *self.note_axis.read().unwrap();
let ScaledAxis {
start: time_start, point: time_point, clamp: time_clamp, scale: time_scale
} = *self.time_axis.read().unwrap();
let color = Color::Rgb(0,255,0);
let color = phrase.as_ref().map(|p|p.read().unwrap().color).unwrap_or(color);
let keys = CustomWidget::new(|to:[u16;2]|Ok(Some(to.clip_w(5))), move|to: &mut TuiOutput|{
if to.area().h() >= 2 {
to.buffer_update(to.area().set_w(5), &|cell, x, y|{
let y = y + note_axis.start as u16;
let y = y + note_start as u16;
if x < keys.area.width && y < keys.area.height {
*cell = keys.get(x, y).clone()
}
@ -73,8 +79,8 @@ impl Content for PhraseEditor<Tui> {
let area = to.area();
to.buffer_update(area, &move |cell, x, y|{
cell.set_bg(notes_bg_null);
let src_x = (x as usize + time_axis.start) * time_axis.scale;
let src_y = y as usize + note_axis.start;
let src_x = (x as usize + time_start) * time_scale;
let src_y = y as usize + note_start;
if src_x < buffer.width && src_y < buffer.height - 1 {
buffer.get(src_x, buffer.height - src_y).map(|src|{
cell.set_symbol(src.symbol());
@ -89,9 +95,9 @@ impl Content for PhraseEditor<Tui> {
let cursor = CustomWidget::new(|to|Ok(Some(to)), move|to: &mut TuiOutput|{
if *entered {
let area = to.area();
if let (Some(time), Some(note)) = (time_axis.point, note_axis.point) {
let x1 = area.x() + (time / time_axis.scale) as u16;
let x2 = x1 + (self.note_len / time_axis.scale) as u16;
if let (Some(time), Some(note)) = (time_point, note_point) {
let x1 = area.x() + (time / time_scale) as u16;
let x2 = x1 + (self.note_len / time_scale) as u16;
let y = area.y() + 1 + note as u16 / 2;
let c = if note % 2 == 0 { "" } else { "" };
for x in x1..x2 {
@ -108,11 +114,11 @@ impl Content for PhraseEditor<Tui> {
move|to: &mut TuiOutput|{
if let Some(_) = phrase {
let now = self.now.load(Ordering::Relaxed); // TODO FIXME: self.now % phrase.read().unwrap().length;
let ScaledAxis { start: first_beat, scale: time_zoom, clamp, .. } = time_axis;
let clamp = clamp.expect("time_axis of sequencer expected to be clamped");
for x in 0..clamp/time_zoom {
let this_step = (x * time_zoom + first_beat + 0) * time_zoom;
let next_step = (x * time_zoom + first_beat + 1) * time_zoom;
let time_clamp = time_clamp
.expect("time_axis of sequencer expected to be clamped");
for x in 0..time_clamp/time_scale {
let this_step = (x * time_scale + time_start + 0) * time_scale;
let next_step = (x * time_scale + time_start + 1) * time_scale;
let x = to.area().x() + x as u16;
let active = this_step <= now && now < next_step;
let character = if active { "|" } else { "·" };
@ -136,18 +142,18 @@ impl Content for PhraseEditor<Tui> {
upper_left = format!("{upper_left}: {}", phrase.read().unwrap().name);
}
let mut upper_right = format!("Zoom: {} (+{}:{}*{}|{})",
ppq_to_name(time_axis.scale),
time_axis.start,
time_axis.point.unwrap_or(0),
time_axis.scale,
time_axis.clamp.unwrap_or(0),
ppq_to_name(time_scale),
time_start,
time_point.unwrap_or(0),
time_scale,
time_clamp.unwrap_or(0),
);
if *focused && *entered {
upper_right = format!("Note: {} (+{}:{}|{}) {upper_right}",
ppq_to_name(*note_len),
note_axis.start,
note_axis.point.unwrap_or(0),
note_axis.clamp.unwrap_or(0),
note_start,
note_point.unwrap_or(0),
note_clamp.unwrap_or(0),
);
}
lay!(
@ -161,8 +167,8 @@ impl<E: Engine> PhraseEditor<E> {
pub fn put (&mut self) {
if let (Some(phrase), Some(time), Some(note)) = (
&self.phrase,
self.time_axis.point,
self.note_axis.point,
self.time_axis.read().unwrap().point,
self.note_axis.read().unwrap().point,
) {
let mut phrase = phrase.write().unwrap();
let key: u7 = u7::from((127 - note) as u8);
@ -178,11 +184,11 @@ impl<E: Engine> PhraseEditor<E> {
pub fn show (&mut self, phrase: Option<&Arc<RwLock<Phrase>>>) {
if let Some(phrase) = phrase {
self.phrase = Some(phrase.clone());
self.time_axis.clamp = Some(phrase.read().unwrap().length);
self.time_axis.write().unwrap().clamp = Some(phrase.read().unwrap().length);
self.buffer = Self::redraw(&*phrase.read().unwrap());
} else {
self.phrase = None;
self.time_axis.clamp = Some(0);
self.time_axis.write().unwrap().clamp = Some(0);
self.buffer = Default::default();
}
}