generated from GarandPLG/rust-flake-template
Refactor board cells to 2D vector and auto‑scroll
Store cells as a nested vector instead of a flat list, simplifying indexing and rendering. Add `is_focused_cell_visible` to detect when the focused cell is outside the viewport and adjust vertical/horizontal offsets accordingly in the skirmish keybindings. Update related methods and widget rendering to use the new 2‑D structure.
This commit is contained in:
@@ -21,15 +21,27 @@ pub fn skirmish_keybindings(app: &mut App, key_event: &KeyEvent) {
|
|||||||
match action {
|
match action {
|
||||||
Action::Up => {
|
Action::Up => {
|
||||||
board.change_focused_cell(MoveFocusedCell::Up);
|
board.change_focused_cell(MoveFocusedCell::Up);
|
||||||
|
if !board.is_focused_cell_visible() {
|
||||||
|
board.vertical_offset.prev();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Action::Down => {
|
Action::Down => {
|
||||||
board.change_focused_cell(MoveFocusedCell::Down);
|
board.change_focused_cell(MoveFocusedCell::Down);
|
||||||
|
if !board.is_focused_cell_visible() {
|
||||||
|
board.vertical_offset.next();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Action::Left => {
|
Action::Left => {
|
||||||
board.change_focused_cell(MoveFocusedCell::Left);
|
board.change_focused_cell(MoveFocusedCell::Left);
|
||||||
|
if !board.is_focused_cell_visible() {
|
||||||
|
board.horizontal_offset.prev();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Action::Right => {
|
Action::Right => {
|
||||||
board.change_focused_cell(MoveFocusedCell::Right);
|
board.change_focused_cell(MoveFocusedCell::Right);
|
||||||
|
if !board.is_focused_cell_visible() {
|
||||||
|
board.horizontal_offset.next();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Action::ScrollUp => {
|
Action::ScrollUp => {
|
||||||
board.vertical_offset.prev();
|
board.vertical_offset.prev();
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ pub struct BoardState {
|
|||||||
pub rows: usize,
|
pub rows: usize,
|
||||||
pub vertical_offset: Offset,
|
pub vertical_offset: Offset,
|
||||||
pub horizontal_offset: Offset,
|
pub horizontal_offset: Offset,
|
||||||
pub cells: Vec<CellWidget>,
|
pub cells: Vec<Vec<CellWidget>>,
|
||||||
pub zoom_level: ZoomLevel,
|
pub zoom_level: ZoomLevel,
|
||||||
focused_cell: FocusedCell,
|
focused_cell: FocusedCell,
|
||||||
}
|
}
|
||||||
@@ -41,11 +41,13 @@ impl BoardState {
|
|||||||
let focused_cell: FocusedCell =
|
let focused_cell: FocusedCell =
|
||||||
FocusedCell::new((map_height / 2) - 1, 2, map_height, map_width);
|
FocusedCell::new((map_height / 2) - 1, 2, map_height, map_width);
|
||||||
|
|
||||||
let mut cells: Vec<CellWidget> = Vec::new();
|
let mut cells: Vec<Vec<CellWidget>> = Vec::new();
|
||||||
|
|
||||||
for row in 0..map_height {
|
for row in 0..map_height {
|
||||||
|
let mut rows: Vec<CellWidget> = Vec::new();
|
||||||
|
|
||||||
for col in 0..map_width {
|
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() {
|
if row == focused_cell.get_row() && col == focused_cell.get_col() {
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
@@ -53,6 +55,8 @@ impl BoardState {
|
|||||||
},
|
},
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cells.push(rows);
|
||||||
}
|
}
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
@@ -72,7 +76,7 @@ impl BoardState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_mut_cell(&mut self, row: usize, col: usize) -> &mut CellWidget {
|
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 {
|
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(old_row, old_col).set_selected(false);
|
||||||
self.get_mut_cell(new_row, new_col).set_selected(true);
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,16 +34,11 @@ impl Widget for BoardWidget<'_> {
|
|||||||
.split(*col_area);
|
.split(*col_area);
|
||||||
|
|
||||||
for (row_idx, cell_area) in vertical.iter().enumerate() {
|
for (row_idx, cell_area) in vertical.iter().enumerate() {
|
||||||
let map_row: usize = row_idx + self.state.vertical_offset.get_value();
|
self.state
|
||||||
let map_col: usize = col_idx + self.state.horizontal_offset.get_value();
|
|
||||||
|
|
||||||
if let Some(cell) = self
|
|
||||||
.state
|
|
||||||
.cells
|
.cells
|
||||||
.get(map_row * self.state.map_width + map_col)
|
.get(row_idx + self.state.vertical_offset.get_value())
|
||||||
{
|
.and_then(|rows| rows.get(col_idx + self.state.horizontal_offset.get_value()))
|
||||||
cell.render(*cell_area, buf);
|
.map(|cell| cell.render(*cell_area, buf));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user