diff --git a/src/app/keybindings/skirmish.rs b/src/app/keybindings/skirmish.rs index 900b07e..15080b6 100644 --- a/src/app/keybindings/skirmish.rs +++ b/src/app/keybindings/skirmish.rs @@ -21,15 +21,27 @@ pub fn skirmish_keybindings(app: &mut App, key_event: &KeyEvent) { match action { Action::Up => { board.change_focused_cell(MoveFocusedCell::Up); + if !board.is_focused_cell_visible() { + board.vertical_offset.prev(); + } } Action::Down => { board.change_focused_cell(MoveFocusedCell::Down); + if !board.is_focused_cell_visible() { + board.vertical_offset.next(); + } } Action::Left => { board.change_focused_cell(MoveFocusedCell::Left); + if !board.is_focused_cell_visible() { + board.horizontal_offset.prev(); + } } Action::Right => { board.change_focused_cell(MoveFocusedCell::Right); + if !board.is_focused_cell_visible() { + board.horizontal_offset.next(); + } } Action::ScrollUp => { board.vertical_offset.prev(); diff --git a/src/app/states/skirmish_states/board.rs b/src/app/states/skirmish_states/board.rs index fa1c155..27dc4c6 100644 --- a/src/app/states/skirmish_states/board.rs +++ b/src/app/states/skirmish_states/board.rs @@ -16,7 +16,7 @@ pub struct BoardState { pub rows: usize, pub vertical_offset: Offset, pub horizontal_offset: Offset, - pub cells: Vec, + pub cells: Vec>, pub zoom_level: ZoomLevel, focused_cell: FocusedCell, } @@ -41,11 +41,13 @@ impl BoardState { let focused_cell: FocusedCell = FocusedCell::new((map_height / 2) - 1, 2, map_height, map_width); - let mut cells: Vec = Vec::new(); + let mut cells: Vec> = Vec::new(); for row in 0..map_height { + let mut rows: Vec = Vec::new(); + for col in 0..map_width { - cells.push(*CellWidget::new(row, col, zoom_level).set_selected( + rows.push(*CellWidget::new(row, col, zoom_level).set_selected( if row == focused_cell.get_row() && col == focused_cell.get_col() { true } else { @@ -53,6 +55,8 @@ impl BoardState { }, )); } + + cells.push(rows); } Self { @@ -72,7 +76,7 @@ impl BoardState { } fn get_mut_cell(&mut self, row: usize, col: usize) -> &mut CellWidget { - &mut self.cells[row * self.map_width + col] + &mut self.cells[row][col] } fn max_offset(map_size: usize, size: usize) -> usize { @@ -133,4 +137,25 @@ impl BoardState { self.get_mut_cell(old_row, old_col).set_selected(false); self.get_mut_cell(new_row, new_col).set_selected(true); } + + pub fn is_focused_cell_visible(&self) -> bool { + let vertical_offset: usize = self.vertical_offset.get_value(); + let horizontal_offset: usize = self.horizontal_offset.get_value(); + + let row: usize = self.focused_cell.get_row(); + let col: usize = self.focused_cell.get_col(); + + if 0usize.saturating_add(vertical_offset) > row + || row >= self.rows.saturating_add(vertical_offset) + { + return false; + } + if 0usize.saturating_add(horizontal_offset) > col + || col >= self.cols.saturating_add(horizontal_offset) + { + return false; + } + + true + } } diff --git a/src/app/widgets/board.rs b/src/app/widgets/board.rs index bb23059..76ece52 100644 --- a/src/app/widgets/board.rs +++ b/src/app/widgets/board.rs @@ -34,16 +34,11 @@ impl Widget for BoardWidget<'_> { .split(*col_area); for (row_idx, cell_area) in vertical.iter().enumerate() { - let map_row: usize = row_idx + self.state.vertical_offset.get_value(); - let map_col: usize = col_idx + self.state.horizontal_offset.get_value(); - - if let Some(cell) = self - .state + self.state .cells - .get(map_row * self.state.map_width + map_col) - { - cell.render(*cell_area, buf); - } + .get(row_idx + self.state.vertical_offset.get_value()) + .and_then(|rows| rows.get(col_idx + self.state.horizontal_offset.get_value())) + .map(|cell| cell.render(*cell_area, buf)); } } }