mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-08 04:36:45 +01:00
195 lines
6 KiB
Rust
195 lines
6 KiB
Rust
use crate::*;
|
|
|
|
pub trait StatusBar: Copy + Widget<Engine = Tui> {
|
|
|
|
type State;
|
|
|
|
fn hotkey_fg () -> Color where Self: Sized;
|
|
|
|
fn update (&mut self, state: &Self::State) where Self: Sized;
|
|
|
|
fn command (commands: &[[impl Widget<Engine = Tui>;3]])
|
|
-> impl Widget<Engine = Tui> + '_
|
|
where
|
|
Self: Sized
|
|
{
|
|
let hotkey_fg = Self::hotkey_fg();
|
|
Stack::right(move |add|{
|
|
Ok(for [a, b, c] in commands.iter() {
|
|
add(&row!(
|
|
" ",
|
|
widget(a),
|
|
widget(b).bold(true).fg(hotkey_fg),
|
|
widget(c),
|
|
))?;
|
|
})
|
|
})
|
|
}
|
|
}
|
|
|
|
#[derive(Copy, Clone)]
|
|
pub struct TransportStatusBar;
|
|
|
|
impl StatusBar for TransportStatusBar {
|
|
type State = ();
|
|
fn hotkey_fg () -> Color {
|
|
TuiTheme::hotkey_fg()
|
|
}
|
|
fn update (&mut self, state: &()) {
|
|
todo!()
|
|
}
|
|
}
|
|
|
|
impl Content for TransportStatusBar {
|
|
type Engine = Tui;
|
|
fn content (&self) -> impl Widget<Engine = Tui> {
|
|
todo!();
|
|
""
|
|
}
|
|
}
|
|
|
|
/// Status bar for sequencer app
|
|
#[derive(Copy, Clone)]
|
|
pub enum SequencerStatusBar {
|
|
Transport,
|
|
PhrasePool,
|
|
PhraseEditor,
|
|
}
|
|
|
|
impl StatusBar for SequencerStatusBar {
|
|
type State = ();
|
|
fn hotkey_fg () -> Color {
|
|
TuiTheme::hotkey_fg()
|
|
}
|
|
fn update (&mut self, state: &()) {
|
|
todo!()
|
|
}
|
|
}
|
|
|
|
impl Content for SequencerStatusBar {
|
|
type Engine = Tui;
|
|
fn content (&self) -> impl Widget<Engine = Tui> {
|
|
todo!();
|
|
""
|
|
}
|
|
}
|
|
|
|
/// Status bar for arranger app
|
|
#[derive(Copy, Clone, Debug)]
|
|
pub enum ArrangerStatus {
|
|
Transport,
|
|
ArrangerMix,
|
|
ArrangerTrack,
|
|
ArrangerScene,
|
|
ArrangerClip,
|
|
PhrasePool,
|
|
PhraseView,
|
|
PhraseEdit,
|
|
}
|
|
|
|
impl StatusBar for ArrangerStatus {
|
|
type State = (ArrangerFocus, ArrangerSelection, bool);
|
|
fn hotkey_fg () -> Color where Self: Sized {
|
|
TuiTheme::hotkey_fg()
|
|
}
|
|
fn update (&mut self, (focused, selected, entered): &Self::State) {
|
|
*self = match focused {
|
|
ArrangerFocus::Menu => { todo!() },
|
|
ArrangerFocus::Transport => ArrangerStatus::Transport,
|
|
ArrangerFocus::Arranger => match selected {
|
|
ArrangerSelection::Mix => ArrangerStatus::ArrangerMix,
|
|
ArrangerSelection::Track(_) => ArrangerStatus::ArrangerTrack,
|
|
ArrangerSelection::Scene(_) => ArrangerStatus::ArrangerScene,
|
|
ArrangerSelection::Clip(_, _) => ArrangerStatus::ArrangerClip,
|
|
},
|
|
ArrangerFocus::PhrasePool => ArrangerStatus::PhrasePool,
|
|
ArrangerFocus::PhraseEditor => match entered {
|
|
true => ArrangerStatus::PhraseEdit,
|
|
false => ArrangerStatus::PhraseView,
|
|
},
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Content for ArrangerStatus {
|
|
type Engine = Tui;
|
|
fn content (&self) -> impl Widget<Engine = Tui> {
|
|
let label = match self {
|
|
Self::Transport => "TRANSPORT",
|
|
Self::ArrangerMix => "PROJECT",
|
|
Self::ArrangerTrack => "TRACK",
|
|
Self::ArrangerScene => "SCENE",
|
|
Self::ArrangerClip => "CLIP",
|
|
Self::PhrasePool => "SEQ LIST",
|
|
Self::PhraseView => "VIEW SEQ",
|
|
Self::PhraseEdit => "EDIT SEQ",
|
|
};
|
|
let status_bar_bg = TuiTheme::status_bar_bg();
|
|
let mode_bg = TuiTheme::mode_bg();
|
|
let mode_fg = TuiTheme::mode_fg();
|
|
let mode = TuiStyle::bold(format!(" {label} "), true).bg(mode_bg).fg(mode_fg);
|
|
let commands = match self {
|
|
Self::ArrangerMix => Self::command(&[
|
|
["", "c", "olor"],
|
|
["", "<>", "resize"],
|
|
["", "+-", "zoom"],
|
|
["", "n", "ame/number"],
|
|
["", "Enter", " stop all"],
|
|
]),
|
|
Self::ArrangerClip => Self::command(&[
|
|
["", "g", "et"],
|
|
["", "s", "et"],
|
|
["", "a", "dd"],
|
|
["", "i", "ns"],
|
|
["", "d", "up"],
|
|
["", "e", "dit"],
|
|
["", "c", "olor"],
|
|
["re", "n", "ame"],
|
|
["", ",.", "select"],
|
|
["", "Enter", " launch"],
|
|
]),
|
|
Self::ArrangerTrack => Self::command(&[
|
|
["re", "n", "ame"],
|
|
["", ",.", "resize"],
|
|
["", "<>", "move"],
|
|
["", "i", "nput"],
|
|
["", "o", "utput"],
|
|
["", "m", "ute"],
|
|
["", "s", "olo"],
|
|
["", "Del", "ete"],
|
|
["", "Enter", " stop"],
|
|
]),
|
|
Self::ArrangerScene => Self::command(&[
|
|
["re", "n", "ame"],
|
|
["", "Del", "ete"],
|
|
["", "Enter", " launch"],
|
|
]),
|
|
Self::PhrasePool => Self::command(&[
|
|
["", "a", "ppend"],
|
|
["", "i", "nsert"],
|
|
["", "d", "uplicate"],
|
|
["", "Del", "ete"],
|
|
["", "c", "olor"],
|
|
["re", "n", "ame"],
|
|
["leng", "t", "h"],
|
|
["", ",.", "move"],
|
|
["", "+-", "resize view"],
|
|
]),
|
|
Self::PhraseView => Self::command(&[
|
|
["", "enter", " edit"],
|
|
["", "arrows/pgup/pgdn", " scroll"],
|
|
["", "+=", "zoom"],
|
|
]),
|
|
Self::PhraseEdit => Self::command(&[
|
|
["", "esc", " exit"],
|
|
["", "a", "ppend"],
|
|
["", "s", "et"],
|
|
["", "][", "length"],
|
|
["", "+-", "zoom"],
|
|
]),
|
|
_ => Self::command(&[])
|
|
};
|
|
//let commands = commands.iter().reduce(String::new(), |s, (a, b, c)| format!("{s} {a}{b}{c}"));
|
|
row!(mode, commands).fill_x().bg(status_bar_bg)
|
|
}
|
|
}
|