Can show legend on game map
This commit is contained in:
@ -33,7 +33,7 @@ impl Widget for ButtonWidget {
|
||||
fn render(self, area: Rect, buf: &mut Buffer) {
|
||||
let label = format!(" {} ", self.label);
|
||||
|
||||
let area = centered_rect_size(label.len() as u16, 1, area);
|
||||
let area = centered_rect_size(label.len() as u16, 1, &area);
|
||||
|
||||
let input = Paragraph::new(label.as_ref()).style(match (self.disabled, self.is_hovered) {
|
||||
(true, _) => Style::default(),
|
||||
|
@ -1,15 +1,63 @@
|
||||
use sea_battle_backend::data::{GameRules, PlayConfiguration};
|
||||
use crate::ui_screens::utils::centered_rect_size;
|
||||
use sea_battle_backend::data::{Coordinates, GameRules, PlayConfiguration};
|
||||
use std::fmt::Display;
|
||||
use tui::buffer::Buffer;
|
||||
use tui::layout::Rect;
|
||||
use tui::style::{Color, Style};
|
||||
use tui::widgets::{BorderType, Widget};
|
||||
|
||||
pub struct ColoredCells {
|
||||
pub color: Color,
|
||||
pub cells: Vec<Coordinates>,
|
||||
}
|
||||
|
||||
pub struct GameMapWidget<'a> {
|
||||
rules: &'a GameRules,
|
||||
default_empty_character: char,
|
||||
colored_cells: Vec<ColoredCells>,
|
||||
legend: Option<String>,
|
||||
}
|
||||
|
||||
impl<'a> GameMapWidget<'a> {
|
||||
pub fn new(rules: &'a GameRules) -> Self {
|
||||
Self { rules }
|
||||
Self {
|
||||
rules,
|
||||
default_empty_character: '.',
|
||||
colored_cells: vec![],
|
||||
legend: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_default_empty_char(mut self, c: char) -> Self {
|
||||
self.default_empty_character = c;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn add_colored_cells(mut self, c: ColoredCells) -> Self {
|
||||
self.colored_cells.push(c);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set_legend<D: Display>(mut self, legend: D) -> Self {
|
||||
self.legend = Some(legend.to_string());
|
||||
self
|
||||
}
|
||||
|
||||
pub fn grid_size(&self) -> (u16, u16) {
|
||||
let w = self.rules.map_width as u16 * 2 + 1;
|
||||
let h = self.rules.map_height as u16 * 2 + 1;
|
||||
|
||||
(w, h)
|
||||
}
|
||||
|
||||
pub fn estimated_size(&self) -> (u16, u16) {
|
||||
let (w, mut h) = self.grid_size();
|
||||
|
||||
if let Some(l) = &self.legend {
|
||||
h += 1 + l.split('\n').count() as u16;
|
||||
}
|
||||
|
||||
(w, h)
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,8 +70,9 @@ impl<'a> Widget for GameMapWidget<'a> {
|
||||
// Paint game grid
|
||||
for y in 0..(self.rules.map_height + 1) {
|
||||
for x in 0..(self.rules.map_width + 1) {
|
||||
let o_x = x as u16 * 2;
|
||||
let o_y = y as u16 * 2;
|
||||
let o_x = area.x + (x as u16 * 2);
|
||||
let o_y = area.y + (y as u16 * 2);
|
||||
|
||||
buf.get_mut(o_x, o_y).set_symbol(match (x, y) {
|
||||
(0, 0) => symbols.top_left,
|
||||
|
||||
@ -52,9 +101,32 @@ impl<'a> Widget for GameMapWidget<'a> {
|
||||
}
|
||||
|
||||
if x < self.rules.map_width && y < self.rules.map_height {
|
||||
buf.get_mut(o_x + 1, o_y + 1).set_char('.');
|
||||
let cell = buf
|
||||
.get_mut(o_x + 1, o_y + 1)
|
||||
.set_char(self.default_empty_character);
|
||||
|
||||
if let Some(c) = self
|
||||
.colored_cells
|
||||
.iter()
|
||||
.find(|c| c.cells.contains(&Coordinates::new(x as i32, y as i32)))
|
||||
{
|
||||
cell.set_bg(c.color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Paint legend (if any)
|
||||
if let Some(legend) = &self.legend {
|
||||
let (_, mut y) = self.grid_size();
|
||||
y += area.y + 1;
|
||||
|
||||
for line in legend.split('\n') {
|
||||
let center_rect = centered_rect_size(line.len() as u16, 1, &area);
|
||||
let x = center_rect.x;
|
||||
buf.set_string(x, y, line, Style::default());
|
||||
y += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user