mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 11:46:41 +01:00
rewrite and put in action MIDIViewport::autoscroll (does nothing)
This commit is contained in:
parent
9f97c44c84
commit
81cb532af3
5 changed files with 61 additions and 86 deletions
|
|
@ -1,6 +1,5 @@
|
|||
mod phrase; pub(crate) use phrase::*;
|
||||
mod jack; pub(crate) use self::jack::*;
|
||||
mod clip; pub(crate) use clip::*;
|
||||
mod phrase; pub(crate) use phrase::*;
|
||||
mod clock; pub(crate) use clock::*;
|
||||
mod note; pub(crate) use note::*;
|
||||
mod player; pub(crate) use player::*;
|
||||
|
|
|
|||
|
|
@ -1,20 +0,0 @@
|
|||
use crate::*;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum ArrangerClipCommand {
|
||||
Play,
|
||||
Get(usize, usize),
|
||||
Set(usize, usize, Option<Arc<RwLock<Phrase>>>),
|
||||
Edit(Option<Arc<RwLock<Phrase>>>),
|
||||
SetLoop(bool),
|
||||
RandomColor,
|
||||
}
|
||||
|
||||
//impl<T: ArrangerApi> Command<T> for ArrangerClipCommand {
|
||||
//fn execute (self, state: &mut T) -> Perhaps<Self> {
|
||||
//match self {
|
||||
//_ => todo!()
|
||||
//}
|
||||
//Ok(None)
|
||||
//}
|
||||
//}
|
||||
|
|
@ -1,6 +1,24 @@
|
|||
use crate::*;
|
||||
use Ordering::Relaxed;
|
||||
|
||||
pub trait MIDIViewport<E: Engine>: MIDIRange + MIDIPoint + HasSize<E> {
|
||||
/// Make sure cursor is within range
|
||||
fn autoscroll (&self) {
|
||||
let note_lo = self.note_lo();
|
||||
let note_axis = self.note_axis();
|
||||
let note_hi = (note_lo + note_axis).min(127);
|
||||
let note_point = self.note_point().min(127);
|
||||
if note_point < note_lo {
|
||||
self.set_note_lo(note_point);
|
||||
} else if note_point > note_hi {
|
||||
self.set_note_lo(note_lo + note_point - note_hi);
|
||||
}
|
||||
}
|
||||
/// Make sure best usage of screen space is achieved by default
|
||||
fn autozoom (&self) {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct MIDIRangeModel {
|
||||
/// Length of visible time axis
|
||||
|
|
@ -16,7 +34,6 @@ pub struct MIDIRangeModel {
|
|||
// Lowest note displayed
|
||||
pub note_lo: Arc<AtomicUsize>,
|
||||
}
|
||||
|
||||
impl From<(usize, bool)> for MIDIRangeModel {
|
||||
fn from ((time_zoom, time_lock): (usize, bool)) -> Self {
|
||||
Self {
|
||||
|
|
@ -29,6 +46,29 @@ impl From<(usize, bool)> for MIDIRangeModel {
|
|||
}
|
||||
}
|
||||
}
|
||||
pub trait MIDIRange {
|
||||
fn time_zoom (&self) -> usize;
|
||||
fn set_time_zoom (&self, x: usize);
|
||||
fn time_lock (&self) -> bool;
|
||||
fn set_time_lock (&self, x: bool);
|
||||
fn time_start (&self) -> usize;
|
||||
fn set_time_start (&self, x: usize);
|
||||
fn note_lo (&self) -> usize;
|
||||
fn set_note_lo (&self, x: usize);
|
||||
fn note_axis (&self) -> usize;
|
||||
fn note_hi (&self) -> usize { self.note_lo() + self.note_axis() }
|
||||
}
|
||||
impl MIDIRange for MIDIRangeModel {
|
||||
fn time_zoom (&self) -> usize { self.time_zoom.load(Relaxed) }
|
||||
fn set_time_zoom (&self, x: usize) { self.time_zoom.store(x, Relaxed); }
|
||||
fn time_lock (&self) -> bool { self.time_lock.load(Relaxed) }
|
||||
fn set_time_lock (&self, x: bool) { self.time_lock.store(x, Relaxed); }
|
||||
fn time_start (&self) -> usize { self.time_start.load(Relaxed) }
|
||||
fn set_time_start (&self, x: usize) { self.time_start.store(x, Relaxed); }
|
||||
fn note_lo (&self) -> usize { self.note_lo.load(Relaxed) }
|
||||
fn set_note_lo (&self, x: usize) { self.note_lo.store(x, Relaxed); }
|
||||
fn note_axis (&self) -> usize { self.note_axis.load(Relaxed) }
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct MIDIPointModel {
|
||||
|
|
@ -39,7 +79,6 @@ pub struct MIDIPointModel {
|
|||
/// Length of note that will be inserted, in pulses
|
||||
pub note_len: Arc<AtomicUsize>,
|
||||
}
|
||||
|
||||
impl Default for MIDIPointModel {
|
||||
fn default () -> Self {
|
||||
Self {
|
||||
|
|
@ -49,76 +88,15 @@ impl Default for MIDIPointModel {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait MIDIRange {
|
||||
fn time_zoom (&self) -> usize;
|
||||
fn set_time_zoom (&self, x: usize);
|
||||
|
||||
fn time_lock (&self) -> bool;
|
||||
fn set_time_lock (&self, x: bool);
|
||||
|
||||
fn time_start (&self) -> usize;
|
||||
fn set_time_start (&self, x: usize);
|
||||
|
||||
fn note_lo (&self) -> usize;
|
||||
fn set_note_lo (&self, x: usize);
|
||||
|
||||
fn note_axis (&self) -> usize;
|
||||
|
||||
fn note_hi (&self) -> usize { self.note_lo() + self.note_axis() }
|
||||
}
|
||||
|
||||
pub trait MIDIPoint {
|
||||
fn note_len (&self) -> usize;
|
||||
fn set_note_len (&self, x: usize);
|
||||
|
||||
fn note_point (&self) -> usize;
|
||||
fn set_note_point (&self, x: usize);
|
||||
|
||||
fn time_point (&self) -> usize;
|
||||
fn set_time_point (&self, x: usize);
|
||||
|
||||
fn note_end (&self) -> usize { self.note_point() + self.note_len() }
|
||||
}
|
||||
|
||||
pub trait MIDIViewport<E: Engine>: MIDIRange + MIDIPoint + HasSize<E> {
|
||||
/// Make sure cursor is within range
|
||||
fn autoscroll (&self) {
|
||||
let note = self.note_point();
|
||||
let height = self.size().h();
|
||||
if note < self.note_lo() {
|
||||
self.set_note_lo(note)
|
||||
}
|
||||
let note_point = self.note_point();
|
||||
let mut note_lo = self.note_lo();
|
||||
let mut note_hi = 127.min((note_lo + height).saturating_sub(2));
|
||||
if note_point > note_hi {
|
||||
note_lo += note_point - note_hi;
|
||||
note_hi = note_point;
|
||||
self.set_note_lo(note_lo);
|
||||
}
|
||||
//(note_point, (note_lo, note_hi))
|
||||
}
|
||||
/// Make sure best usage of screen space is achieved by default
|
||||
fn autozoom (&self) {
|
||||
}
|
||||
}
|
||||
|
||||
impl MIDIRange for MIDIRangeModel {
|
||||
fn time_zoom (&self) -> usize { self.time_zoom.load(Relaxed) }
|
||||
fn set_time_zoom (&self, x: usize) { self.time_zoom.store(x, Relaxed); }
|
||||
|
||||
fn time_lock (&self) -> bool { self.time_lock.load(Relaxed) }
|
||||
fn set_time_lock (&self, x: bool) { self.time_lock.store(x, Relaxed); }
|
||||
|
||||
fn time_start (&self) -> usize { self.time_start.load(Relaxed) }
|
||||
fn set_time_start (&self, x: usize) { self.time_start.store(x, Relaxed); }
|
||||
|
||||
fn note_lo (&self) -> usize { self.note_lo.load(Relaxed) }
|
||||
fn set_note_lo (&self, x: usize) { self.note_lo.store(x, Relaxed); }
|
||||
|
||||
fn note_axis (&self) -> usize { self.note_axis.load(Relaxed) }
|
||||
}
|
||||
impl MIDIPoint for MIDIPointModel {
|
||||
fn note_len (&self) -> usize { self.note_len.load(Relaxed)}
|
||||
fn set_note_len (&self, x: usize) { self.note_len.store(x, Relaxed) }
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
use crate::*;
|
||||
use crate::api::ArrangerTrackCommand;
|
||||
use crate::api::ArrangerSceneCommand;
|
||||
use crate::api::ArrangerClipCommand;
|
||||
|
||||
impl TryFrom<&Arc<RwLock<JackClient>>> for ArrangerTui {
|
||||
type Error = Box<dyn std::error::Error>;
|
||||
|
|
@ -1302,3 +1301,22 @@ impl ArrangerSelection {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum ArrangerClipCommand {
|
||||
Play,
|
||||
Get(usize, usize),
|
||||
Set(usize, usize, Option<Arc<RwLock<Phrase>>>),
|
||||
Edit(Option<Arc<RwLock<Phrase>>>),
|
||||
SetLoop(bool),
|
||||
RandomColor,
|
||||
}
|
||||
|
||||
//impl<T: ArrangerApi> Command<T> for ArrangerClipCommand {
|
||||
//fn execute (self, state: &mut T) -> Perhaps<Self> {
|
||||
//match self {
|
||||
//_ => todo!()
|
||||
//}
|
||||
//Ok(None)
|
||||
//}
|
||||
//}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue