mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 19:56:42 +01:00
fold in Notes and Cursor into PianoHorizontal
This commit is contained in:
parent
2401dc8fcd
commit
709391ff0a
4 changed files with 68 additions and 77 deletions
|
|
@ -12,11 +12,9 @@ mod midi_view; pub use midi_view::*;
|
||||||
mod midi_editor; pub use midi_editor::*;
|
mod midi_editor; pub use midi_editor::*;
|
||||||
mod midi_select; pub use midi_select::*;
|
mod midi_select; pub use midi_select::*;
|
||||||
|
|
||||||
mod piano_h; pub use self::piano_h::*;
|
mod piano_h; pub use self::piano_h::*;
|
||||||
mod piano_h_cursor; pub use self::piano_h_cursor::*;
|
mod piano_h_keys; pub use self::piano_h_keys::*;
|
||||||
mod piano_h_keys; pub use self::piano_h_keys::*;
|
mod piano_h_time; pub use self::piano_h_time::*;
|
||||||
mod piano_h_notes; pub use self::piano_h_notes::*;
|
|
||||||
mod piano_h_time; pub use self::piano_h_time::*;
|
|
||||||
|
|
||||||
pub(crate) use ::tek_time::*;
|
pub(crate) use ::tek_time::*;
|
||||||
pub(crate) use ::tek_jack::{*, jack::*};
|
pub(crate) use ::tek_jack::{*, jack::*};
|
||||||
|
|
|
||||||
|
|
@ -10,10 +10,7 @@ render!(TuiOut: (self: PianoHorizontal) => Bsp::s( // the freeze is in the piano
|
||||||
)),
|
)),
|
||||||
Fill::xy(Bsp::e(
|
Fill::xy(Bsp::e(
|
||||||
Fixed::x(self.keys_width, PianoHorizontalKeys(self)),
|
Fixed::x(self.keys_width, PianoHorizontalKeys(self)),
|
||||||
Fill::xy(self.size.of(lay!(
|
Fill::xy(self.size.of(lay!(self.notes(), self.cursor()))),
|
||||||
Fill::xy(PianoHorizontalNotes(self)),
|
|
||||||
Fill::xy(PianoHorizontalCursor(self)),
|
|
||||||
))),
|
|
||||||
)),
|
)),
|
||||||
));
|
));
|
||||||
impl PianoHorizontal {
|
impl PianoHorizontal {
|
||||||
|
|
@ -76,6 +73,70 @@ impl PianoHorizontal {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fn notes (&self) -> impl Content<TuiOut> {
|
||||||
|
let time_start = self.time_start().get();
|
||||||
|
let note_axis = self.note_axis().get();
|
||||||
|
let note_lo = self.note_lo().get();
|
||||||
|
let note_hi = self.note_hi();
|
||||||
|
let note_point = self.note_point();
|
||||||
|
let buffer = self.buffer.clone();
|
||||||
|
RenderThunk::new(move|render: &mut TuiOut|{
|
||||||
|
let source = buffer.read().unwrap();
|
||||||
|
let [x0, y0, w, h] = render.area().xywh();
|
||||||
|
if h as usize != note_axis {
|
||||||
|
panic!("area height mismatch: {h} <> {note_axis}");
|
||||||
|
}
|
||||||
|
for (area_x, screen_x) in (x0..x0+w).enumerate() {
|
||||||
|
for (area_y, screen_y, note) in note_y_iter(note_lo, note_hi, y0) {
|
||||||
|
let source_x = time_start + area_x;
|
||||||
|
let source_y = note_hi - area_y;
|
||||||
|
// TODO: enable loop rollover:
|
||||||
|
//let source_x = (time_start + area_x) % source.width.max(1);
|
||||||
|
//let source_y = (note_hi - area_y) % source.height.max(1);
|
||||||
|
let is_in_x = source_x < source.width;
|
||||||
|
let is_in_y = source_y < source.height;
|
||||||
|
if is_in_x && is_in_y {
|
||||||
|
if let Some(source_cell) = source.get(source_x, source_y) {
|
||||||
|
if let Some(cell) = render.buffer.cell_mut(ratatui::prelude::Position::from((screen_x, screen_y))) {
|
||||||
|
*cell = source_cell.clone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
fn cursor (&self) -> impl Content<TuiOut> {
|
||||||
|
let style = Some(Style::default().fg(self.color.lightest.rgb));
|
||||||
|
let note_hi = self.note_hi();
|
||||||
|
let note_len = self.note_len();
|
||||||
|
let note_lo = self.note_lo().get();
|
||||||
|
let note_point = self.note_point();
|
||||||
|
let time_point = self.time_point();
|
||||||
|
let time_start = self.time_start().get();
|
||||||
|
let time_zoom = self.time_zoom().get();
|
||||||
|
RenderThunk::new(move|render: &mut TuiOut|{
|
||||||
|
let [x0, y0, w, _] = render.area().xywh();
|
||||||
|
for (_area_y, screen_y, note) in note_y_iter(note_lo, note_hi, y0) {
|
||||||
|
if note == note_point {
|
||||||
|
for x in 0..w {
|
||||||
|
let screen_x = x0 + x;
|
||||||
|
let time_1 = time_start + x as usize * time_zoom;
|
||||||
|
let time_2 = time_1 + time_zoom;
|
||||||
|
if time_1 <= time_point && time_point < time_2 {
|
||||||
|
render.blit(&"█", screen_x, screen_y, style);
|
||||||
|
let tail = note_len as u16 / time_zoom as u16;
|
||||||
|
for x_tail in (screen_x + 1)..(screen_x + tail) {
|
||||||
|
render.blit(&"▂", x_tail, screen_y, style);
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
has_size!(<TuiOut>|self:PianoHorizontal|&self.size);
|
has_size!(<TuiOut>|self:PianoHorizontal|&self.size);
|
||||||
|
|
|
||||||
|
|
@ -1,33 +0,0 @@
|
||||||
use crate::*;
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
pub struct PianoHorizontalCursor<'a>(pub(crate) &'a PianoHorizontal);
|
|
||||||
render!(TuiOut: |self: PianoHorizontalCursor<'a>, render|{
|
|
||||||
let style = Some(Style::default().fg(self.0.color.lightest.rgb));
|
|
||||||
let note_hi = self.0.note_hi();
|
|
||||||
let note_len = self.0.note_len();
|
|
||||||
let note_lo = self.0.note_lo().get();
|
|
||||||
let note_point = self.0.note_point();
|
|
||||||
let time_point = self.0.time_point();
|
|
||||||
let time_start = self.0.time_start().get();
|
|
||||||
let time_zoom = self.0.time_zoom().get();
|
|
||||||
let [x0, y0, w, _] = render.area().xywh();
|
|
||||||
for (area_y, screen_y, note) in note_y_iter(note_lo, note_hi, y0) {
|
|
||||||
if note == note_point {
|
|
||||||
for x in 0..w {
|
|
||||||
let screen_x = x0 + x;
|
|
||||||
let time_1 = time_start + x as usize * time_zoom;
|
|
||||||
let time_2 = time_1 + time_zoom;
|
|
||||||
if time_1 <= time_point && time_point < time_2 {
|
|
||||||
render.blit(&"█", screen_x, screen_y, style);
|
|
||||||
let tail = note_len as u16 / time_zoom as u16;
|
|
||||||
for x_tail in (screen_x + 1)..(screen_x + tail) {
|
|
||||||
render.blit(&"▂", x_tail, screen_y, style);
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
use crate::*;
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
pub struct PianoHorizontalNotes<'a>(pub(crate) &'a PianoHorizontal);
|
|
||||||
|
|
||||||
render!(TuiOut: |self: PianoHorizontalNotes<'a>, render|{
|
|
||||||
let time_start = self.0.time_start().get();
|
|
||||||
let note_axis = self.0.note_axis().get();
|
|
||||||
let note_lo = self.0.note_lo().get();
|
|
||||||
let note_hi = self.0.note_hi();
|
|
||||||
let note_point = self.0.note_point();
|
|
||||||
let source = self.0.buffer.read().unwrap();
|
|
||||||
let [x0, y0, w, h] = render.area().xywh();
|
|
||||||
if h as usize != note_axis {
|
|
||||||
panic!("area height mismatch: {h} <> {note_axis}");
|
|
||||||
}
|
|
||||||
for (area_x, screen_x) in (x0..x0+w).enumerate() {
|
|
||||||
for (area_y, screen_y, note) in note_y_iter(note_lo, note_hi, y0) {
|
|
||||||
let source_x = time_start + area_x;
|
|
||||||
let source_y = note_hi - area_y;
|
|
||||||
// TODO: enable loop rollover:
|
|
||||||
//let source_x = (time_start + area_x) % source.width.max(1);
|
|
||||||
//let source_y = (note_hi - area_y) % source.height.max(1);
|
|
||||||
let is_in_x = source_x < source.width;
|
|
||||||
let is_in_y = source_y < source.height;
|
|
||||||
if is_in_x && is_in_y {
|
|
||||||
if let Some(source_cell) = source.get(source_x, source_y) {
|
|
||||||
if let Some(cell) = render.buffer.cell_mut(ratatui::prelude::Position::from((screen_x, screen_y))) {
|
|
||||||
*cell = source_cell.clone();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue