wip: split MidiRange to TimeRange/NoteRange

This commit is contained in:
🪞👃🪞 2024-12-27 17:07:51 +01:00
parent a9fb6fc17c
commit 8d79537edf
6 changed files with 40 additions and 18 deletions

View file

@ -10,7 +10,7 @@ pub trait HasColor {
#[macro_export] macro_rules! has_color {
(|$self:ident:$Struct:ident$(<$($L:lifetime),*$($T:ident$(:$U:path)?),*>)?|$cb:expr) => {
impl $(<$($L),*$($T $(: $U)?),*>)? HasColor for $Struct $(<$($L),*$($T),*>)? {
fn color (&$self) -> ItemColor { &$cb }
fn color (&$self) -> ItemColor { $cb }
fn color_mut (&mut $self) -> &mut ItemColor { &mut $cb }
}
}

View file

@ -81,29 +81,35 @@ from!(|data:(usize, bool)|MidiRangeModel = Self {
time_zoom: Arc::new(data.0.into()),
time_lock: Arc::new(data.1.into()),
});
pub trait MidiRange {
pub trait TimeRange {
fn time_len (&self) -> &AtomicUsize;
fn time_zoom (&self) -> &AtomicUsize;
fn time_lock (&self) -> &AtomicBool;
fn time_start (&self) -> &AtomicUsize;
fn note_lo (&self) -> &AtomicUsize;
fn note_axis (&self) -> &AtomicUsize;
fn time_axis (&self) -> &AtomicUsize;
fn note_hi (&self) -> usize {
(self.note_lo().get() + self.note_axis().get().saturating_sub(1)).min(127)
}
fn time_end (&self) -> usize {
self.time_start().get() + self.time_axis().get() * self.time_zoom().get()
}
}
impl MidiRange for MidiRangeModel {
pub trait NoteRange {
fn note_lo (&self) -> &AtomicUsize;
fn note_axis (&self) -> &AtomicUsize;
fn note_hi (&self) -> usize {
(self.note_lo().get() + self.note_axis().get().saturating_sub(1)).min(127)
}
}
pub trait MidiRange: TimeRange + NoteRange {}
impl<T: TimeRange + NoteRange> MidiRange for T {}
impl TimeRange for MidiRangeModel {
fn time_len (&self) -> &AtomicUsize { &self.time_len }
fn time_zoom (&self) -> &AtomicUsize { &self.time_zoom }
fn time_lock (&self) -> &AtomicBool { &self.time_lock }
fn time_start (&self) -> &AtomicUsize { &self.time_start }
fn time_axis (&self) -> &AtomicUsize { &self.time_axis }
}
impl NoteRange for MidiRangeModel {
fn note_lo (&self) -> &AtomicUsize { &self.note_lo }
fn note_axis (&self) -> &AtomicUsize { &self.note_axis }
fn time_axis (&self) -> &AtomicUsize { &self.time_axis }
}
#[derive(Debug, Clone)]

View file

@ -21,7 +21,9 @@ pub struct SamplerTui {
pub editing: Option<Arc<RwLock<Sample>>>,
pub mode: Option<SamplerMode>,
/// Size of actual notes area
pub size: Measure<Tui>,
pub size: Measure<Tui>,
/// Lowest note displayed
pub note_lo: AtomicUsize,
}
render!(<Tui>|self: SamplerTui|{
@ -41,8 +43,12 @@ render!(<Tui>|self: SamplerTui|{
});
struct SamplerKeys<'a>(&'a SamplerTui);
render!(<Tui>|self: SamplerKeys<'a>|render(|to|Ok(render_keys_v(to, self))));
has_color!(|self: SamplerKeys<'a>|ItemColor::default());
render!(<Tui>|self: SamplerKeys<'a>|render(|to|Ok(render_keys_v::<Tui, Self>(to, self))));
impl<'a> NoteRange for SamplerKeys<'a> {
fn note_lo (&self) -> &AtomicUsize { &self.0.note_lo }
fn note_axis (&self) -> &AtomicUsize { &self.0.size.y }
}
pub enum SamplerMode {
// Load sample from path
@ -59,6 +65,7 @@ from_jack!(|jack|SamplerTui{
editing: None,
mode: None,
size: Measure::new(),
note_lo: 36.into(),
state: Sampler {
jack: jack.clone(),
name: "Sampler".into(),

View file

@ -127,14 +127,17 @@ pub trait PhraseViewMode: Render<Tui> + HasSize<Tui> + MidiRange + MidiPoint + D
impl MidiView<Tui> for MidiEditorModel {}
impl MidiRange for MidiEditorModel {
impl TimeRange for MidiEditorModel {
fn time_len (&self) -> &AtomicUsize { self.mode.time_len() }
fn time_zoom (&self) -> &AtomicUsize { self.mode.time_zoom() }
fn time_lock (&self) -> &AtomicBool { self.mode.time_lock() }
fn time_start (&self) -> &AtomicUsize { self.mode.time_start() }
fn time_axis (&self) -> &AtomicUsize { self.mode.time_axis() }
}
impl NoteRange for MidiEditorModel {
fn note_lo (&self) -> &AtomicUsize { self.mode.note_lo() }
fn note_axis (&self) -> &AtomicUsize { self.mode.note_axis() }
fn time_axis (&self) -> &AtomicUsize { self.mode.time_axis() }
}
impl MidiPoint for MidiEditorModel {

View file

@ -130,14 +130,16 @@ impl PianoHorizontal {
has_size!(<Tui>|self:PianoHorizontal|&self.size);
impl MidiRange for PianoHorizontal {
impl TimeRange for PianoHorizontal {
fn time_len (&self) -> &AtomicUsize { self.range.time_len() }
fn time_zoom (&self) -> &AtomicUsize { self.range.time_zoom() }
fn time_lock (&self) -> &AtomicBool { self.range.time_lock() }
fn time_start (&self) -> &AtomicUsize { self.range.time_start() }
fn time_axis (&self) -> &AtomicUsize { self.range.time_axis() }
}
impl NoteRange for PianoHorizontal {
fn note_lo (&self) -> &AtomicUsize { self.range.note_lo() }
fn note_axis (&self) -> &AtomicUsize { self.range.note_axis() }
fn time_axis (&self) -> &AtomicUsize { self.range.time_axis() }
}
impl MidiPoint for PianoHorizontal {
fn note_len (&self) -> usize { self.point.note_len()}

View file

@ -2,10 +2,14 @@ use crate::*;
use super::note_y_iter;
pub struct PianoHorizontalKeys<'a>(pub(crate) &'a PianoHorizontal);
render!(<Tui>|self: PianoHorizontalKeys<'a>|render(|to|Ok(render_keys_v(to, self))));
has_color!(|self: PianoHorizontalKeys<'a>|self.0.color);
render!(<Tui>|self: PianoHorizontalKeys<'a>|render(|to|Ok(render_keys_v::<Tui, Self>(to, self))));
has_color!(|self: PianoHorizontalKeys<'a>|self.0.color.base);
impl<'a> NoteRange for PianoHorizontalKeys<'a> {
fn note_lo (&self) -> &AtomicUsize { &self.0.note_lo() }
fn note_axis (&self) -> &AtomicUsize { &self.0.note_axis() }
}
pub fn render_keys_v <E: Engine, T: HasColor + MidiRange> (to: &mut E::Output, state: &T) {
pub fn render_keys_v <E: Engine, T: HasColor + NoteRange> (to: &mut E::Output, state: &T) {
let color = state.color();
let note_lo = state.note_lo().get();
let note_hi = state.note_hi();