mirror of
https://codeberg.org/unspeaker/tek.git
synced 2026-08-07 22:17:07 +02:00
refactor: Mode, View, Bind
This commit is contained in:
parent
51faa82d74
commit
701a651fbd
21 changed files with 901 additions and 880 deletions
|
|
@ -26,7 +26,7 @@ use crate::*;
|
|||
pub trait ClipsView: TracksView + ScenesView {
|
||||
/// Draw clips per scene
|
||||
fn view_scenes_clips <'a> (&'a self) -> impl Draw<Tui> + 'a {
|
||||
crate::view::view_scenes_clips(
|
||||
view_scenes_clips(
|
||||
||self.scenes_with_sizes(),
|
||||
self.tracks_with_sizes(),
|
||||
self.selection(),
|
||||
|
|
@ -87,3 +87,7 @@ impl Arrangement {
|
|||
}
|
||||
|
||||
pub trait HasClipsSize { fn clips_size (&self) -> &Size; }
|
||||
|
||||
impl HasClipsSize for App {
|
||||
fn clips_size (&self) -> &Size { &self.project.size_inner }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ pub trait ScenesView: HasEditor + HasSelection + HasSceneScroll + HasClipsSize +
|
|||
fn w_mid (&self) -> u16;
|
||||
|
||||
fn view_scenes_names (&self) -> impl Draw<Tui> {
|
||||
crate::view::view_scenes_names(
|
||||
view_scenes_names(
|
||||
self.scenes_with_sizes(), self.selection(), self.editor(), self.is_editing()
|
||||
)
|
||||
}
|
||||
|
|
@ -130,16 +130,14 @@ impl HasSceneScroll for Arrangement {
|
|||
fn scene_scroll (&self) -> usize { self.scene_scroll }
|
||||
}
|
||||
|
||||
impl HasSceneScroll for App {
|
||||
fn scene_scroll (&self) -> usize { self.project.scene_scroll() }
|
||||
}
|
||||
|
||||
impl ScenesView for Arrangement {
|
||||
fn h_scenes (&self) -> u16 {
|
||||
(self.size.h() as u16).saturating_sub(20)
|
||||
}
|
||||
fn w_side (&self) -> u16 {
|
||||
(self.size.w() as u16 * 2 / 10).max(20)
|
||||
}
|
||||
fn w_mid (&self) -> u16 {
|
||||
(self.size.w() as u16).saturating_sub(2 * self.w_side()).max(40)
|
||||
}
|
||||
fn h_scenes (&self) -> u16 { (self.size.h() as u16).saturating_sub(20) }
|
||||
fn w_side (&self) -> u16 { (self.size.w() as u16 * 2 / 10).max(20) }
|
||||
fn w_mid (&self) -> u16 { (self.size.w() as u16).saturating_sub(2 * self.w_side()).max(40) }
|
||||
}
|
||||
|
||||
pub type SceneWith<'a, T> =
|
||||
|
|
@ -148,7 +146,7 @@ pub type SceneWith<'a, T> =
|
|||
def_command!(SceneCommand: |scene: Scene| {
|
||||
SetSize { size: usize } => { todo!() },
|
||||
SetZoom { size: usize } => { todo!() },
|
||||
SetName { name: Arc<str> } =>
|
||||
SetName { name: Arc<str> } =>
|
||||
swap_value(&mut scene.name, name, |name|Self::SetName{name}),
|
||||
SetColor { color: ItemTheme } =>
|
||||
swap_value(&mut scene.color, color, |color|Self::SetColor{color}),
|
||||
|
|
@ -158,7 +156,19 @@ def_command!(SceneCommand: |scene: Scene| {
|
|||
#[cfg(all(feature = "select"))] impl_as_mut_opt!(Scene: |self: App| self.project.as_mut_opt());
|
||||
#[cfg(all(feature = "select"))] impl_as_ref_opt!(Scene: |self: Arrangement| self.selected_scene());
|
||||
#[cfg(all(feature = "select"))] impl_as_mut_opt!(Scene: |self: Arrangement| self.selected_scene_mut());
|
||||
impl<T: TracksView+ScenesView+Send+Sync> ClipsView for T {}
|
||||
impl_has!(Vec<Scene>: |self: Arrangement| self.scenes);
|
||||
impl<T: AsRef<Vec<Scene>>+AsMut<Vec<Scene>>> HasScenes for T {}
|
||||
impl<T: AsRefOpt<Scene>+AsMutOpt<Scene>+Send+Sync> HasScene for T {}
|
||||
impl_has!(Vec<Scene>: |self: Arrangement| self.scenes);
|
||||
impl<T: TracksView+ScenesView+Send+Sync> ClipsView for T {}
|
||||
impl<T: AsRef<Vec<Scene>>+AsMut<Vec<Scene>>> HasScenes for T {}
|
||||
impl<T: AsRefOpt<Scene>+AsMutOpt<Scene>+Send+Sync> HasScene for T {}
|
||||
|
||||
impl ScenesView for App {
|
||||
fn w_mid (&self) -> u16 {
|
||||
(self.size.w() as u16).saturating_sub(self.w_side())
|
||||
}
|
||||
fn w_side (&self) -> u16 {
|
||||
20
|
||||
}
|
||||
fn h_scenes (&self) -> u16 {
|
||||
(self.size.h() as u16).saturating_sub(20)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,9 +55,13 @@ impl Track {
|
|||
) -> impl Draw<Tui> + 'a {
|
||||
view_track_per(tracks, callback)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "sampler")]
|
||||
impl Track {
|
||||
|
||||
/// Create a new track connecting the [Sequencer] to a [Sampler].
|
||||
#[cfg(feature = "sampler")] pub fn new_with_sampler (
|
||||
pub fn new_with_sampler (
|
||||
name: &impl AsRef<str>,
|
||||
color: Option<ItemTheme>,
|
||||
jack: &Jack<'static>,
|
||||
|
|
@ -78,7 +82,7 @@ impl Track {
|
|||
Ok(track)
|
||||
}
|
||||
|
||||
#[cfg(feature = "sampler")] pub fn sampler (&self, mut nth: usize) -> Option<&Sampler> {
|
||||
pub fn sampler (&self, mut nth: usize) -> Option<&Sampler> {
|
||||
for device in self.devices.iter() {
|
||||
match device {
|
||||
Device::Sampler(s) => if nth == 0 { return Some(s); } else { nth -= 1; },
|
||||
|
|
@ -88,7 +92,7 @@ impl Track {
|
|||
None
|
||||
}
|
||||
|
||||
#[cfg(feature = "sampler")] pub fn sampler_mut (&mut self, mut nth: usize) -> Option<&mut Sampler> {
|
||||
pub fn sampler_mut (&mut self, mut nth: usize) -> Option<&mut Sampler> {
|
||||
for device in self.devices.iter_mut() {
|
||||
match device {
|
||||
Device::Sampler(s) => if nth == 0 { return Some(s); } else { nth -= 1; },
|
||||
|
|
@ -153,22 +157,22 @@ pub trait HasTrack: AsRefOpt<Track> + AsMutOpt<Track> {
|
|||
|
||||
#[cfg(feature = "port")]
|
||||
fn view_midi_ins_status <'a> (&'a self, theme: ItemTheme) -> impl Draw<Tui> + 'a {
|
||||
crate::view::view_midi_ins_status(theme, self.track())
|
||||
view_midi_ins_status(theme, self.track())
|
||||
}
|
||||
|
||||
#[cfg(feature = "port")]
|
||||
fn view_midi_outs_status (&self, theme: ItemTheme) -> impl Draw<Tui> + '_ {
|
||||
crate::view::view_midi_outs_status(theme, self.track())
|
||||
view_midi_outs_status(theme, self.track())
|
||||
}
|
||||
|
||||
#[cfg(feature = "port")]
|
||||
fn view_audio_ins_status (&self, theme: ItemTheme) -> impl Draw<Tui> {
|
||||
crate::view::view_audio_ins_status(theme, self.track())
|
||||
view_audio_ins_status(theme, self.track())
|
||||
}
|
||||
|
||||
#[cfg(feature = "port")]
|
||||
fn view_audio_outs_status (&self, theme: ItemTheme) -> impl Draw<Tui> {
|
||||
crate::view::view_audio_outs_status(theme, self.track())
|
||||
view_audio_outs_status(theme, self.track())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -179,13 +183,13 @@ pub trait HasTrackScroll: HasTracks {
|
|||
pub trait TracksView: ScenesView + HasMidiIns + HasMidiOuts + HasTrackScroll {
|
||||
/// Draw name of each track
|
||||
fn view_track_names (&self, theme: ItemTheme) -> impl Draw<Tui> {
|
||||
crate::view::view_track_names(
|
||||
view_track_names(
|
||||
theme, self.tracks_with_sizes(), self.tracks().len(), self.scenes().len(), self.selection()
|
||||
)
|
||||
}
|
||||
/// Draw outputs per track
|
||||
fn view_track_outputs <'a> (&'a self, theme: ItemTheme, _h: u16) -> impl Draw<Tui> {
|
||||
crate::view::view_track_outputs(
|
||||
view_track_outputs(
|
||||
theme, self.tracks_with_sizes(), self.midi_outs().iter()
|
||||
)
|
||||
}
|
||||
|
|
@ -195,7 +199,7 @@ pub trait TracksView: ScenesView + HasMidiIns + HasMidiOuts + HasTrackScroll {
|
|||
for track in self.tracks().iter() {
|
||||
h = h.max(track.sequencer.midi_ins.len() as u16);
|
||||
}
|
||||
crate::view::view_track_inputs(theme, self.tracks_with_sizes(), h)
|
||||
view_track_inputs(theme, self.tracks_with_sizes(), h)
|
||||
}
|
||||
/// Iterate over tracks with their corresponding sizes.
|
||||
fn tracks_with_sizes (&self) -> impl TracksSizes<'_> {
|
||||
|
|
@ -247,19 +251,19 @@ impl_as_mut!(Vec<Track>: |self: App| self.project.as_mut());
|
|||
impl Arrangement {
|
||||
|
||||
pub fn view_inputs (&self, _theme: ItemTheme) -> impl Draw<Tui> + '_ {
|
||||
crate::view::view_inputs(
|
||||
view_inputs(
|
||||
self.tracks_with_sizes(), self.midi_ins().as_slice()
|
||||
)
|
||||
}
|
||||
|
||||
pub fn view_outputs (&self, theme: ItemTheme) -> impl Draw<Tui> {
|
||||
crate::view::view_outputs(
|
||||
view_outputs(
|
||||
theme, self.tracks_with_sizes(), self.midi_outs(), self.outputs_height()
|
||||
)
|
||||
}
|
||||
|
||||
pub fn view_track_devices (&self, theme: ItemTheme) -> impl Draw<Tui> {
|
||||
crate::view::view_track_devices(
|
||||
view_track_devices(
|
||||
theme, self.tracks_with_sizes(), self.track(), self.devices_height()
|
||||
)
|
||||
}
|
||||
|
|
@ -334,3 +338,13 @@ impl Arrangement {
|
|||
Ok((index, &mut self.tracks_mut()[index]))
|
||||
}
|
||||
}
|
||||
|
||||
impl HasTrackScroll for App {
|
||||
fn track_scroll (&self) -> usize {
|
||||
self.project.track_scroll()
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn track_width (_index: usize, track: &Track) -> u16 {
|
||||
track.width as u16
|
||||
}
|
||||
|
|
|
|||
|
|
@ -145,6 +145,27 @@ impl Quantize {
|
|||
}
|
||||
}
|
||||
|
||||
/// Implement an arithmetic operation for a unit of time
|
||||
#[macro_export] macro_rules! impl_op {
|
||||
($T:ident, $Op:ident, $method:ident, |$a:ident,$b:ident|{$impl:expr}) => {
|
||||
impl $Op<Self> for $T {
|
||||
type Output = Self; #[inline] fn $method (self, other: Self) -> Self::Output {
|
||||
let $a = self.get(); let $b = other.get(); Self($impl.into())
|
||||
}
|
||||
}
|
||||
impl $Op<usize> for $T {
|
||||
type Output = Self; #[inline] fn $method (self, other: usize) -> Self::Output {
|
||||
let $a = self.get(); let $b = other as f64; Self($impl.into())
|
||||
}
|
||||
}
|
||||
impl $Op<f64> for $T {
|
||||
type Output = Self; #[inline] fn $method (self, other: f64) -> Self::Output {
|
||||
let $a = self.get(); let $b = other; Self($impl.into())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Define and implement a unit of time
|
||||
#[macro_export] macro_rules! impl_time_unit {
|
||||
($T:ident) => {
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ impl Dialog {
|
|||
MenuItem("Resume session".into(), Arc::new(Box::new(|_|Ok(())))),
|
||||
MenuItem("Create new session".into(), Arc::new(Box::new(|app|Ok({
|
||||
app.dialog = Dialog::None;
|
||||
app.mode = app.config.modes.clone().read().unwrap().get(":arranger").cloned().unwrap();
|
||||
app.mode = app.config.modes.get(":arranger").unwrap();
|
||||
})))),
|
||||
MenuItem("Load old session".into(), Arc::new(Box::new(|_|Ok(())))),
|
||||
].into()))
|
||||
|
|
|
|||
|
|
@ -1,5 +1,13 @@
|
|||
use crate::*;
|
||||
|
||||
#[cfg(feature = "lv2_gui")] use ::winit::{
|
||||
application::ApplicationHandler,
|
||||
event::WindowEvent,
|
||||
event_loop::{ActiveEventLoop, ControlFlow, EventLoop},
|
||||
window::{Window, WindowId},
|
||||
platform::x11::EventLoopBuilderExtX11
|
||||
};
|
||||
|
||||
/// A LV2 plugin.
|
||||
#[derive(Debug)] #[cfg(feature = "lv2")] pub struct Lv2 {
|
||||
/// JACK client handle (needs to not be dropped for standalone mode to work).
|
||||
|
|
|
|||
|
|
@ -3,14 +3,13 @@ use ConnectName::*;
|
|||
use ConnectScope::*;
|
||||
use ConnectStatus::*;
|
||||
|
||||
pub mod audio; pub use self::audio::*;
|
||||
pub mod midi; pub use self::midi::*;
|
||||
pub mod connect; pub use self::connect::*;
|
||||
mod audio; pub use self::audio::*;
|
||||
mod midi; pub use self::midi::*;
|
||||
mod connect; pub use self::connect::*;
|
||||
mod register; pub use self::register::*;
|
||||
|
||||
pub trait JackPort: HasJack<'static> {
|
||||
|
||||
type Port: PortSpec + Default;
|
||||
|
||||
type Pair: PortSpec + Default;
|
||||
|
||||
fn new (jack: &Jack<'static>, name: &impl AsRef<str>, connect: &[Connect])
|
||||
|
|
@ -135,29 +134,3 @@ pub trait JackPort: HasJack<'static> {
|
|||
}))
|
||||
}
|
||||
}
|
||||
|
||||
pub trait RegisterPorts: HasJack<'static> {
|
||||
/// Register a MIDI input port.
|
||||
fn midi_in (&self, name: &impl AsRef<str>, connect: &[Connect]) -> Usually<MidiInput>;
|
||||
/// Register a MIDI output port.
|
||||
fn midi_out (&self, name: &impl AsRef<str>, connect: &[Connect]) -> Usually<MidiOutput>;
|
||||
/// Register an audio input port.
|
||||
fn audio_in (&self, name: &impl AsRef<str>, connect: &[Connect]) -> Usually<AudioInput>;
|
||||
/// Register an audio output port.
|
||||
fn audio_out (&self, name: &impl AsRef<str>, connect: &[Connect]) -> Usually<AudioOutput>;
|
||||
}
|
||||
|
||||
impl<J: HasJack<'static>> RegisterPorts for J {
|
||||
fn midi_in (&self, name: &impl AsRef<str>, connect: &[Connect]) -> Usually<MidiInput> {
|
||||
MidiInput::new(self.jack(), name, connect)
|
||||
}
|
||||
fn midi_out (&self, name: &impl AsRef<str>, connect: &[Connect]) -> Usually<MidiOutput> {
|
||||
MidiOutput::new(self.jack(), name, connect)
|
||||
}
|
||||
fn audio_in (&self, name: &impl AsRef<str>, connect: &[Connect]) -> Usually<AudioInput> {
|
||||
AudioInput::new(self.jack(), name, connect)
|
||||
}
|
||||
fn audio_out (&self, name: &impl AsRef<str>, connect: &[Connect]) -> Usually<AudioOutput> {
|
||||
AudioOutput::new(self.jack(), name, connect)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
27
src/device/port/register.rs
Normal file
27
src/device/port/register.rs
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
use crate::*;
|
||||
|
||||
pub trait RegisterPorts: HasJack<'static> {
|
||||
/// Register a MIDI input port.
|
||||
fn midi_in (&self, name: &impl AsRef<str>, connect: &[Connect]) -> Usually<MidiInput>;
|
||||
/// Register a MIDI output port.
|
||||
fn midi_out (&self, name: &impl AsRef<str>, connect: &[Connect]) -> Usually<MidiOutput>;
|
||||
/// Register an audio input port.
|
||||
fn audio_in (&self, name: &impl AsRef<str>, connect: &[Connect]) -> Usually<AudioInput>;
|
||||
/// Register an audio output port.
|
||||
fn audio_out (&self, name: &impl AsRef<str>, connect: &[Connect]) -> Usually<AudioOutput>;
|
||||
}
|
||||
|
||||
impl<J: HasJack<'static>> RegisterPorts for J {
|
||||
fn midi_in (&self, name: &impl AsRef<str>, connect: &[Connect]) -> Usually<MidiInput> {
|
||||
MidiInput::new(self.jack(), name, connect)
|
||||
}
|
||||
fn midi_out (&self, name: &impl AsRef<str>, connect: &[Connect]) -> Usually<MidiOutput> {
|
||||
MidiOutput::new(self.jack(), name, connect)
|
||||
}
|
||||
fn audio_in (&self, name: &impl AsRef<str>, connect: &[Connect]) -> Usually<AudioInput> {
|
||||
AudioInput::new(self.jack(), name, connect)
|
||||
}
|
||||
fn audio_out (&self, name: &impl AsRef<str>, connect: &[Connect]) -> Usually<AudioOutput> {
|
||||
AudioOutput::new(self.jack(), name, connect)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,13 @@
|
|||
use crate::{*, device::*, browse::*, mix::*};
|
||||
|
||||
pub(crate) use symphonia::{
|
||||
default::get_codecs,
|
||||
core::{//errors::Error as SymphoniaError,
|
||||
audio::SampleBuffer, formats::Packet, io::MediaSourceStream, probe::Hint,
|
||||
codecs::{Decoder, CODEC_TYPE_NULL},
|
||||
},
|
||||
};
|
||||
|
||||
mod voice; pub use self::voice::*;
|
||||
mod sample; pub use self::sample::*;
|
||||
mod sample_add; pub use self::sample_add::*;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue