mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-07 12:16:42 +01:00
add arranger help; don't rollover, just stup
This commit is contained in:
parent
47c13e1901
commit
32c9654a0c
7 changed files with 192 additions and 144 deletions
122
.scratch.rs
Normal file
122
.scratch.rs
Normal file
|
|
@ -0,0 +1,122 @@
|
||||||
|
//impl Bar 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::Phrases => ArrangerStatus::PhrasePool,
|
||||||
|
//ArrangerFocus::PhraseEditor => match entered {
|
||||||
|
//true => ArrangerStatus::PhraseEdit,
|
||||||
|
//false => ArrangerStatus::PhraseView,
|
||||||
|
//},
|
||||||
|
//}
|
||||||
|
//}
|
||||||
|
//}
|
||||||
|
|
||||||
|
//render!(<Tui>|self: ArrangerStatus|{
|
||||||
|
|
||||||
|
//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 = Tui::fg(mode_fg, Tui::bg(mode_bg, Tui::bold(true, format!(" {label} "))));
|
||||||
|
|
||||||
|
//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}"));
|
||||||
|
//Tui::bg(status_bar_bg, Fill::w(row!([mode, commands])))
|
||||||
|
|
||||||
|
//});
|
||||||
|
|
||||||
|
///// Status bar for arranger app
|
||||||
|
//#[derive(Copy, Clone, Debug)]
|
||||||
|
//pub enum ArrangerStatus {
|
||||||
|
//Transport,
|
||||||
|
//ArrangerMix,
|
||||||
|
//ArrangerTrack,
|
||||||
|
//ArrangerScene,
|
||||||
|
//ArrangerClip,
|
||||||
|
//PhrasePool,
|
||||||
|
//PhraseView,
|
||||||
|
//PhraseEdit,
|
||||||
|
//}
|
||||||
|
|
@ -108,7 +108,7 @@ render!(<Tui>|self: ArrangerTui|{
|
||||||
let with_transport = |x|col!([row!(![&play, &transport]), &x]);
|
let with_transport = |x|col!([row!(![&play, &transport]), &x]);
|
||||||
let pool_size = if self.show_pool { self.splits[1] } else { 0 };
|
let pool_size = if self.show_pool { self.splits[1] } else { 0 };
|
||||||
let with_pool = |x|Split::left(false, pool_size, PhraseListView(&self.phrases), x);
|
let with_pool = |x|Split::left(false, pool_size, PhraseListView(&self.phrases), x);
|
||||||
let status = SequencerStatus::from(self);
|
let status = ArrangerStatus::from(self);
|
||||||
let with_editbar = |x|Tui::split_n(false, 3, PhraseEditStatus(&self.editor), x);
|
let with_editbar = |x|Tui::split_n(false, 3, PhraseEditStatus(&self.editor), x);
|
||||||
let with_status = |x|Tui::split_n(false, 2, status, x);
|
let with_status = |x|Tui::split_n(false, 2, status, x);
|
||||||
let with_size = |x|lay!([&self.size, x]);
|
let with_size = |x|lay!([&self.size, x]);
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,9 @@ pub fn to_arranger_clip_command (input: &TuiInput, t: usize, len_t: usize, s: us
|
||||||
use ArrangerClipCommand as Clip;
|
use ArrangerClipCommand as Clip;
|
||||||
Some(match input.event() {
|
Some(match input.event() {
|
||||||
key_pat!(Char('w')) => Cmd::Select(if s > 0 { Select::Clip(t, s - 1) } else { Select::Track(t) }),
|
key_pat!(Char('w')) => Cmd::Select(if s > 0 { Select::Clip(t, s - 1) } else { Select::Track(t) }),
|
||||||
key_pat!(Char('s')) => Cmd::Select(Select::Clip(t, (s + 1) % len_s)),
|
key_pat!(Char('s')) => Cmd::Select(Select::Clip(t, (s + 1).min(len_s.saturating_sub(1)))),
|
||||||
key_pat!(Char('a')) => Cmd::Select(if t > 0 { Select::Clip(t - 1, s) } else { Select::Scene(s) }),
|
key_pat!(Char('a')) => Cmd::Select(if t > 0 { Select::Clip(t - 1, s) } else { Select::Scene(s) }),
|
||||||
key_pat!(Char('d')) => Cmd::Select(Select::Clip((t + 1) % len_t, s)),
|
key_pat!(Char('d')) => Cmd::Select(Select::Clip((t + 1).min(len_t.saturating_sub(1)), s)),
|
||||||
key_pat!(Char(',')) => Cmd::Clip(Clip::Set(t, s, None)),
|
key_pat!(Char(',')) => Cmd::Clip(Clip::Set(t, s, None)),
|
||||||
key_pat!(Char('.')) => Cmd::Clip(Clip::Set(t, s, None)),
|
key_pat!(Char('.')) => Cmd::Clip(Clip::Set(t, s, None)),
|
||||||
key_pat!(Char('<')) => Cmd::Clip(Clip::Set(t, s, None)),
|
key_pat!(Char('<')) => Cmd::Clip(Clip::Set(t, s, None)),
|
||||||
|
|
|
||||||
|
|
@ -139,7 +139,7 @@ from!(|args:(&ArrangerTui, usize)|ArrangerVCursor = Self {
|
||||||
scenes_w: SCENES_W_OFFSET + ArrangerScene::longest_name(args.0.scenes()) as u16,
|
scenes_w: SCENES_W_OFFSET + ArrangerScene::longest_name(args.0.scenes()) as u16,
|
||||||
color: args.0.color,
|
color: args.0.color,
|
||||||
reticle: Reticle(Style {
|
reticle: Reticle(Style {
|
||||||
fg: Some(args.0.color.lightest.rgb),
|
fg: Some(args.0.color.lighter.rgb),
|
||||||
bg: None,
|
bg: None,
|
||||||
underline_color: None,
|
underline_color: None,
|
||||||
add_modifier: Modifier::empty(),
|
add_modifier: Modifier::empty(),
|
||||||
|
|
|
||||||
|
|
@ -80,7 +80,7 @@ pub fn to_arranger_scene_command (input: &TuiInput, s: usize, len: usize) -> Opt
|
||||||
use ArrangerSceneCommand as Scene;
|
use ArrangerSceneCommand as Scene;
|
||||||
Some(match input.event() {
|
Some(match input.event() {
|
||||||
key_pat!(Char('w')) => Cmd::Select(if s > 0 { Select::Scene(s - 1) } else { Select::Mix }),
|
key_pat!(Char('w')) => Cmd::Select(if s > 0 { Select::Scene(s - 1) } else { Select::Mix }),
|
||||||
key_pat!(Char('s')) => Cmd::Select(Select::Scene((s + 1) % len)),
|
key_pat!(Char('s')) => Cmd::Select(Select::Scene((s + 1).min(len.saturating_sub(1)))),
|
||||||
key_pat!(Char('d')) => Cmd::Select(Select::Clip(0, s)),
|
key_pat!(Char('d')) => Cmd::Select(Select::Clip(0, s)),
|
||||||
key_pat!(Char(',')) => Cmd::Scene(Scene::Swap(s, s - 1)),
|
key_pat!(Char(',')) => Cmd::Scene(Scene::Swap(s, s - 1)),
|
||||||
key_pat!(Char('.')) => Cmd::Scene(Scene::Swap(s, s + 1)),
|
key_pat!(Char('.')) => Cmd::Scene(Scene::Swap(s, s + 1)),
|
||||||
|
|
|
||||||
|
|
@ -139,7 +139,7 @@ pub fn to_arranger_track_command (input: &TuiInput, t: usize, len: usize) -> Opt
|
||||||
Some(match input.event() {
|
Some(match input.event() {
|
||||||
key_pat!(Char('s')) => Select(Selected::Clip(t, 0)),
|
key_pat!(Char('s')) => Select(Selected::Clip(t, 0)),
|
||||||
key_pat!(Char('a')) => Select(if t > 0 { Selected::Track(t - 1) } else { Selected::Mix }),
|
key_pat!(Char('a')) => Select(if t > 0 { Selected::Track(t - 1) } else { Selected::Mix }),
|
||||||
key_pat!(Char('d')) => Select(Selected::Track((t + 1) % len)),
|
key_pat!(Char('d')) => Select(Selected::Track((t + 1).min(len.saturating_sub(1)))),
|
||||||
key_pat!(Char('c')) => Track(Tracks::SetColor(t, ItemPalette::random())),
|
key_pat!(Char('c')) => Track(Tracks::SetColor(t, ItemPalette::random())),
|
||||||
key_pat!(Char(',')) => Track(Tracks::Swap(t, t - 1)),
|
key_pat!(Char(',')) => Track(Tracks::Swap(t, t - 1)),
|
||||||
key_pat!(Char('.')) => Track(Tracks::Swap(t, t + 1)),
|
key_pat!(Char('.')) => Track(Tracks::Swap(t, t + 1)),
|
||||||
|
|
|
||||||
|
|
@ -44,19 +44,6 @@ from!(|state:&SequencerTui|SequencerStatus = {
|
||||||
res: format!("│{}s│{:.1}kHz│{:.1}ms│", samples, rate / 1000., buffer * 1000.),
|
res: format!("│{}s│{:.1}kHz│{:.1}ms│", samples, rate / 1000., buffer * 1000.),
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
from!(|state:&ArrangerTui|SequencerStatus = {
|
|
||||||
let samples = state.clock.chunk.load(Relaxed);
|
|
||||||
let rate = state.clock.timebase.sr.get() as f64;
|
|
||||||
let buffer = samples as f64 / rate;
|
|
||||||
let width = state.size.w();
|
|
||||||
Self {
|
|
||||||
width,
|
|
||||||
playing: state.clock.is_rolling(),
|
|
||||||
cpu: state.perf.percentage().map(|cpu|format!("│{cpu:.01}%")),
|
|
||||||
size: format!("{}x{}│", width, state.size.h()),
|
|
||||||
res: format!("│{}s│{:.1}kHz│{:.1}ms│", samples, rate / 1000., buffer * 1000.),
|
|
||||||
}
|
|
||||||
});
|
|
||||||
render!(<Tui>|self: SequencerStatus|Fixed::h(2, lay!([
|
render!(<Tui>|self: SequencerStatus|Fixed::h(2, lay!([
|
||||||
Self::help(),
|
Self::help(),
|
||||||
Fill::wh(Align::se({Tui::fg_bg(TuiTheme::orange(), TuiTheme::g(25), self.stats())})),
|
Fill::wh(Align::se({Tui::fg_bg(TuiTheme::orange(), TuiTheme::g(25), self.stats())})),
|
||||||
|
|
@ -73,11 +60,12 @@ impl SequencerStatus {
|
||||||
]);
|
]);
|
||||||
Tui::fg_bg(TuiTheme::g(255), TuiTheme::g(50), row!([
|
Tui::fg_bg(TuiTheme::g(255), TuiTheme::g(50), row!([
|
||||||
single("SPACE", "play/pause"),
|
single("SPACE", "play/pause"),
|
||||||
double((" ✣", "cursor"), ("C-✣", "scroll"), ),
|
double(("▲▼▶◀", "cursor"), ("C-✣", "scroll"), ),
|
||||||
double(("a", "append"), ("s", "set note"),),
|
double(("a", "append"), ("s", "set note"),),
|
||||||
double((",.", "note"), ("<>", "triplet"), ),
|
double((",.", "length"), ("<>", "triplet"), ),
|
||||||
double(("[]", "phrase"), ("{}", "order"), ),
|
double(("[]", "phrase"), ("{}", "order"), ),
|
||||||
double(("q", "enqueue"), ("e", "edit"), ),
|
double(("q", "enqueue"), ("e", "edit"), ),
|
||||||
|
double(("c", "color"), ("", ""),),
|
||||||
]))
|
]))
|
||||||
}
|
}
|
||||||
fn stats <'a> (&'a self) -> impl Render<Tui> + use<'a> {
|
fn stats <'a> (&'a self) -> impl Render<Tui> + use<'a> {
|
||||||
|
|
@ -94,125 +82,63 @@ impl Bar for SequencerStatus {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//impl Bar 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::Phrases => ArrangerStatus::PhrasePool,
|
|
||||||
//ArrangerFocus::PhraseEditor => match entered {
|
|
||||||
//true => ArrangerStatus::PhraseEdit,
|
|
||||||
//false => ArrangerStatus::PhraseView,
|
|
||||||
//},
|
|
||||||
//}
|
|
||||||
//}
|
|
||||||
//}
|
|
||||||
|
|
||||||
//render!(<Tui>|self: ArrangerStatus|{
|
|
||||||
|
|
||||||
//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 = Tui::fg(mode_fg, Tui::bg(mode_bg, Tui::bold(true, format!(" {label} "))));
|
|
||||||
|
|
||||||
//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}"));
|
|
||||||
//Tui::bg(status_bar_bg, Fill::w(row!([mode, commands])))
|
|
||||||
|
|
||||||
//});
|
|
||||||
|
|
||||||
/// Status bar for arranger app
|
/// Status bar for arranger app
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Clone)]
|
||||||
pub enum ArrangerStatus {
|
pub struct ArrangerStatus {
|
||||||
Transport,
|
pub(crate) width: usize,
|
||||||
ArrangerMix,
|
pub(crate) cpu: Option<String>,
|
||||||
ArrangerTrack,
|
pub(crate) size: String,
|
||||||
ArrangerScene,
|
pub(crate) res: String,
|
||||||
ArrangerClip,
|
pub(crate) playing: bool,
|
||||||
PhrasePool,
|
}
|
||||||
PhraseView,
|
from!(|state:&ArrangerTui|ArrangerStatus = {
|
||||||
PhraseEdit,
|
let samples = state.clock.chunk.load(Relaxed);
|
||||||
|
let rate = state.clock.timebase.sr.get() as f64;
|
||||||
|
let buffer = samples as f64 / rate;
|
||||||
|
let width = state.size.w();
|
||||||
|
Self {
|
||||||
|
width,
|
||||||
|
playing: state.clock.is_rolling(),
|
||||||
|
cpu: state.perf.percentage().map(|cpu|format!("│{cpu:.01}%")),
|
||||||
|
size: format!("{}x{}│", width, state.size.h()),
|
||||||
|
res: format!("│{}s│{:.1}kHz│{:.1}ms│", samples, rate / 1000., buffer * 1000.),
|
||||||
|
}
|
||||||
|
});
|
||||||
|
render!(<Tui>|self: ArrangerStatus|Fixed::h(2, lay!([
|
||||||
|
Self::help(),
|
||||||
|
Fill::wh(Align::se({Tui::fg_bg(TuiTheme::orange(), TuiTheme::g(25), self.stats())})),
|
||||||
|
])));
|
||||||
|
impl ArrangerStatus {
|
||||||
|
fn help () -> impl Render<Tui> {
|
||||||
|
let single = |binding, command|row!([" ", col!([
|
||||||
|
Tui::fg(TuiTheme::yellow(), binding),
|
||||||
|
command
|
||||||
|
])]);
|
||||||
|
let double = |(b1, c1), (b2, c2)|col!([
|
||||||
|
row!([" ", Tui::fg(TuiTheme::yellow(), b1), " ", c1,]),
|
||||||
|
row!([" ", Tui::fg(TuiTheme::yellow(), b2), " ", c2,]),
|
||||||
|
]);
|
||||||
|
Tui::fg_bg(TuiTheme::g(255), TuiTheme::g(50), row!([
|
||||||
|
single("SPACE", "play/pause"),
|
||||||
|
single(" Ctrl", " scroll"),
|
||||||
|
single(" wsad", " cell"),
|
||||||
|
double(("q", "enqueue"), ("e", "edit")),
|
||||||
|
single(" ▲▼▶◀", " note"),
|
||||||
|
double(("a", "append"), ("s", "set note"),),
|
||||||
|
double((",.", "length"), ("<>", "triplet"),),
|
||||||
|
double(("[]", "phrase"), ("{}", "order"),),
|
||||||
|
]))
|
||||||
|
}
|
||||||
|
fn stats <'a> (&'a self) -> impl Render<Tui> + use<'a> {
|
||||||
|
row!([&self.cpu, &self.res, &self.size])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Bar for ArrangerStatus {
|
||||||
|
type State = ArrangerTui;
|
||||||
|
fn hotkey_fg () -> Color {
|
||||||
|
TuiTheme::HOTKEY_FG
|
||||||
|
}
|
||||||
|
fn update (&mut self, _: &ArrangerTui) {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue