use crate::*; mod model_track; pub use self::model_track::*; mod model_scene; pub use self::model_scene::*; mod model_select; pub use self::model_select::*; #[derive(Default, Debug)] pub struct Tek { /// Must not be dropped for the duration of the process pub jack: Jack, /// Source of time pub clock: Clock, /// Theme pub color: ItemPalette, /// Contains all clips in the project pub pool: Option, /// Contains the currently edited MIDI clip pub editor: Option, /// Contains a render of the project arrangement, redrawn on update. pub arranger: Arc>, /// List of global midi inputs pub midi_ins: Vec, /// List of global midi outputs pub midi_outs: Vec, /// List of global audio inputs pub audio_ins: Vec, /// List of global audio outputs pub audio_outs: Vec, /// Buffer for writing a midi event pub note_buf: Vec, /// Buffer for writing a chunk of midi events pub midi_buf: Vec>>, /// List of tracks pub tracks: Vec, /// Scroll offset of tracks pub track_scroll: usize, /// List of scenes pub scenes: Vec, /// Scroll offset of scenes pub scene_scroll: usize, /// Selected UI element pub selected: Selection, /// Display size pub size: Measure, /// Performance counter pub perf: PerfModel, /// Whether in edit mode pub editing: AtomicBool, /// Undo history pub history: Vec, /// Port handles pub ports: std::collections::BTreeMap>, /// View definition pub view: SourceIter<'static>, // Input definitions pub keys: SourceIter<'static>, // Input definitions when a clip is focused pub keys_clip: SourceIter<'static>, // Input definitions when a track is focused pub keys_track: SourceIter<'static>, // Input definitions when a scene is focused pub keys_scene: SourceIter<'static>, // Input definitions when the mix is focused pub keys_mix: SourceIter<'static>, // Cache of formatted strings pub view_cache: Arc>, } impl Tek { fn clip (&self) -> Option>> { self.scene()?.clips.get(self.selected().track()?)?.clone() } fn toggle_loop (&mut self) { if let Some(clip) = self.clip() { clip.write().unwrap().toggle_loop() } } fn activate (&mut self) -> Usually<()> { let selected = self.selected().clone(); match selected { Selection::Scene(s) => { let mut clips = vec![]; for (t, _) in self.tracks().iter().enumerate() { clips.push(self.scenes()[s].clips[t].clone()); } for (t, track) in self.tracks_mut().iter_mut().enumerate() { if track.player.play_clip.is_some() || clips[t].is_some() { track.player.enqueue_next(clips[t].as_ref()); } } if self.clock().is_stopped() { self.clock().play_from(Some(0))?; } }, Selection::Clip(t, s) => { let clip = self.scenes()[s].clips[t].clone(); self.tracks_mut()[t].player.enqueue_next(clip.as_ref()); }, _ => {} } Ok(()) } } has_size!(|self: Tek|&self.size); has_clock!(|self: Tek|self.clock); has_clips!(|self: Tek|self.pool.as_ref().expect("no clip pool").clips); has_editor!(|self: Tek|{ editor = self.editor; editor_w = { let size = self.size.w(); let editor = self.editor.as_ref().expect("missing editor"); let time_len = editor.time_len().get(); let time_zoom = editor.time_zoom().get().max(1); (5 + (time_len / time_zoom)).min(size.saturating_sub(20)).max(16) }; editor_h = 15; is_editing = self.editing.load(Relaxed); }); //has_sampler!(|self: Tek|{ //sampler = self.sampler; //index = self.editor.as_ref().map(|e|e.note_pos()).unwrap_or(0); //});