list of 'guests' (WIP)
This commit is contained in:
parent
979428b4fd
commit
5dee5f499c
|
@ -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"
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
80
src/main.rs
80
src/main.rs
|
@ -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());
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue