mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 19:56:42 +01:00
add/remove tracks
This commit is contained in:
parent
685c49cfd9
commit
a4c3593840
2 changed files with 66 additions and 35 deletions
|
|
@ -100,6 +100,9 @@ pub fn run (device: impl Device + Send + Sync + 'static) -> Result<(), Box<dyn E
|
||||||
|
|
||||||
impl<T: Render + Handle + PortList + Send + Sync> Device for T {}
|
impl<T: Render + Handle + PortList + Send + Sync> Device for T {}
|
||||||
|
|
||||||
|
pub trait Named {
|
||||||
|
}
|
||||||
|
|
||||||
pub trait Handle {
|
pub trait Handle {
|
||||||
// Handle an input event.
|
// Handle an input event.
|
||||||
// Returns Ok(true) if the device handled the event.
|
// Returns Ok(true) if the device handled the event.
|
||||||
|
|
|
||||||
|
|
@ -14,11 +14,11 @@ pub struct Launcher {
|
||||||
show_help: bool,
|
show_help: bool,
|
||||||
view: LauncherView,
|
view: LauncherView,
|
||||||
}
|
}
|
||||||
#[derive(PartialEq)]
|
|
||||||
pub enum LauncherView {
|
pub enum LauncherView {
|
||||||
Tracks,
|
Tracks,
|
||||||
Sequencer,
|
Sequencer,
|
||||||
Chains
|
Chains,
|
||||||
|
Modal(Box<dyn Device>),
|
||||||
}
|
}
|
||||||
pub struct Scene {
|
pub struct Scene {
|
||||||
name: String,
|
name: String,
|
||||||
|
|
@ -226,17 +226,23 @@ pub fn render (state: &Launcher, buf: &mut Buffer, area: Rect) -> Usually<Rect>
|
||||||
vec![]
|
vec![]
|
||||||
};
|
};
|
||||||
|
|
||||||
if state.view == LauncherView::Tracks {
|
match state.view {
|
||||||
draw_box_styled(buf, track_area, style);
|
LauncherView::Tracks => {
|
||||||
}
|
draw_box_styled(buf, track_area, style);
|
||||||
|
},
|
||||||
|
_ => {},
|
||||||
|
};
|
||||||
draw_highlight(state, buf, &track_highlight, match state.view {
|
draw_highlight(state, buf, &track_highlight, match state.view {
|
||||||
LauncherView::Tracks => Style::default().green().not_dim(),
|
LauncherView::Tracks => Style::default().green().not_dim(),
|
||||||
_ => Style::default().green().dim()
|
_ => Style::default().green().dim()
|
||||||
});
|
});
|
||||||
|
|
||||||
if state.view == LauncherView::Chains {
|
match state.view {
|
||||||
draw_box_styled(buf, Rect { height: 18, ..chain_area }, style);
|
LauncherView::Chains => {
|
||||||
}
|
draw_box_styled(buf, Rect { height: 18, ..chain_area }, style);
|
||||||
|
},
|
||||||
|
_ => {},
|
||||||
|
};
|
||||||
if let Some(chain) = &chain {
|
if let Some(chain) = &chain {
|
||||||
if let Some(plugin) = plugins.get(chain.focus) {
|
if let Some(plugin) = plugins.get(chain.focus) {
|
||||||
draw_highlight(state, buf, &Some(*plugin), match state.view {
|
draw_highlight(state, buf, &Some(*plugin), match state.view {
|
||||||
|
|
@ -246,14 +252,17 @@ pub fn render (state: &Launcher, buf: &mut Buffer, area: Rect) -> Usually<Rect>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if state.view == LauncherView::Sequencer {
|
match state.view {
|
||||||
draw_box_styled(buf, seq_area, style);
|
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)?;
|
draw_sequencer(state, buf, seq_area.x, seq_area.y + 1, seq_area.width, seq_area.height - 2)?;
|
||||||
|
|
||||||
if state.show_help {
|
if state.show_help {
|
||||||
let style = Some(Style::default().bold().white().not_dim().on_black().italic());
|
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);
|
hide.blit(buf, width - hide.len() as u16, height - 1, style);
|
||||||
}
|
}
|
||||||
Ok(area)
|
Ok(area)
|
||||||
|
|
@ -404,6 +413,9 @@ fn draw_highlight (
|
||||||
|
|
||||||
pub fn handle (state: &mut Launcher, event: &AppEvent) -> Usually<bool> {
|
pub fn handle (state: &mut Launcher, event: &AppEvent) -> Usually<bool> {
|
||||||
Ok(handle_keymap(state, event, KEYMAP)? || match state.view {
|
Ok(handle_keymap(state, event, KEYMAP)? || match state.view {
|
||||||
|
LauncherView::Modal(ref mut device) => {
|
||||||
|
device.handle(event)?
|
||||||
|
},
|
||||||
LauncherView::Tracks => {
|
LauncherView::Tracks => {
|
||||||
handle_keymap(state, event, KEYMAP_TRACKS)?
|
handle_keymap(state, event, KEYMAP_TRACKS)?
|
||||||
},
|
},
|
||||||
|
|
@ -421,25 +433,39 @@ pub fn handle (state: &mut Launcher, event: &AppEvent) -> Usually<bool> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
pub const KEYMAP: &'static [KeyBinding<Launcher>] = keymap!(Launcher {
|
pub const KEYMAP: &'static [KeyBinding<Launcher>] = keymap!(Launcher {
|
||||||
[Char('n'), NONE, "rename", "rename current element", rename],
|
[F(1), NONE, "toggle_help", "toggle help", toggle_help],
|
||||||
[F(1), NONE, "toggle_help", "toggle help", toggle_help],
|
[Tab, SHIFT, "focus_prev", "focus previous area", focus_prev],
|
||||||
[Tab, SHIFT, "focus_prev", "focus previous area", focus_prev],
|
[Tab, NONE, "focus_next", "focus next area", focus_next],
|
||||||
[Tab, NONE, "focus_next", "focus next area", focus_next],
|
[Char(' '), NONE, "play_toggle", "play or pause", play_toggle],
|
||||||
[Char(' '), NONE, "play_toggle", "play or pause", play_toggle],
|
[Char('r'), NONE, "record_toggle", "toggle recording", record_toggle],
|
||||||
[Char('r'), NONE, "record_toggle", "toggle recording", record_toggle],
|
[Char('d'), NONE, "overdub_toggle", "toggle overdub", overdub_toggle],
|
||||||
[Char('d'), NONE, "overdub_toggle", "toggle overdub", overdub_toggle],
|
[Char('m'), NONE, "monitor_toggle", "toggle input monitoring", monitor_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],
|
//[Char(' '), SHIFT, "play_start", "play from start", play_start],
|
||||||
});
|
});
|
||||||
pub const KEYMAP_TRACKS: &'static [KeyBinding<Launcher>] = keymap!(Launcher {
|
pub const KEYMAP_TRACKS: &'static [KeyBinding<Launcher>] = keymap!(Launcher {
|
||||||
[Up, NONE, "cursor_up", "move cursor up", cursor_up],
|
[Up, NONE, "cursor_up", "move cursor up", cursor_up],
|
||||||
[Down, NONE, "cursor_down", "move cursor down", cursor_down],
|
[Down, NONE, "cursor_down", "move cursor down", cursor_down],
|
||||||
[Left, NONE, "cursor_left", "move cursor left", cursor_left],
|
[Left, NONE, "cursor_left", "move cursor left", cursor_left],
|
||||||
[Right, NONE, "cursor_right", "move cursor right", cursor_right],
|
[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 next phrase", clip_next],
|
||||||
[Char(','), NONE, "clip_next", "set clip to last phrase", clip_prev],
|
[Char(','), NONE, "clip_prev", "set clip to last phrase", clip_prev],
|
||||||
|
[Delete, CONTROL, "delete_track", "delete track", delete_track],
|
||||||
});
|
});
|
||||||
fn rename (_: &mut Launcher) -> Usually<bool> {
|
fn rename (state: &mut Launcher) -> Usually<bool> {
|
||||||
|
Ok(true)
|
||||||
|
}
|
||||||
|
fn add_track (state: &mut Launcher) -> Usually<bool> {
|
||||||
|
state.tracks.push(Track::new("", &state.timebase, vec![])?);
|
||||||
|
state.cursor.0 = state.tracks.len();
|
||||||
|
Ok(true)
|
||||||
|
}
|
||||||
|
fn delete_track (state: &mut Launcher) -> Usually<bool> {
|
||||||
|
if state.cursor.0 >= 1 {
|
||||||
|
state.tracks.remove(state.cursor.0 - 1);
|
||||||
|
state.cursor.0 = state.cursor.0.min(state.tracks.len());
|
||||||
|
}
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
fn cursor_up (state: &mut Launcher) -> Usually<bool> {
|
fn cursor_up (state: &mut Launcher) -> Usually<bool> {
|
||||||
|
|
@ -463,18 +489,20 @@ fn toggle_help (state: &mut Launcher) -> Usually<bool> {
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
fn focus_next (state: &mut Launcher) -> Usually<bool> {
|
fn focus_next (state: &mut Launcher) -> Usually<bool> {
|
||||||
state.view = match state.view {
|
match state.view {
|
||||||
LauncherView::Tracks => LauncherView::Sequencer,
|
LauncherView::Tracks => { state.view = LauncherView::Sequencer; },
|
||||||
LauncherView::Sequencer => LauncherView::Chains,
|
LauncherView::Sequencer => { state.view = LauncherView::Chains; },
|
||||||
LauncherView::Chains => LauncherView::Tracks,
|
LauncherView::Chains => { state.view = LauncherView::Tracks; },
|
||||||
|
_ => {},
|
||||||
};
|
};
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
fn focus_prev (state: &mut Launcher) -> Usually<bool> {
|
fn focus_prev (state: &mut Launcher) -> Usually<bool> {
|
||||||
state.view = match state.view {
|
match state.view {
|
||||||
LauncherView::Tracks => LauncherView::Chains,
|
LauncherView::Tracks => { state.view = LauncherView::Chains; },
|
||||||
LauncherView::Chains => LauncherView::Sequencer,
|
LauncherView::Chains => { state.view = LauncherView::Sequencer; },
|
||||||
LauncherView::Sequencer => LauncherView::Tracks,
|
LauncherView::Sequencer => { state.view = LauncherView::Tracks; },
|
||||||
|
_ => {},
|
||||||
};
|
};
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue