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

View file

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

View file

@ -111,7 +111,8 @@ public partial class Main : Node2D
quit: () => GetTree().Quit(), quit: () => GetTree().Quit(),
quickSave: OnQuickSave, quickSave: OnQuickSave,
quickLoad: OnQuickLoad, quickLoad: OnQuickLoad,
undo: OnUndo); undo: OnUndo,
deleteSelected: OnDeleteSelected);
_automationHarness = new AutomationHarness(dir, facade); _automationHarness = new AutomationHarness(dir, facade);
AddChild(_automationHarness); AddChild(_automationHarness);
@ -207,6 +208,12 @@ public partial class Main : Node2D
OnUndo(); OnUndo();
GetViewport().SetInputAsHandled(); 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) private void OnCollisionOccurred(int col, int row, string victimKind, int destroyerId)
{ {
if (_sim == null) return; if (_sim == null) return;

View file

@ -79,4 +79,6 @@ public partial class DetailPanel : PanelContainer
} }
public new void Hide() => Visible = false; 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 Le moteur expose deja les commandes et events requis ; cote Godot il manque
les surfaces d'interaction et d'animation. 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 ### 1.4 Touche Suppr pour retirer une piece
Le bouton `[Retirer]` du `DetailPanel` existe. Ajouter en complement : Le bouton `[Retirer]` du `DetailPanel` existe. Ajouter en complement :
selection + `Delete` → meme effet que le bouton. 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()