mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 19:56:42 +01:00
app: wrap keys and view in Configuration
This commit is contained in:
parent
0e5207a79d
commit
6ed0627056
4 changed files with 102 additions and 94 deletions
|
|
@ -75,8 +75,7 @@ provide!(usize: |self: MidiEditor| {
|
|||
":time-zoom-prev" => self.time_zoom().get().saturating_sub(1).max(1),
|
||||
});
|
||||
|
||||
|
||||
handle!(TuiIn: |self: Tek, input|Ok(if let Some(command) = self.keys.command(self, input) {
|
||||
handle!(TuiIn: |self: Tek, input|Ok(if let Some(command) = self.config.keys.command(self, input) {
|
||||
let undo = command.execute(self)?;
|
||||
if let Some(undo) = undo {
|
||||
self.history.push(undo);
|
||||
|
|
|
|||
|
|
@ -48,14 +48,12 @@ pub struct Tek {
|
|||
pub history: Vec<TekCommand>,
|
||||
/// Port handles
|
||||
pub ports: std::collections::BTreeMap<u32, Port<Unowned>>,
|
||||
/// View definition
|
||||
pub view: SourceIter<'static>,
|
||||
// Cache of formatted strings
|
||||
pub view_cache: Arc<RwLock<ViewCache>>,
|
||||
// Modal overlay
|
||||
pub modal: Option<Modal>,
|
||||
// Input keymap
|
||||
pub keys: InputMap<'static, Self, TekCommand, TuiIn, TokenIter<'static>>
|
||||
// View and input definition
|
||||
pub config: Configuration
|
||||
}
|
||||
|
||||
impl Tek {
|
||||
|
|
@ -421,6 +419,15 @@ pub trait HasSelection {
|
|||
fn selected_mut (&mut self) -> &mut Selection;
|
||||
}
|
||||
|
||||
/// Configuration
|
||||
#[derive(Default, Debug)]
|
||||
pub struct Configuration {
|
||||
/// View definition
|
||||
pub view: SourceIter<'static>,
|
||||
// Input keymap
|
||||
pub keys: InputMap<'static, Tek, TekCommand, TuiIn, TokenIter<'static>>
|
||||
}
|
||||
|
||||
/// Various possible modal overlays
|
||||
#[derive(PartialEq, Clone, Copy, Debug)]
|
||||
pub enum Modal {
|
||||
|
|
@ -442,11 +449,11 @@ pub enum Selection {
|
|||
/// A track is selected.
|
||||
Track(usize),
|
||||
/// A clip (track × scene) is selected.
|
||||
TrackClip { track: usize, scene: usize },
|
||||
TrackClip { track: usize, scene: usize },
|
||||
/// A track's MIDI input connection is selected.
|
||||
TrackInput { track: usize, port: usize },
|
||||
TrackInput { track: usize, port: usize },
|
||||
/// A track's MIDI output connection is selected.
|
||||
TrackOutput { track: usize, port: usize },
|
||||
TrackOutput { track: usize, port: usize },
|
||||
/// A track device slot is selected.
|
||||
TrackDevice { track: usize, device: usize },
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use crate::*;
|
|||
pub(crate) use std::fmt::Write;
|
||||
pub(crate) use ::tengri::tui::ratatui::prelude::Position;
|
||||
|
||||
view!(TuiOut: |self: Tek| self.size.of(View(self, self.view)); {
|
||||
view!(TuiOut: |self: Tek| self.size.of(View(self, self.config.view)); {
|
||||
":nil" => Box::new("nil"),
|
||||
":modal" => self.view_modal(),
|
||||
":status" => self.view_status(),
|
||||
|
|
@ -42,7 +42,7 @@ impl Tek {
|
|||
}
|
||||
|
||||
fn view_modal_help (&self) -> impl Content<TuiOut> + use<'_> {
|
||||
let bindings = ||self.keys.layers.iter()
|
||||
let bindings = ||self.config.keys.layers.iter()
|
||||
.filter_map(|a|(a.0)(self).then_some(a.1))
|
||||
.flat_map(|a|a)
|
||||
.filter_map(|x|if let Value::Exp(_, iter)=x.value{
|
||||
|
|
|
|||
|
|
@ -105,89 +105,6 @@ impl Cli {
|
|||
jack: jack.clone(),
|
||||
color: ItemTheme::random(),
|
||||
clock: Clock::new(jack, self.bpm)?,
|
||||
view: SourceIter(match mode {
|
||||
LaunchMode::Clock =>
|
||||
include_str!("../../config/view_transport.edn"),
|
||||
LaunchMode::Sequencer =>
|
||||
include_str!("../../config/view_sequencer.edn"),
|
||||
LaunchMode::Groovebox =>
|
||||
include_str!("../../config/view_groovebox.edn"),
|
||||
LaunchMode::Arranger { .. } =>
|
||||
include_str!("../../config/view_arranger.edn"),
|
||||
LaunchMode::Sampler =>
|
||||
include_str!("../../config/view_sampler.edn"),
|
||||
_ => todo!("{mode:?}"),
|
||||
}),
|
||||
keys: match mode {
|
||||
LaunchMode::Sampler => InputMap::default()
|
||||
.layer(SourceIter(include_str!("../../config/keys_global.edn")).into())
|
||||
.layer(SourceIter(include_str!("../../config/keys_sampler.edn")).into()),
|
||||
LaunchMode::Clock => InputMap::default()
|
||||
.layer(SourceIter(include_str!("../../config/keys_global.edn")).into())
|
||||
.layer(SourceIter(include_str!("../../config/keys_clock.edn")).into()),
|
||||
LaunchMode::Sequencer => InputMap::default()
|
||||
.layer_if(|state: &Tek|matches!(
|
||||
state.pool.as_ref().map(|p|p.mode.as_ref()).flatten(),
|
||||
Some(PoolMode::Import(..))|Some(PoolMode::Export(..))
|
||||
), SourceIter(include_str!("../../config/keys_pool_file.edn")).into())
|
||||
.layer_if(|state: &Tek|matches!(
|
||||
state.pool.as_ref().map(|p|p.mode.as_ref()).flatten(),
|
||||
Some(PoolMode::Rename(..))
|
||||
), SourceIter(include_str!("../../config/keys_clip_rename.edn")).into())
|
||||
.layer_if(|state: &Tek|matches!(
|
||||
state.pool.as_ref().map(|p|p.mode.as_ref()).flatten(),
|
||||
Some(PoolMode::Length(..))
|
||||
), SourceIter(include_str!("../../config/keys_clip_length.edn")).into())
|
||||
.layer(SourceIter(include_str!("../../config/keys_global.edn")).into())
|
||||
.layer(SourceIter(include_str!("../../config/keys_editor.edn")).into())
|
||||
.layer(SourceIter(include_str!("../../config/keys_clock.edn")).into())
|
||||
.layer(SourceIter(include_str!("../../config/keys_sequencer.edn")).into()),
|
||||
LaunchMode::Groovebox => InputMap::default()
|
||||
.layer_if(|state: &Tek|matches!(
|
||||
state.pool.as_ref().map(|p|p.mode.as_ref()).flatten(),
|
||||
Some(PoolMode::Import(..))|Some(PoolMode::Export(..))
|
||||
), SourceIter(include_str!("../../config/keys_pool_file.edn")).into())
|
||||
.layer_if(|state: &Tek|matches!(
|
||||
state.pool.as_ref().map(|p|p.mode.as_ref()).flatten(),
|
||||
Some(PoolMode::Rename(..))
|
||||
), SourceIter(include_str!("../../config/keys_clip_rename.edn")).into())
|
||||
.layer_if(|state: &Tek|matches!(
|
||||
state.pool.as_ref().map(|p|p.mode.as_ref()).flatten(),
|
||||
Some(PoolMode::Length(..))
|
||||
), SourceIter(include_str!("../../config/keys_clip_length.edn")).into())
|
||||
.layer(SourceIter(include_str!("../../config/keys_global.edn")).into())
|
||||
.layer(SourceIter(include_str!("../../config/keys_editor.edn")).into())
|
||||
.layer(SourceIter(include_str!("../../config/keys_clock.edn")).into())
|
||||
.layer(SourceIter(include_str!("../../config/keys_sequencer.edn")).into())
|
||||
.layer(SourceIter(include_str!("../../config/keys_groovebox.edn")).into()),
|
||||
LaunchMode::Arranger {..} => InputMap::default()
|
||||
.layer_if(|state: &Tek|matches!(
|
||||
state.pool.as_ref().map(|p|p.mode.as_ref()).flatten(),
|
||||
Some(PoolMode::Import(..))|Some(PoolMode::Export(..))
|
||||
), SourceIter(include_str!("../../config/keys_pool_file.edn")).into())
|
||||
.layer_if(|state: &Tek|matches!(
|
||||
state.pool.as_ref().map(|p|p.mode.as_ref()).flatten(),
|
||||
Some(PoolMode::Rename(..))
|
||||
), SourceIter(include_str!("../../config/keys_clip_rename.edn")).into())
|
||||
.layer_if(|state: &Tek|matches!(
|
||||
state.pool.as_ref().map(|p|p.mode.as_ref()).flatten(),
|
||||
Some(PoolMode::Length(..))
|
||||
), SourceIter(include_str!("../../config/keys_clip_length.edn")).into())
|
||||
.layer(SourceIter(include_str!("../../config/keys_global.edn")).into())
|
||||
.layer_if(|state: &Tek|state.is_editing(),
|
||||
SourceIter(include_str!("../../config/keys_editor.edn")).into())
|
||||
.layer_if(|state: &Tek|state.selected.is_clip()&&!state.is_editing(),
|
||||
SourceIter(include_str!("../../config/keys_clip.edn")).into())
|
||||
.layer_if(|state: &Tek|state.selected.is_track()&&!state.is_editing(),
|
||||
SourceIter(include_str!("../../config/keys_track.edn")).into())
|
||||
.layer_if(|state: &Tek|state.selected.is_scene()&&!state.is_editing(),
|
||||
SourceIter(include_str!("../../config/keys_scene.edn")).into())
|
||||
.layer_if(|state: &Tek|state.selected.is_mix()&&!state.is_editing(),
|
||||
SourceIter(include_str!("../../config/keys_mix.edn")).into())
|
||||
.layer(SourceIter(include_str!("../../config/keys_clock.edn")).into())
|
||||
.layer(SourceIter(include_str!("../../config/keys_arranger.edn")).into()),
|
||||
_ => todo!("{mode:?}"),
|
||||
},
|
||||
pool: match mode {
|
||||
LaunchMode::Sequencer | LaunchMode::Groovebox => clip.as_ref().map(Into::into),
|
||||
LaunchMode::Arranger { .. } => Some(Default::default()),
|
||||
|
|
@ -222,6 +139,91 @@ impl Cli {
|
|||
},
|
||||
scenes,
|
||||
selected: Selection::TrackClip { track: 0, scene: 0 },
|
||||
config: Configuration {
|
||||
view: SourceIter(match mode {
|
||||
LaunchMode::Clock =>
|
||||
include_str!("../../config/view_transport.edn"),
|
||||
LaunchMode::Sequencer =>
|
||||
include_str!("../../config/view_sequencer.edn"),
|
||||
LaunchMode::Groovebox =>
|
||||
include_str!("../../config/view_groovebox.edn"),
|
||||
LaunchMode::Arranger { .. } =>
|
||||
include_str!("../../config/view_arranger.edn"),
|
||||
LaunchMode::Sampler =>
|
||||
include_str!("../../config/view_sampler.edn"),
|
||||
_ => todo!("{mode:?}"),
|
||||
}),
|
||||
keys: match mode {
|
||||
LaunchMode::Sampler => InputMap::default()
|
||||
.layer(SourceIter(include_str!("../../config/keys_global.edn")).into())
|
||||
.layer(SourceIter(include_str!("../../config/keys_sampler.edn")).into()),
|
||||
LaunchMode::Clock => InputMap::default()
|
||||
.layer(SourceIter(include_str!("../../config/keys_global.edn")).into())
|
||||
.layer(SourceIter(include_str!("../../config/keys_clock.edn")).into()),
|
||||
LaunchMode::Sequencer => InputMap::default()
|
||||
.layer_if(|state: &Tek|matches!(
|
||||
state.pool.as_ref().map(|p|p.mode.as_ref()).flatten(),
|
||||
Some(PoolMode::Import(..))|Some(PoolMode::Export(..))
|
||||
), SourceIter(include_str!("../../config/keys_pool_file.edn")).into())
|
||||
.layer_if(|state: &Tek|matches!(
|
||||
state.pool.as_ref().map(|p|p.mode.as_ref()).flatten(),
|
||||
Some(PoolMode::Rename(..))
|
||||
), SourceIter(include_str!("../../config/keys_clip_rename.edn")).into())
|
||||
.layer_if(|state: &Tek|matches!(
|
||||
state.pool.as_ref().map(|p|p.mode.as_ref()).flatten(),
|
||||
Some(PoolMode::Length(..))
|
||||
), SourceIter(include_str!("../../config/keys_clip_length.edn")).into())
|
||||
.layer(SourceIter(include_str!("../../config/keys_global.edn")).into())
|
||||
.layer(SourceIter(include_str!("../../config/keys_editor.edn")).into())
|
||||
.layer(SourceIter(include_str!("../../config/keys_clock.edn")).into())
|
||||
.layer(SourceIter(include_str!("../../config/keys_sequencer.edn")).into()),
|
||||
LaunchMode::Groovebox => InputMap::default()
|
||||
.layer_if(|state: &Tek|matches!(
|
||||
state.pool.as_ref().map(|p|p.mode.as_ref()).flatten(),
|
||||
Some(PoolMode::Import(..))|Some(PoolMode::Export(..))
|
||||
), SourceIter(include_str!("../../config/keys_pool_file.edn")).into())
|
||||
.layer_if(|state: &Tek|matches!(
|
||||
state.pool.as_ref().map(|p|p.mode.as_ref()).flatten(),
|
||||
Some(PoolMode::Rename(..))
|
||||
), SourceIter(include_str!("../../config/keys_clip_rename.edn")).into())
|
||||
.layer_if(|state: &Tek|matches!(
|
||||
state.pool.as_ref().map(|p|p.mode.as_ref()).flatten(),
|
||||
Some(PoolMode::Length(..))
|
||||
), SourceIter(include_str!("../../config/keys_clip_length.edn")).into())
|
||||
.layer(SourceIter(include_str!("../../config/keys_global.edn")).into())
|
||||
.layer(SourceIter(include_str!("../../config/keys_editor.edn")).into())
|
||||
.layer(SourceIter(include_str!("../../config/keys_clock.edn")).into())
|
||||
.layer(SourceIter(include_str!("../../config/keys_sequencer.edn")).into())
|
||||
.layer(SourceIter(include_str!("../../config/keys_groovebox.edn")).into()),
|
||||
LaunchMode::Arranger {..} => InputMap::default()
|
||||
.layer_if(|state: &Tek|matches!(
|
||||
state.pool.as_ref().map(|p|p.mode.as_ref()).flatten(),
|
||||
Some(PoolMode::Import(..))|Some(PoolMode::Export(..))
|
||||
), SourceIter(include_str!("../../config/keys_pool_file.edn")).into())
|
||||
.layer_if(|state: &Tek|matches!(
|
||||
state.pool.as_ref().map(|p|p.mode.as_ref()).flatten(),
|
||||
Some(PoolMode::Rename(..))
|
||||
), SourceIter(include_str!("../../config/keys_clip_rename.edn")).into())
|
||||
.layer_if(|state: &Tek|matches!(
|
||||
state.pool.as_ref().map(|p|p.mode.as_ref()).flatten(),
|
||||
Some(PoolMode::Length(..))
|
||||
), SourceIter(include_str!("../../config/keys_clip_length.edn")).into())
|
||||
.layer(SourceIter(include_str!("../../config/keys_global.edn")).into())
|
||||
.layer_if(|state: &Tek|state.is_editing(),
|
||||
SourceIter(include_str!("../../config/keys_editor.edn")).into())
|
||||
.layer_if(|state: &Tek|state.selected.is_clip()&&!state.is_editing(),
|
||||
SourceIter(include_str!("../../config/keys_clip.edn")).into())
|
||||
.layer_if(|state: &Tek|state.selected.is_track()&&!state.is_editing(),
|
||||
SourceIter(include_str!("../../config/keys_track.edn")).into())
|
||||
.layer_if(|state: &Tek|state.selected.is_scene()&&!state.is_editing(),
|
||||
SourceIter(include_str!("../../config/keys_scene.edn")).into())
|
||||
.layer_if(|state: &Tek|state.selected.is_mix()&&!state.is_editing(),
|
||||
SourceIter(include_str!("../../config/keys_mix.edn")).into())
|
||||
.layer(SourceIter(include_str!("../../config/keys_clock.edn")).into())
|
||||
.layer(SourceIter(include_str!("../../config/keys_arranger.edn")).into()),
|
||||
_ => todo!("{mode:?}"),
|
||||
},
|
||||
},
|
||||
..Default::default()
|
||||
};
|
||||
if let &LaunchMode::Arranger { scenes, tracks, track_width, .. } = mode {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue