mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 11:46:41 +01:00
98 lines
3.1 KiB
Rust
98 lines
3.1 KiB
Rust
use crate::*;
|
|
use std::sync::atomic::Ordering;
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct MidiRangeModel {
|
|
pub time_len: Arc<AtomicUsize>,
|
|
/// Length of visible time axis
|
|
pub time_axis: Arc<AtomicUsize>,
|
|
/// Earliest time displayed
|
|
pub time_start: Arc<AtomicUsize>,
|
|
/// Time step
|
|
pub time_zoom: Arc<AtomicUsize>,
|
|
/// Auto rezoom to fit in time axis
|
|
pub time_lock: Arc<AtomicBool>,
|
|
/// Length of visible note axis
|
|
pub note_axis: Arc<AtomicUsize>,
|
|
// Lowest note displayed
|
|
pub note_lo: Arc<AtomicUsize>,
|
|
}
|
|
|
|
from!(|data:(usize, bool)|MidiRangeModel = Self {
|
|
time_len: Arc::new(0.into()),
|
|
note_axis: Arc::new(0.into()),
|
|
note_lo: Arc::new(0.into()),
|
|
time_axis: Arc::new(0.into()),
|
|
time_start: Arc::new(0.into()),
|
|
time_zoom: Arc::new(data.0.into()),
|
|
time_lock: Arc::new(data.1.into()),
|
|
});
|
|
|
|
pub trait TimeRange {
|
|
fn time_len (&self) -> &AtomicUsize;
|
|
fn get_time_len (&self) -> usize {
|
|
self.time_len().load(Ordering::Relaxed)
|
|
}
|
|
fn time_zoom (&self) -> &AtomicUsize;
|
|
fn get_time_zoom (&self) -> usize {
|
|
self.time_zoom().load(Ordering::Relaxed)
|
|
}
|
|
fn set_time_zoom (&self, value: usize) -> usize {
|
|
self.time_zoom().swap(value, Ordering::Relaxed)
|
|
}
|
|
fn time_lock (&self) -> &AtomicBool;
|
|
fn get_time_lock (&self) -> bool {
|
|
self.time_lock().load(Ordering::Relaxed)
|
|
}
|
|
fn set_time_lock (&self, value: bool) -> bool {
|
|
self.time_lock().swap(value, Ordering::Relaxed)
|
|
}
|
|
fn time_start (&self) -> &AtomicUsize;
|
|
fn get_time_start (&self) -> usize {
|
|
self.time_start().load(Ordering::Relaxed)
|
|
}
|
|
fn set_time_start (&self, value: usize) -> usize {
|
|
self.time_start().swap(value, Ordering::Relaxed)
|
|
}
|
|
fn time_axis (&self) -> &AtomicUsize;
|
|
fn get_time_axis (&self) -> usize {
|
|
self.time_axis().load(Ordering::Relaxed)
|
|
}
|
|
fn get_time_end (&self) -> usize {
|
|
self.time_start().get() + self.time_axis().get() * self.time_zoom().get()
|
|
}
|
|
}
|
|
|
|
pub trait NoteRange {
|
|
fn note_lo (&self) -> &AtomicUsize;
|
|
fn get_note_lo (&self) -> usize {
|
|
self.note_lo().load(Ordering::Relaxed)
|
|
}
|
|
fn set_note_lo (&self, x: usize) -> usize {
|
|
self.note_lo().swap(x, Ordering::Relaxed)
|
|
}
|
|
fn note_axis (&self) -> &AtomicUsize;
|
|
fn get_note_axis (&self) -> usize {
|
|
self.note_axis().load(Ordering::Relaxed)
|
|
}
|
|
fn get_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 }
|
|
}
|