mirror of
https://codeberg.org/unspeaker/tek.git
synced 2026-10-08 18:56:42 +02:00
This commit is contained in:
parent
186b81f29c
commit
ca774cca41
21 changed files with 2160 additions and 2191 deletions
554
src/tek_ctrl.rs
554
src/tek_ctrl.rs
|
|
@ -5,7 +5,7 @@ impl_from!(AppCmd: |x: BrowseCmd| AppCmd::Browse { command: x });
|
|||
impl_from!(AppCmd: |x: MidiClipCmd| AppCmd::MidiClip { command: x });
|
||||
impl_from!(AppCmd: |x: MidiEditCmd| AppCmd::MidiEdit { command: x });
|
||||
impl_from!(AppCmd: |x: ModeCmd| AppCmd::Mode { command: x });
|
||||
impl_from!(AppCmd: |x: PoolCmd| AppCmd::Pool { command: x });
|
||||
//impl_from!(AppCmd: |x: PoolCmd| AppCmd::Pool { command: x });
|
||||
impl_from!(AppCmd: |x: ProjectCmd| AppCmd::Project { command: x });
|
||||
impl_from!(AppCmd: |x: SceneCmd| AppCmd::Scene { command: x });
|
||||
impl_from!(AppCmd: |x: ScenesCmd| AppCmd::Scenes { command: x });
|
||||
|
|
@ -62,9 +62,9 @@ impl_from!(AppCmd: |x: TracksCmd| AppCmd::Tracks { command: x });
|
|||
#[command(MidiEdit = "edit")] pub fn cmd_midi_edit (&mut self, command: MidiEditCmd) -> Perhaps<AppCmd> {
|
||||
Ok(command.dispatch(self)?.map(Into::into))
|
||||
}
|
||||
#[command(Pool = "pool")] pub fn cmd_pool (&mut self, command: PoolCmd) -> Perhaps<AppCmd> {
|
||||
Ok(command.dispatch(self)?.map(Into::into))
|
||||
}
|
||||
//#[command(Pool = "pool")] pub fn cmd_pool (&mut self, command: PoolCmd) -> Perhaps<AppCmd> {
|
||||
//Ok(command.dispatch(self)?.map(Into::into))
|
||||
//}
|
||||
#[command(Scene = "scene")] pub fn cmd_scene (&mut self, command: SceneCmd) -> Perhaps<AppCmd> {
|
||||
Ok(command.dispatch(self)?.map(Into::into))
|
||||
}
|
||||
|
|
@ -90,12 +90,11 @@ impl<T: HasProject> ProjectControl for T {}
|
|||
}
|
||||
}
|
||||
|
||||
impl<T: HasClock + Namespace<u32> + Namespace<f64> + Namespace<Option<u32>>> ClockControl for T {}
|
||||
|
||||
impl<T> ClockControl for T where T: HasClock
|
||||
+ Namespace<u32> + Namespace<f64> + Namespace<Option<u32>>
|
||||
{}
|
||||
#[tek_proc::commands(ClockCmd = "clock")] pub trait ClockControl: HasClock
|
||||
+ Namespace<u32>
|
||||
+ Namespace<f64>
|
||||
+ Namespace<Option<u32>>
|
||||
+ Namespace<u32> + Namespace<f64> + Namespace<Option<u32>>
|
||||
{
|
||||
#[command(SeekUsec = "usec")] fn seek_usec (&mut self, usec: f64) -> Perhaps<ClockCmd> {
|
||||
self.clock().playhead.update_from_usec(usec);
|
||||
|
|
@ -153,7 +152,7 @@ impl<T: HasTracks
|
|||
+ Namespace<Option<Arc<str>>>
|
||||
+ Namespace<Option<ItemTheme>>
|
||||
+ Namespace<Option<Arc<[Connect]>>>
|
||||
+ Namespace<Option<Vec<Option<Arc<RwLock<MidiClip>>>>>>
|
||||
+ Namespace<ClipPool>
|
||||
> TracksControl for T {}
|
||||
|
||||
#[tek_proc::commands(TracksCmd)] pub trait TracksControl: HasTracks
|
||||
|
|
@ -166,7 +165,7 @@ impl<T: HasTracks
|
|||
+ Namespace<Option<Arc<str>>>
|
||||
+ Namespace<Option<ItemTheme>>
|
||||
+ Namespace<Option<Arc<[Connect]>>>
|
||||
+ Namespace<Option<Vec<Option<Arc<RwLock<MidiClip>>>>>>
|
||||
+ Namespace<ClipPool>
|
||||
{
|
||||
/// Stop all playing clips
|
||||
#[command(Stop = "stop")] fn tracks_stop_all (&mut self) -> Perhaps<TracksCmd> {
|
||||
|
|
@ -176,12 +175,12 @@ impl<T: HasTracks
|
|||
Ok(None)
|
||||
}
|
||||
/// Launch multiple clips
|
||||
#[command(Launch = "launch")] fn tracks_launch (
|
||||
&mut self, clips: Option<Vec<Option<Arc<RwLock<MidiClip>>>>>
|
||||
) -> Perhaps<TracksCmd> {
|
||||
#[command(Launch = "launch")] fn tracks_launch (&mut self, clips: Option<ClipPool>)
|
||||
-> Perhaps<TracksCmd>
|
||||
{
|
||||
if let Some(clips) = clips {
|
||||
for (clip, track) in clips.iter().zip(self.tracks_mut()) {
|
||||
track.sequencer.enqueue_next(clip.as_ref());
|
||||
for (clip, track) in clips.0.read().iter().zip(self.tracks_mut()) {
|
||||
track.sequencer.enqueue_next(clip);
|
||||
}
|
||||
} else {
|
||||
for track in self.tracks_mut().iter_mut() {
|
||||
|
|
@ -322,15 +321,11 @@ impl<T: HasScenes
|
|||
}
|
||||
|
||||
impl<T: HasScene
|
||||
+ Namespace<usize>
|
||||
+ Namespace<Arc<str>>
|
||||
+ Namespace<ItemTheme>
|
||||
+ Namespace<usize> + Namespace<Arc<str>> + Namespace<ItemTheme>
|
||||
> SceneControl for T {}
|
||||
|
||||
#[tek_proc::commands(SceneCmd)] pub trait SceneControl: HasScene
|
||||
+ Namespace<usize>
|
||||
+ Namespace<Arc<str>>
|
||||
+ Namespace<ItemTheme>
|
||||
+ Namespace<usize> + Namespace<Arc<str>> + Namespace<ItemTheme>
|
||||
{
|
||||
#[command(SetSize = "size")] fn scene_set_size (&mut self, _size: usize) -> Perhaps<SceneCmd> {
|
||||
todo!()
|
||||
|
|
@ -357,23 +352,20 @@ impl<T: HasScene
|
|||
#[tek_proc::commands(SamplerCmd = "sampler")] pub trait SamplerControl: HasSampler
|
||||
+ Namespace<usize>
|
||||
{
|
||||
|
||||
#[command(RecordToggle = "rec-toggle")]
|
||||
fn record_toggle (&mut self, slot: usize) -> Perhaps<SamplerCmd>
|
||||
#[command(RecToggle = "rec-toggle")] fn record_toggle (&mut self, slot: usize) -> Perhaps<SamplerCmd>
|
||||
where Self: Sized
|
||||
{
|
||||
let sampler = self.sampler_mut();
|
||||
let recording = sampler.recording.as_ref().map(|x|x.0);
|
||||
let _ = SamplerCmd::RecordFinish.dispatch(self)?;
|
||||
let _ = SamplerCmd::RecFinish.dispatch(self)?;
|
||||
// autoslice: continue recording at next slot
|
||||
if recording != Some(slot) {
|
||||
SamplerCmd::RecordBegin { slot }.dispatch(self)
|
||||
SamplerCmd::RecBegin { slot }.dispatch(self)
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
#[command(RecordBegin = "rec-begin")] fn record_begin (&mut self, slot: usize) -> Perhaps<SamplerCmd> {
|
||||
#[command(RecBegin = "rec-begin")] fn record_begin (&mut self, slot: usize) -> Perhaps<SamplerCmd> {
|
||||
let sampler = self.sampler_mut();
|
||||
sampler.recording = Some((
|
||||
slot,
|
||||
|
|
@ -383,7 +375,7 @@ impl<T: HasScene
|
|||
));
|
||||
Ok(None)
|
||||
}
|
||||
#[command(RecordFinish = "rec-finish")] fn record_finish (&mut self) -> Perhaps<SamplerCmd> {
|
||||
#[command(RecFinish = "rec-finish")] fn record_finish (&mut self) -> Perhaps<SamplerCmd> {
|
||||
let sampler = self.sampler_mut();
|
||||
let _prev_sample = sampler.recording.as_mut().map(|(index, sample)|{
|
||||
std::mem::swap(sample, &mut sampler.samples.0[*index]);
|
||||
|
|
@ -391,14 +383,14 @@ impl<T: HasScene
|
|||
}); // TODO: undo
|
||||
Ok(None)
|
||||
}
|
||||
#[command(RecordCancel = "rec-cancel")] fn record_cancel (&mut self) -> Perhaps<SamplerCmd> {
|
||||
#[command(RecCancel = "rec-cancel")] fn record_cancel (&mut self) -> Perhaps<SamplerCmd> {
|
||||
self.sampler_mut().recording = None;
|
||||
Ok(None)
|
||||
}
|
||||
#[command(PlaySample = "sample-play")] fn sample_play (&mut self, slot: usize) -> Perhaps<SamplerCmd> {
|
||||
let sampler = self.sampler_mut();
|
||||
if let Some(ref sample) = sampler.samples.0[slot] {
|
||||
sampler.voices.try_write().unwrap().push(Sample::play(sample, 0, &u7::from(128)));
|
||||
sampler.voices.write().push(Sample::play(sample, 0, &u7::from(128)));
|
||||
}
|
||||
Ok(None)
|
||||
}
|
||||
|
|
@ -414,7 +406,7 @@ impl<T: HasEditor
|
|||
+ Namespace<bool>
|
||||
+ Namespace<usize>
|
||||
+ Namespace<Option<u32>>
|
||||
+ Namespace<Option<Arc<RwLock<MidiClip>>>>
|
||||
+ Namespace<ClipSlot>
|
||||
> MidiEditControl for T {}
|
||||
|
||||
#[tek_proc::commands(MidiEditCmd)] pub trait MidiEditControl: HasEditor
|
||||
|
|
@ -423,7 +415,7 @@ impl<T: HasEditor
|
|||
+ Namespace<bool>
|
||||
+ Namespace<usize>
|
||||
+ Namespace<Option<u32>>
|
||||
+ Namespace<Option<Arc<RwLock<MidiClip>>>>
|
||||
+ Namespace<ClipSlot>
|
||||
{
|
||||
#[command(Toggle = "toggle")] fn edit_toggle (&mut self) -> Perhaps<MidiEditCmd> {
|
||||
if self.is_editing() {
|
||||
|
|
@ -433,9 +425,9 @@ impl<T: HasEditor
|
|||
}
|
||||
Ok(Some(MidiEditCmd::Toggle))
|
||||
}
|
||||
#[command(Show = "show")] fn edit_show (&mut self, clip: Option<Arc<RwLock<MidiClip>>>) -> Perhaps<MidiEditCmd> {
|
||||
Ok(self.editor_mut().as_mut().map(|mut editor|{
|
||||
editor.set_clip(clip.as_ref());
|
||||
#[command(Show = "show")] fn edit_show (&mut self, clip: ClipSlot) -> Perhaps<MidiEditCmd> {
|
||||
Ok(self.editor_mut().as_mut().map(|editor|{
|
||||
editor.mode.clip.0 = clip.0;
|
||||
editor.redraw();
|
||||
None
|
||||
}).flatten())
|
||||
|
|
@ -447,7 +439,7 @@ impl<T: HasEditor
|
|||
}).flatten())
|
||||
}
|
||||
#[command(AppendNote = "append")] fn edit_note_append (&mut self, advance: bool) -> Perhaps<MidiEditCmd> {
|
||||
Ok(self.editor_mut().as_mut().map(|mut editor|{
|
||||
Ok(self.editor_mut().as_mut().map(|editor|{
|
||||
editor.put_note(advance);
|
||||
editor.redraw();
|
||||
None
|
||||
|
|
@ -505,230 +497,227 @@ impl<T: HasEditor
|
|||
// TODO: 1-9 seek markers that by default start every 8th of the clip
|
||||
}
|
||||
|
||||
impl<T: HasPool
|
||||
+ Namespace<bool>
|
||||
+ Namespace<usize>
|
||||
+ Namespace<Arc<str>>
|
||||
+ Namespace<PathBuf>
|
||||
+ Namespace<MidiClip>
|
||||
+ Namespace<ItemColor>
|
||||
+ Namespace<BrowseCmd>
|
||||
> PoolControl for T {}
|
||||
//impl<T: HasPool
|
||||
//+ Namespace<bool>
|
||||
//+ Namespace<usize>
|
||||
//+ Namespace<Arc<str>>
|
||||
//+ Namespace<PathBuf>
|
||||
//+ Namespace<MidiClip>
|
||||
//+ Namespace<ItemColor>
|
||||
//+ Namespace<BrowseCmd>
|
||||
//> PoolControl for T {}
|
||||
|
||||
#[tek_proc::commands(PoolCmd = "pool")] pub trait PoolControl: HasPool
|
||||
+ Namespace<bool>
|
||||
+ Namespace<usize>
|
||||
+ Namespace<Arc<str>>
|
||||
+ Namespace<PathBuf>
|
||||
+ Namespace<MidiClip>
|
||||
+ Namespace<ItemColor>
|
||||
+ Namespace<BrowseCmd>
|
||||
{
|
||||
/// Toggle visibility of pool
|
||||
#[command(Show = "show")] fn show (&mut self, visible: bool) -> Perhaps<PoolCmd> {
|
||||
self.pool_mut().visible = visible;
|
||||
Ok(Some(PoolCmd::Show { visible: !visible }))
|
||||
}
|
||||
/// Set selected clip
|
||||
#[command(Select = "select")] fn select (&mut self, index: usize) -> Perhaps<PoolCmd> {
|
||||
self.pool_mut().set_clip_index(index);
|
||||
Ok(None)
|
||||
}
|
||||
/// Delete a clip from the pool
|
||||
#[command(Delete = "delete")] fn delete (&mut self, index: usize) -> Perhaps<PoolCmd> {
|
||||
let clip = self.pool_mut().clips_mut().remove(index).try_read().unwrap().clone();
|
||||
Ok(Some(PoolCmd::Add { index, clip }))
|
||||
}
|
||||
/// Switch places of two clips in pool
|
||||
#[command(Swap = "swap")] fn swap (&mut self, index: usize, other: usize) -> Perhaps<PoolCmd> {
|
||||
self.pool_mut().clips_mut().swap(index, other);
|
||||
Ok(Some(PoolCmd::Swap { index, other }))
|
||||
}
|
||||
/// Add clip to pool
|
||||
#[command(Add = "add")] fn clip_add (&mut self, index: usize, clip: MidiClip) -> Perhaps<PoolCmd> {
|
||||
let mut index = index;
|
||||
let clip = Arc::new(RwLock::new(clip.clone()));
|
||||
let mut clips = self.pool_mut().clips_mut();
|
||||
if index >= clips.len() {
|
||||
index = clips.len();
|
||||
clips.push(clip)
|
||||
} else {
|
||||
clips.insert(index, clip);
|
||||
}
|
||||
Ok(Some(PoolCmd::Delete { index }))
|
||||
}
|
||||
/// Set name of clip
|
||||
#[command(SetName = "set-name")] fn clip_set_name (&mut self, index: usize, name: Arc<str>) -> Perhaps<PoolCmd> {
|
||||
let clip = &mut self.pool_mut().clips_mut()[index];
|
||||
let old_name = clip.try_read().unwrap().name.clone();
|
||||
clip.try_write().unwrap().name = name.clone();
|
||||
Ok(Some(PoolCmd::SetName { index, name: old_name }))
|
||||
}
|
||||
/// Set length of clip
|
||||
#[command(SetLength = "set-length")] fn clip_set_length (&mut self, index: usize, length: usize) -> Perhaps<PoolCmd> {
|
||||
let clip = &mut self.pool_mut().clips_mut()[index];
|
||||
let old_len = clip.try_read().unwrap().length;
|
||||
clip.try_write().unwrap().length = length;
|
||||
Ok(Some(PoolCmd::SetLength { index, length: old_len }))
|
||||
}
|
||||
/// Set color of clip
|
||||
#[command(SetColor = "set-color")] fn clip_set_color (&mut self, index: usize, color: ItemColor) -> Perhaps<PoolCmd> {
|
||||
let mut color = ItemTheme::from(color);
|
||||
std::mem::swap(&mut color, &mut self.pool().clips()[index].try_write().unwrap().color);
|
||||
Ok(Some(PoolCmd::SetColor { index, color: color.base }))
|
||||
}
|
||||
/// Enter crop mode
|
||||
#[command(CropBegin = "crop/begin")] fn crop_begin (&mut self) -> Perhaps<PoolCmd> {
|
||||
let index = self.pool().clip_index();
|
||||
let length = self.pool().clips()[index].try_read().unwrap().length;
|
||||
*self.pool_mut().mode_mut() = Some(PoolMode::Length(index, length, ClipLengthFocus::Bar));
|
||||
Ok(None)
|
||||
}
|
||||
/// Exit crop mode, discard
|
||||
#[command(CropCancel = "crop/cancel")] fn crop_cancel (&mut self) -> Perhaps<PoolCmd> {
|
||||
if let Some(PoolMode::Length(..)) = self.pool_mut().mode_mut().clone() {
|
||||
*self.pool_mut().mode_mut() = None;
|
||||
}
|
||||
Ok(None)
|
||||
}
|
||||
#[command(CropSet = "crop/set")] fn crop_set (&mut self, _length: usize) -> Perhaps<PoolCmd> {
|
||||
if let Some(PoolMode::Length(clip, ref mut length, ref mut _focus))
|
||||
= self.pool_mut().mode_mut().clone()
|
||||
{
|
||||
let old_length;
|
||||
{
|
||||
let clip = self.pool().clips()[clip].clone();//.try_write().unwrap();
|
||||
old_length = Some(clip.try_read().unwrap().length);
|
||||
clip.try_write().unwrap().length = *length;
|
||||
}
|
||||
*self.pool_mut().mode_mut() = None;
|
||||
return Ok(old_length.map(|l|PoolCmd::CropSet { _length: l }))
|
||||
}
|
||||
Ok(None)
|
||||
}
|
||||
#[command(CropNext = "crop/next")] fn crop_next (&mut self) -> Perhaps<PoolCmd> {
|
||||
if let Some(PoolMode::Length(
|
||||
_clip, ref mut _length, ref mut focus
|
||||
)) = self.pool_mut().mode_mut().clone() {
|
||||
focus.next()
|
||||
};
|
||||
Ok(None)
|
||||
}
|
||||
#[command(CropPrev = "crop/prev")] fn crop_prev (&mut self) -> Perhaps<PoolCmd> {
|
||||
if let Some(PoolMode::Length(
|
||||
_clip, ref mut _length, ref mut focus
|
||||
)) = self.pool_mut().mode_mut().clone() {
|
||||
focus.prev()
|
||||
};
|
||||
Ok(None)
|
||||
}
|
||||
#[command(CropInc = "crop/inc")] fn crop_inc (&mut self) -> Perhaps<PoolCmd> {
|
||||
if let Some(PoolMode::Length(
|
||||
_clip, ref mut length, ref mut focus
|
||||
)) = self.pool_mut().mode_mut().clone() {
|
||||
match focus {
|
||||
ClipLengthFocus::Bar => { *length += 4 * PPQ },
|
||||
ClipLengthFocus::Beat => { *length += PPQ },
|
||||
ClipLengthFocus::Tick => { *length += 1 },
|
||||
}
|
||||
}
|
||||
Ok(None)
|
||||
}
|
||||
#[command(CropDec = "crop/dec")] fn crop_dec (&mut self) -> Perhaps<PoolCmd> {
|
||||
if let Some(PoolMode::Length(
|
||||
_clip, ref mut length, ref mut focus
|
||||
)) = self.pool_mut().mode_mut().clone() {
|
||||
match focus {
|
||||
ClipLengthFocus::Bar => { *length = length.saturating_sub(4 * PPQ) },
|
||||
ClipLengthFocus::Beat => { *length = length.saturating_sub(PPQ) },
|
||||
ClipLengthFocus::Tick => { *length = length.saturating_sub(1) },
|
||||
}
|
||||
}
|
||||
Ok(None)
|
||||
}
|
||||
/// Enter rename mode
|
||||
#[command(RenameBegin = "rename/begin")] fn rename_begin (&mut self) -> Perhaps<PoolCmd> {
|
||||
let index = self.pool().clip_index();
|
||||
let name = self.pool().clips()[index].try_read().unwrap().name.clone();
|
||||
*self.pool_mut().mode_mut() = Some(PoolMode::Rename(index, name));
|
||||
Ok(None)
|
||||
}
|
||||
/// Exit rename mode, discard
|
||||
#[command(RenameCancel = "rename/cancel")] fn rename_cancel (&mut self) -> Perhaps<PoolCmd> {
|
||||
if let Some(PoolMode::Rename(clip, ref mut old_name)) = self.pool_mut().mode_mut().clone() {
|
||||
self.pool().clips()[clip].try_write().unwrap().name = old_name.clone().into();
|
||||
}
|
||||
Ok(None)
|
||||
}
|
||||
/// Exit rename mode, update name
|
||||
#[command(RenameConfirm = "rename/confirm")] fn rename_confirm (&mut self) -> Perhaps<PoolCmd> {
|
||||
Ok(if let Some(PoolMode::Rename(_clip, ref mut old_name)) = self.pool_mut().mode_mut().clone() {
|
||||
let old_name = old_name.clone();
|
||||
*self.pool_mut().mode_mut() = None;
|
||||
Some(PoolCmd::RenameSet { value: old_name })
|
||||
} else {
|
||||
None
|
||||
})
|
||||
}
|
||||
#[command(RenameSet = "rename/set")] fn rename_set (&mut self, value: Arc<str>) -> Perhaps<PoolCmd> {
|
||||
if let Some(PoolMode::Rename(clip, ref mut _old_name)) = self.pool_mut().mode_mut().clone() {
|
||||
self.pool().clips()[clip].try_write().unwrap().name = value.clone();
|
||||
}
|
||||
Ok(None)
|
||||
}
|
||||
///// Import from file
|
||||
//#[command(Browse = "browse")]
|
||||
//fn browse (&mut self, command: BrowseCmd) -> Perhaps<PoolCmd> {
|
||||
//Ok(if let Some(browse) = self.pool_mut().browse.as_mut() {
|
||||
//command.act(browse)?.map(|command|PoolCmd::Browse{command})
|
||||
//#[tek_proc::commands(PolCmd = "pool")] pub trait PoolControl: HasPool
|
||||
//+ Namespace<bool>
|
||||
//+ Namespace<usize>
|
||||
//+ Namespace<Arc<str>>
|
||||
//+ Namespace<PathBuf>
|
||||
//+ Namespace<MidiClip>
|
||||
//+ Namespace<ItemColor>
|
||||
//+ Namespace<BrowseCmd>
|
||||
//{
|
||||
///// Toggle visibility of pool
|
||||
//#[command(Show = "show")] fn show (&mut self, visible: bool) -> Perhaps<PoolCmd> {
|
||||
//self.pool_mut().visible = visible;
|
||||
//Ok(Some(PoolCmd::Show { visible: !visible }))
|
||||
//}
|
||||
///// Set selected clip
|
||||
//#[command(Select = "select")] fn select (&mut self, index: usize) -> Perhaps<PoolCmd> {
|
||||
//self.pool_mut().set_clip_index(index);
|
||||
//Ok(None)
|
||||
//}
|
||||
///// Delete a clip from the pool
|
||||
//#[command(Delete = "delete")] fn delete (&mut self, index: usize) -> Perhaps<PoolCmd> {
|
||||
//let clip = self.pool_mut().remove(index).read().clone();
|
||||
//Ok(Some(PoolCmd::Add { index, clip }))
|
||||
//}
|
||||
///// Switch places of two clips in pool
|
||||
//#[command(Swap = "swap")] fn swap (&mut self, index: usize, other: usize) -> Perhaps<PoolCmd> {
|
||||
//self.pool_mut().swap(index, other);
|
||||
//Ok(Some(PoolCmd::Swap { index, other }))
|
||||
//}
|
||||
///// Add clip to pool
|
||||
//#[command(Add = "add")] fn clip_add (&mut self, index: usize, clip: MidiClip) -> Perhaps<PoolCmd> {
|
||||
//let mut index = index;
|
||||
//let clip = Arc::new(RwLock::new(clip.clone()));
|
||||
//let mut clips = self.pool_mut().clips_mut();
|
||||
//if index >= clips.len() {
|
||||
//index = clips.len();
|
||||
//clips.push(clip)
|
||||
//} else {
|
||||
//clips.insert(index, clip);
|
||||
//}
|
||||
//Ok(Some(PoolCmd::Delete { index }))
|
||||
//}
|
||||
///// Set name of clip
|
||||
//#[command(SetName = "set-name")] fn clip_set_name (&mut self, index: usize, name: Arc<str>) -> Perhaps<PoolCmd> {
|
||||
//Ok(self.pool_mut().clips.read().get(index).map(|clip|{
|
||||
//let old_name = clip.read().name.clone();
|
||||
//clip.write().name = name.clone();
|
||||
//PoolCmd::SetName { index, name: old_name }
|
||||
//}))
|
||||
//}
|
||||
///// Set length of clip
|
||||
//#[command(SetLength = "set-length")] fn clip_set_length (&mut self, index: usize, length: usize) -> Perhaps<PoolCmd> {
|
||||
//Ok(self.pool_mut().clips.read().get(index).map(|clip|{
|
||||
//let old_len = clip.read().length;
|
||||
//clip.write().length = length;
|
||||
//PoolCmd::SetLength { index, length: old_len }
|
||||
//}))
|
||||
//}
|
||||
///// Set color of clip
|
||||
//#[command(SetColor = "set-color")] fn clip_set_color (&mut self, index: usize, color: ItemColor) -> Perhaps<PoolCmd> {
|
||||
//let mut color = ItemTheme::from(color);
|
||||
//std::mem::swap(&mut color, &mut self.pool().clips.read()[index].write().color);
|
||||
//Ok(Some(PoolCmd::SetColor { index, color: color.base }))
|
||||
//}
|
||||
///// Enter crop mode
|
||||
//#[command(CropBegin = "crop/begin")] fn crop_begin (&mut self) -> Perhaps<PoolCmd> {
|
||||
//let index = self.pool().clip_index();
|
||||
//let length = self.pool().clips.read()[index].read().length;
|
||||
//*self.pool_mut().mode_mut() = Some(PoolMode::Length(index, length, ClipLengthFocus::Bar));
|
||||
//Ok(None)
|
||||
//}
|
||||
///// Exit crop mode, discard
|
||||
//#[command(CropCancel = "crop/cancel")] fn crop_cancel (&mut self) -> Perhaps<PoolCmd> {
|
||||
//if let Some(PoolMode::Length(..)) = self.pool_mut().mode_mut().clone() {
|
||||
//*self.pool_mut().mode_mut() = None;
|
||||
//}
|
||||
//Ok(None)
|
||||
//}
|
||||
//#[command(CropSet = "crop/set")] fn crop_set (&mut self, _length: usize) -> Perhaps<PoolCmd> {
|
||||
//if let Some(PoolMode::Length(clip, ref mut length, ref mut _focus))
|
||||
//= self.pool_mut().mode_mut().clone()
|
||||
//{
|
||||
//let old_length;
|
||||
//{
|
||||
//let clip = self.pool().clips.read()[clip].clone();//.write();
|
||||
//old_length = Some(clip.read().length);
|
||||
//clip.write().length = *length;
|
||||
//}
|
||||
//*self.pool_mut().mode_mut() = None;
|
||||
//return Ok(old_length.map(|l|PoolCmd::CropSet { _length: l }))
|
||||
//}
|
||||
//Ok(None)
|
||||
//}
|
||||
//#[command(CropNext = "crop/next")] fn crop_next (&mut self) -> Perhaps<PoolCmd> {
|
||||
//if let Some(PoolMode::Length(
|
||||
//_clip, ref mut _length, ref mut focus
|
||||
//)) = self.pool_mut().mode_mut().clone() {
|
||||
//focus.next()
|
||||
//};
|
||||
//Ok(None)
|
||||
//}
|
||||
//#[command(CropPrev = "crop/prev")] fn crop_prev (&mut self) -> Perhaps<PoolCmd> {
|
||||
//if let Some(PoolMode::Length(
|
||||
//_clip, ref mut _length, ref mut focus
|
||||
//)) = self.pool_mut().mode_mut().clone() {
|
||||
//focus.prev()
|
||||
//};
|
||||
//Ok(None)
|
||||
//}
|
||||
//#[command(CropInc = "crop/inc")] fn crop_inc (&mut self) -> Perhaps<PoolCmd> {
|
||||
//if let Some(PoolMode::Length(
|
||||
//_clip, ref mut length, ref mut focus
|
||||
//)) = self.pool_mut().mode_mut().clone() {
|
||||
//match focus {
|
||||
//ClipLengthFocus::Bar => { *length += 4 * PPQ },
|
||||
//ClipLengthFocus::Beat => { *length += PPQ },
|
||||
//ClipLengthFocus::Tick => { *length += 1 },
|
||||
//}
|
||||
//}
|
||||
//Ok(None)
|
||||
//}
|
||||
//#[command(CropDec = "crop/dec")] fn crop_dec (&mut self) -> Perhaps<PoolCmd> {
|
||||
//if let Some(PoolMode::Length(
|
||||
//_clip, ref mut length, ref mut focus
|
||||
//)) = self.pool_mut().mode_mut().clone() {
|
||||
//match focus {
|
||||
//ClipLengthFocus::Bar => { *length = length.saturating_sub(4 * PPQ) },
|
||||
//ClipLengthFocus::Beat => { *length = length.saturating_sub(PPQ) },
|
||||
//ClipLengthFocus::Tick => { *length = length.saturating_sub(1) },
|
||||
//}
|
||||
//}
|
||||
//Ok(None)
|
||||
//}
|
||||
///// Enter rename mode
|
||||
//#[command(RenameBegin = "rename/begin")] fn rename_begin (&mut self) -> Perhaps<PoolCmd> {
|
||||
//let index = self.pool().clip_index();
|
||||
//let name = self.pool().clips.read()[index].read().name.clone();
|
||||
//*self.pool_mut().mode_mut() = Some(PoolMode::Rename(index, name));
|
||||
//Ok(None)
|
||||
//}
|
||||
///// Exit rename mode, discard
|
||||
//#[command(RenameCancel = "rename/cancel")] fn rename_cancel (&mut self) -> Perhaps<PoolCmd> {
|
||||
//if let Some(PoolMode::Rename(clip, ref mut old_name)) = self.pool_mut().mode_mut().clone() {
|
||||
//self.pool().clips.read()[clip].write().name = old_name.clone().into();
|
||||
//}
|
||||
//Ok(None)
|
||||
//}
|
||||
///// Exit rename mode, update name
|
||||
//#[command(RenameConfirm = "rename/confirm")] fn rename_confirm (&mut self) -> Perhaps<PoolCmd> {
|
||||
//Ok(if let Some(PoolMode::Rename(_clip, ref mut old_name)) = self.pool_mut().mode_mut().clone() {
|
||||
//let old_name = old_name.clone();
|
||||
//*self.pool_mut().mode_mut() = None;
|
||||
//Some(PoolCmd::RenameSet { value: old_name })
|
||||
//} else {
|
||||
//None
|
||||
//})
|
||||
//}
|
||||
/// Import clip to pool from file
|
||||
#[command(Import = "import")]
|
||||
fn clip_import (&mut self, index: usize, path: PathBuf) -> Perhaps<PoolCmd>
|
||||
where Self: Sized
|
||||
{
|
||||
let bytes = std::fs::read(&path)?;
|
||||
let smf = Smf::parse(bytes.as_slice())?;
|
||||
let mut t = 0u32;
|
||||
let mut events = vec![];
|
||||
for track in smf.tracks.iter() {
|
||||
for event in track.iter() {
|
||||
t += event.delta.as_int();
|
||||
if let TrackEventKind::Midi { channel, message } = event.kind {
|
||||
events.push((t, channel.as_int(), message));
|
||||
}
|
||||
}
|
||||
}
|
||||
let mut clip = MidiClip::new("imported", true, t as usize + 1, None, None);
|
||||
for event in events.iter() {
|
||||
clip.notes[event.0 as usize].push(event.2);
|
||||
}
|
||||
Ok(PoolCmd::Add { index, clip }.dispatch(self)?)
|
||||
}
|
||||
///// Export to file
|
||||
//#[command(Export = "export")]
|
||||
//fn export (&mut self, command: BrowseCmd) -> Perhaps<PoolCmd> {
|
||||
//Ok(if let Some(browse) = self.pool_mut().browse.as_mut() {
|
||||
//command.act(browse)?.map(|command|PoolCmd::Export{command})
|
||||
//} else {
|
||||
//None
|
||||
//})
|
||||
//#[command(RenameSet = "rename/set")] fn rename_set (&mut self, value: Arc<str>) -> Perhaps<PoolCmd> {
|
||||
//if let Some(PoolMode::Rename(clip, ref mut _old_name)) = self.pool_mut().mode_mut().clone() {
|
||||
//self.pool().clips.read()[clip].write().name = value.clone();
|
||||
//}
|
||||
//Ok(None)
|
||||
//}
|
||||
}
|
||||
/////// Import from file
|
||||
////#[command(Browse = "browse")]
|
||||
////fn browse (&mut self, command: BrowseCmd) -> Perhaps<PoolCmd> {
|
||||
////Ok(if let Some(browse) = self.pool_mut().browse.as_mut() {
|
||||
////command.act(browse)?.map(|command|PoolCmd::Browse{command})
|
||||
////} else {
|
||||
////None
|
||||
////})
|
||||
////}
|
||||
///// Import clip to pool from file
|
||||
//#[command(Import = "import")]
|
||||
//fn clip_import (&mut self, index: usize, path: PathBuf) -> Perhaps<PoolCmd>
|
||||
//where Self: Sized
|
||||
//{
|
||||
//let bytes = std::fs::read(&path)?;
|
||||
//let smf = Smf::parse(bytes.as_slice())?;
|
||||
//let mut t = 0u32;
|
||||
//let mut events = vec![];
|
||||
//for track in smf.tracks.iter() {
|
||||
//for event in track.iter() {
|
||||
//t += event.delta.as_int();
|
||||
//if let TrackEventKind::Midi { channel, message } = event.kind {
|
||||
//events.push((t, channel.as_int(), message));
|
||||
//}
|
||||
//}
|
||||
//}
|
||||
//let mut clip = MidiClip::new("imported", true, t as usize + 1, None, None);
|
||||
//for event in events.iter() {
|
||||
//clip.notes[event.0 as usize].push(event.2);
|
||||
//}
|
||||
//Ok(PoolCmd::Add { index, clip }.dispatch(self)?)
|
||||
//}
|
||||
/////// Export to file
|
||||
////#[command(Export = "export")]
|
||||
////fn export (&mut self, command: BrowseCmd) -> Perhaps<PoolCmd> {
|
||||
////Ok(if let Some(browse) = self.pool_mut().browse.as_mut() {
|
||||
////command.act(browse)?.map(|command|PoolCmd::Export{command})
|
||||
////} else {
|
||||
////None
|
||||
////})
|
||||
////}
|
||||
//}
|
||||
|
||||
impl<T> ModeControl for T where T: HasModeStack
|
||||
+ Namespace<Vec<Arc<str>>>
|
||||
+ Namespace<Arc<str>>
|
||||
+ Namespace<usize>
|
||||
+ Namespace<Vec<Arc<str>>> + Namespace<Arc<str>> + Namespace<usize>
|
||||
{}
|
||||
|
||||
#[tek_proc::commands(ModeCmd)] pub trait ModeControl: HasModeStack
|
||||
+ Namespace<Vec<Arc<str>>>
|
||||
+ Namespace<Arc<str>>
|
||||
+ Namespace<usize>
|
||||
+ Namespace<Vec<Arc<str>>> + Namespace<Arc<str>> + Namespace<usize>
|
||||
{
|
||||
#[command(Reset = "reset")] fn mode_reset (&mut self, modes: Vec<Arc<str>>) -> Perhaps<ModeCmd> {
|
||||
*self.modes_mut() = modes.into();
|
||||
|
|
@ -744,36 +733,46 @@ impl<T> ModeControl for T where T: HasModeStack
|
|||
}
|
||||
}
|
||||
|
||||
impl<T: HasClips + Namespace<Option<bool>> + Namespace<Option<ItemTheme>> > MidiClipControl for T {}
|
||||
#[tek_proc::commands(MidiClipCmd)] pub trait MidiClipControl: HasClips
|
||||
+ Namespace<Option<bool>>
|
||||
+ Namespace<Option<ItemTheme>>
|
||||
pub trait HasClip {
|
||||
fn clip (&self) -> RwLockReadGuard<'_, Option<Arc<RwLock<MidiClip>>>>;
|
||||
fn clip_mut (&self) -> RwLockWriteGuard<'_, Option<Arc<RwLock<MidiClip>>>>;
|
||||
}
|
||||
impl<T: AsRef<Slot<MidiClip>>> HasClip for T {
|
||||
fn clip (&self) -> RwLockReadGuard<'_, Option<Arc<RwLock<MidiClip>>>> {
|
||||
self.as_ref().0.read()
|
||||
}
|
||||
fn clip_mut (&self) -> RwLockWriteGuard<'_, Option<Arc<RwLock<MidiClip>>>> {
|
||||
self.as_ref().0.write()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> MidiClipControl for T where T: HasClip
|
||||
+ Namespace<Option<bool>> + Namespace<Option<ItemTheme>> {}
|
||||
#[tek_proc::commands(MidiClipCmd)] pub trait MidiClipControl: HasClip
|
||||
+ Namespace<Option<bool>> + Namespace<Option<ItemTheme>>
|
||||
{
|
||||
/// Create a clip at the current position if it does not already exist.
|
||||
#[command(Upsert = "upsert")] fn clip_upsert (&mut self) -> Perhaps<MidiClipCmd> {
|
||||
let clip = self.clip();
|
||||
//let old = self.scenes[scene].clips[track].clone();
|
||||
//self.scenes[scene].clips[track] = clip;
|
||||
//old
|
||||
todo!()
|
||||
if self.clip().is_some() {
|
||||
Ok(None)
|
||||
} else {
|
||||
*self.clip_mut() = Some(Default::default());
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
#[command(SetColor = "color")] fn clip_set_color (&mut self, color: Option<ItemTheme>) -> Perhaps<MidiClipCmd> {
|
||||
Ok(self.clip().map(|clip|MidiClipCmd::SetColor {
|
||||
color: Some(clip.write().set_color(color))
|
||||
}))
|
||||
Ok(self.clip().as_ref().map(|clip|MidiClipCmd::SetColor { color: Some(clip.write().set_color(color)) }))
|
||||
}
|
||||
/// Toggle looping for the active clip
|
||||
#[command(SetLoop = "loop")] fn clip_toggle_loop (&mut self, looping: Option<bool>) -> Perhaps<MidiClipCmd> {
|
||||
Ok(self.clip().map(|clip|MidiClipCmd::SetLoop {
|
||||
looping: Some(clip.write().toggle_loop(looping))
|
||||
}))
|
||||
Ok(self.clip().as_ref().map(|clip|MidiClipCmd::SetLoop { looping: Some(clip.write().toggle_loop(looping)) }))
|
||||
}
|
||||
}
|
||||
impl<T: Namespace<usize> + Namespace<PathBuf> + Namespace<Arc<str>>> BrowseControl for T {}
|
||||
|
||||
impl<T> BrowseControl for T where T:
|
||||
Namespace<usize> + Namespace<PathBuf> + Namespace<Arc<str>> {}
|
||||
#[tek_proc::commands(BrowseCmd = "browse")] pub trait BrowseControl:
|
||||
Namespace<usize> +
|
||||
Namespace<PathBuf> +
|
||||
Namespace<Arc<str>>
|
||||
Namespace<usize> + Namespace<PathBuf> + Namespace<Arc<str>>
|
||||
{
|
||||
/// Toggle visibility of browser
|
||||
#[command(Show = "show")] fn show (&mut self) -> Perhaps<BrowseCmd> {
|
||||
|
|
@ -793,11 +792,9 @@ impl<T: Namespace<usize> + Namespace<PathBuf> + Namespace<Arc<str>>> BrowseContr
|
|||
}
|
||||
}
|
||||
|
||||
#[tek_proc::commands(AxisCmd)]
|
||||
impl App {
|
||||
/// Increment a given data axis.
|
||||
#[command(Inc = "inc")]
|
||||
pub fn inc (&mut self, axis: ControlAxis) -> Perhaps<AxisCmd> {
|
||||
#[tek_proc::commands(AxisCmd)] impl App {
|
||||
/// Increment the given data axis.
|
||||
#[command(Inc = "inc")] pub fn inc (&mut self, axis: ControlAxis) -> Perhaps<AxisCmd> {
|
||||
Ok(match (&self.dialog, axis) {
|
||||
(Dialog::None, _) => todo!(),
|
||||
(Dialog::Menu(_, _), ControlAxis::Y) => {
|
||||
|
|
@ -807,9 +804,8 @@ impl App {
|
|||
_ => todo!()
|
||||
})
|
||||
}
|
||||
/// Decrement a given data axis.
|
||||
#[command(Dec = "dec")]
|
||||
pub fn dec (&mut self, axis: ControlAxis) -> Perhaps<AxisCmd> {
|
||||
/// Decrement the given data axis.
|
||||
#[command(Dec = "dec")] pub fn dec (&mut self, axis: ControlAxis) -> Perhaps<AxisCmd> {
|
||||
Ok(match (&self.dialog, axis) {
|
||||
(Dialog::None, _) => None,
|
||||
(Dialog::Menu(_, _), ControlAxis::Y) => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue