mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-07 12:16:42 +01:00
97 lines
3.5 KiB
Rust
97 lines
3.5 KiB
Rust
use crate::*;
|
|
impl Tek {
|
|
pub fn scenes_add (&mut self, n: usize) -> Usually<()> {
|
|
let scene_color_1 = ItemColor::random();
|
|
let scene_color_2 = ItemColor::random();
|
|
for i in 0..n {
|
|
let _ = self.scene_add(None, Some(
|
|
scene_color_1.mix(scene_color_2, i as f32 / n as f32).into()
|
|
))?;
|
|
}
|
|
Ok(())
|
|
}
|
|
pub fn scene_add (&mut self, name: Option<&str>, color: Option<ItemPalette>)
|
|
-> Usually<(usize, &mut Scene)>
|
|
{
|
|
let scene = Scene {
|
|
name: name.map_or_else(||self.scene_default_name(), |x|x.to_string().into()),
|
|
clips: vec![None;self.tracks().len()],
|
|
color: color.unwrap_or_else(ItemPalette::random),
|
|
};
|
|
self.scenes_mut().push(scene);
|
|
let index = self.scenes().len() - 1;
|
|
Ok((index, &mut self.scenes_mut()[index]))
|
|
}
|
|
pub fn scene_default_name (&self) -> Arc<str> {
|
|
format!("Sc{:3>}", self.scenes().len() + 1).into()
|
|
}
|
|
}
|
|
pub trait HasScenes: HasSelection + HasEditor + Send + Sync {
|
|
fn scenes (&self) -> &Vec<Scene>;
|
|
fn scenes_mut (&mut self) -> &mut Vec<Scene>;
|
|
fn scene_longest (&self) -> usize {
|
|
self.scenes().iter().map(|s|s.name.len()).fold(0, usize::max)
|
|
}
|
|
fn scene (&self) -> Option<&Scene> {
|
|
self.selected().scene().and_then(|s|self.scenes().get(s))
|
|
}
|
|
fn scene_mut (&mut self) -> Option<&mut Scene> {
|
|
self.selected().scene().and_then(|s|self.scenes_mut().get_mut(s))
|
|
}
|
|
fn scene_del (&mut self, index: usize) {
|
|
self.selected().scene().and_then(|s|Some(self.scenes_mut().remove(index)));
|
|
}
|
|
}
|
|
#[derive(Debug, Default)] pub struct Scene {
|
|
/// Name of scene
|
|
pub name: Arc<str>,
|
|
/// Clips in scene, one per track
|
|
pub clips: Vec<Option<Arc<RwLock<MidiClip>>>>,
|
|
/// Identifying color of scene
|
|
pub color: ItemPalette,
|
|
}
|
|
impl Scene {
|
|
/// Returns the pulse length of the longest clip in the scene
|
|
fn pulses (&self) -> usize {
|
|
self.clips.iter().fold(0, |a, p|{
|
|
a.max(p.as_ref().map(|q|q.read().unwrap().length).unwrap_or(0))
|
|
})
|
|
}
|
|
/// Returns true if all clips in the scene are
|
|
/// currently playing on the given collection of tracks.
|
|
fn is_playing (&self, tracks: &[Track]) -> bool {
|
|
self.clips.iter().any(|clip|clip.is_some()) && self.clips.iter().enumerate()
|
|
.all(|(track_index, clip)|match clip {
|
|
Some(c) => tracks
|
|
.get(track_index)
|
|
.map(|track|{
|
|
if let Some((_, Some(clip))) = track.player().play_clip() {
|
|
*clip.read().unwrap() == *c.read().unwrap()
|
|
} else {
|
|
false
|
|
}
|
|
})
|
|
.unwrap_or(false),
|
|
None => true
|
|
})
|
|
}
|
|
pub fn clip (&self, index: usize) -> Option<&Arc<RwLock<MidiClip>>> {
|
|
match self.clips.get(index) { Some(Some(clip)) => Some(clip), _ => None }
|
|
}
|
|
}
|
|
impl HasScenes for Tek {
|
|
fn scenes (&self) -> &Vec<Scene> { &self.scenes }
|
|
fn scenes_mut (&mut self) -> &mut Vec<Scene> { &mut self.scenes }
|
|
}
|
|
#[cfg(test)] #[test] fn test_model_scene () {
|
|
let mut app = Tek::default();
|
|
let _ = app.scene_longest();
|
|
let _ = app.scene();
|
|
let _ = app.scene_mut();
|
|
let _ = app.scene_add(None, None);
|
|
app.scene_del(0);
|
|
|
|
let scene = Scene::default();
|
|
let _ = scene.pulses();
|
|
let _ = scene.is_playing(&[]);
|
|
}
|