Files
war-in-tunnels/src/app/widgets/board.rs
T
GarandPLG 110d4c411a
Nix package / build (push) Successful in 7m59s
Linux package builds (test) / linux (push) Successful in 2m29s
Linux package builds (test) / aur (push) Successful in 7m18s
Rust checks / check (push) Successful in 3m21s
Add tab navigation for building and recruitment UI
- Add selection indices and option lists to SkirmishState.
- Implement `cycle_popup_option` and expose Left/Right actions in
  keybindings.
- Introduce `cancel_focused_tasks` in BoardState for Delete handling.
- CellWidget now displays recruitment progress on Base structures.
- Update README and documentation to describe new tabs and arrow
  navigation.
- Adjust test counts and add extensive task‑cancellation tests.
2026-10-23 17:53:46 +02:00

69 lines
2.4 KiB
Rust

use crate::app::states::skirmish_states::{BoardState, Players, tasks::Task, units::Unit};
use crate::app::widgets::CellWidget;
use ratatui::{
buffer::Buffer,
layout::{Constraint, Layout, Rect},
widgets::Widget,
};
use std::{collections::HashSet, rc::Rc};
pub struct BoardWidget<'a> {
state: &'a BoardState,
}
impl<'a> BoardWidget<'a> {
pub fn new(state: &'a BoardState) -> Self {
Self { state }
}
}
impl Widget for BoardWidget<'_> {
fn render(self, area: Rect, buf: &mut Buffer) {
let mut queued_path: HashSet<(usize, usize)> = HashSet::new();
for row in &self.state.cells {
for cell in row {
if let Some(unit) = cell.get_ref_option_unit()
&& unit.get_owner() == Players::Player
{
for task in unit.get_ref_tasks() {
queued_path.extend(task.get_path().iter().copied());
}
}
}
}
let horizontal: Rc<[Rect]> =
Layout::horizontal(vec![
Constraint::Length(self.state.cell_width as u16);
self.state.cols
])
.split(area);
for (col_idx, col_area) in horizontal.iter().enumerate() {
let vertical: Rc<[Rect]> =
Layout::vertical(vec![
Constraint::Length(self.state.cell_height as u16);
self.state.rows
])
.split(*col_area);
for (row_idx, cell_area) in vertical.iter().enumerate() {
self.state
.cells
.get(row_idx + self.state.vertical_offset.get_value())
.and_then(|rows| rows.get(col_idx + self.state.horizontal_offset.get_value()))
.map(|cell: &CellWidget| -> () {
let mut cell: CellWidget = cell.clone();
let coords: (usize, usize) = (
row_idx + self.state.vertical_offset.get_value(),
col_idx + self.state.horizontal_offset.get_value(),
);
if queued_path.contains(&coords) {
cell.set_marked(true);
}
cell.render(*cell_area, buf);
});
}
}
}
}