From a4c3593840d0282f108546365fa5aa21ef07664c Mon Sep 17 00:00:00 2001 From: unspeaker Date: Fri, 28 Jun 2024 00:33:35 +0300 Subject: [PATCH] add/remove tracks --- src/device.rs | 3 ++ src/device/launcher.rs | 98 +++++++++++++++++++++++++++--------------- 2 files changed, 66 insertions(+), 35 deletions(-) diff --git a/src/device.rs b/src/device.rs index ffdb21e7..f9880e35 100644 --- a/src/device.rs +++ b/src/device.rs @@ -100,6 +100,9 @@ pub fn run (device: impl Device + Send + Sync + 'static) -> Result<(), Box Device for T {} +pub trait Named { +} + pub trait Handle { // Handle an input event. // Returns Ok(true) if the device handled the event. diff --git a/src/device/launcher.rs b/src/device/launcher.rs index 591abd21..62c7e960 100644 --- a/src/device/launcher.rs +++ b/src/device/launcher.rs @@ -14,11 +14,11 @@ pub struct Launcher { show_help: bool, view: LauncherView, } -#[derive(PartialEq)] pub enum LauncherView { Tracks, Sequencer, - Chains + Chains, + Modal(Box), } pub struct Scene { name: String, @@ -226,17 +226,23 @@ pub fn render (state: &Launcher, buf: &mut Buffer, area: Rect) -> Usually vec![] }; - if state.view == LauncherView::Tracks { - draw_box_styled(buf, track_area, style); - } + match state.view { + LauncherView::Tracks => { + draw_box_styled(buf, track_area, style); + }, + _ => {}, + }; draw_highlight(state, buf, &track_highlight, match state.view { LauncherView::Tracks => Style::default().green().not_dim(), _ => Style::default().green().dim() }); - if state.view == LauncherView::Chains { - draw_box_styled(buf, Rect { height: 18, ..chain_area }, style); - } + match state.view { + LauncherView::Chains => { + draw_box_styled(buf, Rect { height: 18, ..chain_area }, style); + }, + _ => {}, + }; if let Some(chain) = &chain { if let Some(plugin) = plugins.get(chain.focus) { draw_highlight(state, buf, &Some(*plugin), match state.view { @@ -246,14 +252,17 @@ pub fn render (state: &Launcher, buf: &mut Buffer, area: Rect) -> Usually } } - if state.view == LauncherView::Sequencer { - draw_box_styled(buf, seq_area, style); - } + match state.view { + LauncherView::Sequencer => { + draw_box_styled(buf, seq_area, style); + }, + _ => {}, + }; draw_sequencer(state, buf, seq_area.x, seq_area.y + 1, seq_area.width, seq_area.height - 2)?; if state.show_help { let style = Some(Style::default().bold().white().not_dim().on_black().italic()); - let hide = "[Left/Right] Track [Up/Down] Scene [,/.] Value [F1] Toggle help "; + let hide = "[Left Right] Track [Up Down] Scene [, .] Value [F1] Toggle help "; hide.blit(buf, width - hide.len() as u16, height - 1, style); } Ok(area) @@ -404,6 +413,9 @@ fn draw_highlight ( pub fn handle (state: &mut Launcher, event: &AppEvent) -> Usually { Ok(handle_keymap(state, event, KEYMAP)? || match state.view { + LauncherView::Modal(ref mut device) => { + device.handle(event)? + }, LauncherView::Tracks => { handle_keymap(state, event, KEYMAP_TRACKS)? }, @@ -421,25 +433,39 @@ pub fn handle (state: &mut Launcher, event: &AppEvent) -> Usually { }) } pub const KEYMAP: &'static [KeyBinding] = keymap!(Launcher { - [Char('n'), NONE, "rename", "rename current element", rename], - [F(1), NONE, "toggle_help", "toggle help", toggle_help], - [Tab, SHIFT, "focus_prev", "focus previous area", focus_prev], - [Tab, NONE, "focus_next", "focus next area", focus_next], - [Char(' '), NONE, "play_toggle", "play or pause", play_toggle], - [Char('r'), NONE, "record_toggle", "toggle recording", record_toggle], - [Char('d'), NONE, "overdub_toggle", "toggle overdub", overdub_toggle], - [Char('m'), NONE, "monitor_toggle", "toggle input monitoring", monitor_toggle], + [F(1), NONE, "toggle_help", "toggle help", toggle_help], + [Tab, SHIFT, "focus_prev", "focus previous area", focus_prev], + [Tab, NONE, "focus_next", "focus next area", focus_next], + [Char(' '), NONE, "play_toggle", "play or pause", play_toggle], + [Char('r'), NONE, "record_toggle", "toggle recording", record_toggle], + [Char('d'), NONE, "overdub_toggle", "toggle overdub", overdub_toggle], + [Char('m'), NONE, "monitor_toggle", "toggle input monitoring", monitor_toggle], + [Char('r'), CONTROL, "rename", "rename current element", rename], + [Char('t'), CONTROL, "add_track", "add a new track", add_track], //[Char(' '), SHIFT, "play_start", "play from start", play_start], }); pub const KEYMAP_TRACKS: &'static [KeyBinding] = keymap!(Launcher { - [Up, NONE, "cursor_up", "move cursor up", cursor_up], - [Down, NONE, "cursor_down", "move cursor down", cursor_down], - [Left, NONE, "cursor_left", "move cursor left", cursor_left], - [Right, NONE, "cursor_right", "move cursor right", cursor_right], - [Char('.'), NONE, "clip_next", "set clip to next phrase", clip_next], - [Char(','), NONE, "clip_next", "set clip to last phrase", clip_prev], + [Up, NONE, "cursor_up", "move cursor up", cursor_up], + [Down, NONE, "cursor_down", "move cursor down", cursor_down], + [Left, NONE, "cursor_left", "move cursor left", cursor_left], + [Right, NONE, "cursor_right", "move cursor right", cursor_right], + [Char('.'), NONE, "clip_next", "set clip to next phrase", clip_next], + [Char(','), NONE, "clip_prev", "set clip to last phrase", clip_prev], + [Delete, CONTROL, "delete_track", "delete track", delete_track], }); -fn rename (_: &mut Launcher) -> Usually { +fn rename (state: &mut Launcher) -> Usually { + Ok(true) +} +fn add_track (state: &mut Launcher) -> Usually { + state.tracks.push(Track::new("", &state.timebase, vec![])?); + state.cursor.0 = state.tracks.len(); + Ok(true) +} +fn delete_track (state: &mut Launcher) -> Usually { + if state.cursor.0 >= 1 { + state.tracks.remove(state.cursor.0 - 1); + state.cursor.0 = state.cursor.0.min(state.tracks.len()); + } Ok(true) } fn cursor_up (state: &mut Launcher) -> Usually { @@ -463,18 +489,20 @@ fn toggle_help (state: &mut Launcher) -> Usually { Ok(true) } fn focus_next (state: &mut Launcher) -> Usually { - state.view = match state.view { - LauncherView::Tracks => LauncherView::Sequencer, - LauncherView::Sequencer => LauncherView::Chains, - LauncherView::Chains => LauncherView::Tracks, + match state.view { + LauncherView::Tracks => { state.view = LauncherView::Sequencer; }, + LauncherView::Sequencer => { state.view = LauncherView::Chains; }, + LauncherView::Chains => { state.view = LauncherView::Tracks; }, + _ => {}, }; Ok(true) } fn focus_prev (state: &mut Launcher) -> Usually { - state.view = match state.view { - LauncherView::Tracks => LauncherView::Chains, - LauncherView::Chains => LauncherView::Sequencer, - LauncherView::Sequencer => LauncherView::Tracks, + match state.view { + LauncherView::Tracks => { state.view = LauncherView::Chains; }, + LauncherView::Chains => { state.view = LauncherView::Sequencer; }, + LauncherView::Sequencer => { state.view = LauncherView::Tracks; }, + _ => {}, }; Ok(true) }