mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-07 12:16:42 +01:00
281 lines
10 KiB
Rust
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)
|
|
}
|
|
}
|