Improve game rules configuration screen

This commit is contained in:
Pierre HUBERT 2022-10-02 19:17:29 +02:00
parent c9f643e224
commit 17a4edf417
9 changed files with 51 additions and 28 deletions

View File

@ -1,3 +1,6 @@
use std::time::Duration;
use tui::style::Color;
pub const TICK_RATE: Duration = Duration::from_millis(250);
pub const HIGHLIGHT_COLOR: Color = Color::Green;

View File

@ -14,13 +14,14 @@ use tui::Terminal;
use cli_player::server::start_server_if_missing;
use cli_player::ui_screens::*;
use sea_battle_backend::data::GameRules;
async fn run_app<B: Backend>(terminal: &mut Terminal<B>) -> Result<(), Box<dyn Error>> {
// Temporary code
let res = select_bot_type::select_bot_type(terminal)?;
let res = configure_game_rules::configure_play_rules(GameRules::default(), terminal)?; // select_bot_type::select_bot_type(terminal)?;
Err(io::Error::new(
ErrorKind::Other,
format!("configured rules: {:?}", res),
format!("result: {:?}", res),
))?;
Ok(())
}

View File

@ -1,6 +1,5 @@
extern crate num as num_renamed;
use std::cmp::max;
use std::io;
use std::time::{Duration, Instant};
@ -64,7 +63,7 @@ pub fn configure_play_rules<B: Backend>(
// Navigate between fields
KeyCode::Up | KeyCode::Left => cursor_pos -= 1,
KeyCode::Down | KeyCode::Right => cursor_pos += 1,
KeyCode::Down | KeyCode::Right | KeyCode::Tab => cursor_pos += 1,
// Submit results
KeyCode::Enter => {
@ -127,9 +126,11 @@ pub fn configure_play_rules<B: Backend>(
}
// Apply new cursor position
cursor_pos = max(0, cursor_pos);
if let Some(val) = num_renamed::FromPrimitive::from_u64(cursor_pos as u64) {
model.curr_field = val;
model.curr_field = if cursor_pos < 0 {
EditingField::OK
} else {
num_renamed::FromPrimitive::from_u64(cursor_pos as u64)
.unwrap_or(EditingField::MapWidth)
}
}
if last_tick.elapsed() >= TICK_RATE {

View File

@ -4,14 +4,14 @@ use std::time::{Duration, Instant};
use crossterm::event;
use crossterm::event::{Event, KeyCode};
use tui::backend::Backend;
use tui::style::{Color, Modifier, Style};
use tui::style::*;
use tui::text::*;
use tui::widgets::*;
use tui::{Frame, Terminal};
use sea_battle_backend::data::{BotDescription, BotType, PlayConfiguration};
use crate::constants::TICK_RATE;
use crate::constants::{HIGHLIGHT_COLOR, TICK_RATE};
use crate::ui_screens::utils::centered_rect_size;
use crate::ui_screens::ScreenResult;
@ -86,7 +86,7 @@ fn ui<B: Backend>(f: &mut Frame<B>, model: &mut SelectPlayModeScreen) {
)
.highlight_style(
Style::default()
.fg(Color::Green)
.fg(HIGHLIGHT_COLOR)
.add_modifier(Modifier::BOLD),
)
.highlight_symbol(">> ");

View File

@ -1,14 +1,14 @@
use std::io;
use std::time::{Duration, Instant};
use crate::constants::TICK_RATE;
use crate::constants::{HIGHLIGHT_COLOR, TICK_RATE};
use crate::ui_screens::utils::centered_rect_size;
use crossterm::event;
use crossterm::event::{Event, KeyCode};
use tui::backend::Backend;
use tui::style::{Color, Modifier, Style};
use tui::style::*;
use tui::text::Text;
use tui::widgets::{Block, Borders, List, ListItem, ListState};
use tui::widgets::*;
use tui::{Frame, Terminal};
#[derive(Debug, Eq, PartialEq, Copy, Clone, Default)]
@ -95,7 +95,7 @@ fn ui<B: Backend>(f: &mut Frame<B>, model: &mut SelectPlayModeScreen) {
)
.highlight_style(
Style::default()
.fg(Color::Green)
.fg(HIGHLIGHT_COLOR)
.add_modifier(Modifier::BOLD),
)
.highlight_symbol(">> ");

View File

@ -1,5 +1,6 @@
use std::fmt::Display;
use crate::constants::HIGHLIGHT_COLOR;
use tui::buffer::Buffer;
use tui::layout::Rect;
use tui::style::{Color, Style};
@ -37,7 +38,7 @@ impl Widget for ButtonWidget {
let input = Paragraph::new(label.as_ref()).style(match (self.disabled, self.is_hovered) {
(true, _) => Style::default(),
(_, false) => Style::default().bg(Color::DarkGray),
(_, true) => Style::default().fg(Color::White).bg(Color::Yellow),
(_, true) => Style::default().fg(Color::White).bg(HIGHLIGHT_COLOR),
});
input.render(area, buf);

View File

@ -1,7 +1,8 @@
use crate::constants::HIGHLIGHT_COLOR;
use std::fmt::Display;
use tui::buffer::Buffer;
use tui::layout::Rect;
use tui::style::{Color, Style};
use tui::style::*;
use tui::widgets::*;
pub struct CheckboxWidget {
@ -48,7 +49,7 @@ impl Widget for CheckboxWidget {
let input = Paragraph::new(paragraph.as_ref()).style(match &self.is_editing {
false => Style::default(),
true => Style::default().fg(Color::Yellow),
true => Style::default().fg(HIGHLIGHT_COLOR),
});
input.render(area, buf);

View File

@ -1,8 +1,9 @@
use std::fmt::Display;
use crate::constants::HIGHLIGHT_COLOR;
use tui::buffer::Buffer;
use tui::layout::Rect;
use tui::style::{Color, Style};
use tui::style::*;
use tui::text::*;
use tui::widgets::{Block, Borders, Paragraph, Widget};
@ -37,20 +38,25 @@ impl Widget for TextEditorWidget {
self.value.to_string(),
match &self.input_mode {
InputMode::Normal => Style::default(),
InputMode::Editing => Style::default().fg(Color::Yellow),
InputMode::Editing => Style::default().fg(HIGHLIGHT_COLOR),
},
);
let mut spans = vec![span];
// Add cursor if field is highlighted
if self.input_mode == InputMode::Editing {
spans.push(Span::styled(" ", Style::default().bg(Color::Yellow)))
spans.push(Span::styled(" ", Style::default().bg(HIGHLIGHT_COLOR)))
}
let text = Text::from(Spans::from(spans));
let input = Paragraph::new(text).block(
Block::default()
.borders(Borders::ALL)
.border_style(match self.input_mode {
InputMode::Normal => Style::default(),
InputMode::Editing => Style::default().fg(HIGHLIGHT_COLOR),
})
.title(self.label.as_ref()),
);

View File

@ -91,18 +91,28 @@ impl GameRules {
let mut errors = vec![];
if self.map_width < config.min_map_width || self.map_width > config.max_map_width {
errors.push("Map width is outside bounds!");
if self.map_width < config.min_map_width {
errors.push("Map width is too small!");
}
if self.map_height < config.min_map_height || self.map_height > config.max_map_height {
errors.push("Map height is outside bounds!");
if self.map_width > config.max_map_width {
errors.push("Map width is too big!");
}
if self.boats_list().len() < config.min_boats_number
|| self.boats_list().len() > config.max_boats_number
{
errors.push("The number of boats is invalid!");
if self.map_height < config.min_map_height {
errors.push("Map height is too small!");
}
if self.map_height > config.max_map_height {
errors.push("Map height is too big!");
}
if self.boats_list().len() < config.min_boats_number {
errors.push("There is not enough boats!");
}
if self.boats_list().len() > config.max_boats_number {
errors.push("There are too many boats!");
}
for boat in self.boats_list() {