Add Delete/Backspace shortcut to remove the selected piece

DetailPanel exposes the currently-shown piece id; Main's key handler
delegates Delete or Backspace to the same path as the Retirer button
when a piece is selected. Harness gains "delete" under key() so UI
tests can exercise the shortcut directly.
This commit is contained in:
Samuel Bouchet 2026-04-17 22:23:38 +02:00
parent c4f6ecbf44
commit 6c28665c38
6 changed files with 54 additions and 9 deletions

View file

@ -30,6 +30,7 @@ internal class AutomationFacade
public Action QuickSave { get; }
public Action QuickLoad { get; }
public Action Undo { get; }
public Action DeleteSelected { get; }
public AutomationFacade(
Func<GameSim?> sim,
@ -47,7 +48,8 @@ internal class AutomationFacade
Action quit,
Action quickSave,
Action quickLoad,
Action undo)
Action undo,
Action deleteSelected)
{
Sim = sim;
Input = input;
@ -65,5 +67,6 @@ internal class AutomationFacade
QuickSave = quickSave;
QuickLoad = quickLoad;
Undo = undo;
DeleteSelected = deleteSelected;
}
}

View file

@ -154,6 +154,10 @@ internal class CommandDispatcher
case "esc":
_facade.Input.Cancel();
break;
case "delete":
case "del":
_facade.DeleteSelected();
break;
default:
throw new InvalidOperationException($"Unsupported key: {key}");
}

View file

@ -111,7 +111,8 @@ public partial class Main : Node2D
quit: () => GetTree().Quit(),
quickSave: OnQuickSave,
quickLoad: OnQuickLoad,
undo: OnUndo);
undo: OnUndo,
deleteSelected: OnDeleteSelected);
_automationHarness = new AutomationHarness(dir, facade);
AddChild(_automationHarness);
@ -207,6 +208,12 @@ public partial class Main : Node2D
OnUndo();
GetViewport().SetInputAsHandled();
}
else if ((key.Keycode == Key.Delete || key.Keycode == Key.Backspace)
&& _detailPanel.CurrentPieceId is int pid)
{
OnRemoveRequested(pid);
GetViewport().SetInputAsHandled();
}
}
}
@ -894,6 +901,12 @@ public partial class Main : Node2D
}
}
private void OnDeleteSelected()
{
if (_detailPanel.CurrentPieceId is int pid)
OnRemoveRequested(pid);
}
private void OnCollisionOccurred(int col, int row, string victimKind, int destroyerId)
{
if (_sim == null) return;

View file

@ -79,4 +79,6 @@ public partial class DetailPanel : PanelContainer
}
public new void Hide() => Visible = false;
public int? CurrentPieceId => Visible ? _currentPieceId : null;
}

View file

@ -12,13 +12,6 @@ et l'extension de la campagne.
Le moteur expose deja les commandes et events requis ; cote Godot il manque
les surfaces d'interaction et d'animation.
### 1.3 Collision — camera pan/zoom + notification
L'engine emet deja `PieceReturnedToStockEvent` + auto-pause. Il reste a :
- Animer un pan + zoom de la camera vers la case de collision.
- Afficher une notification dans un coin de l'ecran
(ex : "Tour II detruite par Dame — retournee au stock").
- Reprise a Espace apres lecture.
### 1.4 Touche Suppr pour retirer une piece
Le bouton `[Retirer]` du `DetailPanel` existe. Ajouter en complement :
selection + `Delete` → meme effet que le bouton.

View file

@ -0,0 +1,30 @@
"""Smoke test for Delete key removing a selected piece."""
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parents[2]))
from tools.automation.harness import Harness
def main():
with Harness.launch(run_name="delete_key") as h:
h.load_mission("campaign_01", 0)
h.place("Pawn", (0, 0), (0, 1))
# Select the piece by clicking its start cell
h.click_cell(0, 0)
h.screenshot("01_selected")
assert len(h.state()['pieces']) == 1
# Press Delete
h.key("delete")
h.screenshot("02_deleted")
s = h.state()
assert len(s['pieces']) == 0, "Piece should be removed"
assert s['remainingStock']['Pawn'] == 4, "Stock should be replenished"
print("OK — Delete key removes the selected piece")
if __name__ == "__main__":
main()