mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 11:46:41 +01:00
wip: down to 13 errors
This commit is contained in:
parent
6ce83fb27a
commit
ebdb8881e9
19 changed files with 793 additions and 691 deletions
|
|
@ -6,27 +6,21 @@ pub struct App {
|
|||
pub jack: Jack,
|
||||
/// Port handles
|
||||
pub ports: std::collections::BTreeMap<u32, Port<Unowned>>,
|
||||
/// Source of time
|
||||
pub clock: Clock,
|
||||
/// Display size
|
||||
pub size: Measure<TuiOut>,
|
||||
/// Performance counter
|
||||
pub perf: PerfModel,
|
||||
|
||||
// View and input definition
|
||||
pub config: Configuration,
|
||||
/// Undo history
|
||||
pub history: Vec<AppCommand>,
|
||||
// Dialog overlay
|
||||
pub dialog: Option<Dialog>,
|
||||
/// Browses external resources, such as directories
|
||||
pub browser: Option<Browser>,
|
||||
/// Contains all clips in the project
|
||||
pub pool: Option<Pool>,
|
||||
/// Contains the currently edited MIDI clip
|
||||
pub editor: Option<MidiEditor>,
|
||||
pub config: Configuration,
|
||||
/// Contains the currently edited musical arrangement
|
||||
pub arranger: Arrangement,
|
||||
pub project: Arrangement,
|
||||
/// Undo history
|
||||
pub history: Vec<AppCommand>,
|
||||
// Dialog overlay
|
||||
pub dialog: Option<Dialog>,
|
||||
/// Contains the currently edited MIDI clip
|
||||
pub editor: Option<MidiEditor>,
|
||||
|
||||
// Cache of formatted strings
|
||||
pub view_cache: Arc<RwLock<ViewCache>>,
|
||||
|
|
@ -34,11 +28,12 @@ pub struct App {
|
|||
pub color: ItemTheme,
|
||||
}
|
||||
|
||||
has!(Option<Selection>: |self: App|self.arrangement.selected);
|
||||
has!(Vec<JackMidiIn>: |self: App|self.arrangement.midi_ins);
|
||||
has!(Vec<JackMidiOut>: |self: App|self.arrangement.midi_outs);
|
||||
has!(Vec<Scene>: |self: App|self.arrangement.scenes);
|
||||
has!(Vec<Track>: |self: App|self.arrangement.tracks);
|
||||
has!(Option<Selection>: |self: App|self.project.selected);
|
||||
has!(Vec<JackMidiIn>: |self: App|self.project.midi_ins);
|
||||
has!(Vec<JackMidiOut>: |self: App|self.project.midi_outs);
|
||||
has!(Vec<Scene>: |self: App|self.project.scenes);
|
||||
has!(Vec<Track>: |self: App|self.project.tracks);
|
||||
has!(Clock: |self: App|self.project.clock);
|
||||
|
||||
impl App {
|
||||
pub fn toggle_dialog (&mut self, dialog: Option<Dialog>) {
|
||||
|
|
@ -67,11 +62,85 @@ impl App {
|
|||
}
|
||||
pub(crate) fn device_add (&mut self, index: usize) -> Usually<()> {
|
||||
match index {
|
||||
0 => self.arrangement.device_add_sampler(),
|
||||
1 => self.arrangement.device_add_lv2(),
|
||||
0 => self.device_add_sampler(),
|
||||
1 => self.device_add_lv2(),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
fn device_add_lv2 (&mut self) -> Usually<()> {
|
||||
todo!();
|
||||
Ok(())
|
||||
}
|
||||
fn device_add_sampler (&mut self, jack: &Jack) -> Usually<usize> {
|
||||
let name = jack.with_client(|c|c.name().to_string());
|
||||
let midi = self.track().expect("no active track").sequencer.midi_outs[0].name();
|
||||
let sampler = if let Ok(sampler) = Sampler::new(
|
||||
jack,
|
||||
&format!("{}/Sampler", Has::<Track>::get(self).name),
|
||||
&[PortConnect::exact(format!("{name}:{midi}"))],
|
||||
&[&[], &[]],
|
||||
&[&[], &[]]
|
||||
) {
|
||||
self.dialog = None;
|
||||
Device::Sampler(sampler)
|
||||
} else {
|
||||
self.dialog = Some(Dialog::Message(Message::FailedToAddDevice));
|
||||
return Err("failed to add device".into())
|
||||
};
|
||||
Has::<Track>::get_mut(self).expect("no active track").devices.push(sampler);
|
||||
Ok(())
|
||||
}
|
||||
// Create new clip in pool when entering empty cell
|
||||
fn clip_auto_create (&mut self) -> Option<Arc<RwLock<MidiClip>>> {
|
||||
if let Some(pool) = Has::<Option<Pool>>::get(self)
|
||||
&& let Some(Selection::TrackClip { track, scene }) = self.get()
|
||||
&& let Some(scene) = Has::<Vec<Scene>>::get_mut(self).get_mut(*scene)
|
||||
&& let Some(slot) = scene.clips.get_mut(*track)
|
||||
&& slot.is_none()
|
||||
&& let Some(track) = Has::<Vec<Track>>::get_mut(self).get_mut(*track)
|
||||
{
|
||||
let (index, mut clip) = pool.add_new_clip();
|
||||
// autocolor: new clip colors from scene and track color
|
||||
let color = track.color.base.mix(scene.color.base, 0.5);
|
||||
clip.write().unwrap().color = ItemColor::random_near(color, 0.2).into();
|
||||
if let Some(ref mut editor) = Has::<Option<MidiEditor>>::get_mut(self) {
|
||||
editor.set_clip(Some(&clip));
|
||||
}
|
||||
*slot = Some(clip.clone());
|
||||
Some(clip)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "pool", feature = "editor"))]
|
||||
pub trait AutoRemove:
|
||||
Has<Vec<Scene>> +
|
||||
Has<Vec<Track>> +
|
||||
Has<Option<MidiEditor>> +
|
||||
Has<Option<Selection>> +
|
||||
Has<Option<Pool>> +
|
||||
Send + Sync
|
||||
{
|
||||
// Remove clip from arrangement when exiting empty clip editor
|
||||
fn clip_auto_remove (&mut self) {
|
||||
if let Some(ref mut pool) = Has::<Option<Pool>>::get(self)
|
||||
&& let Some(Selection::TrackClip { track, scene }) = self.get()
|
||||
&& let Some(scene) = Has::<Vec<Scene>>::get_mut(self).get_mut(*scene)
|
||||
&& let Some(slot) = scene.clips.get_mut(*track)
|
||||
&& let Some(clip) = slot.as_mut()
|
||||
{
|
||||
let mut swapped = None;
|
||||
if clip.read().unwrap().count_midi_messages() == 0 {
|
||||
std::mem::swap(&mut swapped, slot);
|
||||
}
|
||||
if let Some(clip) = swapped {
|
||||
pool.delete_clip(&clip.read().unwrap());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Various possible dialog overlays
|
||||
|
|
@ -81,8 +150,8 @@ pub enum Dialog {
|
|||
Menu,
|
||||
Device(usize),
|
||||
Message(Message),
|
||||
Save,
|
||||
Load,
|
||||
Save(Browser),
|
||||
Load(Browser),
|
||||
Options,
|
||||
}
|
||||
|
||||
|
|
@ -234,27 +303,4 @@ impl App {
|
|||
0
|
||||
}
|
||||
}
|
||||
fn device_add_lv2 (&mut self) -> Usually<()> {
|
||||
todo!();
|
||||
Ok(())
|
||||
}
|
||||
fn device_add_sampler (&mut self, jack: &Jack) -> Usually<usize> {
|
||||
let name = jack.with_client(|c|c.name().to_string());
|
||||
let midi = self.track().expect("no active track").sequencer.midi_outs[0].name();
|
||||
let sampler = if let Ok(sampler) = Sampler::new(
|
||||
jack,
|
||||
&format!("{}/Sampler", Has::<Track>::get(self).name),
|
||||
&[PortConnect::exact(format!("{name}:{midi}"))],
|
||||
&[&[], &[]],
|
||||
&[&[], &[]]
|
||||
) {
|
||||
self.dialog = None;
|
||||
Device::Sampler(sampler)
|
||||
} else {
|
||||
self.dialog = Some(Dialog::Message(Message::FailedToAddDevice));
|
||||
return Err("failed to add device".into())
|
||||
};
|
||||
Has::<Track>::get_mut(self).expect("no active track").devices.push(sampler);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue