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, /// Performance counter pub perf: PerfModel, /// Available view modes and input bindings pub config: Config, /// Currently selected mode pub mode: Arc>>, /// Undo history pub history: Vec<(AppCommand, Option)>, /// 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>>> } /// 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> = Default::default(); /// ``` #[derive(Default, Debug)] pub struct Mode { pub path: PathBuf, pub name: Vec, pub info: Vec, pub view: Vec, pub keys: Vec, pub modes: Modes, } /// An input binding. /// /// ``` /// let bind: tek::Bind<(), ()> = Default::default(); /// ``` #[derive(Debug)] pub struct Bind( /// Map of each event (e.g. key combination) to /// all command expressions bound to it by /// all loaded input layers. pub BTreeMap>> ); /// An input binding. /// /// ``` /// let binding: tek::Binding<()> = Default::default(); /// ``` #[derive(Debug, Clone)] pub struct Binding { pub commands: Arc<[C]>, pub condition: Option, pub description: Option>, pub source: Option>, } /// 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 Arcbool + 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, /// Callback pub ArcUsually<()> + 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, /// 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, /// 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, /// MIDI outs to connect to (multiple instances accepted) #[arg(short='i', long)] midi_from_re: Vec, /// MIDI ins to connect to (multiple instances accepted) #[arg(short='O', long)] midi_to: Vec, /// MIDI ins to connect to (multiple instances accepted) #[arg(short='o', long)] midi_to_re: Vec, /// Audio outs to connect to left input #[arg(short='l', long)] left_from: Vec, /// Audio outs to connect to right input #[arg(short='r', long)] right_from: Vec, /// Audio ins to connect from left output #[arg(short='L', long)] left_to: Vec, /// Audio ins to connect from right output #[arg(short='R', long)] right_to: Vec, /// Tracks to create #[arg(short='t', long)] tracks: Option, /// Scenes to create #[arg(short='s', long)] scenes: Option, }, /// 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), Browse(BrowseTarget, Arc), Options, }