extends RefCounted class_name ShortcutPolicy ## Esc-Verhalten des Map-Editors (Karte t_c46d31c2, Karte 1/3) — bewusst pure ## Funktion: main.gd fragt pro Esc-Taste ab WELCHE Zustandsänderung fällig ist ## und macht nur noch den Text. tests/test_shortcuts.gd prüft alle Kombos. ## ## Priorität (spec „Esc = Auswahl aufheben / Werkzeug abbrechen / Ghost abbrechen"): ## 1. aktives Sonder-Werkzeug verlassen (Terrain/Spawns → Objekt-Werkzeug) ## 2. Ghost-Preview (Platzieren) abbrechen ## 3. Auswahl aufheben ## Rückgabe-Werte: ## "exit_terrain" | "exit_spawns" | "exit_teststart" | "cancel_grab" ## "cancel_placement" | "clear_selection" | "none" ## grabbing (Karte t_55257792): G-Greifen läuft — Esc rollt die Positionen ## zurück (Blender-Semantik). Vorrang NACH Werkzeug-Exit (im Terrain- ## Werkzeug gibt es kein Greifen), VOR Platzieren/Greifen-Auswahlheben. static func esc_action(tool_mode: String, placing: bool, has_selection: bool, grabbing := false) -> String: if tool_mode == "terrain": return "exit_terrain" if tool_mode == "spawns": return "exit_spawns" if tool_mode == "teststart": # Karte t_96e3c4ee (Wiederanbindung 20.10.): Esc verlässt das # Test-Start-Werkzeug — der gesetzte Punkt BLEIBT bestehen. return "exit_teststart" if grabbing: return "cancel_grab" if placing: return "cancel_placement" if has_selection: return "clear_selection" return "none" ## Karte 3/3 (t_11b5c25b): Dürfen die globalen Tasten (F1–F5, H) gerade wirken? ## Nein, wenn ein Textfeld/SpinBox fokussiert ist (Tippen geht vor) oder ein ## Dialog/Fenster offen ist (Taste soll nicht HINTER dem Dialog wirken). ## Pure Funktion — main.gd liefert nur die beiden Fakten (testbar, wie esc_action). static func tool_keys_allowed(text_focused: bool, dialog_open: bool) -> bool: return not text_focused and not dialog_open ## Karte 3/3: Verlust-Operation (Neue Map / Öffnen) bei ungespeicherten ## Änderungen → erst NACHFRAGEN (deutscher Dialog), sonst direkt ausführen. ## Pure Entscheidung — der Dialog selbst lebt in main.gd. static func needs_dirty_confirm(dirty: bool) -> bool: return dirty