mirror of
https://codeberg.org/unspeaker/tek.git
synced 2026-02-21 16:29:04 +01:00
This commit is contained in:
parent
abf950aea4
commit
817d2a722c
7 changed files with 214 additions and 217 deletions
205
app/tek.rs
205
app/tek.rs
|
|
@ -7,21 +7,10 @@
|
|||
trait_alias,
|
||||
type_alias_impl_trait,
|
||||
type_changing_struct_update)]
|
||||
|
||||
#[allow(unused)] pub(crate) use ::{
|
||||
std::{
|
||||
cmp::Ord,
|
||||
collections::BTreeMap,
|
||||
error::Error,
|
||||
ffi::OsString,
|
||||
fmt::{Write, Debug, Formatter},
|
||||
fs::File,
|
||||
ops::{Add, Sub, Mul, Div, Rem},
|
||||
path::{Path, PathBuf},
|
||||
sync::{Arc, RwLock, atomic::{AtomicBool, AtomicUsize, Ordering::Relaxed}},
|
||||
thread::{spawn, JoinHandle},
|
||||
},
|
||||
};
|
||||
mod tek_struct; pub use self::tek_struct::*;
|
||||
mod tek_trait; pub use self::tek_trait::*;
|
||||
mod tek_type; pub use self::tek_type::*;
|
||||
mod tek_impls;
|
||||
extern crate xdg;
|
||||
pub(crate) use ::xdg::BaseDirectories;
|
||||
pub extern crate atomic_float;
|
||||
|
|
@ -44,15 +33,11 @@ pub(crate) use tengri::{
|
|||
},
|
||||
};
|
||||
#[cfg(feature = "sampler")] pub(crate) use symphonia::{
|
||||
core::{
|
||||
formats::Packet,
|
||||
codecs::{Decoder, CODEC_TYPE_NULL},
|
||||
//errors::Error as SymphoniaError,
|
||||
io::MediaSourceStream,
|
||||
probe::Hint,
|
||||
audio::SampleBuffer,
|
||||
},
|
||||
default::get_codecs,
|
||||
core::{//errors::Error as SymphoniaError,
|
||||
audio::SampleBuffer, formats::Packet, io::MediaSourceStream, probe::Hint,
|
||||
codecs::{Decoder, CODEC_TYPE_NULL},
|
||||
},
|
||||
};
|
||||
#[cfg(feature = "lv2_gui")] use ::winit::{
|
||||
application::ApplicationHandler,
|
||||
|
|
@ -61,19 +46,20 @@ pub(crate) use tengri::{
|
|||
window::{Window, WindowId},
|
||||
platform::x11::EventLoopBuilderExtX11
|
||||
};
|
||||
|
||||
#[cfg(test)] mod tek_test;
|
||||
|
||||
mod tek_struct;
|
||||
pub use self::tek_struct::*;
|
||||
|
||||
mod tek_trait;
|
||||
pub use self::tek_trait::*;
|
||||
|
||||
mod tek_type;
|
||||
pub use self::tek_type::*;
|
||||
|
||||
mod tek_impls;
|
||||
#[allow(unused)] pub(crate) use ::{
|
||||
std::{
|
||||
cmp::Ord,
|
||||
collections::BTreeMap,
|
||||
error::Error,
|
||||
ffi::OsString,
|
||||
fmt::{Write, Debug, Formatter},
|
||||
fs::File,
|
||||
ops::{Add, Sub, Mul, Div, Rem},
|
||||
path::{Path, PathBuf},
|
||||
sync::{Arc, RwLock, atomic::{AtomicBool, AtomicUsize, Ordering::Relaxed}},
|
||||
thread::{spawn, JoinHandle},
|
||||
},
|
||||
};
|
||||
|
||||
pub(crate) use ConnectName::*;
|
||||
pub(crate) use ConnectScope::*;
|
||||
|
|
@ -92,23 +78,23 @@ pub(crate) use JackState::*;
|
|||
/// let jack = tek::Jack::new(&"test_tek").expect("failed to connect to jack");
|
||||
/// let proj = Default::default();
|
||||
/// let conf = Default::default();
|
||||
/// let tek = tek::tek(&jack, proj, conf, "");
|
||||
/// let tek = tek::tek(&jack, proj, conf, "mode-doctest");
|
||||
/// ```
|
||||
pub fn tek (
|
||||
jack: &Jack<'static>, project: Arrangement, config: Config, mode: impl AsRef<str>
|
||||
) -> App {
|
||||
let mode: &str = mode.as_ref();
|
||||
App {
|
||||
color: ItemTheme::random(),
|
||||
dialog: Dialog::welcome(),
|
||||
jack: jack.clone(),
|
||||
mode: config.get_mode(mode).expect("failed to find mode"),
|
||||
mode: config.get_mode(mode).expect(&format!("failed to find mode '{mode}'")),
|
||||
config,
|
||||
project,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn tek_confirm (state: &mut App) -> Perhaps<AppCommand> {
|
||||
Ok(match &state.dialog {
|
||||
Dialog::Menu(index, items) => {
|
||||
|
|
@ -202,6 +188,7 @@ fn collect_commands (
|
|||
}
|
||||
Ok(commands)
|
||||
}
|
||||
|
||||
fn execute_commands (
|
||||
app: &mut App, commands: Vec<AppCommand>
|
||||
) -> Usually<Vec<(AppCommand, Option<AppCommand>)>> {
|
||||
|
|
@ -213,6 +200,7 @@ fn execute_commands (
|
|||
}
|
||||
Ok(history)
|
||||
}
|
||||
|
||||
pub fn tek_jack_process (app: &mut App, client: &Client, scope: &ProcessScope) -> Control {
|
||||
let t0 = app.perf.get_t0();
|
||||
app.clock().update_from_scope(scope).unwrap();
|
||||
|
|
@ -236,6 +224,7 @@ pub fn tek_jack_process (app: &mut App, client: &Client, scope: &ProcessScope) -
|
|||
app.perf.update_from_jack_scope(t0, scope);
|
||||
result
|
||||
}
|
||||
|
||||
pub fn tek_jack_event (app: &mut App, event: JackEvent) {
|
||||
use JackEvent::*;
|
||||
match event {
|
||||
|
|
@ -258,9 +247,11 @@ pub fn tek_jack_event (app: &mut App, event: JackEvent) {
|
|||
_ => { panic!("{event:?}"); }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tek_show_version () {
|
||||
println!("todo version");
|
||||
}
|
||||
|
||||
pub fn tek_print_config (config: &Config) {
|
||||
use ::ansi_term::Color::*;
|
||||
println!("{:?}", config.dirs);
|
||||
|
|
@ -313,6 +304,7 @@ pub fn tek_print_config (config: &Config) {
|
|||
println!();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tek_print_status (project: &Arrangement) {
|
||||
println!("Name: {:?}", &project.name);
|
||||
println!("JACK: {:?}", &project.jack);
|
||||
|
|
@ -432,94 +424,6 @@ pub fn note_pitch_to_name (n: usize) -> &'static str {
|
|||
NOTE_NAMES[n]
|
||||
}
|
||||
|
||||
|
||||
//macro_rules! impl_port {
|
||||
//($Name:ident : $Spec:ident -> $Pair:ident |$jack:ident, $name:ident|$port:expr) => {
|
||||
//#[derive(Debug)] pub struct $Name {
|
||||
///// Handle to JACK client, for receiving reconnect events.
|
||||
//jack: Jack<'static>,
|
||||
///// Port name
|
||||
//name: Arc<str>,
|
||||
///// Port handle.
|
||||
//port: Port<$Spec>,
|
||||
///// List of ports to connect to.
|
||||
//conn: Vec<PortConnect>
|
||||
//}
|
||||
//impl AsRef<Port<$Spec>> for $Name {
|
||||
//fn as_ref (&self) -> &Port<$Spec> { &self.port }
|
||||
//}
|
||||
//impl $Name {
|
||||
//pub fn new ($jack: &Jack, name: impl AsRef<str>, connect: &[PortConnect])
|
||||
//-> Usually<Self>
|
||||
//{
|
||||
//let $name = name.as_ref();
|
||||
//let jack = $jack.clone();
|
||||
//let port = $port?;
|
||||
//let name = $name.into();
|
||||
//let conn = connect.to_vec();
|
||||
//let port = Self { jack, port, name, conn };
|
||||
//port.connect_to_matching()?;
|
||||
//Ok(port)
|
||||
//}
|
||||
//pub fn name (&self) -> &Arc<str> { &self.name }
|
||||
//pub fn port (&self) -> &Port<$Spec> { &self.port }
|
||||
//pub fn port_mut (&mut self) -> &mut Port<$Spec> { &mut self.port }
|
||||
//pub fn into_port (self) -> Port<$Spec> { self.port }
|
||||
//pub fn close (self) -> Usually<()> {
|
||||
//let Self { jack, port, .. } = self;
|
||||
//Ok(jack.with_client(|client|client.unregister_port(port))?)
|
||||
//}
|
||||
//}
|
||||
//impl HasJack<'static> for $Name {
|
||||
//fn jack (&self) -> &'static Jack<'static> { &self.jack }
|
||||
//}
|
||||
//impl JackPort<'static> for $Name {
|
||||
//type Port = $Spec;
|
||||
//type Pair = $Pair;
|
||||
//fn port (&self) -> &Port<$Spec> { &self.port }
|
||||
//}
|
||||
//impl ConnectTo<'static, &str> for $Name {
|
||||
//fn connect_to (&self, to: &str) -> Usually<PortConnectStatus> {
|
||||
//self.with_client(|c|if let Some(ref port) = c.port_by_name(to.as_ref()) {
|
||||
//self.connect_to(port)
|
||||
//} else {
|
||||
//Ok(Missing)
|
||||
//})
|
||||
//}
|
||||
//}
|
||||
//impl ConnectTo<'static, &Port<Unowned>> for $Name {
|
||||
//fn connect_to (&self, port: &Port<Unowned>) -> Usually<PortConnectStatus> {
|
||||
//self.with_client(|c|Ok(if let Ok(_) = c.connect_ports(&self.port, port) {
|
||||
//Connected
|
||||
//} else if let Ok(_) = c.connect_ports(port, &self.port) {
|
||||
//Connected
|
||||
//} else {
|
||||
//Mismatch
|
||||
//}))
|
||||
//}
|
||||
//}
|
||||
//impl ConnectTo<'static, &Port<$Pair>> for $Name {
|
||||
//fn connect_to (&self, port: &Port<$Pair>) -> Usually<PortConnectStatus> {
|
||||
//self.with_client(|c|Ok(if let Ok(_) = c.connect_ports(&self.port, port) {
|
||||
//Connected
|
||||
//} else if let Ok(_) = c.connect_ports(port, &self.port) {
|
||||
//Connected
|
||||
//} else {
|
||||
//Mismatch
|
||||
//}))
|
||||
//}
|
||||
//}
|
||||
//impl ConnectAuto<'static> for $Name {
|
||||
//fn connections (&self) -> &[PortConnect] {
|
||||
//&self.conn
|
||||
//}
|
||||
//}
|
||||
//};
|
||||
//}
|
||||
|
||||
|
||||
|
||||
|
||||
pub fn swap_value <T: Clone + PartialEq, U> (
|
||||
target: &mut T, value: &T, returned: impl Fn(T)->U
|
||||
) -> Perhaps<U> {
|
||||
|
|
@ -1104,10 +1008,13 @@ mod size {
|
|||
def_sizes_iter!(TracksSizes => Track);
|
||||
}
|
||||
|
||||
pub(crate) use self::view::*;
|
||||
pub use self::view::*;
|
||||
mod view {
|
||||
use crate::*;
|
||||
|
||||
/// ```
|
||||
/// let _ = tek::view_logo();
|
||||
/// ```
|
||||
pub fn view_logo () -> impl Content<TuiOut> {
|
||||
Fixed::XY(32, 7, Tui::bold(true, Tui::fg(Rgb(240,200,180), col!{
|
||||
Fixed::Y(1, ""),
|
||||
|
|
@ -1118,6 +1025,11 @@ mod view {
|
|||
})))
|
||||
}
|
||||
|
||||
/// ```
|
||||
/// let x = std::sync::Arc::<std::sync::RwLock<String>>::default();
|
||||
/// let _ = tek::view_transport(true, x.clone(), x.clone(), x.clone());
|
||||
/// let _ = tek::view_transport(false, x.clone(), x.clone(), x.clone());
|
||||
/// ```
|
||||
pub fn view_transport (
|
||||
play: bool,
|
||||
bpm: Arc<RwLock<String>>,
|
||||
|
|
@ -1135,6 +1047,11 @@ mod view {
|
|||
)))
|
||||
}
|
||||
|
||||
/// ```
|
||||
/// let x = std::sync::Arc::<std::sync::RwLock<String>>::default();
|
||||
/// let _ = tek::view_status(None, x.clone(), x.clone(), x.clone());
|
||||
/// let _ = tek::view_status(Some("".into()), x.clone(), x.clone(), x.clone());
|
||||
/// ```
|
||||
pub fn view_status (
|
||||
sel: Option<Arc<str>>,
|
||||
sr: Arc<RwLock<String>>,
|
||||
|
|
@ -1152,6 +1069,9 @@ mod view {
|
|||
)))
|
||||
}
|
||||
|
||||
/// ```
|
||||
/// let _ = tek::button_play_pause(true);
|
||||
/// ```
|
||||
pub fn button_play_pause (playing: bool) -> impl Content<TuiOut> {
|
||||
let compact = true;//self.is_editing();
|
||||
Tui::bg(if playing { Rgb(0, 128, 0) } else { Rgb(128, 64, 0) },
|
||||
|
|
@ -1178,12 +1098,21 @@ mod view {
|
|||
Bsp::e(Fixed::X(20, Fill::Y(Align::nw(button))), Fill::XY(Align::c(content))))
|
||||
}
|
||||
|
||||
pub fn wrap (bg: Color, fg: Color, content: impl Content<TuiOut>) -> impl Content<TuiOut> {
|
||||
/// ```
|
||||
/// let bg = tengri::ratatui::style::Color::Red;
|
||||
/// let fg = tengri::ratatui::style::Color::Green;
|
||||
/// let _ = tek::view_wrap(bg, fg, "and then blue, too!");
|
||||
/// ```
|
||||
pub fn view_wrap (bg: Color, fg: Color, content: impl Content<TuiOut>) -> impl Content<TuiOut> {
|
||||
let left = Tui::fg_bg(bg, Reset, Fixed::X(1, Repeat::Y("▐")));
|
||||
let right = Tui::fg_bg(bg, Reset, Fixed::X(1, Repeat::Y("▌")));
|
||||
Bsp::e(left, Bsp::w(right, Tui::fg_bg(fg, bg, content)))
|
||||
}
|
||||
|
||||
/// ```
|
||||
/// let _ = tek::view_meter("", 0.0);
|
||||
/// let _ = tek::view_meters(&[0.0, 0.0]);
|
||||
/// ```
|
||||
pub fn view_meter <'a> (label: &'a str, value: f32) -> impl Content<TuiOut> + 'a {
|
||||
col!(
|
||||
FieldH(ItemTheme::G[128], label, format!("{:>+9.3}", value)),
|
||||
|
|
@ -1331,3 +1260,21 @@ mod view {
|
|||
Ok(label1.len() + label2.len() + 4)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)] mod test_view_meter {
|
||||
use super::*;
|
||||
use proptest::prelude::*;
|
||||
proptest! {
|
||||
#[test] fn proptest_view_meter (
|
||||
label in "\\PC*", value in f32::MIN..f32::MAX
|
||||
) {
|
||||
let _ = view_meter(&label, value);
|
||||
}
|
||||
#[test] fn proptest_view_meters (
|
||||
value1 in f32::MIN..f32::MAX,
|
||||
value2 in f32::MIN..f32::MAX
|
||||
) {
|
||||
let _ = view_meters(&[value1, value2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue