generated from GarandPLG/rust-flake-template
Refactor cell marking, add undo, update keybindings
CellWidget::set_selected and set_marked now return &mut Self for method chaining. Added BoardState::undo_marked_cell to remove the last marked cell and restore focus. Backspace triggers undo, Delete clears marking.
This commit is contained in:
@@ -29,14 +29,16 @@ pub enum Action {
|
||||
ScrollLeft,
|
||||
/// Scroll right without moving the cursor.
|
||||
ScrollRight,
|
||||
/// Select the current item.
|
||||
/// Toggle selecting cell.
|
||||
Space,
|
||||
/// Unmark last selected cell.
|
||||
Backspace,
|
||||
/// Cancel marking cell.
|
||||
Delete,
|
||||
/// Submit or confirm the current choice.
|
||||
Enter,
|
||||
/// Return to the main menu or previous screen.
|
||||
Esc,
|
||||
/// Delete the character before the cursor.
|
||||
Backspace,
|
||||
/// Zoom the view in.
|
||||
ZoomIn,
|
||||
/// Zoom the view out.
|
||||
@@ -199,15 +201,33 @@ pub static KEYBINDINGS: &[KeyBinding] = &[
|
||||
symbol: "Space",
|
||||
description: "Marking cells",
|
||||
},
|
||||
// KeyBinding {
|
||||
// action: Action::Enter,
|
||||
// code: KeyCode::Enter,
|
||||
// kind: KeyEventKind::Press,
|
||||
// modifiers: KeyModifiers::NONE,
|
||||
// group: Group::Select,
|
||||
// symbol: "Enter",
|
||||
// description: "Submit",
|
||||
// },
|
||||
KeyBinding {
|
||||
action: Action::Backspace,
|
||||
code: KeyCode::Backspace,
|
||||
kind: KeyEventKind::Press,
|
||||
modifiers: KeyModifiers::NONE,
|
||||
group: Group::Select,
|
||||
symbol: "Backspace",
|
||||
description: "Unmark cell",
|
||||
},
|
||||
KeyBinding {
|
||||
action: Action::Delete,
|
||||
code: KeyCode::Delete,
|
||||
kind: KeyEventKind::Press,
|
||||
modifiers: KeyModifiers::NONE,
|
||||
group: Group::Select,
|
||||
symbol: "Delete",
|
||||
description: "Cancel marking",
|
||||
},
|
||||
KeyBinding {
|
||||
action: Action::Enter,
|
||||
code: KeyCode::Enter,
|
||||
kind: KeyEventKind::Press,
|
||||
modifiers: KeyModifiers::NONE,
|
||||
group: Group::Select,
|
||||
symbol: "Enter",
|
||||
description: "Submit",
|
||||
},
|
||||
KeyBinding {
|
||||
action: Action::Esc,
|
||||
code: KeyCode::Esc,
|
||||
@@ -217,15 +237,6 @@ pub static KEYBINDINGS: &[KeyBinding] = &[
|
||||
symbol: "Esc",
|
||||
description: "Main menu",
|
||||
},
|
||||
KeyBinding {
|
||||
action: Action::Backspace,
|
||||
code: KeyCode::Backspace,
|
||||
kind: KeyEventKind::Press,
|
||||
modifiers: KeyModifiers::NONE,
|
||||
group: Group::Select,
|
||||
symbol: "Backspace",
|
||||
description: "Cancel marking",
|
||||
},
|
||||
KeyBinding {
|
||||
action: Action::ZoomIn,
|
||||
code: KeyCode::Char(','),
|
||||
|
||||
@@ -84,7 +84,8 @@ pub fn skirmish_keybindings(app: &mut App, key_event: &KeyEvent) {
|
||||
ZoomLevel::ZoomedOut => {}
|
||||
},
|
||||
Action::Space => board.toggle_marking(),
|
||||
Action::Backspace => {
|
||||
Action::Backspace => board.undo_marked_cell(),
|
||||
Action::Delete => {
|
||||
board.marking_cells = false;
|
||||
board.clear_marked_cells()
|
||||
}
|
||||
|
||||
@@ -116,16 +116,35 @@ impl BoardState {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_marked_cell(&mut self, new_cell: (usize, usize), old_cell: (usize, usize)) {
|
||||
pub fn set_marked_cell(&mut self, new_cell: (usize, usize)) {
|
||||
let cell: &mut CellWidget = self.get_mut_cell(new_cell.0, new_cell.1);
|
||||
|
||||
if cell.get_marked() && old_cell != new_cell {
|
||||
self.get_mut_cell(old_cell.0, old_cell.1).set_marked(false);
|
||||
self.marked_cells.pop();
|
||||
} else {
|
||||
if !cell.get_marked() {
|
||||
cell.set_marked(true);
|
||||
self.marked_cells.push((new_cell.0, new_cell.1));
|
||||
}
|
||||
|
||||
self.marked_cells.push((new_cell.0, new_cell.1));
|
||||
}
|
||||
|
||||
pub fn undo_marked_cell(&mut self) {
|
||||
if self.marked_cells.len() < 2 {
|
||||
return;
|
||||
}
|
||||
|
||||
let old: (usize, usize) = self.marked_cells[self.marked_cells.len() - 1];
|
||||
let new: (usize, usize) = self.marked_cells[self.marked_cells.len() - 2];
|
||||
let old_is_unique: bool = self.marked_cells.iter().filter(|x| **x == old).count() == 1;
|
||||
|
||||
let old_cell: &mut CellWidget = self.get_mut_cell(old.0, old.1).set_selected(false);
|
||||
if old_is_unique {
|
||||
old_cell.set_marked(false);
|
||||
}
|
||||
|
||||
self.get_mut_cell(new.0, new.1).set_selected(true);
|
||||
|
||||
self.marked_cells.pop();
|
||||
|
||||
self.focused_cell.set_focused_cell(new);
|
||||
}
|
||||
|
||||
pub fn start_marking_cells(&mut self) {
|
||||
@@ -226,7 +245,7 @@ impl BoardState {
|
||||
self.get_mut_cell(new_cell.0, new_cell.1).set_selected(true);
|
||||
|
||||
if self.marking_cells {
|
||||
self.set_marked_cell(new_cell, old_cell);
|
||||
self.set_marked_cell(new_cell);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,4 +49,9 @@ impl FocusedCell {
|
||||
|
||||
(self.row, self.col)
|
||||
}
|
||||
|
||||
pub fn set_focused_cell(&mut self, cell: (usize, usize)) {
|
||||
self.row = cell.0.max(0).min(self.max_row - 1);
|
||||
self.col = cell.1.max(0).min(self.max_col - 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ const ACTIONS: &[Action] = &[
|
||||
Action::VolumeDown,
|
||||
Action::Space,
|
||||
Action::Backspace,
|
||||
Action::Delete,
|
||||
Action::Mute,
|
||||
Action::Quit,
|
||||
Action::Quit2,
|
||||
|
||||
@@ -48,8 +48,9 @@ impl CellWidget {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_selected(&mut self, selected: bool) {
|
||||
pub fn set_selected(&mut self, selected: bool) -> &mut Self {
|
||||
self.selected = selected;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set_zoom_level(&mut self, zoom_level: ZoomLevel) {
|
||||
@@ -64,8 +65,9 @@ impl CellWidget {
|
||||
self.marked
|
||||
}
|
||||
|
||||
pub fn set_marked(&mut self, marked: bool) {
|
||||
self.marked = marked
|
||||
pub fn set_marked(&mut self, marked: bool) -> &mut Self {
|
||||
self.marked = marked;
|
||||
self
|
||||
}
|
||||
|
||||
fn col_to_letters(&self) -> String {
|
||||
@@ -90,8 +92,9 @@ impl CellWidget {
|
||||
|
||||
fn fg_color(&self) -> Color {
|
||||
match self.tag {
|
||||
_ if self.marked => Color::LightMagenta,
|
||||
_ if self.selected => Color::LightYellow,
|
||||
_ if self.marked && self.selected => Color::Magenta,
|
||||
_ if self.marked && !self.selected => Color::LightMagenta,
|
||||
_ if self.selected && !self.marked => Color::LightYellow,
|
||||
CellTag::Base(Players::Player) if !self.selected => Color::LightBlue,
|
||||
CellTag::Base(Players::Enemy) if !self.selected => Color::LightRed,
|
||||
CellTag::Tunel if !self.selected => Color::Gray,
|
||||
|
||||
Reference in New Issue
Block a user