WIP moving views

This commit is contained in:
Niko Abeler 2023-01-10 19:46:44 +01:00
parent 46027a340e
commit 72a43400a0
3 changed files with 114 additions and 85 deletions

View File

@ -56,7 +56,7 @@ impl<'a> DebugView<'a> {
view view
} }
pub fn control(&mut self) -> (bool, Option<AppStatus>) { pub fn control(&mut self, _game: &mut Game) -> (bool, Option<AppStatus>) {
match read() { match read() {
Ok(Event::Key(event)) => { Ok(Event::Key(event)) => {
match event.code { match event.code {

100
src/ui/guest_selection.rs Normal file
View File

@ -0,0 +1,100 @@
use crossterm::event::{read, Event, KeyCode};
use tui::{backend::Backend, Frame};
use crate::game::Game;
use super::{AppStatus, DefaultLayout, controls::Controls, status_line::StatusLine};
pub struct GuestSelectionView<'a> {
guest_list: Vec<tui::widgets::ListItem<'a>>,
guest_list_state: tui::widgets::ListState,
}
impl<'a> GuestSelectionView<'a> {
pub fn new(game: &Game) -> GuestSelectionView<'a> {
let guest_list = game.state.guests().iter().map(|creature_id| {
let creature = game.state.get_creature(*creature_id).unwrap();
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<AppStatus>) {
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) => {
// let guest_id = &self.game.state.guests()[selected];
// self.conversation = Chat::new();
// self.greet_guest(Some(*guest_id));
// self.status = AppStatus::TalkToGuest(Some(*guest_id));
},
None => {}
}
}
},
KeyCode::Char('?') => {
return (true, Some(AppStatus::Debug))
},
KeyCode::Char('.') => {
game.step();
return (true, Some(AppStatus::Initial));
},
KeyCode::Esc => {
return (false, None);
},
_ => {}
}
},
_ => {}
}
(true, None)
}
pub fn draw<B: Backend>(&mut self, f: &mut Frame<B>, game: &Game) {
let chunks = DefaultLayout::default(f.size());
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(">>");
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);
}
}

View File

