tek/crates/tek_tui/src/tui_status.rs

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)
}
}