mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 11:46:41 +01:00
remove modality; rename splits
This commit is contained in:
parent
03e3a82238
commit
999dc5906e
3 changed files with 125 additions and 7 deletions
|
|
@ -8,22 +8,22 @@ pub trait LayoutSplit<E: Engine> {
|
||||||
) -> Split<E, A, B> {
|
) -> Split<E, A, B> {
|
||||||
Split::new(flip, direction, amount, a, b)
|
Split::new(flip, direction, amount, a, b)
|
||||||
}
|
}
|
||||||
fn split_up <A: Render<E>, B: Render<E>> (
|
fn split_n <A: Render<E>, B: Render<E>> (
|
||||||
flip: bool, amount: E::Unit, a: A, b: B
|
flip: bool, amount: E::Unit, a: A, b: B
|
||||||
) -> Split<E, A, B> {
|
) -> Split<E, A, B> {
|
||||||
Self::split(flip, Direction::Up, amount, a, b)
|
Self::split(flip, Direction::Up, amount, a, b)
|
||||||
}
|
}
|
||||||
fn split_down <A: Render<E>, B: Render<E>> (
|
fn split_s <A: Render<E>, B: Render<E>> (
|
||||||
flip: bool, amount: E::Unit, a: A, b: B
|
flip: bool, amount: E::Unit, a: A, b: B
|
||||||
) -> Split<E, A, B> {
|
) -> Split<E, A, B> {
|
||||||
Self::split(flip, Direction::Down, amount, a, b)
|
Self::split(flip, Direction::Down, amount, a, b)
|
||||||
}
|
}
|
||||||
fn split_left <A: Render<E>, B: Render<E>> (
|
fn split_w <A: Render<E>, B: Render<E>> (
|
||||||
flip: bool, amount: E::Unit, a: A, b: B
|
flip: bool, amount: E::Unit, a: A, b: B
|
||||||
) -> Split<E, A, B> {
|
) -> Split<E, A, B> {
|
||||||
Self::split(flip, Direction::Left, amount, a, b)
|
Self::split(flip, Direction::Left, amount, a, b)
|
||||||
}
|
}
|
||||||
fn split_right <A: Render<E>, B: Render<E>> (
|
fn split_e <A: Render<E>, B: Render<E>> (
|
||||||
flip: bool, amount: E::Unit, a: A, b: B
|
flip: bool, amount: E::Unit, a: A, b: B
|
||||||
) -> Split<E, A, B> {
|
) -> Split<E, A, B> {
|
||||||
Self::split(flip, Direction::Right, amount, a, b)
|
Self::split(flip, Direction::Right, amount, a, b)
|
||||||
|
|
|
||||||
|
|
@ -173,12 +173,12 @@ audio!(|self:SequencerTui,client,scope|{
|
||||||
Control::Continue
|
Control::Continue
|
||||||
});
|
});
|
||||||
|
|
||||||
render!(|self: SequencerTui|lay!([self.size, Tui::split_up(false, 3,
|
render!(|self: SequencerTui|lay!([self.size, Tui::split_n(false, 3,
|
||||||
Tui::fill_xy(col!([
|
Tui::fill_xy(col!([
|
||||||
PhraseEditStatus(&self.editor),
|
PhraseEditStatus(&self.editor),
|
||||||
SequencerStatusBar::from(self)
|
SequencerStatusBar::from(self)
|
||||||
])),
|
])),
|
||||||
Tui::split_right(false, if self.size.w() > 60 {
|
Tui::split_e(false, if self.size.w() > 60 {
|
||||||
20
|
20
|
||||||
} else if self.size.w() > 40 {
|
} else if self.size.w() > 40 {
|
||||||
15
|
15
|
||||||
|
|
@ -322,3 +322,121 @@ impl Handle<Tui> for SequencerTui {
|
||||||
SequencerCommand::execute_with_state(self, i)
|
SequencerCommand::execute_with_state(self, i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Status bar for sequencer app
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct SequencerStatusBar {
|
||||||
|
pub(crate) width: usize,
|
||||||
|
pub(crate) cpu: Option<String>,
|
||||||
|
pub(crate) size: String,
|
||||||
|
pub(crate) res: String,
|
||||||
|
pub(crate) mode: &'static str,
|
||||||
|
pub(crate) help: &'static [(&'static str, &'static str, &'static str)]
|
||||||
|
}
|
||||||
|
|
||||||
|
impl StatusBar for SequencerStatusBar {
|
||||||
|
type State = SequencerTui;
|
||||||
|
fn hotkey_fg () -> Color {
|
||||||
|
TuiTheme::HOTKEY_FG
|
||||||
|
}
|
||||||
|
fn update (&mut self, _: &SequencerTui) {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&SequencerTui> for SequencerStatusBar {
|
||||||
|
fn from (state: &SequencerTui) -> Self {
|
||||||
|
let samples = state.clock.chunk.load(Ordering::Relaxed);
|
||||||
|
let rate = state.clock.timebase.sr.get() as f64;
|
||||||
|
let buffer = samples as f64 / rate;
|
||||||
|
let width = state.size.w();
|
||||||
|
Self {
|
||||||
|
width,
|
||||||
|
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.),
|
||||||
|
mode: " SEQUENCER ",
|
||||||
|
help: &[
|
||||||
|
("", "SPACE", " play/pause"),
|
||||||
|
("", "✣", " cursor"),
|
||||||
|
("", "Ctrl-✣", " scroll"),
|
||||||
|
("", ".,", " length"),
|
||||||
|
("", "><", " triplet"),
|
||||||
|
("", "[]", " phrase"),
|
||||||
|
("", "{}", " order"),
|
||||||
|
("en", "q", "ueue"),
|
||||||
|
("", "e", "dit"),
|
||||||
|
("", "a", "dd note"),
|
||||||
|
("", "A", "dd phrase"),
|
||||||
|
("", "D", "uplicate phrase"),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render!(|self: SequencerStatusBar|{
|
||||||
|
lay!(|add|if self.width > 40 {
|
||||||
|
add(&Tui::fill_x(Tui::fixed_y(1, lay!([
|
||||||
|
Tui::fill_x(Tui::at_w(SequencerModeline::from(self))),
|
||||||
|
Tui::fill_x(Tui::at_e(SequencerStats::from(self))),
|
||||||
|
]))))
|
||||||
|
} else {
|
||||||
|
add(&Tui::fill_x(Tui::fixed_y(2, col!(![
|
||||||
|
Tui::fill_x(Tui::center_x(SequencerModeline::from(self))),
|
||||||
|
Tui::fill_x(Tui::center_x(SequencerStats::from(self))),
|
||||||
|
]))))
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
struct SequencerModeline {
|
||||||
|
mode: &'static str,
|
||||||
|
help: &'static [(&'static str, &'static str, &'static str)]
|
||||||
|
}
|
||||||
|
impl From<&SequencerStatusBar> for SequencerModeline {
|
||||||
|
fn from (state: &SequencerStatusBar) -> Self {
|
||||||
|
Self {
|
||||||
|
mode: state.mode,
|
||||||
|
help: state.help,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
render!(|self: SequencerModeline|{
|
||||||
|
let black = TuiTheme::g(0);
|
||||||
|
let light = TuiTheme::g(50);
|
||||||
|
let white = TuiTheme::g(255);
|
||||||
|
let orange = TuiTheme::orange();
|
||||||
|
let yellow = TuiTheme::yellow();
|
||||||
|
row!([
|
||||||
|
//Tui::bg(orange, Tui::fg(black, Tui::bold(true, self.mode))),
|
||||||
|
Tui::bg(light, Tui::fg(white, row!((prefix, hotkey, suffix) in self.help.iter() => {
|
||||||
|
row!([" ", prefix, Tui::fg(yellow, *hotkey), suffix])
|
||||||
|
})))
|
||||||
|
])
|
||||||
|
});
|
||||||
|
|
||||||
|
struct SequencerStats<'a> {
|
||||||
|
cpu: &'a Option<String>,
|
||||||
|
size: &'a String,
|
||||||
|
res: &'a String,
|
||||||
|
}
|
||||||
|
impl<'a> From<&'a SequencerStatusBar> for SequencerStats<'a> {
|
||||||
|
fn from (state: &'a SequencerStatusBar) -> Self {
|
||||||
|
Self {
|
||||||
|
cpu: &state.cpu,
|
||||||
|
size: &state.size,
|
||||||
|
res: &state.res,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
render!(|self:SequencerStats<'a>|{
|
||||||
|
let orange = TuiTheme::orange();
|
||||||
|
let dark = TuiTheme::g(25);
|
||||||
|
let cpu = &self.cpu;
|
||||||
|
let res = &self.res;
|
||||||
|
let size = &self.size;
|
||||||
|
Tui::bg(dark, row!([
|
||||||
|
Tui::fg(orange, cpu),
|
||||||
|
Tui::fg(orange, res),
|
||||||
|
Tui::fg(orange, size),
|
||||||
|
]))
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ render!(|self: PianoHorizontal|{
|
||||||
let time_point = self.point.time_point();
|
let time_point = self.point.time_point();
|
||||||
let note_point = self.point.note_point();
|
let note_point = self.point.note_point();
|
||||||
let note_len = self.point.note_len();
|
let note_len = self.point.note_len();
|
||||||
Tui::bg(bg, Tui::split_down(false, 1,
|
Tui::bg(bg, Tui::split_s(false, 1,
|
||||||
Tui::debug(Tui::fill_x(Tui::push_x(5, Tui::bg(fg.darkest.rgb, Tui::fg(fg.lightest.rgb,
|
Tui::debug(Tui::fill_x(Tui::push_x(5, Tui::bg(fg.darkest.rgb, Tui::fg(fg.lightest.rgb,
|
||||||
PianoHorizontalTimeline {
|
PianoHorizontalTimeline {
|
||||||
time_start,
|
time_start,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue