use crate::*; pub struct PhraseSelector<'a> { pub(crate) title: &'static str, pub(crate) phrase: &'a Option<(Moment, Option>>)>, pub(crate) focused: bool, pub(crate) entered: bool, } impl<'a> PhraseSelector<'a> { pub fn play_phrase ( state: &'a T, focused: bool, entered: bool, ) -> Self { Self { focused, entered: focused && entered, phrase: state.next_phrase(), title: "Now:", } } pub fn next_phrase ( 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 { 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(), ) } }