tek/crates/tek_tui/src/tui_view_phrase_selector.rs

63 lines
2.2 KiB
Rust

use crate::*;
pub struct PhraseSelector<'a> {
pub(crate) title: &'static str,
pub(crate) phrase: &'a Option<(Moment, Option<Arc<RwLock<Phrase>>>)>,
pub(crate) focused: bool,
pub(crate) entered: bool,
}
impl<'a> PhraseSelector<'a> {
pub fn play_phrase <T: HasPlayPhrase> (
state: &'a T,
focused: bool,
entered: bool,
) -> Self {
Self {
focused,
entered: focused && entered,
phrase: state.next_phrase(),
title: "Now:",
}
}
pub fn next_phrase <T: HasPlayPhrase> (
state: &'a T,
focused: bool,
entered: bool,
) -> Self {
Self {
focused,
entered: focused && entered,
phrase: state.next_phrase(),
title: "Next:",
}
}
}
// TODO: Display phrases always in order of appearance
impl<'a> Content for PhraseSelector<'a> {
type Engine = Tui;
fn content (&self) -> impl Render<Engine = Tui> {
let Self { title, phrase, focused, entered } = self;
let content = Layers::new(move|add|{
if let Some((instant, Some(phrase))) = phrase {
let Phrase { ref name, color, length, .. } = *phrase.read().unwrap();
let length = PhraseLength::new(length, None);
let length = length.align_e().fill_x();
let row1 = lay!(format!(" ").align_w().fill_x(), length).fill_x();
let row2 = format!(" {name}");
let row2 = TuiStyle::bold(row2, true);
add(&col!(row1, row2).fill_x().bg(color.base.rgb))?;
}
Ok(())
});
let border_color = if *focused {Color::Rgb(100, 110, 40)} else {Color::Rgb(70, 80, 50)};
let border = Lozenge(Style::default().bg(Color::Rgb(40, 50, 30)).fg(border_color));
let content = content.fill_xy().bg(Color::Rgb(28, 35, 25)).border(border);
let title_color = if *focused {Color::Rgb(150, 160, 90)} else {Color::Rgb(120, 130, 100)};
lay!(
content,
TuiStyle::fg(*title, title_color).push_x(1).align_nw().fill_xy(),
)
}
}