use std::rc::Rc; use crossterm::event::{read, Event, KeyCode}; use tui::{Terminal, backend::Backend, Frame}; use crate::{state::{self, GameState}, person::Person}; /** * |........................| * | Conversations/Selection| * | | * |........................| * | Available Options | * |........................| */ enum AppStatus { Initial, GuestSelection, TalkToGuest(Rc), } pub struct App<'a> { state: GameState, guest_list: Vec>, guest_state: tui::widgets::ListState, status: AppStatus, } impl<'a> App<'a> { pub fn new(state: GameState) -> App<'a> { App { state: state, guest_list: vec![], guest_state: tui::widgets::ListState::default(), status: AppStatus::Initial, } } pub fn step(&mut self) -> bool { match &self.status { AppStatus::Initial => { // determine guests self.guest_list = self.state.people.iter().map(|guest| { tui::widgets::ListItem::new(guest.name.clone()) }).collect(); self.guest_state = tui::widgets::ListState::default(); self.guest_state.select(Some(0)); self.status = AppStatus::GuestSelection; true }, AppStatus::GuestSelection => { match read() { Ok(Event::Key(event)) => { match event.code { KeyCode::Up => { let selected = self.guest_state.selected().unwrap(); if selected > 0 { self.guest_state.select(Some(selected - 1)); } }, KeyCode::Down => { let selected = self.guest_state.selected().unwrap(); if selected < self.guest_list.len() - 1 { self.guest_state.select(Some(selected + 1)); } }, KeyCode::Enter => { let selected = self.guest_state.selected().unwrap(); let guest = &self.state.people[selected]; self.status = AppStatus::TalkToGuest(guest.clone()); }, KeyCode::Esc => { return false; }, _ => {} } }, _ => {} } true }, AppStatus::TalkToGuest(guest) => { match read() { Ok(Event::Key(event)) => { match event.code { KeyCode::Esc => { self.status = AppStatus::GuestSelection; }, _ => {} } }, _ => {} } true } } } pub fn draw(&mut self, f: &mut Frame) { match &self.status { AppStatus::Initial => { self.draw_initial(f); }, AppStatus::GuestSelection => { self.draw_guest_selection(f); }, AppStatus::TalkToGuest(guest) => { self.draw_talk_to_guest(f, guest.clone()); } } } pub fn draw_initial(&mut self, f: &mut Frame) {} pub fn draw_guest_selection(&mut self, f: &mut Frame) { let main_window = tui::widgets::List::new(self.guest_list.clone()) .block(tui::widgets::Block::default().title("Guests").borders(tui::widgets::Borders::ALL)) .style(tui::style::Style::default().fg(tui::style::Color::White)) .highlight_style(tui::style::Style::default().add_modifier(tui::style::Modifier::ITALIC)) .highlight_symbol(">>"); f.render_stateful_widget(main_window, f.size(), &mut self.guest_state); } fn draw_talk_to_guest(&self, f: &mut Frame, guest: Rc) { let main_window = tui::widgets::Paragraph::new(guest.name.clone()) .block(tui::widgets::Block::default().title("Guests").borders(tui::widgets::Borders::ALL)) .style(tui::style::Style::default().fg(tui::style::Color::White)); f.render_widget(main_window, f.size()); } }