mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 11:46:41 +01:00
cleanup; remove tracks/scenes[_mut]() methods
in favor of direct property access
This commit is contained in:
parent
bb8e1f14eb
commit
f1847b62b8
8 changed files with 125 additions and 154 deletions
|
|
@ -36,8 +36,8 @@ impl ArrangerTui {
|
|||
self.clock().play_from(Some(0))?;
|
||||
}
|
||||
} else if let ArrangerSelection::Clip(t, s) = self.selected {
|
||||
let phrase = self.scenes()[s].clips[t].clone();
|
||||
self.tracks_mut()[t].player.enqueue_next(phrase.as_ref());
|
||||
let phrase = self.scenes[s].clips[t].clone();
|
||||
self.tracks[t].player.enqueue_next(phrase.as_ref());
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -51,19 +51,11 @@ impl ArrangerTui {
|
|||
}
|
||||
pub fn randomize_color (&mut self) {
|
||||
match self.selected {
|
||||
ArrangerSelection::Mix => {
|
||||
self.color = ItemPalette::random()
|
||||
},
|
||||
ArrangerSelection::Track(t) => {
|
||||
self.tracks_mut()[t].color = ItemPalette::random()
|
||||
},
|
||||
ArrangerSelection::Scene(s) => {
|
||||
self.scenes_mut()[s].color = ItemPalette::random()
|
||||
},
|
||||
ArrangerSelection::Clip(t, s) => {
|
||||
if let Some(phrase) = &self.scenes_mut()[s].clips[t] {
|
||||
phrase.write().unwrap().color = ItemPalette::random();
|
||||
}
|
||||
ArrangerSelection::Mix => { self.color = ItemPalette::random() },
|
||||
ArrangerSelection::Track(t) => { self.tracks[t].color = ItemPalette::random() },
|
||||
ArrangerSelection::Scene(s) => { self.scenes[s].color = ItemPalette::random() },
|
||||
ArrangerSelection::Clip(t, s) => if let Some(phrase) = &self.scenes[s].clips[t] {
|
||||
phrase.write().unwrap().color = ItemPalette::random();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -138,7 +130,7 @@ audio!(|self: ArrangerTui, client, scope|{
|
|||
// FIXME: one of these per playing track
|
||||
//self.now.set(0.);
|
||||
//if let ArrangerSelection::Clip(t, s) = self.selected {
|
||||
//let phrase = self.scenes().get(s).map(|scene|scene.clips.get(t));
|
||||
//let phrase = self.scenes.get(s).map(|scene|scene.clips.get(t));
|
||||
//if let Some(Some(Some(phrase))) = phrase {
|
||||
//if let Some(track) = self.tracks().get(t) {
|
||||
//if let Some((ref started_at, Some(ref playing))) = track.player.play_phrase {
|
||||
|
|
|
|||
|
|
@ -20,9 +20,37 @@ use KeyCode::{Char, Delete, Tab};
|
|||
PutClip(usize, usize, Option<Arc<RwLock<Phrase>>>),
|
||||
EnqueueClip(usize, usize),
|
||||
EnqueueScene(usize),
|
||||
StopTrack(usize),
|
||||
StopAll,
|
||||
}
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum ArrangerTrackCommand {
|
||||
Add,
|
||||
Delete(usize),
|
||||
Stop(usize),
|
||||
Swap(usize, usize),
|
||||
SetSize(usize),
|
||||
SetZoom(usize),
|
||||
SetColor(usize, ItemPalette),
|
||||
}
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum ArrangerSceneCommand {
|
||||
Add,
|
||||
Delete(usize),
|
||||
Swap(usize, usize),
|
||||
SetSize(usize),
|
||||
SetZoom(usize),
|
||||
SetColor(usize, ItemPalette),
|
||||
}
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum ArrangerClipCommand {
|
||||
Play,
|
||||
Get(usize, usize),
|
||||
Set(usize, usize, Option<Arc<RwLock<Phrase>>>),
|
||||
Edit(Option<Arc<RwLock<Phrase>>>),
|
||||
SetLoop(bool),
|
||||
SetColor(ItemPalette),
|
||||
}
|
||||
|
||||
input_to_command!(ArrangerCommand: <Tui>|state: ArrangerTui, input|{
|
||||
use ArrangerSelection as Selected;
|
||||
use ArrangerSceneCommand as Scene;
|
||||
|
|
@ -186,10 +214,6 @@ command!(|self:ArrangerCommand,state:ArrangerTui|match self {
|
|||
}
|
||||
None
|
||||
},
|
||||
Self::StopTrack(track) => {
|
||||
state.tracks[track].player.enqueue_next(None);
|
||||
None
|
||||
},
|
||||
Self::StopAll => {
|
||||
for track in 0..state.tracks.len() {
|
||||
state.tracks[track].player.enqueue_next(None);
|
||||
|
|
@ -197,16 +221,30 @@ command!(|self:ArrangerCommand,state:ArrangerTui|match self {
|
|||
None
|
||||
},
|
||||
});
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum ArrangerClipCommand {
|
||||
Play,
|
||||
Get(usize, usize),
|
||||
Set(usize, usize, Option<Arc<RwLock<Phrase>>>),
|
||||
Edit(Option<Arc<RwLock<Phrase>>>),
|
||||
SetLoop(bool),
|
||||
SetColor(ItemPalette),
|
||||
}
|
||||
command!(|self: ArrangerTrackCommand, state: ArrangerTui|match self {
|
||||
Self::SetColor(index, color) => {
|
||||
let old = state.tracks[index].color;
|
||||
state.tracks[index].color = color;
|
||||
Some(Self::SetColor(index, old))
|
||||
},
|
||||
Self::Stop(track) => {
|
||||
state.tracks[track].player.enqueue_next(None);
|
||||
None
|
||||
},
|
||||
_ => None
|
||||
});
|
||||
command!(|self:ArrangerSceneCommand,state:ArrangerTui|match self {
|
||||
Self::Delete(index) => {
|
||||
state.scene_del(index);
|
||||
None
|
||||
},
|
||||
Self::SetColor(index, color) => {
|
||||
let old = state.scenes[index].color;
|
||||
state.scenes[index].color = color;
|
||||
Some(Self::SetColor(index, old))
|
||||
},
|
||||
_ => None
|
||||
});
|
||||
command!(|self:ArrangerClipCommand, _state:ArrangerTui|match self {
|
||||
_ => None
|
||||
});
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ from!(<'a>|args:(&'a ArrangerTui, usize)|ArrangerVClips<'a> = Self {
|
|||
size: &args.0.size,
|
||||
scenes: &args.0.scenes,
|
||||
tracks: &args.0.tracks,
|
||||
rows: ArrangerScene::ppqs(args.0.scenes(), args.1),
|
||||
rows: ArrangerScene::ppqs(&args.0.scenes, args.1),
|
||||
});
|
||||
|
||||
render!(<Tui>|self: ArrangerVClips<'a>|Fill::wh(
|
||||
|
|
|
|||
|
|
@ -11,10 +11,10 @@ pub struct ArrangerVCursor {
|
|||
}
|
||||
|
||||
from!(|args:(&ArrangerTui, usize)|ArrangerVCursor = Self {
|
||||
cols: ArrangerTrack::widths(args.0.tracks()),
|
||||
rows: ArrangerScene::ppqs(args.0.scenes(), args.1),
|
||||
cols: ArrangerTrack::widths(&args.0.tracks),
|
||||
rows: ArrangerScene::ppqs(&args.0.scenes, args.1),
|
||||
selected: args.0.selected(),
|
||||
scenes_w: SCENES_W_OFFSET + ArrangerScene::longest_name(args.0.scenes()) as u16,
|
||||
scenes_w: SCENES_W_OFFSET + ArrangerScene::longest_name(&args.0.scenes) as u16,
|
||||
color: args.0.color,
|
||||
reticle: Reticle(Style {
|
||||
fg: Some(args.0.color.lighter.rgb),
|
||||
|
|
|
|||
|
|
@ -9,10 +9,10 @@ pub struct ArrangerVHead<'a> {
|
|||
}
|
||||
|
||||
from!(<'a>|state: &'a ArrangerTui|ArrangerVHead<'a> = Self { // A
|
||||
tracks: state.tracks(),
|
||||
tracks: &state.tracks,
|
||||
timebase: state.clock().timebase(),
|
||||
current: &state.clock().playhead,
|
||||
scenes_w: SCENES_W_OFFSET + ArrangerScene::longest_name(state.scenes()) as u16,
|
||||
scenes_w: SCENES_W_OFFSET + ArrangerScene::longest_name(&state.scenes) as u16,
|
||||
});
|
||||
|
||||
render!(<Tui>|self: ArrangerVHead<'a>|Tui::push_x(self.scenes_w, row!(
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@ pub struct ArrangerVColSep {
|
|||
|
||||
from!(|state:&ArrangerTui|ArrangerVColSep = Self {
|
||||
fg: TuiTheme::separator_fg(false),
|
||||
cols: ArrangerTrack::widths(state.tracks()),
|
||||
scenes_w: SCENES_W_OFFSET + ArrangerScene::longest_name(state.scenes()) as u16,
|
||||
cols: ArrangerTrack::widths(&state.tracks),
|
||||
scenes_w: SCENES_W_OFFSET + ArrangerScene::longest_name(&state.scenes) as u16,
|
||||
});
|
||||
|
||||
render!(<Tui>|self: ArrangerVColSep|render(move|to: &mut TuiOutput|{
|
||||
|
|
@ -30,7 +30,7 @@ pub struct ArrangerVRowSep {
|
|||
|
||||
from!(|args:(&ArrangerTui, usize)|ArrangerVRowSep = Self {
|
||||
fg: TuiTheme::separator_fg(false),
|
||||
rows: ArrangerScene::ppqs(args.0.scenes(), args.1),
|
||||
rows: ArrangerScene::ppqs(&args.0.scenes, args.1),
|
||||
});
|
||||
|
||||
render!(<Tui>|self: ArrangerVRowSep|render(move|to: &mut TuiOutput|{
|
||||
|
|
|
|||
|
|
@ -1,22 +1,33 @@
|
|||
use crate::*;
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum ArrangerSceneCommand {
|
||||
Add,
|
||||
Delete(usize),
|
||||
Swap(usize, usize),
|
||||
SetSize(usize),
|
||||
SetZoom(usize),
|
||||
SetColor(usize, ItemPalette),
|
||||
|
||||
impl ArrangerTui {
|
||||
pub fn scene_add (&mut self, name: Option<&str>, color: Option<ItemPalette>)
|
||||
-> Usually<&mut ArrangerScene>
|
||||
{
|
||||
let name = name.map_or_else(||self.scene_default_name(), |x|x.to_string());
|
||||
let scene = ArrangerScene {
|
||||
name: Arc::new(name.into()),
|
||||
clips: vec![None;self.tracks.len()],
|
||||
color: color.unwrap_or_else(||ItemPalette::random()),
|
||||
};
|
||||
self.scenes.push(scene);
|
||||
let index = self.scenes.len() - 1;
|
||||
Ok(&mut self.scenes[index])
|
||||
}
|
||||
pub fn scene_del (&mut self, index: usize) {
|
||||
todo!("delete scene");
|
||||
}
|
||||
fn scene_default_name (&self) -> String {
|
||||
format!("S{:3>}", self.scenes.len() + 1)
|
||||
}
|
||||
pub fn selected_scene (&self) -> Option<&ArrangerScene> {
|
||||
self.selected.scene().map(|s|self.scenes.get(s)).flatten()
|
||||
}
|
||||
pub fn selected_scene_mut (&mut self) -> Option<&mut ArrangerScene> {
|
||||
self.selected.scene().map(|s|self.scenes.get_mut(s)).flatten()
|
||||
}
|
||||
}
|
||||
command!(|self:ArrangerSceneCommand,state:ArrangerTui|match self {
|
||||
//Self::Delete(index) => { state.scene_del(index); },
|
||||
Self::SetColor(index, color) => {
|
||||
let old = state.scenes[index].color;
|
||||
state.scenes[index].color = color;
|
||||
Some(Self::SetColor(index, old))
|
||||
},
|
||||
_ => None
|
||||
});
|
||||
|
||||
#[derive(Default, Debug, Clone)] pub struct ArrangerScene {
|
||||
/// Name of scene
|
||||
pub(crate) name: Arc<RwLock<String>>,
|
||||
|
|
@ -25,6 +36,7 @@ command!(|self:ArrangerSceneCommand,state:ArrangerTui|match self {
|
|||
/// Identifying color of scene
|
||||
pub(crate) color: ItemPalette,
|
||||
}
|
||||
|
||||
impl ArrangerScene {
|
||||
pub fn name (&self) -> &Arc<RwLock<String>> {
|
||||
&self.name
|
||||
|
|
@ -80,33 +92,3 @@ impl ArrangerScene {
|
|||
match self.clips().get(index) { Some(Some(clip)) => Some(clip), _ => None }
|
||||
}
|
||||
}
|
||||
impl ArrangerTui {
|
||||
pub fn scenes (&self) -> &Vec<ArrangerScene> {
|
||||
&self.scenes
|
||||
}
|
||||
pub fn scenes_mut (&mut self) -> &mut Vec<ArrangerScene> {
|
||||
&mut self.scenes
|
||||
}
|
||||
pub fn scene_add (&mut self, name: Option<&str>, color: Option<ItemPalette>)
|
||||
-> Usually<&mut ArrangerScene>
|
||||
{
|
||||
let name = name.map_or_else(||self.scene_default_name(), |x|x.to_string());
|
||||
let scene = ArrangerScene {
|
||||
name: Arc::new(name.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(&mut self.scenes_mut()[index])
|
||||
}
|
||||
fn scene_default_name (&self) -> String {
|
||||
format!("S{:3>}", self.scenes().len() + 1)
|
||||
}
|
||||
pub fn selected_scene (&self) -> Option<&ArrangerScene> {
|
||||
self.selected.scene().map(|s|self.scenes().get(s)).flatten()
|
||||
}
|
||||
pub fn selected_scene_mut (&mut self) -> Option<&mut ArrangerScene> {
|
||||
self.selected.scene().map(|s|self.scenes_mut().get_mut(s)).flatten()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,32 +1,31 @@
|
|||
use crate::*;
|
||||
use KeyCode::{Char, Delete};
|
||||
|
||||
pub fn to_arranger_track_command (input: &TuiInput, t: usize, len: usize) -> Option<ArrangerCommand> {
|
||||
use ArrangerCommand::*;
|
||||
use ArrangerSelection as Selected;
|
||||
use ArrangerTrackCommand as Tracks;
|
||||
Some(match input.event() {
|
||||
key_pat!(Char('s')) => Select(Selected::Clip(t, 0)),
|
||||
key_pat!(Char('a')) => Select(if t > 0 { Selected::Track(t - 1) } else { Selected::Mix }),
|
||||
key_pat!(Char('d')) => Select(Selected::Track((t + 1).min(len.saturating_sub(1)))),
|
||||
key_pat!(Char('c')) => Track(Tracks::SetColor(t, ItemPalette::random())),
|
||||
key_pat!(Char(',')) => Track(Tracks::Swap(t, t - 1)),
|
||||
key_pat!(Char('.')) => Track(Tracks::Swap(t, t + 1)),
|
||||
key_pat!(Char('<')) => Track(Tracks::Swap(t, t - 1)),
|
||||
key_pat!(Char('>')) => Track(Tracks::Swap(t, t + 1)),
|
||||
key_pat!(Delete) => Track(Tracks::Delete(t)),
|
||||
//key_pat!(Char('c')) => Cmd::Track(Track::Color(t, ItemPalette::random())),
|
||||
_ => return None
|
||||
})
|
||||
impl ArrangerTui {
|
||||
pub fn track_next_name (&self) -> String {
|
||||
format!("T{}", self.tracks.len() + 1)
|
||||
}
|
||||
pub fn track_add (&mut self, name: Option<&str>, color: Option<ItemPalette>)
|
||||
-> Usually<&mut ArrangerTrack>
|
||||
{
|
||||
let name = name.map_or_else(||self.track_next_name(), |x|x.to_string());
|
||||
let track = ArrangerTrack {
|
||||
width: name.len() + 2,
|
||||
name: Arc::new(name.into()),
|
||||
color: color.unwrap_or_else(||ItemPalette::random()),
|
||||
player: PhrasePlayerModel::from(&self.clock),
|
||||
};
|
||||
self.tracks.push(track);
|
||||
let index = self.tracks.len() - 1;
|
||||
Ok(&mut self.tracks[index])
|
||||
}
|
||||
pub fn track_del (&mut self, index: usize) {
|
||||
self.tracks.remove(index);
|
||||
for scene in self.scenes.iter_mut() {
|
||||
scene.clips.remove(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
command!(|self: ArrangerTrackCommand, state: ArrangerTui|match self {
|
||||
Self::SetColor(index, color) => {
|
||||
let old = state.tracks[index].color;
|
||||
state.tracks[index].color = color;
|
||||
Some(Self::SetColor(index, old))
|
||||
},
|
||||
_ => None
|
||||
});
|
||||
|
||||
#[derive(Debug)] pub struct ArrangerTrack {
|
||||
/// Name of track
|
||||
|
|
@ -38,8 +37,10 @@ command!(|self: ArrangerTrackCommand, state: ArrangerTui|match self {
|
|||
/// MIDI player state
|
||||
pub(crate) player: PhrasePlayerModel,
|
||||
}
|
||||
|
||||
has_clock!(|self:ArrangerTrack|self.player.clock());
|
||||
has_player!(|self:ArrangerTrack|self.player);
|
||||
|
||||
impl ArrangerTrack {
|
||||
pub fn widths (tracks: &[Self]) -> Vec<(usize, usize)> {
|
||||
let mut widths = vec![];
|
||||
|
|
@ -92,17 +93,6 @@ impl ArrangerTrack {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum ArrangerTrackCommand {
|
||||
Add,
|
||||
Delete(usize),
|
||||
Stop,
|
||||
Swap(usize, usize),
|
||||
SetSize(usize),
|
||||
SetZoom(usize),
|
||||
SetColor(usize, ItemPalette),
|
||||
}
|
||||
|
||||
/// Hosts the JACK callback for a collection of tracks
|
||||
pub struct TracksAudio<'a>(
|
||||
// Track collection
|
||||
|
|
@ -126,34 +116,3 @@ impl<'a> Audio for TracksAudio<'a> {
|
|||
Control::Continue
|
||||
}
|
||||
}
|
||||
impl ArrangerTui {
|
||||
pub fn tracks (&self) -> &Vec<ArrangerTrack> {
|
||||
&self.tracks
|
||||
}
|
||||
pub fn tracks_mut (&mut self) -> &mut Vec<ArrangerTrack> {
|
||||
&mut self.tracks
|
||||
}
|
||||
pub fn track_next_name (&self) -> String {
|
||||
format!("T{}", self.tracks().len() + 1)
|
||||
}
|
||||
pub fn track_add (&mut self, name: Option<&str>, color: Option<ItemPalette>)
|
||||
-> Usually<&mut ArrangerTrack>
|
||||
{
|
||||
let name = name.map_or_else(||self.track_next_name(), |x|x.to_string());
|
||||
let track = ArrangerTrack {
|
||||
width: name.len() + 2,
|
||||
name: Arc::new(name.into()),
|
||||
color: color.unwrap_or_else(||ItemPalette::random()),
|
||||
player: PhrasePlayerModel::from(&self.clock),
|
||||
};
|
||||
self.tracks_mut().push(track);
|
||||
let index = self.tracks().len() - 1;
|
||||
Ok(&mut self.tracks_mut()[index])
|
||||
}
|
||||
pub fn track_del (&mut self, index: usize) {
|
||||
self.tracks_mut().remove(index);
|
||||
for scene in self.scenes_mut().iter_mut() {
|
||||
scene.clips.remove(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue