wip: 21 errors!

This commit is contained in:
🪞👃🪞 2024-09-05 17:38:32 +03:00
parent 694970bf0d
commit ea5bc2e3b1
30 changed files with 392 additions and 362 deletions

View file

@ -1,71 +1,69 @@
use crate::*;
impl<T, U> Handle for Arranger<T, U> {
fn handle (&mut self, event: &AppEvent) -> Usually<bool> {
match self.modal.as_mut() {
Some(modal) => {
let result = modal.handle(event)?;
if modal.exited() {
self.modal = None;
}
Ok(result)
},
None => match event {
AppEvent::Input(crossterm::event::Event::Key(event)) => {
for (code, modifiers, _, _, command) in [
key!(Char('`'), NONE, "mode_switch", "switch the display mode", || {
self.mode.to_next();
Ok(true)
}),
key!(Up, NONE, "cursor_up", "move cursor up", || {
match self.mode {
ArrangerViewMode::Horizontal => self.track_prev(),
_ => self.scene_prev(),
};
self.show_phrase()?;
Ok(true)
}),
key!(Down, NONE, "cursor_down", "move cursor down", || {
match self.mode {
ArrangerViewMode::Horizontal => self.track_next(),
_ => self.scene_next(),
};
self.show_phrase()?;
Ok(true)
}),
key!(Left, NONE, "cursor_left", "move cursor left", || {
match self.mode {
ArrangerViewMode::Horizontal => self.scene_prev(),
_ => self.track_prev(),
};
self.show_phrase()?;
Ok(true)
}),
key!(Right, NONE, "cursor_right", "move cursor right", || {
match self.mode {
ArrangerViewMode::Horizontal => self.scene_next(),
_ => self.track_next(),
};
self.show_phrase()?;
Ok(true)
}),
key!(Char('.'), NONE, "increment", "set next clip at cursor", || { self.phrase_next(); Ok(true) }),
key!(Char(','), NONE, "decrement", "set previous clip at cursor", || { self.phrase_prev(); Ok(true) }),
key!(Enter, NONE, "activate", "activate item at cursor", || { self.activate(); Ok(true) }),
key!(Char('a'), CONTROL, "scene_add", "add a new scene", || { self.scene_add(None)?; Ok(true) }),
key!(Char('t'), CONTROL, "track_add", "add a new track", || { self.track_add(None)?; Ok(true) }),
key!(Char('n'), NONE, "rename", "rename item at cursor", || { self.rename_selected(); Ok(true) }),
key!(Char('l'), NONE, "length", "set length of item at cursor", || { todo!(); Ok(true) }),
key!(Char('c'), NONE, "color", "set color of item at cursor", || { todo!(); Ok(true) })
].iter() {
if *code == event.code && modifiers.bits() == event.modifiers.bits() {
return command()
}
}
return Ok(false)
},
_ => Ok(false)
impl Handle<Tui> for Arranger<Tui> {
fn handle (&mut self, from: &Tui) -> Perhaps<bool> {
if let Some(modal) = self.modal.as_mut() {
let result = modal.handle(from)?;
if modal.exited() {
self.modal = None;
}
return Ok(result)
}
match from.event() {
TuiEvent::Input(crossterm::event::Event::Key(event)) => {
for (code, modifiers, _, _, command) in [
key!(Char('`'), NONE, "mode_switch", "switch the display mode", || {
self.mode.to_next();
Ok(true)
}),
key!(Up, NONE, "cursor_up", "move cursor up", || {
match self.mode {
ArrangerViewMode::Horizontal => self.track_prev(),
_ => self.scene_prev(),
};
self.show_phrase()?;
Ok(true)
}),
key!(Down, NONE, "cursor_down", "move cursor down", || {
match self.mode {
ArrangerViewMode::Horizontal => self.track_next(),
_ => self.scene_next(),
};
self.show_phrase()?;
Ok(true)
}),
key!(Left, NONE, "cursor_left", "move cursor left", || {
match self.mode {
ArrangerViewMode::Horizontal => self.scene_prev(),
_ => self.track_prev(),
};
self.show_phrase()?;
Ok(true)
}),
key!(Right, NONE, "cursor_right", "move cursor right", || {
match self.mode {
ArrangerViewMode::Horizontal => self.scene_next(),
_ => self.track_next(),
};
self.show_phrase()?;
Ok(true)
}),
key!(Char('.'), NONE, "increment", "set next clip at cursor", || { self.phrase_next(); Ok(true) }),
key!(Char(','), NONE, "decrement", "set previous clip at cursor", || { self.phrase_prev(); Ok(true) }),
key!(Enter, NONE, "activate", "activate item at cursor", || { self.activate(); Ok(true) }),
key!(Char('a'), CONTROL, "scene_add", "add a new scene", || { self.scene_add(None)?; Ok(true) }),
key!(Char('t'), CONTROL, "track_add", "add a new track", || { self.track_add(None)?; Ok(true) }),
key!(Char('n'), NONE, "rename", "rename item at cursor", || { self.rename_selected(); Ok(true) }),
key!(Char('l'), NONE, "length", "set length of item at cursor", || { todo!(); Ok(true) }),
key!(Char('c'), NONE, "color", "set color of item at cursor", || { todo!(); Ok(true) })
].iter() {
if *code == event.code && modifiers.bits() == event.modifiers.bits() {
return command()
}
}
return Ok(None)
},
_ => Ok(None)
}
}
}

View file

@ -42,7 +42,7 @@ impl Render<Tui> for ArrangerRenameModal {
height: 3
};
to.fill_bg(bg_area, Nord::BG0);
Lozenge(Style::default().bold().white().dim()).draw(to.buffer, bg_area)?;
Lozenge(Style::default().bold().white().dim()).draw(to.with_rect(bg_area));
let label = match self.target {
ArrangerFocus::Mix => "Rename project:",
ArrangerFocus::Track(_) => "Rename track:",
@ -58,10 +58,10 @@ impl Render<Tui> for ArrangerRenameModal {
Ok(Some(area))
}
}
impl Handle<Tui> for TransportQuantize {
impl Handle<Tui> for ArrangerRenameModal {
fn handle (&mut self, from: &Tui) -> Perhaps<bool> {
match e {
AppEvent::Input(Event::Key(k)) => {
match from.event() {
TuiEvent::Input(Event::Key(k)) => {
match k.code {
KeyCode::Esc => {
self.exit();
@ -90,9 +90,9 @@ impl Handle<Tui> for TransportQuantize {
},
_ => {}
}
Ok(true)
Ok(Some(true))
},
_ => Ok(false),
_ => Ok(None),
}
}
}

View file

@ -3,7 +3,7 @@ use crate::*;
use super::Arranger;
/// Track management methods
impl<T, U> Arranger<T, U> {
impl<E: Engine> Arranger<E> {
pub fn track (&self) -> Option<&Sequencer> {
self.selected.track().map(|t|self.tracks.get(t)).flatten()
}

View file

@ -29,14 +29,14 @@ impl<'a> Render<Tui> for TrackNameColumn<'a> {
let offset = 0; // track scroll offset
for y in 0..area.height {
if y == 0 {
"Mixer".blit(to.buffer, area.x + 1, area.y + y, Some(DIM))?;
to.blit(&"Mixer", area.x + 1, area.y + y, Some(DIM))?;
} else if y % 2 == 0 {
let index = (y as usize - 2) / 2 + offset;
if let Some(track) = tracks.get(index) {
let selected = selected.track() == Some(index);
let style = if selected { yellow } else { white };
format!(" {index:>02} ").blit(to.buffer, area.x, area.y + y, style)?;
track.name.read().unwrap().blit(to.buffer, area.x + 4, area.y + y, style)?;
to.blit(&format!(" {index:>02} "), area.x, area.y + y, style)?;
to.blit(&*track.name.read().unwrap(), area.x + 4, area.y + y, style)?;
}
}
}
@ -60,7 +60,7 @@ impl<'a> Render<Tui> for TrackMonitorColumn<'a> {
let index = (y as usize - 2) / 2;
if let Some(track) = tracks.get(index) {
let style = if track.monitoring { on } else { off };
" MON ".blit(to.buffer, area.x, area.y + y, style)?;
to.blit(&" MON ", area.x, area.y + y, style)?;
} else {
area.height = y;
break
@ -88,7 +88,7 @@ impl<'a> Render<Tui> for TrackRecordColumn<'a> {
let index = (y as usize - 2) / 2;
if let Some(track) = tracks.get(index) {
let style = if track.recording { on } else { off };
" REC ".blit(to.buffer, area.x, area.y + y, style)?;
to.blit(&" REC ", area.x, area.y + y, style)?;
} else {
area.height = y;
break
@ -115,7 +115,7 @@ impl<'a> Render<Tui> for TrackOverdubColumn<'a> {
} else if y % 2 == 0 {
let index = (y as usize - 2) / 2;
if let Some(track) = tracks.get(index) {
" OVR ".blit(to.buffer, area.x, area.y + y, if track.overdub {
to.blit(&" OVR ", area.x, area.y + y, if track.overdub {
on
} else {
off
@ -203,7 +203,7 @@ impl<'a> Render<Tui> for TrackScenesColumn<'a> {
}
let name = scene.name.read().unwrap();
let mut x3 = name.len() as u16;
to.blit(&name, x + x2, y, sep)?;
to.blit(&*name, x + x2, y, sep)?;
for (i, clip) in scene.clips.iter().enumerate() {
let active_track = selected.track() == Some(i);
if let Some(clip) = clip {

View file

@ -33,7 +33,7 @@ pub fn draw <'a, 'b> (
cols: &'b [(usize, usize)],
rows: &'b [(usize, usize)],
) -> Perhaps<Rect> {
let mut area = to.area;
let mut area = to.area();
area.height = 2 + (rows[rows.len() - 1].1 / 96) as u16;
let offset = 3 + scene_name_max_len(state.scenes.as_ref()) as u16;
let tracks = state.tracks.as_ref();
@ -53,13 +53,13 @@ struct ColumnSeparators<'a>(u16, &'a [(usize, usize)]);
impl<'a> Render<Tui> for ColumnSeparators<'a> {
fn render (&self, to: &mut Tui) -> Perhaps<Rect> {
let area = to.area;
let area = to.area();
let Self(offset, cols) = self;
let style = Some(Style::default().fg(Nord::SEPARATOR));
for (_, x) in cols.iter() {
let x = offset + area.x + *x as u16 - 1;
for y in area.y..area.height+area.y {
"".blit(to.buffer, x, y, style)?;
to.blit(&"", x, y, style)?;
}
}
Ok(Some(area))
@ -70,15 +70,15 @@ struct RowSeparators<'a>(&'a [(usize, usize)]);
impl<'a> Render<Tui> for RowSeparators<'a> {
fn render (&self, to: &mut Tui) -> Perhaps<Rect> {
let mut area = to.area;
let area = to.area();
let Self(rows) = self;
for (_, y) in rows.iter() {
let y = area.y + (*y / 96) as u16 + 1;
if y >= to.buffer.area.height {
if y >= to.buffer().area.height {
break
}
for x in area.x..area.width+area.y-2 {
let cell = to.buffer.get_mut(x, y);
let cell = to.buffer().get_mut(x, y);
cell.modifier = Modifier::UNDERLINED;
cell.underline_color = Nord::SEPARATOR;
}
@ -93,7 +93,7 @@ struct CursorFocus<'a>(
impl<'a> Render<Tui> for CursorFocus<'a> {
fn render (&self, to: &mut Tui) -> Perhaps<Rect> {
let mut area = to.area;
let mut area = to.area();
let Self(selected, offset, cols, rows) = *self;
let get_track_area = |t: usize| Rect {
x: offset + area.x + cols[t].1 as u16 - 1,
@ -118,7 +118,7 @@ impl<'a> Render<Tui> for CursorFocus<'a> {
let mut clip_area: Option<Rect> = None;
let area = match selected {
ArrangerFocus::Mix => {
fill_bg(to.buffer, area, COLOR_BG0);
to.fill_bg(area, COLOR_BG0);
area
},
ArrangerFocus::Track(t) => {
@ -137,21 +137,21 @@ impl<'a> Render<Tui> for CursorFocus<'a> {
},
};
if let Some(Rect { x, y, width, height }) = track_area {
fill_fg(to.buffer, Rect { x, y, width: 1, height }, COLOR_BG5);
fill_fg(to.buffer, Rect { x: x + width, y, width: 1, height }, COLOR_BG5);
to.fill_fg(Rect { x, y, width: 1, height }, COLOR_BG5);
to.fill_fg(Rect { x: x + width, y, width: 1, height }, COLOR_BG5);
}
if let Some(Rect { y, height, .. }) = scene_area {
fill_ul(to.buffer, Rect { x: area.x, y: y - 1, width: area.width, height: 1 }, COLOR_BG5);
fill_ul(to.buffer, Rect { x: area.x, y: y + height - 1, width: area.width, height: 1 }, COLOR_BG5);
to.fill_ul(Rect { x: area.x, y: y - 1, width: area.width, height: 1 }, COLOR_BG5);
to.fill_ul(Rect { x: area.x, y: y + height - 1, width: area.width, height: 1 }, COLOR_BG5);
}
if let Some(clip_area) = clip_area {
fill_bg(to.buffer, clip_area, COLOR_BG0);
to.fill_bg(clip_area, COLOR_BG0);
} else if let Some(track_area) = track_area {
fill_bg(to.buffer, track_area, COLOR_BG0);
to.fill_bg(track_area, COLOR_BG0);
} else if let Some(scene_area) = scene_area {
fill_bg(to.buffer, scene_area, COLOR_BG0);
to.fill_bg(scene_area, COLOR_BG0);
}
Ok(area)
Ok(Some(area))
}
}
@ -159,7 +159,7 @@ struct TracksHeader<'a>(u16, &'a[(usize, usize)], &'a [Sequencer]);
impl<'a> Render<Tui> for TracksHeader<'a> {
fn render (&self, to: &mut Tui) -> Perhaps<Rect> {
let mut area = to.area;
let area = to.area();
let Self(offset, track_cols, tracks) = *self;
let Rect { y, width, .. } = area;
for (track, (w, x)) in tracks.iter().zip(track_cols) {
@ -168,8 +168,8 @@ impl<'a> Render<Tui> for TracksHeader<'a> {
break
}
let name = track.name.read().unwrap();
fill_bg(to.buffer, Rect { x: offset + x, y, width: *w as u16, height: 2 }, COLOR_BG1);
name.blit(to.buffer, offset + x + 1, y, Some(Style::default().white()))?;
to.fill_bg(Rect { x: offset + x, y, width: *w as u16, height: 2 }, COLOR_BG1);
to.blit(&*name, offset + x + 1, y, Some(Style::default().white()))?;
}
Ok(Some(Rect { x: area.x, y, width, height: 2 }))
}
@ -179,15 +179,15 @@ struct SceneRows<'a>(u16, &'a[(usize, usize)], &'a[(usize, usize)], &'a[Sequence
impl<'a> Render<Tui> for SceneRows<'a> {
fn render (&self, to: &mut Tui) -> Perhaps<Rect> {
let area = to.area;
let area = to.area();
let Self(offset, track_cols, scene_rows, tracks, scenes) = *self;
let black = Some(Style::default().fg(Nord::SEPARATOR));
let Rect { mut y, height, .. } = area;
let Rect { mut y, height: _height, .. } = area;
for (_, x) in track_cols.iter() {
let x = *x as u16;
if x > 0 {
for y in area.y-2..y-2 {
"".blit(to.buffer, x - 1, y, black)?;
to.blit(&"", x - 1, y, black)?;
}
}
}
@ -196,10 +196,8 @@ impl<'a> Render<Tui> for SceneRows<'a> {
//break
//}
let h = 1.max((pulses / 96) as u16);
SceneRow(tracks, scene, track_cols, offset).render(&mut TuiOutput {
buffer: to.buffer,
area: Rect { x: area.x, y, width: area.width, height: h, }
})?;
SceneRow(tracks, scene, track_cols, offset)
.render(to.with_area(area.x, y, area.width, h))?;
y = y + h
}
Ok(Some(area))
@ -210,29 +208,24 @@ struct SceneRow<'a>(&'a[Sequencer], &'a Scene, &'a[(usize, usize)], u16);
impl<'a> Render<Tui> for SceneRow<'a> {
fn render (&self, to: &mut Tui) -> Perhaps<Rect> {
let mut area = to.area();
let area = to.area();
let Self(tracks, scene, track_cols, offset) = self;
let Rect { x, y, width, .. } = area;
let playing = scene.is_playing(tracks);
(if playing { "" } else { " " }).blit(to.buffer(), x, y, None)?;
scene.name.read().unwrap().blit(to.buffer(), x + 1, y, Some(Style::default().white()))?;
to.blit(&if playing { "" } else { " " }, x, y, None)?;
to.blit(&*scene.name.read().unwrap(), x + 1, y, Some(Style::default().white()))?;
to.fill_bg(Rect { x: x, y, width: offset.saturating_sub(1), height: area.height }, COLOR_BG1);
for (track, (w, x)) in track_cols.iter().enumerate() {
let x = *x as u16 + offset;
if x > width {
break
}
if let (Some(track), Some(Some(clip))) = (
tracks.get(track), scene.clips.get(track)
) {
SceneClip(track, *clip).render(&mut TuiOutput {
buffer: to.buffer,
area: Rect { x, y, width: *w as u16, height: area.height, }
})?;
SceneClip(track, *clip).render(to.with_area(x, y, *w as u16, area.height))?;
}
}
Ok(Some(area))
}
}
@ -241,20 +234,20 @@ struct SceneClip<'a>(&'a Sequencer, usize);
impl<'a> Render<Tui> for SceneClip<'a> {
fn render (&self, to: &mut Tui) -> Perhaps<Rect> {
let area = to.area;
let area = to.area();
let Self(track, clip) = self;
let style = Some(Style::default().white());
if let Some(phrase) = track.phrases.get(*clip) {
let phrase = phrase.read().unwrap();
let name = phrase.name.read().unwrap();
format!("{clip:02} {name}").blit(to.buffer, area.x + 1, area.y, style)?;
fill_bg(to.buffer, area, if track.sequence == Some(*clip) {
to.blit(&format!("{clip:02} {name}"), area.x + 1, area.y, style)?;
to.fill_bg(area, if track.sequence == Some(*clip) {
Nord::PLAYING
} else {
COLOR_BG1
});
} else {
fill_bg(to.buffer, area, COLOR_BG0)
to.fill_bg(area, COLOR_BG0)
}
Ok(Some(area))
}

View file

@ -79,7 +79,7 @@ pub fn scene_ppqs (tracks: &[Sequencer], scenes: &[Scene]) -> Vec<(usize, usize)
scenes
}
impl<T, U> Arranger<T, U> {
impl<E: Engine> Arranger<E> {
pub fn scene (&self) -> Option<&Scene> {
self.selected.scene().map(|s|self.scenes.get(s)).flatten()
}

View file

@ -2,7 +2,7 @@ use crate::*;
impl Handle<Tui> for TransportQuantize {
fn handle (&mut self, from: &Tui) -> Perhaps<bool> {
handle_keymap(self, e, KEYMAP_SEQUENCER)
handle_keymap(self, &from.event(), KEYMAP_SEQUENCER)
}
}

View file

@ -11,19 +11,11 @@ impl Sequencer {
.add_ref(&SequenceRange)
.add_ref(&SequenceLoopRange)
.add_ref(&SequenceNoteRange)
.render(&mut TuiOutput {
buffer: to.buffer,
area: Rect {
x: area.x,
y: area.y,
height: area.height,
width: 10,
}
})?;
.render(to.with_area(area.x, area.y, area.height, 10))?;
area.x = area.x + 10;
area.width = area.width.saturating_sub(10);
area.height = area.height.min(66);
Lozenge(Style::default().fg(Nord::BG2)).draw(to.buffer, area)?;
Lozenge(Style::default().fg(Nord::BG2)).draw(to.with_rect(area))?;
area.x = area.x + 1;
area.width = area.width.saturating_sub(1);
Layered::new()
@ -32,10 +24,7 @@ impl Sequencer {
.add_ref(&SequenceNotes(&self))
.add_ref(&SequenceCursor(&self))
.add_ref(&SequenceZoom(&self))
.render(&mut TuiOutput {
buffer: to.buffer,
area: area
})?;
.render(to.with_rect(area))?;
Ok(())
}
@ -63,9 +52,9 @@ impl<'a> Render<Tui> for SequenceName<'a> {
fn render (&self, to: &mut Tui) -> Perhaps<Rect> {
let Rect { x, y, .. } = to.area();
let frame = Rect { x, y, width: 10, height: 4 };
Lozenge(Style::default().fg(Nord::BG2)).draw(to.buffer, frame)?;
"Name:".blit(to.buffer, x + 1, y + 1, STYLE_LABEL)?;
self.0.name.read().unwrap().blit(to.buffer, x + 1, y + 2, STYLE_VALUE)?;
Lozenge(Style::default().fg(Nord::BG2)).draw(to.with_rect(frame))?;
to.blit(&"Name:", x + 1, y + 1, STYLE_LABEL)?;
to.blit(&*self.0.name.read().unwrap(), x + 1, y + 2, STYLE_VALUE)?;
Ok(Some(frame))
}
}
@ -76,11 +65,11 @@ impl<'a> Render<Tui> for SequenceRange {
fn render (&self, to: &mut Tui) -> Perhaps<Rect> {
let Rect { x, y, .. } = to.area();
let frame = Rect { x, y, width: 10, height: 6 };
Lozenge(Style::default().fg(Nord::BG2)).draw(to.buffer, frame)?;
"Start: ".blit(to.buffer, x + 1, y + 1, STYLE_LABEL)?;
" 1.1.1".blit(to.buffer, x + 1, y + 2, STYLE_VALUE)?;
"End: ".blit(to.buffer, x + 1, y + 3, STYLE_LABEL)?;
" 2.1.1".blit(to.buffer, x + 1, y + 4, STYLE_VALUE)?;
Lozenge(Style::default().fg(Nord::BG2)).draw(to.with_rect(frame))?;
to.blit(&"Start: ", x + 1, y + 1, STYLE_LABEL)?;
to.blit(&" 1.1.1", x + 1, y + 2, STYLE_VALUE)?;
to.blit(&"End: ", x + 1, y + 3, STYLE_LABEL)?;
to.blit(&" 2.1.1", x + 1, y + 4, STYLE_VALUE)?;
Ok(Some(frame))
}
}
@ -91,12 +80,12 @@ impl<'a> Render<Tui> for SequenceLoopRange {
fn render (&self, to: &mut Tui) -> Perhaps<Rect> {
let Rect { x, y, .. } = to.area();
let range = Rect { x, y, width: 10, height: 7 };
Lozenge(Style::default().fg(Nord::BG2)).draw(to.buffer, range)?;
"Loop [ ]".blit(to.buffer, x + 1, y + 1, STYLE_LABEL)?;
"From: ".blit(to.buffer, x + 1, y + 2, STYLE_LABEL)?;
" 1.1.1".blit(to.buffer, x + 1, y + 3, STYLE_VALUE)?;
"Length: ".blit(to.buffer, x + 1, y + 4, STYLE_LABEL)?;
" 1.0.0".blit(to.buffer, x + 1, y + 5, STYLE_VALUE)?;
Lozenge(Style::default().fg(Nord::BG2)).draw(to.with_rect(range))?;
to.blit(&"Loop [ ]", x + 1, y + 1, STYLE_LABEL)?;
to.blit(&"From: ", x + 1, y + 2, STYLE_LABEL)?;
to.blit(&" 1.1.1", x + 1, y + 3, STYLE_VALUE)?;
to.blit(&"Length: ", x + 1, y + 4, STYLE_LABEL)?;
to.blit(&" 1.0.0", x + 1, y + 5, STYLE_VALUE)?;
Ok(Some(range))
}
}
@ -107,15 +96,15 @@ impl<'a> Render<Tui> for SequenceNoteRange {
fn render (&self, to: &mut Tui) -> Perhaps<Rect> {
let Rect { x, y, .. } = to.area();
let range = Rect { x, y, width: 10, height: 9 };
Lozenge(Style::default().fg(Nord::BG2)).draw(to.buffer, range)?;
"Notes: ".blit(to.buffer, x + 1, y + 1, STYLE_LABEL)?;
"C#0-C#9 ".blit(to.buffer, x + 1, y + 2, STYLE_VALUE)?;
"[ /2 ]".blit(to.buffer, x + 1, y + 3, STYLE_LABEL)?;
"[ x2 ]".blit(to.buffer, x + 1, y + 4, STYLE_LABEL)?;
"[ Rev ]".blit(to.buffer, x + 1, y + 5, STYLE_LABEL)?;
"[ Inv ]".blit(to.buffer, x + 1, y + 6, STYLE_LABEL)?;
"[ Dup ]".blit(to.buffer, x + 1, y + 7, STYLE_LABEL)?;
Ok(Some(to.area))
Lozenge(Style::default().fg(Nord::BG2)).draw(to.with_rect(range))?;
to.blit(&"Notes: ", x + 1, y + 1, STYLE_LABEL)?;
to.blit(&"C#0-C#9 ", x + 1, y + 2, STYLE_VALUE)?;
to.blit(&"[ /2 ]", x + 1, y + 3, STYLE_LABEL)?;
to.blit(&"[ x2 ]", x + 1, y + 4, STYLE_LABEL)?;
to.blit(&"[ Rev ]", x + 1, y + 5, STYLE_LABEL)?;
to.blit(&"[ Inv ]", x + 1, y + 6, STYLE_LABEL)?;
to.blit(&"[ Dup ]", x + 1, y + 7, STYLE_LABEL)?;
Ok(Some(to.area()))
}
}
@ -123,22 +112,23 @@ struct SequenceKeys<'a>(&'a Sequencer);
impl<'a> Render<Tui> for SequenceKeys<'a> {
fn render (&self, to: &mut Tui) -> Perhaps<Rect> {
if to.area.height < 2 {
return Ok(Some(to.area))
let area = to.area();
if area.height < 2 {
return Ok(Some(area))
}
let area = Rect {
x: to.area.x,
y: to.area.y + 1,
x: area.x,
y: area.y + 1,
width: 5,
height: to.area.height - 2
height: area.height - 2
};
buffer_update(to.buffer, area, &|cell, x, y|{
buffer_update(to.buffer(), area, &|cell, x, y|{
let y = y + self.0.note_axis.start as u16;
if x < self.0.keys.area.width && y < self.0.keys.area.height {
*cell = self.0.keys.get(x, y).clone()
}
});
Ok(Some(to.area))
Ok(Some(area))
}
}
@ -195,7 +185,7 @@ impl<'a> Render<Tui> for SequenceZoom<'a> {
let quant = ppq_to_name(self.0.time_axis.scale);
let quant_x = area.x + area.width - 1 - quant.len() as u16;
let quant_y = area.y + area.height - 2;
buffer.blit(&quant, quant_x, quant_y, self.0.style_focus())
to.blit(&quant, quant_x, quant_y, self.0.style_focus())
}
}

View file

@ -14,7 +14,7 @@ impl Handle<Tui> for TransportToolbar {
impl Handle<Tui> for TransportPlayPauseButton {
fn handle (&mut self, from: &Tui) -> Perhaps<bool> {
Ok(false)
Ok(None)
}
}
@ -26,7 +26,7 @@ impl Handle<Tui> for TransportBPM {
//TransportFocus::BPM => {
//transport.timebase.bpm.fetch_sub(1.0, Ordering::Relaxed);
//},
Ok(false)
Ok(None)
}
}
@ -38,7 +38,7 @@ impl Handle<Tui> for TransportQuantize {
//TransportFocus::Quant => {
//transport.quant.value = prev_note_length(transport.quant);
//},
Ok(false)
Ok(None)
}
}
@ -50,6 +50,7 @@ impl Handle<Tui> for TransportSync {
//TransportFocus::Sync => {
//transport.sync.value = prev_note_length(transport.sync);
//},
Ok(None)
}
}
@ -61,6 +62,6 @@ impl Handle<Tui> for TransportClock {
//TransportFocus::Sync => {
//transport.sync.value = prev_note_length(transport.sync);
//},
Ok(false)
Ok(None)
}
}

View file

@ -71,11 +71,12 @@ impl Render<Tui> for TransportBPM {
impl Render<Tui> for TransportQuantize {
fn render (&self, to: &mut Tui) -> Perhaps<Rect> {
let area = to.area();
let Rect { x, y, .. } = to.area;
let Rect { x, y, .. } = to.area();
let Self { value, focused } = self;
"QUANT".blit(to.buffer, x, y, Some(NOT_DIM))?;
let width = ppq_to_name(*value as usize).blit(to.buffer, x, y + 1, Some(NOT_DIM_BOLD))?.width;
to.blit(&"QUANT", x, y, Some(NOT_DIM))?;
let name = ppq_to_name(*value as usize);
let width = name.len() as u16;
to.blit(&name, x, y + 1, Some(NOT_DIM_BOLD))?;
let area = Rect { x, y, width: (width + 2).max(10), height: 2 };
if *focused {
let area = Rect { x: area.x - 1, width: area.width - 1, ..area };
@ -88,11 +89,12 @@ impl Render<Tui> for TransportQuantize {
impl Render<Tui> for TransportSync {
fn render (&self, to: &mut Tui) -> Perhaps<Rect> {
let area = to.area();
let Rect { x, y, .. } = to.area;
let Rect { x, y, .. } = to.area();
let Self { value, focused } = self;
"SYNC".blit(to.buffer, x, y, Some(NOT_DIM))?;
let width = ppq_to_name(*value as usize).blit(to.buffer, x, y + 1, Some(NOT_DIM_BOLD))?.width;
to.blit(&"SYNC", x, y, Some(NOT_DIM))?;
let name = ppq_to_name(*value as usize);
let width = name.len() as u16;
to.blit(&name, x, y + 1, Some(NOT_DIM_BOLD))?;
let area = Rect { x, y, width: (width + 2).max(10), height: 2 };
if *focused {
let area = Rect { x: area.x - 1, width: area.width - 1, ..area };
@ -106,7 +108,7 @@ impl Render<Tui> for TransportSync {
impl Render<Tui> for TransportClock {
fn render (&self, to: &mut Tui) -> Perhaps<Rect> {
let Rect { x, y, width, .. } = to.area();
let Self { frame, pulse, ppq, usecs, focused } = self;
let Self { frame: _frame, pulse, ppq, usecs, focused } = self;
let (beats, pulses) = if *ppq > 0 { (pulse / ppq, pulse % ppq) } else { (0, 0) };
let (bars, beats) = ((beats / 4) + 1, (beats % 4) + 1);
let (seconds, msecs) = (usecs / 1000000, usecs / 1000 % 1000);