From 0af3b17810b9ce8bd15b99fff2bc1e4e8f2f8c41 Mon Sep 17 00:00:00 2001 From: Niko Abeler Date: Wed, 4 Jan 2023 19:41:31 +0100 Subject: [PATCH] chat refactoring WIP --- src/main.rs | 4 +-- src/ui/chat.rs | 57 +++++++++++++++++++++++++++++++++++++ src/{app.rs => ui/mod.rs} | 59 +++++++++++++++++++++------------------ 3 files changed, 91 insertions(+), 29 deletions(-) create mode 100644 src/ui/chat.rs rename src/{app.rs => ui/mod.rs} (86%) diff --git a/src/main.rs b/src/main.rs index 06822ee..0d6ad44 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,11 +5,11 @@ mod time; mod generators; mod creature; mod site; -mod app; +mod ui; mod entity; mod game; -use app::App; +use ui::App; use noise::{Perlin, ScalePoint, Add, NoiseFn, ScaleBias}; use noise::utils::{NoiseMapBuilder, PlaneMapBuilder}; use image::{RgbImage, Rgb}; diff --git a/src/ui/chat.rs b/src/ui/chat.rs new file mode 100644 index 0000000..65a07ad --- /dev/null +++ b/src/ui/chat.rs @@ -0,0 +1,57 @@ +use tui::{text::{Span}, style::{Style, Color}}; + +use crate::entity::EntityId; + +pub struct ChatLine { + pub speaker_id: EntityId, + pub speaker: String, + pub text: String, + pub action: bool, +} + +pub struct Chat { + pub lines: Vec, +} + +impl ChatLine { + pub fn new(speaker_id: EntityId, speaker: String, text: String, action: bool) -> ChatLine { + ChatLine { + speaker_id: speaker_id, + speaker: speaker, + text: text, + action: action, + } + } + + pub fn to_spans(&self) -> tui::text::Spans { + let mut spans = Vec::new(); + spans.push(Span::styled(format!("{}: ", self.speaker), Style::default().fg(Color::Red))); + spans.push(Span::styled(format!("{}", self.text), Style::default().fg(Color::White))); + tui::text::Spans::from(spans) + } + +} + +impl Chat { + pub fn new() -> Chat { + Chat { + lines: Vec::new(), + } + } + + pub fn add_line(&mut self, line: ChatLine) { + self.lines.push(line); + } + + pub fn to_spans(&self) -> Vec { + let mut spans = Vec::new(); + for line in &self.lines { + spans.push(line.to_spans()); + spans.push(tui::text::Spans::from(vec![ + Span::styled("\n", Style::default().fg(Color::White)) + ])); + } + spans + } + +} \ No newline at end of file diff --git a/src/app.rs b/src/ui/mod.rs similarity index 86% rename from src/app.rs rename to src/ui/mod.rs index 5056665..f1feef8 100644 --- a/src/app.rs +++ b/src/ui/mod.rs @@ -1,8 +1,12 @@ +mod chat; + use crossterm::event::{read, Event, KeyCode}; use tui::{backend::Backend, Frame, layout::Layout}; use crate::{game::Game, entity::EntityId}; +use self::chat::{Chat, ChatLine}; + /** * |........................| * | Conversations/Selection| @@ -23,7 +27,7 @@ pub struct App<'a> { guest_list: Vec>, guest_list_state: tui::widgets::ListState, status: AppStatus, - conversation: Vec>, + conversation: Chat, } impl<'a> App<'a> { @@ -33,7 +37,7 @@ impl<'a> App<'a> { guest_list: vec![], guest_list_state: tui::widgets::ListState::default(), status: AppStatus::Initial, - conversation: Vec::new(), + conversation: Chat::new(), } } @@ -69,7 +73,7 @@ impl<'a> App<'a> { KeyCode::Enter => { let selected = self.guest_list_state.selected().unwrap(); let guest_id = &self.game.state.guests()[selected]; - self.conversation = Vec::new(); + self.conversation = Chat::new(); self.greet_guest(Some(*guest_id)); self.status = AppStatus::TalkToGuest(Some(*guest_id)); }, @@ -174,7 +178,7 @@ impl<'a> App<'a> { .fg(tui::style::Color::Green) .bg(tui::style::Color::Black); - let mut full_text = self.conversation.clone(); + let mut full_text = self.conversation.to_spans(); full_text.push(tui::text::Spans::from(vec![ tui::text::Span::styled("(a) ", key_style), tui::text::Span::raw("What's your business?"), @@ -192,32 +196,33 @@ impl<'a> App<'a> { */ fn greet_guest(&mut self, guest_id: Option) { let guest = self.game.state.get_creature(guest_id.unwrap()).unwrap(); - self.conversation.push( - tui::text::Spans::from(vec![ - tui::text::Span::styled("Greetings traveller?\n", tui::style::Style::default().fg(tui::style::Color::Yellow)), - ]) - ); - self.conversation.push( - tui::text::Spans::from(vec![ - tui::text::Span::raw("Hello, I'm "), - tui::text::Span::styled(guest.name.clone(), tui::style::Style::default().add_modifier(tui::style::Modifier::BOLD)), - tui::text::Span::raw(".\n"), - ]) - ); + self.conversation.add_line(ChatLine::new( + 0, + "You".to_owned(), + "Greetings traveller!".to_owned(), + false + )); + self.conversation.add_line(ChatLine::new( + guest_id.unwrap(), + guest.name.clone(), + "Hello, I'm ".to_owned() + &guest.name + ".", + false + )); } fn ask_business(&mut self, guest: Option) { let guest = self.game.state.get_creature(guest.unwrap()).unwrap(); - self.conversation.push( - tui::text::Spans::from(vec![ - tui::text::Span::styled("What's your business?\n", tui::style::Style::default().fg(tui::style::Color::Yellow)) - ]) - ); - self.conversation.push( - tui::text::Spans::from(vec![ - tui::text::Span::raw(guest.say_agenda(& self.game.state)), - tui::text::Span::raw("\n"), - ]) - ); + self.conversation.add_line(ChatLine::new( + 0, + "You".to_owned(), + "What's your business?".to_owned(), + false + )); + self.conversation.add_line(ChatLine::new( + guest.entity.id, + guest.name.clone(), + guest.say_agenda(& self.game.state), + false + )); } } \ No newline at end of file