use crossterm::event::{read, Event, KeyCode}; use tui::{backend::Backend, Frame}; use crate::game::Game; use super::{AppStatus, DefaultLayout, controls::Controls, status_line::StatusLine, talk_to_guest::TalkToGuestView, debug_view::DebugView}; struct Guest { name: String, profession: String, inventory_size: usize, } pub struct GuestSelectionView { guest_list: Vec, // tui::widgets::ListItem guest_list_state: tui::widgets::ListState, } impl GuestSelectionView { pub fn new(game: &Game) -> GuestSelectionView { let guest_list = game.state.guests().iter().map(|creature_id| { let creature = game.state.get_creature(*creature_id).unwrap(); Guest { name: creature.name.clone(), profession: format!("{}", creature.profession), inventory_size: game.state.get_inventory(creature.entity.id).len(), } // tui::widgets::ListItem::new(format!( // "{} ({}, {} items)", // creature.name, // creature.profession, game.state.get_inventory(creature.entity.id).len() // )) }).collect(); let mut guest_list_state = tui::widgets::ListState::default(); guest_list_state.select(Some(0)); GuestSelectionView { guest_list, guest_list_state, } } pub fn control(&mut self, game: &mut Game) -> (bool, Option) { match read() { Ok(Event::Key(event)) => { match event.code { KeyCode::Up => { let selected = self.guest_list_state.selected().unwrap(); if selected > 0 { self.guest_list_state.select(Some(selected - 1)); } }, KeyCode::Down => { let selected = self.guest_list_state.selected().unwrap(); if selected < self.guest_list.len() - 1 { self.guest_list_state.select(Some(selected + 1)); } }, KeyCode::Enter => { if game.state.guests().len() > 0 { match self.guest_list_state.selected() { Some(selected) => { return (true, Some(AppStatus::TalkToGuest(TalkToGuestView::new(game, game.state.guests()[selected])))) }, None => {} } } }, KeyCode::Char('?') => { return (true, Some(AppStatus::Debug(DebugView::new(game)))) }, KeyCode::Char('.') => { game.step(); return (true, Some(AppStatus::Initial)); }, KeyCode::Esc => { return (false, None); }, _ => {} } }, _ => {} } (true, None) } pub fn draw(&mut self, f: &mut Frame, game: &Game) { let chunks = DefaultLayout::default(f.size()); let main_window = tui::widgets::List::new(self.guest_list.iter().map(|guest| { tui::widgets::ListItem::new(format!( "{} ({}, {} items)", guest.name, guest.profession, guest.inventory_size )) }).collect::>()) .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(">>"); let mut binding = Controls::new(); let controls = binding .add("↑↓".to_owned(), "select guest".to_owned()) .add("⏎".to_owned(), "talk to guest".to_owned()) .add(".".to_owned(), "pass one day".to_owned()) .add("Esc".to_owned(), "quit".to_owned()) .render(); StatusLine::draw(f, chunks.status, game); f.render_stateful_widget(main_window, chunks.main, &mut self.guest_list_state); f.render_widget(controls, chunks.controls); } }