wip9 (15e)

This commit is contained in:
🪞👃🪞 2024-12-09 20:37:15 +01:00
parent 2f772eceef
commit f9d1456897
11 changed files with 252 additions and 209 deletions

View file

@ -1,8 +1,15 @@
use crate::*;
#[macro_export] macro_rules! lay {
($(move)*|$add:ident|$expr:expr) => { Layers::new($(move)*|$add|$expr) };
($($expr:expr),* $(,)?) => { Layers::new(move|add|{ $(add(&$expr)?;)* Ok(()) }) }
([$($expr:expr),* $(,)?]) => {
Layers::new(move|add|{ $(add(&$expr)?;)* Ok(()) })
};
(![$($expr:expr),* $(,)?]) => {
Layers::new(|add|{ $(add(&$expr)?;)* Ok(()) })
};
($expr:expr) => {
Layers::new($expr)
};
}
pub struct Layers<

View file

@ -1,21 +1,22 @@
use crate::*;
#[macro_export] macro_rules! col {
($($move:ident)?|$add:ident|$expr:expr) => {
Stack::down($(move)?|$add|$expr)
};
($pat:pat in $collection:expr => $item:expr) => {
Stack::down(move |add|{
for $pat in $collection { add(&$item)?; }
Ok(())
})
};
($($expr:expr),* $(,)?) => {
([$($expr:expr),* $(,)?]) => {
Stack::down(move|add|{ $(add(&$expr)?;)* Ok(()) })
};
(![$($expr:expr),* $(,)?]) => {
Stack::down(|add|{ $(add(&$expr)?;)* Ok(()) })
};
($expr:expr) => {
Stack::down($expr)
};
($pat:pat in $collection:expr => $item:expr) => {
Stack::down(move|add|{ for $pat in $collection { add(&$item)?; } Ok(()) })
};
}
#[macro_export] macro_rules! col_up {
($($move:ident)?|$add:ident|$expr:expr) => {
($(move)?|$add:ident|$expr:expr) => {
Stack::up($(move)?|$add|$expr)
};
($pat:pat in $collection:expr => $item:expr) => {
@ -24,17 +25,23 @@ use crate::*;
Ok(())
})
};
($($expr:expr),* $(,)?) => { Stack::up(move|add|{ $(add(&$expr)?;)* Ok(()) }) };
($($expr:expr),* $(,)?) => {
Stack::up(move|add|{ $(add(&$expr)?;)* Ok(()) })
};
}
#[macro_export] macro_rules! row {
($($move:ident)?|$add:ident|$expr:expr) => {
Stack::right($(move)?|$add|$expr)
([$($expr:expr),* $(,)?]) => {
Stack::right(move|add|{ $(add(&$expr)?;)* Ok(()) })
};
(![$($expr:expr),* $(,)?]) => {
Stack::right(|add|{ $(add(&$expr)?;)* Ok(()) })
};
($expr:expr) => {
Stack::right($expr)
};
($pat:pat in $collection:expr => $item:expr) => {
Stack::right(move |add|{ for $pat in $collection { add(&$item)?; } Ok(()) })
};
($($expr:expr),* $(,)?) => {
Stack::right(move|add|{ $(add(&$expr)?;)* Ok(()) })
Stack::right(move|add|{ for $pat in $collection { add(&$item)?; } Ok(()) })
};
}

View file

@ -56,7 +56,7 @@ impl FocusWrap<TransportFocus> for TransportFocus {
let focused = focus == self;
let corners = focused.then_some(CORNERS);
//let highlight = focused.then_some(Tui::bg(Color::Rgb(60, 70, 50)));
lay!(corners, /*highlight,*/ *content)
lay!([corners, /*highlight,*/ *content])
}
}
@ -67,7 +67,7 @@ impl FocusWrap<TransportFocus> for Option<TransportFocus> {
let focused = Some(focus) == self;
let corners = focused.then_some(CORNERS);
//let highlight = focused.then_some(Background(Color::Rgb(60, 70, 50)));
lay!(corners, /*highlight,*/ *content)
lay!([corners, /*highlight,*/ *content])
}
}

