mirror of
https://codeberg.org/unspeaker/tek.git
synced 2026-02-21 08:19:03 +01:00
213 lines
6.1 KiB
Rust
213 lines
6.1 KiB
Rust
use crate::*;
|
|
use clap::{self, Parser, Subcommand};
|
|
use builder_pattern::Builder;
|
|
|
|
/// Total state
|
|
///
|
|
/// ```
|
|
/// let app: tek::App = Default::default();
|
|
/// ```
|
|
#[derive(Default, Debug)] pub struct App {
|
|
/// Base color.
|
|
pub color: ItemTheme,
|
|
/// Must not be dropped for the duration of the process
|
|
pub jack: Jack<'static>,
|
|
/// Display size
|
|
pub size: Measure<TuiOut>,
|
|
/// Performance counter
|
|
pub perf: PerfModel,
|
|
/// Available view modes and input bindings
|
|
pub config: Config,
|
|
/// Currently selected mode
|
|
pub mode: Arc<Mode<Arc<str>>>,
|
|
/// Undo history
|
|
pub history: Vec<(AppCommand, Option<AppCommand>)>,
|
|
/// Dialog overlay
|
|
pub dialog: Dialog,
|
|
/// Contains all recently created clips.
|
|
pub pool: Pool,
|
|
/// Contains the currently edited musical arrangement
|
|
pub project: Arrangement,
|
|
/// Error, if any
|
|
pub error: Arc<RwLock<Option<Arc<str>>>>
|
|
}
|
|
|
|
/// Configuration: mode, view, and bind definitions.
|
|
///
|
|
/// ```
|
|
/// let conf: tek::Config = Default::default();
|
|
/// ```
|
|
#[derive(Default, Debug)] pub struct Config {
|
|
/// XDG base directories of running user.
|
|
pub dirs: BaseDirectories,
|
|
/// Active collection of interaction modes.
|
|
pub modes: Modes,
|
|
/// Active collection of event bindings.
|
|
pub binds: Binds,
|
|
/// Active collection of view definitions.
|
|
pub views: Views,
|
|
}
|
|
|
|
/// Group of view and keys definitions.
|
|
///
|
|
/// ```
|
|
/// let mode: tek::Mode<std::sync::Arc<str>> = Default::default();
|
|
/// ```
|
|
#[derive(Default, Debug)] pub struct Mode<D: Language + Ord> {
|
|
pub path: PathBuf,
|
|
pub name: Vec<D>,
|
|
pub info: Vec<D>,
|
|
pub view: Vec<D>,
|
|
pub keys: Vec<D>,
|
|
pub modes: Modes,
|
|
}
|
|
|
|
/// An input binding.
|
|
///
|
|
/// ```
|
|
/// let bind: tek::Bind<(), ()> = Default::default();
|
|
/// ```
|
|
#[derive(Debug)] pub struct Bind<E, C>(
|
|
/// Map of each event (e.g. key combination) to
|
|
/// all command expressions bound to it by
|
|
/// all loaded input layers.
|
|
pub BTreeMap<E, Vec<Binding<C>>>
|
|
);
|
|
|
|
/// An input binding.
|
|
///
|
|
/// ```
|
|
/// let binding: tek::Binding<()> = Default::default();
|
|
/// ```
|
|
#[derive(Debug, Clone)] pub struct Binding<C> {
|
|
pub commands: Arc<[C]>,
|
|
pub condition: Option<Condition>,
|
|
pub description: Option<Arc<str>>,
|
|
pub source: Option<Arc<PathBuf>>,
|
|
}
|
|
|
|
/// Condition that must evaluate to true in order to enable an input layer.
|
|
///
|
|
/// ```
|
|
/// let condition = tek::Condition(std::sync::Arc::new(Box::new(||{true})));
|
|
/// ```
|
|
#[derive(Clone)] pub struct Condition(
|
|
pub Arc<Box<dyn Fn()->bool + Send + Sync>>
|
|
);
|
|
|
|
/// List of menu items.
|
|
///
|
|
/// ```
|
|
/// let items: tek::MenuItems = Default::default();
|
|
/// ```
|
|
#[derive(Debug, Clone, Default, PartialEq)] pub struct MenuItems(
|
|
pub Arc<[MenuItem]>
|
|
);
|
|
|
|
/// An item of a menu.
|
|
///
|
|
/// ```
|
|
/// let item: tek::MenuItem = Default::default();
|
|
/// ```
|
|
#[derive(Clone)] pub struct MenuItem(
|
|
/// Label
|
|
pub Arc<str>,
|
|
/// Callback
|
|
pub Arc<Box<dyn Fn(&mut App)->Usually<()> + Send + Sync>>
|
|
);
|
|
|
|
/// The command-line interface descriptor.
|
|
///
|
|
/// ```
|
|
/// let cli: tek::Cli = Default::default();
|
|
/// ```
|
|
#[derive(Debug, Parser, Default)]
|
|
#[command(name = "tek", version, about = Some(HEADER), long_about = Some(HEADER))]
|
|
pub struct Cli {
|
|
/// Pre-defined configuration modes.
|
|
///
|
|
/// TODO: Replace these with scripted configurations.
|
|
#[command(subcommand)] pub action: Action,
|
|
}
|
|
|
|
/// Application modes that can be passed to the mommand line interface.
|
|
///
|
|
/// ```
|
|
/// let action: tek::Action = Default::default();
|
|
/// ```
|
|
#[derive(Debug, Clone, Subcommand, Default)] pub enum Action {
|
|
/// Continue where you left off
|
|
#[default] Resume,
|
|
/// Run headlessly in current session.
|
|
Headless,
|
|
/// Show status of current session.
|
|
Status,
|
|
/// List known sessions.
|
|
List,
|
|
/// Continue work in a copy of the current session.
|
|
Fork,
|
|
/// Create a new empty session.
|
|
New {
|
|
/// Name of JACK client
|
|
#[arg(short='n', long)] name: Option<String>,
|
|
/// Whether to attempt to become transport master
|
|
#[arg(short='Y', long, default_value_t = false)] sync_lead: bool,
|
|
/// Whether to sync to external transport master
|
|
#[arg(short='y', long, default_value_t = true)] sync_follow: bool,
|
|
/// Initial tempo in beats per minute
|
|
#[arg(short='b', long, default_value = None)] bpm: Option<f64>,
|
|
/// Whether to include a transport toolbar (default: true)
|
|
#[arg(short='c', long, default_value_t = true)] show_clock: bool,
|
|
/// MIDI outs to connect to (multiple instances accepted)
|
|
#[arg(short='I', long)] midi_from: Vec<String>,
|
|
/// MIDI outs to connect to (multiple instances accepted)
|
|
#[arg(short='i', long)] midi_from_re: Vec<String>,
|
|
/// MIDI ins to connect to (multiple instances accepted)
|
|
#[arg(short='O', long)] midi_to: Vec<String>,
|
|
/// MIDI ins to connect to (multiple instances accepted)
|
|
#[arg(short='o', long)] midi_to_re: Vec<String>,
|
|
/// Audio outs to connect to left input
|
|
#[arg(short='l', long)] left_from: Vec<String>,
|
|
/// Audio outs to connect to right input
|
|
#[arg(short='r', long)] right_from: Vec<String>,
|
|
/// Audio ins to connect from left output
|
|
#[arg(short='L', long)] left_to: Vec<String>,
|
|
/// Audio ins to connect from right output
|
|
#[arg(short='R', long)] right_to: Vec<String>,
|
|
/// Tracks to create
|
|
#[arg(short='t', long)] tracks: Option<usize>,
|
|
/// Scenes to create
|
|
#[arg(short='s', long)] scenes: Option<usize>,
|
|
},
|
|
/// Import media as new session.
|
|
Import,
|
|
/// Show configuration.
|
|
Config,
|
|
/// Show version.
|
|
Version,
|
|
}
|
|
|
|
/// A control axis.
|
|
///
|
|
/// ```
|
|
/// let axis = tek::ControlAxis::X;
|
|
/// ```
|
|
#[derive(Debug, Copy, Clone)]
|
|
pub enum ControlAxis {
|
|
X, Y, Z, I
|
|
}
|
|
|
|
/// Various possible dialog modes.
|
|
///
|
|
/// ```
|
|
/// let dialog: tek::Dialog = Default::default();
|
|
/// ```
|
|
#[derive(Debug, Clone, Default, PartialEq)] pub enum Dialog {
|
|
#[default] None,
|
|
Help(usize),
|
|
Menu(usize, MenuItems),
|
|
Device(usize),
|
|
Message(Arc<str>),
|
|
Browse(BrowseTarget, Arc<Browse>),
|
|
Options,
|
|
}
|