list of 'guests' (WIP)

This commit is contained in:
Niko Abeler 2022-12-31 11:44:42 +01:00
parent 979428b4fd
commit 5dee5f499c
4 changed files with 167 additions and 9 deletions

View File

@ -7,3 +7,5 @@ edition = "2021"
noise = { version = "0.8.2", features = ["images"] } noise = { version = "0.8.2", features = ["images"] }
rand = "0.8.5" rand = "0.8.5"
image = "0.24.5" image = "0.24.5"
tui = "0.19"
crossterm = "0.25"

88
src/app.rs Normal file
View File

@ -0,0 +1,88 @@
use crossterm::event::{read, Event, KeyCode};
use tui::{Terminal, backend::Backend, Frame};
use crate::state::{self, GameState};
/**
* |........................|
* | Conversations/Selection|
* | |
* |........................|
* | Available Options |
* |........................|
*/
enum AppStatus {
Initial,
GuestSelection,
}
pub struct App<'a> {
state: GameState,
guest_list: Vec<tui::widgets::ListItem<'a>>,
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::Esc => {
return false;
},
_ => {}
}
},
_ => {}
}
true
}
}
}
pub fn draw<B: Backend>(&mut self, f: &mut Frame<B>) {
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);
}
}

View File

@ -4,13 +4,32 @@ mod events;
mod time; mod time;
mod generators; mod generators;
mod person; mod person;
mod app;
use app::App;
use noise::{Perlin, ScalePoint, Add, NoiseFn, ScaleBias}; use noise::{Perlin, ScalePoint, Add, NoiseFn, ScaleBias};
use noise::utils::{NoiseMapBuilder, PlaneMapBuilder}; use noise::utils::{NoiseMapBuilder, PlaneMapBuilder};
use image::{RgbImage, Rgb}; use image::{RgbImage, Rgb};
use rand::prelude::*; use rand::prelude::*;
use tui::Frame;
use tui::backend::Backend;
use tui::style::{Style, Color, Modifier};
use tui::widgets::List;
use world::World; use world::World;
use std::{io, thread, time::Duration};
use tui::{
backend::CrosstermBackend,
widgets::{Widget, Block, Borders},
layout::{Layout, Constraint, Direction},
Terminal
};
use crossterm::{
event::{read, DisableMouseCapture, EnableMouseCapture, Event, KeyCode},
execute,
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
};
const N_TOWNS: usize = 10; const N_TOWNS: usize = 10;
const WORLD_SIZE: usize = 256; const WORLD_SIZE: usize = 256;
@ -89,22 +108,65 @@ fn build_world() -> World {
world world
} }
fn main() { fn draw_state<B: Backend>(f: &mut Frame<B>, state: &state::GameState) {
let mut items: Vec<tui::widgets::ListItem> = vec![];
let mut state = state::GameState::new(build_world()); for e in state.events.iter() {
items.push(tui::widgets::ListItem::new(format!("{}", e.description())));
}
state.step_n(36000); let main_window = List::new(items)
.block(Block::default().title("List").borders(Borders::ALL))
.style(Style::default().fg(Color::White))
.highlight_style(Style::default().add_modifier(Modifier::ITALIC))
.highlight_symbol(">>");
f.render_widget(main_window, f.size());
}
fn main() -> Result<(), io::Error> {
let mut world_state = state::GameState::new(build_world());
world_state.step_n(36000);
let mut rng = rand::thread_rng(); let mut rng = rand::thread_rng();
for _ in 0..N_TOWNS { for _ in 0..N_TOWNS {
state.step_n(rng.gen_range(0..360*3)); world_state.step_n(rng.gen_range(0..360*3));
state.found_town(); world_state.found_town();
}
for event in &state.events {
println!("{}", event.description());
} }
// setup terminal
enable_raw_mode()?;
let mut stdout = io::stdout();
execute!(stdout, EnterAlternateScreen, EnableMouseCapture)?;
let backend = CrosstermBackend::new(stdout);
let mut terminal = Terminal::new(backend)?;
let mut app = App::new(world_state);
loop {
terminal.draw(|f| app.draw(f))?;
if !app.step() {
break;
}
}
// restore terminal
disable_raw_mode()?;
execute!(
terminal.backend_mut(),
LeaveAlternateScreen,
DisableMouseCapture
)?;
terminal.show_cursor()?;
Ok(())
// for event in &state.events {
// println!("{}", event.description());
// }
} }

View File

@ -1,4 +1,4 @@
use std::rc::Rc; use std::{rc::Rc, fmt::Display};
use crate::{time::Time, world::Town, generators::PersonNameGenerator}; use crate::{time::Time, world::Town, generators::PersonNameGenerator};
@ -27,3 +27,9 @@ impl Person {
} }
} }
} }
impl Display for Person {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.name)
}
}