diff --git a/rust/.gitignore b/rust/.gitignore index 3a8cabc..454e0a3 100644 --- a/rust/.gitignore +++ b/rust/.gitignore @@ -1,2 +1,3 @@ /target +.vscode .idea diff --git a/rust/cli_player/src/cli_args.rs b/rust/cli_player/src/cli_args.rs index 2427eb8..00b9285 100644 --- a/rust/cli_player/src/cli_args.rs +++ b/rust/cli_player/src/cli_args.rs @@ -1,4 +1,10 @@ -use clap::Parser; +use clap::{Parser, ValueEnum}; + +#[derive(Clone, Copy, Debug, ValueEnum)] +pub enum TestDevScreen { + Popup, + Input, +} #[derive(Parser, Debug)] pub struct CliArgs { @@ -15,6 +21,9 @@ pub struct CliArgs { /// Local server listen address #[clap(short, long, default_value = "127.0.0.1:5679")] pub listen_address: String, + + #[clap(long, value_enum)] + pub dev_screen: Option, } impl CliArgs { diff --git a/rust/cli_player/src/main.rs b/rust/cli_player/src/main.rs index d2a144f..bf49cd6 100644 --- a/rust/cli_player/src/main.rs +++ b/rust/cli_player/src/main.rs @@ -1,7 +1,9 @@ use std::error::Error; +use std::fmt::Debug; use std::io; use std::io::ErrorKind; +use cli_player::cli_args::{cli_args, TestDevScreen}; use crossterm::event::DisableMouseCapture; use crossterm::event::EnableMouseCapture; use crossterm::execute; @@ -13,25 +15,44 @@ use tui::backend::{Backend, CrosstermBackend}; use tui::Terminal; use cli_player::server::start_server_if_missing; +use cli_player::ui_screens::popup_screen::PopupScreen; use cli_player::ui_screens::*; use sea_battle_backend::data::GameRules; -async fn run_app(terminal: &mut Terminal) -> Result<(), Box> { +async fn run_dev( + terminal: &mut Terminal, + d: TestDevScreen, +) -> Result<(), Box> { + let res = match d { + TestDevScreen::Popup => PopupScreen::new("Welcome there!!") + .show(terminal)? + .as_string(), + TestDevScreen::Input => input_screen::InputScreen::new("Whas it your name ?") + .set_title("A custom title") + .show(terminal)? + .as_string(), + }; + // Temporary code // let res = configure_game_rules::configure_play_rules(GameRules::default(), terminal)?; // select_bot_type::select_bot_type(terminal)?; /*let mut rules = GameRules::default(); rules.boats_can_touch = true; let res = set_boats_layout::set_boat_layout(&rules, terminal)?; // select_bot_type::select_bot_type(terminal)?;*/ - /*let res = popup_screen::popup_screen("Hi\nWelcome there", terminal);*/ // let res = confirm_dialog::confirm_dialog("Do you really want to interrupt game ?", terminal)?; // select_bot_type::select_bot_type(terminal)?; - let res = input_screen::InputScreen::new("Whas it your name ?") - .set_title("custom title") - .show(terminal)?; // select_bot_type::select_bot_type(terminal)?; + // select_bot_type::select_bot_type(terminal)?; Err(io::Error::new( ErrorKind::Other, - format!("result: {:?}", res), - ))?; - Ok(()) + format!("DEV result: {:?}", res), + ))? +} + +async fn run_app(terminal: &mut Terminal) -> Result<(), Box> { + if let Some(d) = cli_args().dev_screen { + run_dev(terminal, d).await + } else { + // TODO : run app + Ok(()) + } } #[tokio::main] diff --git a/rust/cli_player/src/ui_screens/mod.rs b/rust/cli_player/src/ui_screens/mod.rs index 460d17e..dd0f2df 100644 --- a/rust/cli_player/src/ui_screens/mod.rs +++ b/rust/cli_player/src/ui_screens/mod.rs @@ -1,3 +1,5 @@ +use std::fmt::Debug; + pub mod configure_game_rules; pub mod confirm_dialog; pub mod input_screen; @@ -12,3 +14,9 @@ pub enum ScreenResult { Ok(E), Canceled, } + +impl ScreenResult { + pub fn as_string(&self) -> String { + format!("{:#?}", self) + } +} diff --git a/rust/cli_player/src/ui_screens/popup_screen.rs b/rust/cli_player/src/ui_screens/popup_screen.rs index 7c0efe2..235e213 100644 --- a/rust/cli_player/src/ui_screens/popup_screen.rs +++ b/rust/cli_player/src/ui_screens/popup_screen.rs @@ -14,77 +14,78 @@ use crate::ui_screens::utils::centered_rect_size; use crate::ui_screens::ScreenResult; use crate::ui_widgets::button_widget::ButtonWidget; -struct PopupScreen<'a> { +pub struct PopupScreen<'a> { title: &'a str, msg: &'a str, } -pub fn popup_screen( - msg: &str, - terminal: &mut Terminal, -) -> io::Result> { - let mut model = PopupScreen { - title: "Message", - msg, - }; - - let mut last_tick = Instant::now(); - loop { - terminal.draw(|f| ui(f, &mut model))?; - - let timeout = TICK_RATE - .checked_sub(last_tick.elapsed()) - .unwrap_or_else(|| Duration::from_secs(0)); - - if event::poll(timeout)? { - if let Event::Key(key) = event::read()? { - match key.code { - KeyCode::Char('q') => return Ok(ScreenResult::Canceled), - KeyCode::Enter => { - return Ok(ScreenResult::Ok(())); - } - _ => {} - } - } - } - if last_tick.elapsed() >= TICK_RATE { - last_tick = Instant::now(); +impl<'a> PopupScreen<'a> { + pub fn new(msg: &'a str) -> Self { + Self { + title: "Message", + msg, } } -} - -fn ui(f: &mut Frame, model: &mut PopupScreen) { - // Preprocess message - let lines = textwrap::wrap(model.msg, f.size().width as usize - 20); - let line_max_len = lines.iter().map(|l| l.len()).max().unwrap(); - - let area = centered_rect_size(line_max_len as u16 + 4, 5 + lines.len() as u16, &f.size()); - - let block = Block::default().borders(Borders::ALL).title(model.title); - f.render_widget(block, area); - - // Create two chunks with equal horizontal screen space - let chunks = Layout::default() - .direction(Direction::Vertical) - .constraints( - [ - Constraint::Length(lines.len() as u16), - Constraint::Length(3), - ] - .as_ref(), - ) - .split(area.inner(&Margin { - horizontal: 2, - vertical: 1, - })); - - let text = lines - .iter() - .map(|s| Spans::from(s.as_ref())) - .collect::>(); - let paragraph = Paragraph::new(text); - f.render_widget(paragraph, chunks[0]); - - let ok_button = ButtonWidget::new("OK", true); - f.render_widget(ok_button, chunks[1]); + + pub fn show(mut self, terminal: &mut Terminal) -> io::Result> { + let mut last_tick = Instant::now(); + loop { + terminal.draw(|f| self.ui(f))?; + + let timeout = TICK_RATE + .checked_sub(last_tick.elapsed()) + .unwrap_or_else(|| Duration::from_secs(0)); + + if event::poll(timeout)? { + if let Event::Key(key) = event::read()? { + match key.code { + KeyCode::Char('q') => return Ok(ScreenResult::Canceled), + KeyCode::Enter => { + return Ok(ScreenResult::Ok(())); + } + _ => {} + } + } + } + if last_tick.elapsed() >= TICK_RATE { + last_tick = Instant::now(); + } + } + } + + fn ui(&mut self, f: &mut Frame) { + // Preprocess message + let lines = textwrap::wrap(self.msg, f.size().width as usize - 20); + let line_max_len = lines.iter().map(|l| l.len()).max().unwrap(); + + let area = centered_rect_size(line_max_len as u16 + 4, 5 + lines.len() as u16, &f.size()); + + let block = Block::default().borders(Borders::ALL).title(self.title); + f.render_widget(block, area); + + // Create two chunks with equal horizontal screen space + let chunks = Layout::default() + .direction(Direction::Vertical) + .constraints( + [ + Constraint::Length(lines.len() as u16), + Constraint::Length(3), + ] + .as_ref(), + ) + .split(area.inner(&Margin { + horizontal: 2, + vertical: 1, + })); + + let text = lines + .iter() + .map(|s| Spans::from(s.as_ref())) + .collect::>(); + let paragraph = Paragraph::new(text); + f.render_widget(paragraph, chunks[0]); + + let ok_button = ButtonWidget::new("OK", true); + f.render_widget(ok_button, chunks[1]); + } }