diff --git a/crates/tek/src/core/color.rs b/crates/tek/src/core/color.rs index fd678201..a935c3fa 100644 --- a/crates/tek/src/core/color.rs +++ b/crates/tek/src/core/color.rs @@ -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 } } } diff --git a/crates/tek/src/midi/midi_note.rs b/crates/tek/src/midi/midi_note.rs index 71b90a45..8452d1fb 100644 --- a/crates/tek/src/midi/midi_note.rs +++ b/crates/tek/src/midi/midi_note.rs @@ -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 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)] diff --git a/crates/tek/src/tui/app_sampler.rs b/crates/tek/src/tui/app_sampler.rs index 049473fc..04fc9db1 100644 --- a/crates/tek/src/tui/app_sampler.rs +++ b/crates/tek/src/tui/app_sampler.rs @@ -21,7 +21,9 @@ pub struct SamplerTui { pub editing: Option>>, pub mode: Option, /// Size of actual notes area - pub size: Measure, + pub size: Measure, + /// Lowest note displayed + pub note_lo: AtomicUsize, } render!(|self: SamplerTui|{ @@ -41,8 +43,12 @@ render!(|self: SamplerTui|{ }); struct SamplerKeys<'a>(&'a SamplerTui); -render!(|self: SamplerKeys<'a>|render(|to|Ok(render_keys_v(to, self)))); has_color!(|self: SamplerKeys<'a>|ItemColor::default()); +render!(|self: SamplerKeys<'a>|render(|to|Ok(render_keys_v::(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(), diff --git a/crates/tek/src/tui/phrase_editor.rs b/crates/tek/src/tui/phrase_editor.rs index c8ed9c50..30f56684 100644 --- a/crates/tek/src/tui/phrase_editor.rs +++ b/crates/tek/src/tui/phrase_editor.rs @@ -127,14 +127,17 @@ pub trait PhraseViewMode: Render + HasSize + MidiRange + MidiPoint + D impl MidiView 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 { diff --git a/crates/tek/src/tui/piano_h.rs b/crates/tek/src/tui/piano_h.rs index 867210b9..58645814 100644 --- a/crates/tek/src/tui/piano_h.rs +++ b/crates/tek/src/tui/piano_h.rs @@ -130,14 +130,16 @@ impl PianoHorizontal { has_size!(|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()} diff --git a/crates/tek/src/tui/piano_h/piano_h_keys.rs b/crates/tek/src/tui/piano_h/piano_h_keys.rs index 1a80ece6..0fd34c09 100644 --- a/crates/tek/src/tui/piano_h/piano_h_keys.rs +++ b/crates/tek/src/tui/piano_h/piano_h_keys.rs @@ -2,10 +2,14 @@ use crate::*; use super::note_y_iter; pub struct PianoHorizontalKeys<'a>(pub(crate) &'a PianoHorizontal); -render!(|self: PianoHorizontalKeys<'a>|render(|to|Ok(render_keys_v(to, self)))); -has_color!(|self: PianoHorizontalKeys<'a>|self.0.color); +render!(|self: PianoHorizontalKeys<'a>|render(|to|Ok(render_keys_v::(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 (to: &mut E::Output, state: &T) { +pub fn render_keys_v (to: &mut E::Output, state: &T) { let color = state.color(); let note_lo = state.note_lo().get(); let note_hi = state.note_hi();