tek/crates/device/src/arranger/arranger_api.rs

281 lines
10 KiB
Rust

use crate::*;
#[tengri_proc::expose]
impl Arrangement {
fn _todo_usize_stub_ (&self) -> usize { todo!() }
fn _todo_arc_str_stub_ (&self) -> Arc<str> { todo!() }
fn _todo_item_theme_stub (&self) -> ItemTheme { todo!() }
fn _todo_opt_item_theme_stub (&self) -> Option<ItemTheme> { todo!() }
fn select_nothing (&self) -> Selection {
Selection::Nothing
}
}
#[tengri_proc::command(Arrangement)]
impl ArrangementCommand {
fn home (arranger: &mut Arrangement) -> Perhaps<Self> {
arranger.editor = None;
Ok(None)
}
fn edit (arranger: &mut Arrangement) -> Perhaps<Self> {
let selection = arranger.selection().clone();
arranger.editor = if arranger.editor.is_some() {
None
} else {
match selection {
Selection::TrackClip { track, scene } => {
let clip = &mut arranger.scenes_mut()[scene].clips[track];
if clip.is_none() {
//app.clip_auto_create();
*clip = Some(Arc::new(RwLock::new(MidiClip::new(
&format!("t{track:02}s{scene:02}"),
false, 384, None, Some(ItemTheme::random())
))));
}
clip.as_ref().map(|c|c.into())
}
_ => {
None
}
}
};
if let Some(editor) = arranger.editor.as_mut() {
if let Some(clip) = editor.clip() {
let length = clip.read().unwrap().length.max(1);
let width = arranger.inner_size.w().saturating_sub(20).max(1);
editor.set_time_zoom(length / width);
editor.redraw();
}
}
Ok(None)
}
/// Set the selection
fn select (arranger: &mut Arrangement, s: Selection) -> Perhaps<Self> {
*arranger.selection_mut() = s;
Ok(None)
}
/// Launch a clip or scene
fn launch (arranger: &mut Arrangement) -> Perhaps<Self> {
match *arranger.selection() {
Selection::Track(t) => {
arranger.tracks[t].sequencer.enqueue_next(None)
},
Selection::TrackClip { track, scene } => {
arranger.tracks[track].sequencer.enqueue_next(arranger.scenes[scene].clips[track].as_ref())
},
Selection::Scene(s) => {
for t in 0..arranger.tracks.len() {
arranger.tracks[t].sequencer.enqueue_next(arranger.scenes[s].clips[t].as_ref())
}
},
_ => {}
};
Ok(None)
}
/// Set the color of the selected entity
fn set_color (arranger: &mut Arrangement, palette: Option<ItemTheme>) -> Perhaps<Self> {
let mut palette = palette.unwrap_or_else(||ItemTheme::random());
let selection = *arranger.selection();
Ok(Some(Self::SetColor { palette: Some(match selection {
Selection::Mix => {
std::mem::swap(&mut palette, &mut arranger.color);
palette
},
Selection::Scene(s) => {
std::mem::swap(&mut palette, &mut arranger.scenes[s].color);
palette
}
Selection::Track(t) => {
std::mem::swap(&mut palette, &mut arranger.tracks[t].color);
palette
}
Selection::TrackClip { track, scene } => {
if let Some(ref clip) = arranger.scenes[scene].clips[track] {
let mut clip = clip.write().unwrap();
std::mem::swap(&mut palette, &mut clip.color);
palette
} else {
return Ok(None)
}
},
_ => todo!()
}) }))
}
fn track (arranger: &mut Arrangement, track: TrackCommand) -> Perhaps<Self> {
todo!("delegate")
}
fn track_add (arranger: &mut Arrangement) -> Perhaps<Self> {
let index = arranger.track_add(None, None, &[], &[])?.0;
*arranger.selection_mut() = match arranger.selection() {
Selection::Track(_) => Selection::Track(index),
Selection::TrackClip { track, scene } => Selection::TrackClip {
track: index, scene: *scene
},
_ => *arranger.selection()
};
Ok(Some(Self::TrackDelete { index }))
}
fn track_swap (arranger: &mut Arrangement, index: usize, other: usize) -> Perhaps<Self> {
todo!();
Ok(Some(Self::TrackSwap { index, other }))
}
fn track_delete (arranger: &mut Arrangement, index: usize) -> Perhaps<Self> {
let exists = arranger.tracks().get(index).is_some();
if exists {
let track = arranger.tracks_mut().remove(index);
let Track { sequencer: Sequencer { midi_ins, midi_outs, .. }, .. } = track;
for port in midi_ins.into_iter() {
port.close()?;
}
for port in midi_outs.into_iter() {
port.close()?;
}
for scene in arranger.scenes_mut().iter_mut() {
scene.clips.remove(index);
}
}
Ok(None)
//TODO:Ok(Some(Self::TrackAdd ( index, track: Some(deleted_track) })
}
fn midi_in (arranger: &mut Arrangement, input: MidiInputCommand) -> Perhaps<Self> {
todo!("delegate");
Ok(None)
}
fn midi_in_add (arranger: &mut Arrangement) -> Perhaps<Self> {
arranger.midi_in_add()?;
Ok(None)
}
fn midi_out (arranger: &mut Arrangement, input: MidiOutputCommand) -> Perhaps<Self> {
todo!("delegate");
Ok(None)
}
fn midi_out_add (arranger: &mut Arrangement) -> Perhaps<Self> {
arranger.midi_out_add()?;
Ok(None)
}
fn device (arranger: &mut Arrangement, input: DeviceCommand) -> Perhaps<Self> {
todo!("delegate");
Ok(None)
}
fn device_add (arranger: &mut Arrangement, i: usize) -> Perhaps<Self> {
todo!("delegate");
Ok(None)
}
fn scene (arranger: &mut Arrangement, scene: SceneCommand) -> Perhaps<Self> {
todo!("delegate");
Ok(None)
}
fn output_add (arranger: &mut Arrangement) -> Perhaps<Self> {
arranger.midi_outs.push(JackMidiOut::new(
arranger.jack(),
format!("/M{}", arranger.midi_outs.len() + 1),
&[]
)?);
Ok(None)
}
fn input_add (arranger: &mut Arrangement) -> Perhaps<Self> {
arranger.midi_ins.push(JackMidiIn::new(
arranger.jack(),
format!("M{}/", arranger.midi_ins.len() + 1),
&[]
)?);
Ok(None)
}
fn scene_add (arranger: &mut Arrangement) -> Perhaps<Self> {
let index = arranger.scene_add(None, None)?.0;
*arranger.selection_mut() = match arranger.selection() {
Selection::Scene(_) => Selection::Scene(index),
Selection::TrackClip { track, scene } => Selection::TrackClip {
track: *track,
scene: index
},
_ => *arranger.selection()
};
Ok(None) // TODO
}
fn scene_swap (arranger: &mut Arrangement, index: usize, other: usize) -> Perhaps<Self> {
todo!();
Ok(Some(Self::SceneSwap { index, other }))
}
fn scene_delete (arranger: &mut Arrangement, index: usize) -> Perhaps<Self> {
let scenes = arranger.scenes_mut();
Ok(if scenes.get(index).is_some() {
let _scene = scenes.remove(index);
None
} else {
None
})
}
fn scene_launch (arranger: &mut Arrangement, index: usize) -> Perhaps<Self> {
for track in 0..arranger.tracks.len() {
let clip = arranger.scenes[index].clips[track].as_ref();
arranger.tracks[track].sequencer.enqueue_next(clip);
}
Ok(None)
}
fn clip (arranger: &mut Arrangement, scene: ClipCommand) -> Perhaps<Self> {
todo!("delegate")
}
fn clip_get (arranger: &mut Arrangement, a: usize, b: usize) -> Perhaps<Self> {
//(Get [a: usize, b: usize] cmd_todo!("\n\rtodo: clip: get: {a} {b}"))
//("get" [a: usize, b: usize] Some(Self::Get(a.unwrap(), b.unwrap())))
todo!()
}
fn clip_put (arranger: &mut Arrangement, a: usize, b: usize) -> Perhaps<Self> {
//(Put [t: usize, s: usize, c: MaybeClip]
//Some(Self::Put(t, s, arranger.clip_put(t, s, c))))
//("put" [a: usize, b: usize, c: MaybeClip] Some(Self::Put(a.unwrap(), b.unwrap(), c.unwrap())))
todo!()
}
fn clip_del (arranger: &mut Arrangement, a: usize, b: usize) -> Perhaps<Self> {
//("delete" [a: usize, b: usize] Some(Self::Put(a.unwrap(), b.unwrap(), None))))
todo!()
}
fn clip_enqueue (arranger: &mut Arrangement, a: usize, b: usize) -> Perhaps<Self> {
//(Enqueue [t: usize, s: usize]
//cmd!(arranger.tracks[t].sequencer.enqueue_next(arranger.scenes[s].clips[t].as_ref())))
//("enqueue" [a: usize, b: usize] Some(Self::Enqueue(a.unwrap(), b.unwrap())))
todo!()
}
fn clip_edit (arranger: &mut Arrangement, a: usize, b: usize) -> Perhaps<Self> {
//(Edit [clip: MaybeClip] cmd_todo!("\n\rtodo: clip: edit: {clip:?}"))
//("edit" [a: MaybeClip] Some(Self::Edit(a.unwrap())))
todo!()
}
}
impl<'state> Context<'state, TrackCommand> for Arrangement {
fn get <'source> (&'state self, iter: &mut TokenIter<'source>) -> Option<TrackCommand> {
Context::get(&self, iter)
}
}
impl<'state> Context<'state, MidiInputCommand> for Arrangement {
fn get <'source> (&'state self, iter: &mut TokenIter<'source>) -> Option<MidiInputCommand> {
Context::get(&self, iter)
}
}
impl<'state> Context<'state, MidiOutputCommand> for Arrangement {
fn get <'source> (&'state self, iter: &mut TokenIter<'source>) -> Option<MidiOutputCommand> {
Context::get(&self, iter)
}
}
impl<'state> Context<'state, DeviceCommand> for Arrangement {
fn get <'source> (&'state self, iter: &mut TokenIter<'source>) -> Option<DeviceCommand> {
Context::get(&self, iter)
}
}
impl<'state> Context<'state, SceneCommand> for Arrangement {
fn get <'source> (&'state self, iter: &mut TokenIter<'source>) -> Option<SceneCommand> {
Context::get(&self, iter)
}
}
impl<'state> Context<'state, ClipCommand> for Arrangement {
fn get <'source> (&'state self, iter: &mut TokenIter<'source>) -> Option<ClipCommand> {
Context::get(&self, iter)
}
}