View file

@ -138,6 +138,15 @@ pub fn buffer_update (buf: &mut Buffer, area: [u16;4], callback: &impl Fn(&mut C
}
}
impl Render<Tui> for () {
fn min_size (&self, _: [u16;2]) -> Perhaps<[u16;2]> {
Ok(None)
}
fn render (&self, to: &mut TuiOutput) -> Usually<()> {
Ok(())
}
}
impl Render<Tui> for &str {
fn min_size (&self, _: [u16;2]) -> Perhaps<[u16;2]> {
// TODO: line breaks

View file

@ -8,7 +8,7 @@ render!(|self: ArrangerTui|{
Tui::to_south(
self.splits[0],
Tui::to_south(
lay!(
lay!([
Layers::new(move |add|{
match self.mode {
ArrangerMode::Horizontal =>
@ -30,7 +30,7 @@ render!(|self: ArrangerTui|{
}))
.fg(TuiTheme::title_fg(arranger_focused))
.push_x(1),
),
]),
Split::right(
self.splits[1],
PhraseListView::from(self),
@ -85,6 +85,14 @@ fn track_widths (tracks: &[ArrangerTrack]) -> Vec<(usize, usize)> {
widths
}
fn any_size <E: Engine> (_: E::Size) -> Perhaps<E::Size>{
Ok(Some([0.into(),0.into()].into()))
}
fn custom_render <F: Fn(&mut TuiOutput)->Usually<()>+Send+Sync> (render: F) -> impl Render<Tui> {
Widget::new(|_|Ok(Some([0u16,0u16].into())), render)
}
pub fn arranger_content_vertical (
view: &ArrangerTui,
factor: usize
@ -100,9 +108,8 @@ pub fn arranger_content_vertical (
let sep_fg = TuiTheme::separator_fg(false);
let header_h = 3u16;//5u16;
let scenes_w = 3 + ArrangerScene::longest_name(scenes) as u16; // x of 1st track
let rows: &[(usize, usize)] = rows.as_ref();
let cols: &[(usize, usize)] = cols.as_ref();
let any_size = |_|Ok(Some([0,0]));
//let rows: &[(usize, usize)] = rows_.as_ref();
//let cols: &[(usize, usize)] = cols_.as_ref();
// track titles
let header = row!((track, w) in tracks.iter().zip(cols.iter().map(|col|col.0)) => {
@ -135,12 +142,12 @@ pub fn arranger_content_vertical (
}).unwrap_or(String::from(""));
let timer = Tui::to_south(until_next, elapsed);
// name of active MIDI input
let input = format!("▎>{}", track.player.midi_ins().get(0)
let _input = format!("▎>{}", track.player.midi_ins().get(0)
.map(|port|port.short_name())
.transpose()?
.unwrap_or("(none)".into()));
// name of active MIDI output
let output = format!("▎<{}", track.player.midi_outs().get(0)
let _output = format!("▎<{}", track.player.midi_outs().get(0)
.map(|port|port.short_name())
.transpose()?
.unwrap_or("(none)".into()));
@ -189,93 +196,144 @@ pub fn arranger_content_vertical (
)
}));
let arrangement = Tui::bg(bg.rgb, lay!(move|add|{
// column separators
add(&Widget::new(any_size, move|to: &mut TuiOutput|{
let style = Some(Style::default().fg(sep_fg));
Ok(for x in cols.iter().map(|col|col.1) {
let x = scenes_w + to.area().x() + x as u16;
for y in to.area().y()..to.area().y2() { to.blit(&"", x, y, style); }
})
}))?;
// row separators
add(&Widget::new(any_size, move|to: &mut TuiOutput|{
Ok(for y in rows.iter().map(|row|row.1) {
let y = to.area().y() + (y / PPQ) as u16 + 1;
if y >= to.buffer.area.height { break }
for x in to.area().x()..to.area().x2().saturating_sub(2) {
if x < to.buffer.area.x && y < to.buffer.area.y {
let cell = to.buffer.get_mut(x, y);
cell.modifier = Modifier::UNDERLINED;
cell.underline_color = sep_fg;
}
}
})
}))?;
// full grid with header and footer
add(&Tui::to_south(header, content))?;
// cursor
add(&Widget::new(any_size, move|to: &mut TuiOutput|{
let area = to.area();
let focused = view.arranger_focused();
let selected = view.selected;
let get_track_area = |t: usize| [
scenes_w + area.x() + cols[t].1 as u16, area.y(),
cols[t].0 as u16, area.h(),
];
let get_scene_area = |s: usize| [
area.x(), header_h + area.y() + (rows[s].1 / PPQ) as u16,
area.w(), (rows[s].0 / PPQ) as u16
];
let get_clip_area = |t: usize, s: usize| [
scenes_w + area.x() + cols[t].1 as u16,
header_h + area.y() + (rows[s].1/PPQ) as u16,
cols[t].0 as u16,
(rows[s].0 / PPQ) as u16
];
let mut track_area: Option<[u16;4]> = None;
let mut scene_area: Option<[u16;4]> = None;
let mut clip_area: Option<[u16;4]> = None;
let area = match selected {
ArrangerSelection::Mix => area,
ArrangerSelection::Track(t) => {
track_area = Some(get_track_area(t));
area
},
ArrangerSelection::Scene(s) => {
scene_area = Some(get_scene_area(s));
area
},
ArrangerSelection::Clip(t, s) => {
track_area = Some(get_track_area(t));
scene_area = Some(get_scene_area(s));
clip_area = Some(get_clip_area(t, s));
area
},
};
let bg = TuiTheme::border_bg();
if let Some([x, y, width, height]) = track_area {
to.fill_fg([x, y, 1, height], bg);
to.fill_fg([x + width, y, 1, height], bg);
}
if let Some([_, y, _, height]) = scene_area {
to.fill_ul([area.x(), y - 1, area.w(), 1], bg);
to.fill_ul([area.x(), y + height - 1, area.w(), 1], bg);
}
Ok(if focused {
to.render_in(if let Some(clip_area) = clip_area { clip_area }
else if let Some(track_area) = track_area { track_area.clip_h(header_h) }
else if let Some(scene_area) = scene_area { scene_area.clip_w(scenes_w) }
else { area.clip_w(scenes_w).clip_h(header_h) }, &CORNERS)?
})
}))
}));
let color = TuiTheme::title_fg(view.arranger_focused());
let size = format!("{}x{}", view.size.w(), view.size.h());
let lower_right = Tui::at_se(Tui::fill_xy(Tui::pull_x(1, Tui::fg(color, size))));
lay!(arrangement, lower_right)
lay!([
Tui::bg(bg.rgb, lay!(![
ArrangerVerticalColumnSeparator::from(view),
ArrangerVerticalRowSeparator::from((view, factor)),
col!(![header, content]),
ArrangerCursor::from((view, factor)),
])),
Tui::at_se(Tui::fill_xy(Tui::pull_x(1, Tui::fg(color, format!("{}x{}", view.size.w(), view.size.h()))))),
])
}
struct ArrangerVerticalColumnSeparator {
cols: Vec<(usize, usize)>,
scenes_w: u16,
sep_fg: Color,
}
impl From<&ArrangerTui> for ArrangerVerticalColumnSeparator {
fn from (state: &ArrangerTui) -> Self {
Self {
cols: track_widths(state.tracks()),
scenes_w: 3 + ArrangerScene::longest_name(state.scenes()) as u16,
sep_fg: TuiTheme::separator_fg(false),
}
}
}
render!(|self: ArrangerVerticalColumnSeparator|custom_render(move|to: &mut TuiOutput|{
let style = Some(Style::default().fg(self.sep_fg));
Ok(for x in self.cols.iter().map(|col|col.1) {
let x = self.scenes_w + to.area().x() + x as u16;
for y in to.area().y()..to.area().y2() {
to.blit(&"", x, y, style);
}
})
}));
struct ArrangerVerticalRowSeparator {
rows: Vec<(usize, usize)>,
sep_fg: Color,
}
impl From<(&ArrangerTui, usize)> for ArrangerVerticalRowSeparator {
fn from ((state, factor): (&ArrangerTui, usize)) -> Self {
Self {
rows: ArrangerScene::ppqs(state.scenes(), factor),
sep_fg: TuiTheme::separator_fg(false),
}
}
}
render!(|self: ArrangerVerticalRowSeparator|custom_render(move|to: &mut TuiOutput|{
Ok(for y in self.rows.iter().map(|row|row.1) {
let y = to.area().y() + (y / PPQ) as u16 + 1;
if y >= to.buffer.area.height { break }
for x in to.area().x()..to.area().x2().saturating_sub(2) {
if x < to.buffer.area.x && y < to.buffer.area.y {
let cell = to.buffer.get_mut(x, y);
cell.modifier = Modifier::UNDERLINED;
cell.underline_color = self.sep_fg;
}
}
})
}));
struct ArrangerCursor {
cols: Vec<(usize, usize)>,
rows: Vec<(usize, usize)>,
focused: bool,
selected: ArrangerSelection,
scenes_w: u16,
header_h: u16,
}
impl From<(&ArrangerTui, usize)> for ArrangerCursor {
fn from ((state, factor): (&ArrangerTui, usize)) -> Self {
Self {
cols: track_widths(state.tracks()),
rows: ArrangerScene::ppqs(state.scenes(), factor),
focused: state.arranger_focused(),
selected: state.selected,
scenes_w: 3 + ArrangerScene::longest_name(state.scenes()) as u16,
header_h: 3,
}
}
}
render!(|self: ArrangerCursor|custom_render(move|to: &mut TuiOutput|{
let area = to.area();
let focused = self.focused;
let selected = self.selected;
let get_track_area = |t: usize| [
self.scenes_w + area.x() + self.cols[t].1 as u16, area.y(),
self.cols[t].0 as u16, area.h(),
];
let get_scene_area = |s: usize| [
area.x(), self.header_h + area.y() + (self.rows[s].1 / PPQ) as u16,
area.w(), (self.rows[s].0 / PPQ) as u16
];
let get_clip_area = |t: usize, s: usize| [
self.scenes_w + area.x() + self.cols[t].1 as u16,
self.header_h + area.y() + (self.rows[s].1/PPQ) as u16,
self.cols[t].0 as u16,
(self.rows[s].0 / PPQ) as u16
];
let mut track_area: Option<[u16;4]> = None;
let mut scene_area: Option<[u16;4]> = None;
let mut clip_area: Option<[u16;4]> = None;
let area = match selected {
ArrangerSelection::Mix => area,
ArrangerSelection::Track(t) => {
track_area = Some(get_track_area(t));
area
},
ArrangerSelection::Scene(s) => {
scene_area = Some(get_scene_area(s));
area
},
ArrangerSelection::Clip(t, s) => {
track_area = Some(get_track_area(t));
scene_area = Some(get_scene_area(s));
clip_area = Some(get_clip_area(t, s));
area
},
};
let bg = TuiTheme::border_bg();
if let Some([x, y, width, height]) = track_area {
to.fill_fg([x, y, 1, height], bg);
to.fill_fg([x + width, y, 1, height], bg);
}
if let Some([_, y, _, height]) = scene_area {
to.fill_ul([area.x(), y - 1, area.w(), 1], bg);
to.fill_ul([area.x(), y + height - 1, area.w(), 1], bg);
}
Ok(if focused {
to.render_in(if let Some(clip_area) = clip_area { clip_area }
else if let Some(track_area) = track_area { track_area.clip_h(self.header_h) }
else if let Some(scene_area) = scene_area { scene_area.clip_w(self.scenes_w) }
else { area.clip_w(self.scenes_w).clip_h(self.header_h) }, &CORNERS)?
})
}));
pub fn arranger_content_horizontal (
view: &ArrangerTui,
) -> impl Render<Tui> + use<'_> {

View file

@ -63,31 +63,6 @@ render!(|self: PhraseView<'a>|{
//now: _,
..
} = self;
let upper_left = format!(
"╭{note_hi} {note_hi_name} {}",
phrase.as_ref().map(|p|p.read().unwrap().name.clone()).unwrap_or(String::new())
);
let lower_left = format!(
"╰{note_lo} {note_lo_name}"
);
let mut lower_right = format!(
" {} ", size.format()
);
if *focused && *entered {
lower_right = format!("Note: {} ({}) {} {lower_right}",
note_point, to_note_name(*note_point), pulses_to_name(*note_len)
);
}
let mut upper_right = format!(
"[{}]",
if *entered {""} else {" "}
);
if let Some(phrase) = phrase {
upper_right = format!("Time: {}/{} {} {upper_right}",
time_point, phrase.read().unwrap().length, pulses_to_name(view_mode.time_zoom()),
)
};
let title_color = if *focused{Color::Rgb(150, 160, 90)}else{Color::Rgb(120, 130, 100)};
// is it r6d that `to` is the receiver?
let keys = move|to: &mut TuiOutput|{
Ok(if to.area().h() >= 2 { view_mode.render_keys(to, *note_hi, *note_lo) })
@ -124,7 +99,24 @@ render!(|self: PhraseView<'a>|{
////}
//Ok(())
//};
let indicators = lay!(|add|{
let indicators = lay!(move|add|{
let title_color = if *focused{Color::Rgb(150, 160, 90)}else{Color::Rgb(120, 130, 100)};
let upper_left = format!("{note_hi} {note_hi_name} {}",
phrase.as_ref().map(|p|p.read().unwrap().name.clone()).unwrap_or(String::new())
);
let lower_left = format!("{note_lo} {note_lo_name}");
let mut lower_right = format!(" {} ", size.format());
if *focused && *entered {
lower_right = format!("Note: {} ({}) {} {lower_right}",
note_point, to_note_name(*note_point), pulses_to_name(*note_len)
);
}
let mut upper_right = format!("[{}]", if *entered {""} else {" "});
if let Some(phrase) = phrase {
upper_right = format!("Time: {}/{} {} {upper_right}",
time_point, phrase.read().unwrap().length, pulses_to_name(view_mode.time_zoom()),
)
};
add(&Tui::at_nw(Tui::fg(title_color, upper_left)))?;
add(&Tui::at_sw(Tui::fg(title_color, lower_left)))?;
add(&Tui::fill_xy(Tui::at_ne(Tui::pull_x(1, Tui::fg(title_color, upper_right)))))?;
@ -133,12 +125,15 @@ render!(|self: PhraseView<'a>|{
});
let content = Tui::bg(Color::Rgb(40, 50, 30), Tui::fill_x(Tui::to_east(
Tui::push_y(1, Tui::fill_y(Widget::new(|to:[u16;2]|Ok(Some(to.clip_w(2))), keys))),
Tui::fill_x(lay!(
Tui::fill_x(lay!([
Tui::push_y(1, Tui::fill_x(Widget::new(|to|Ok(Some(to)), notes))),
Tui::push_y(1, Widget::new(|to|Ok(Some(to)), cursor))
)),
])),
)));
lay!(indicators, content)
lay!([
indicators,
content
])
});
#[derive(Copy, Clone, Debug)]

View file

@ -1,45 +1,17 @@
use crate::*;
render!(|self:PhraseLength|{
render!(|self: PhraseLength|{
let bars = ||self.bars_string();
let beats = ||self.beats_string();
let ticks = ||self.ticks_string();
row!(|add|(match self.focus {
row!(move|add|match self.focus {
None =>
add(&row!(" ", bars(), "B", beats(), "b", ticks(), "T")),
add(&row!([" ", bars(), "B", beats(), "b", ticks(), "T"])),
Some(PhraseLengthFocus::Bar) =>
add(&row!("[", bars(), "]", beats(), "b", ticks(), "T")),
add(&row!(["[", bars(), "]", beats(), "b", ticks(), "T"])),
Some(PhraseLengthFocus::Beat) =>
add(&row!(" ", bars(), "[", beats(), "]", ticks(), "T")),
add(&row!([" ", bars(), "[", beats(), "]", ticks(), "T"])),
Some(PhraseLengthFocus::Tick) =>
add(&row!(" ", bars(), "B", beats(), "[", ticks(), "]")),
}))
//Layers::new(move|add|{
//match self.focus {
//None => add(&row!(
//" ", self.bars_string(),
//".", self.beats_string(),
//".", self.ticks_string(),
//" "
//)),
//Some(PhraseLengthFocus::Bar) => add(&row!(
//"[", self.bars_string(),
//"]", self.beats_string(),
//".", self.ticks_string(),
//" "
//)),
//Some(PhraseLengthFocus::Beat) => add(&row!(
//" ", self.bars_string(),
//"[", self.beats_string(),
//"]", self.ticks_string(),
//" "
//)),
//Some(PhraseLengthFocus::Tick) => add(&row!(
//" ", self.bars_string(),
//".", self.beats_string(),
//"[", self.ticks_string(),
//"]"
//)),
//}
//})
add(&row!([" ", bars(), "B", beats(), "[", ticks(), "]"])),
})
});

View file

@ -25,7 +25,7 @@ impl<'a, T: HasPhraseList> From<&'a T> for PhraseListView<'a> {
// TODO: Display phrases always in order of appearance
render!(|self: PhraseListView<'a>|{
let Self { title, focused, entered, phrases, index, mode } = self;
let content = Stack::down(move|add|match mode {
let content = col!(|add|match mode {
Some(PhrasesMode::Import(_, ref browser)) => {
add(browser)
},
@ -34,7 +34,7 @@ render!(|self: PhraseListView<'a>|{
},
_ => {
for (i, phrase) in phrases.iter().enumerate() {
add(&Layers::new(|add|{
add(&lay!(|add|{
let Phrase { ref name, color, length, .. } = *phrase.read().unwrap();
let mut length = PhraseLength::new(length, None);
if let Some(PhrasesMode::Length(phrase, new_length, focus)) = mode {
@ -44,7 +44,7 @@ render!(|self: PhraseListView<'a>|{
}
}
let length = Tui::fill_x(Tui::at_e(length));
let row1 = Tui::fill_x(lay!(Tui::fill_x(Tui::at_w(format!(" {i}"))), length));
let row1 = Tui::fill_x(lay!([Tui::fill_x(Tui::at_w(format!(" {i}"))), length]));
let mut row2 = format!(" {name}");
if let Some(PhrasesMode::Rename(phrase, _)) = mode {
if *focused && i == *phrase {
@ -63,13 +63,13 @@ render!(|self: PhraseListView<'a>|{
}
});
let border_color = if *focused {Color::Rgb(100, 110, 40)} else {Color::Rgb(70, 80, 50)};
let content = Tui::bg(Color::Rgb(28, 35, 25), Tui::fill_xy(content));
let title_color = if *focused {Color::Rgb(150, 160, 90)} else {Color::Rgb(120, 130, 100)};
let upper_left = format!("[{}] {title}", if *entered {""} else {" "});
let upper_right = format!("({})", phrases.len());
lay!(
Lozenge(Style::default().bg(Color::Rgb(40, 50, 30)).fg(border_color)).wrap(content),
lay!([
Lozenge(Style::default().bg(Color::Rgb(40, 50, 30)).fg(border_color))
.wrap(Tui::bg(Color::Rgb(28, 35, 25), Tui::fill_xy(content))),
Tui::fill_xy(Tui::at_nw(Tui::push_x(1, Tui::fg(title_color, upper_left.to_string())))),
Tui::fill_xy(Tui::at_ne(Tui::pull_x(1, Tui::fg(title_color, upper_right.to_string())))),
)
])
});

View file

@ -42,7 +42,7 @@ render!(|self:PhraseSelector<'a>|{
let Phrase { ref name, color, length, .. } = *phrase.read().unwrap();
let length = PhraseLength::new(length, None);
let length = Tui::fill_x(Tui::at_e(length));
let row1 = Tui::fill_x(lay!(Tui::fill_x(Tui::at_w(format!(" "))), length));
let row1 = Tui::fill_x(lay!([Tui::fill_x(Tui::at_w(format!(" "))), length]));
let row2 = format!(" {name}");
let row2 = Tui::bold(true, row2);
add(&Tui::bg(color.base.rgb, Tui::fill_x(Tui::to_south(row1, row2))))?;

View file

@ -2,16 +2,6 @@
use crate::*;
render!(|self: SequencerTui|{
let play = PhraseSelector::play_phrase(
&self.player,
self.focused() == SequencerFocus::PhrasePlay,
self.entered()
);
let next = PhraseSelector::next_phrase(
&self.player,
self.focused() == SequencerFocus::PhraseNext,
self.entered()
);
Tui::to_north(
SequencerStatusBar::from(self),
Tui::to_south(
@ -19,14 +9,19 @@ render!(|self: SequencerTui|{
Tui::min_y(
20,
Tui::to_east(
20,
Tui::to_south(
Tui::fixed_y(4, play),
Tui::to_south(
Tui::fixed_y(4, next),
PhraseListView::from(self)
)
),
Tui::min_x(20, col!([
Tui::fixed_y(4, PhraseSelector::play_phrase(
&self.player,
self.focused() == SequencerFocus::PhrasePlay,
self.entered()
)),
Tui::fixed_y(4, PhraseSelector::next_phrase(
&self.player,
self.focused() == SequencerFocus::PhraseNext,
self.entered()
)),
PhraseListView::from(self)
])),
PhraseView::from(self)
)
)
@ -45,7 +40,7 @@ render!(|self: SequencerStatusBar|{
Tui::to_east(
Tui::bg(orange, Tui::fg(black, Tui::bold(true, self.mode))),
Tui::bg(light, row!((prefix, hotkey, suffix) in self.help.iter() => {
row!(" ", prefix, Tui::fg(yellow, *hotkey), suffix)
row!([" ", prefix, Tui::fg(yellow, *hotkey), suffix])
}))
)
};
@ -55,17 +50,17 @@ render!(|self: SequencerStatusBar|{
let cpu = &self.cpu;
let res = &self.res;
let size = &self.size;
Tui::bg(dark, row!(
Tui::bg(dark, row!([
Tui::fg(orange, cpu),
Tui::fg(orange, res),
Tui::fg(orange, size),
))
]))
};
lay!(|add|if self.width > 60 {
add(&row!(modeline, statusbar))
add(&row!(![modeline, statusbar]))
} else if self.width > 0 {
add(&col!(modeline, statusbar))
add(&col!(![modeline, statusbar]))
} else {
Ok(())
})

View file

@ -11,7 +11,7 @@ pub trait StatusBar: Render<Tui> {
{
let hotkey_fg = Self::hotkey_fg();
row!([a, b, c] in commands.iter() => {
row!(a, Tui::fg(hotkey_fg, Tui::bold(true, b)), c)
row!([a, Tui::fg(hotkey_fg, Tui::bold(true, b)), c])
})
//Tui::reduce(commands.iter(), |prev, [a, b, c]|
//Tui::to_east(prev,