@ -1,6 +1,7 @@
mod chat; mod chat;
mod controls; mod controls;
mod debug_view; mod debug_view;
mod guest_selection;
mod status_line; mod status_line;
use crossterm::event::{read, Event, KeyCode}; use crossterm::event::{read, Event, KeyCode};
@ -8,7 +9,7 @@ use tui::{backend::Backend, Frame, layout::Layout};
use crate::{game::Game, entity::{EntityId, EntityType}, world::Terrain}; use crate::{game::Game, entity::{EntityId, EntityType}, world::Terrain};
use self::{chat::{Chat, ChatLine}, controls::Controls, debug_view::DebugView}; use self::{chat::{Chat, ChatLine}, controls::Controls, debug_view::DebugView, guest_selection::GuestSelectionView};
/** /**
* |........................| * |........................|
@ -32,15 +33,14 @@ pub struct App<'a> {
status: AppStatus, status: AppStatus,
// Guest Selection // Guest Selection
guest_list: Vec<tui::widgets::ListItem<'a>>, guest_selection: Option<GuestSelectionView<'a>>,
guest_list_state: tui::widgets::ListState,
// Conversation // Conversation
conversation: Chat, conversation: Chat,
conversation_scroll: u16, conversation_scroll: u16,
// Debug // Debug
debug_view: Option<debug_view::DebugView<'a>>, debug_view: Option<DebugView<'a>>,
} }
pub struct DefaultLayout { pub struct DefaultLayout {
@ -74,8 +74,7 @@ impl<'a> App<'a> {
pub fn new(state: Game) -> App<'a> { pub fn new(state: Game) -> App<'a> {
App { App {
game: state, game: state,
guest_list: vec![], guest_selection: None,
guest_list_state: tui::widgets::ListState::default(),
status: AppStatus::Initial, status: AppStatus::Initial,
conversation: Chat::new(), conversation: Chat::new(),
conversation_scroll: 0, conversation_scroll: 0,
@ -86,65 +85,17 @@ impl<'a> App<'a> {
pub fn step(&mut self) -> bool { pub fn step(&mut self) -> bool {
match &self.status { match &self.status {
AppStatus::Initial => { AppStatus::Initial => {
// determine guests self.guest_selection = Some(GuestSelectionView::new(&self.game));
self.guest_list = self.game.state.guests().iter().map(|creature_id| {
let creature = self.game.state.get_creature(*creature_id).unwrap();
tui::widgets::ListItem::new(format!(
"{} ({}, {} items)",
creature.name,
creature.profession, self.game.state.get_inventory(creature.entity.id).len()
))
}).collect();
self.guest_list_state = tui::widgets::ListState::default();
self.guest_list_state.select(Some(0));
self.status = AppStatus::GuestSelection; self.status = AppStatus::GuestSelection;
true true
}, },
AppStatus::GuestSelection => { AppStatus::GuestSelection => {
match read() { let ret = self.guest_selection.as_mut().unwrap().control(&mut self.game);
Ok(Event::Key(event)) => { if let Some(next) = ret.1 {
match event.code { self.debug_view = None;
KeyCode::Up => { self.status = next;
let selected = self.guest_list_state.selected().unwrap();
if selected > 0 {
self.guest_list_state.select(Some(selected - 1));
} }
}, ret.0
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 self.game.state.guests().len() > 0 {
match self.guest_list_state.selected() {
Some(selected) => {
let guest_id = &self.game.state.guests()[selected];
self.conversation = Chat::new();
self.greet_guest(Some(*guest_id));
self.status = AppStatus::TalkToGuest(Some(*guest_id));
},
None => {}
}
}
},
KeyCode::Char('?') => {
self.open_debug();
},
KeyCode::Char('.') => {
self.game.step();
self.status = AppStatus::Initial;
},
KeyCode::Esc => {
return false;
},
_ => {}
}
},
_ => {}
}
true
}, },
AppStatus::TalkToGuest(guest) => { AppStatus::TalkToGuest(guest) => {
match read() { match read() {
@ -189,7 +140,7 @@ impl<'a> App<'a> {
true true
}, },
AppStatus::Debug => { AppStatus::Debug => {
let ret = self.debug_view.as_mut().unwrap().control(); let ret = self.debug_view.as_mut().unwrap().control(&mut self.game);
if let Some(next) = ret.1 { if let Some(next) = ret.1 {
self.debug_view = None; self.debug_view = None;
self.status = next; self.status = next;
@ -214,7 +165,7 @@ impl<'a> App<'a> {
self.draw_initial(f); self.draw_initial(f);
}, },
AppStatus::GuestSelection => { AppStatus::GuestSelection => {
self.draw_guest_selection(f); self.guest_selection.as_mut().unwrap().draw(f, &self.game);
}, },
AppStatus::TalkToGuest(guest_id) => { AppStatus::TalkToGuest(guest_id) => {
self.draw_talk_to_guest(f, *guest_id); self.draw_talk_to_guest(f, *guest_id);
@ -252,28 +203,6 @@ impl<'a> App<'a> {
pub fn draw_initial<B: Backend>(&mut self, _f: &mut Frame<B>) {} pub fn draw_initial<B: Backend>(&mut self, _f: &mut Frame<B>) {}
pub fn draw_guest_selection<B: Backend>(&mut self, f: &mut Frame<B>) {
let chunks = DefaultLayout::default(f.size());
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(">>");
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();
self.draw_status(f, chunks.status);
f.render_stateful_widget(main_window, chunks.main, &mut self.guest_list_state);
f.render_widget(controls, chunks.controls);
}
fn draw_talk_to_guest<B: Backend>(&self, f: &mut Frame<B>, guest: Option<EntityId>) { fn draw_talk_to_guest<B: Backend>(&self, f: &mut Frame<B>, guest: Option<EntityId>) {
let chunks = DefaultLayout::default(f.size()); let chunks = DefaultLayout::default(f.size());