scopedvr-map-core/ui/panels/toolbar.gd
slyphax 83af25b6fb VR-Host: main läuft ohne Fenster, Modelle aus dem Projekt, Terrain in Stücken (nur Quest)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 19:38:42 +01:00

157 lines
7 KiB
GDScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

extends HBoxContainer
## Toolbar (aus main.gd ausgezogen, Karte t_eaccbfed U1 — Logik unverändert):
## Menü Datei + Undo/Redo + Gitter/Höhenlinien + Symmetrie + Toolbar-Aktionen
## aus der Registry (Karte prüfen, ▶ Karte testen). Neue Aktionen melden sich
## künftig in registry.gd an (U2–U7, T1-F5 bleibt unverändert erreichbar).
##
## NACHBESSERUNG 20.10. (Operator, Sly-Befund „Damit kann man nicht mehr
## arbeiten"): Diese Leiste erbte von EditorPanel (= VBoxContainer) und wurde
## dadurch SELBST senkrecht — jeder Knopf bekam eine eigene, fensterbreite
## Zeile, die Leiste wuchs auf ~11×40 px und drückte das 3D-Fenster auf einen
## Briefmarken-Streifen. Eine Leiste braucht eine WAAGERECHTE Zeile: extends
## HBoxContainer. Die Helfer der Basis (main-Zeiger, Label-Bauer) braucht nur
## die senkrechte Spalte; hier genügt der main-Zeiger.
var main # core/ui/main.gd (script-erweitert → untypisiert)
func setup(p_main) -> void:
main = p_main
# Eine Leiste darf NIE in die Höhe wachsen (sie würde dem 3D-Fenster die
# Fläche wegnehmen): genau eine Knopfzeile, oben ausgerichtet.
size_flags_vertical = Control.SIZE_SHRINK_BEGIN
size_flags_horizontal = Control.SIZE_EXPAND_FILL
func panel_title() -> String:
return "Werkzeuge"
var undo_btn: Button
var redo_btn: Button
var settings_btn: Button # „⚙ Einstellungen“ öffnet das Einstellungen-Fenster
var title_label: Label
var file_label: Label
static func spec() -> Dictionary:
return {"titel": "Toolbar", "gruppe": "toolbar", "order": 0}
func build() -> void:
add_theme_constant_override("separation", UIScale.px(8)) # U7-Raster (4/8)
var file_menu := MenuButton.new()
file_menu.text = "Datei"
file_menu.flat = false
file_menu.custom_minimum_size = UIScale.v2(90, 40)
# U7: Klartext-Tooltip am Datei-Menü (alle Map-Aktionen an einem Ort).
file_menu.tooltip_text = "Map-Aktionen: neu, öffnen, speichern, testen, Updates"
var popup := file_menu.get_popup()
popup.add_item("Neue Map…", 0)
popup.add_item("Öffnen…", 1)
popup.add_item("Kartengröße ändern…", 6)
popup.add_separator()
popup.add_item("Speichern (Strg+S)", 2)
popup.add_item("Speichern unter…", 3)
popup.add_separator()
popup.add_item("▶ Karte testen", 5)
popup.add_separator()
if not main.vr_host:
popup.add_item("🖐 Hand-Haltung der Waffen…", 8)
popup.add_item("🔄 Updates prüfen", 7)
popup.add_item("Beenden", 4)
# FIX 20.10. (Sly-Befund „Kartengröße ändern tut nichts“): id_pressed sendet
# die Menü-ID. main.call.bind("_on_menu_action") hängt die ID aber ALS
# ARGUMENT an call() → effektiv call(6, "_on_menu_action") →
# „Cannot convert argument 1 from int to StringName“ (map-builder.log
# 20.10.) — das GESAMTE Datei-Menü verpufft, kein Eintrag tut etwas.
# Lambda macht die Reihenfolge (Name zuerst, ID als Argument) explizit,
# Stil wie grid_btn/contours_btn oben.
popup.id_pressed.connect(func(id: int) -> void: main.call("_on_menu_action", id))
add_child(file_menu)
undo_btn = Button.new()
undo_btn.text = "↩ Rückgängig"
undo_btn.custom_minimum_size = UIScale.v2(140, 40)
undo_btn.tooltip_text = "Letzte Aktion zurücknehmen (Strg+Z)"
undo_btn.pressed.connect(main.call.bind("_do_undo"))
add_child(undo_btn)
redo_btn = Button.new()
redo_btn.text = "↪ Wiederholen"
redo_btn.custom_minimum_size = UIScale.v2(150, 40)
redo_btn.tooltip_text = "Zurückgenommene Aktion wiederherstellen (Strg+Y)"
redo_btn.pressed.connect(main.call.bind("_do_redo"))
add_child(redo_btn)
# Toolbar-Aktionen DATENGETRIEBEN aus der Registry (Operator-Vorgabe
# 20.10.): Karte prüfen, ▶ Karte testen — künftige Karten melden sich
# hier an, ohne main.gd anzufassen. Die Buttons bekommen den Registry-Namen
# als Node-Namen (main kann sie per get_node/find_child ansprechen, z. B.
# der Shake-Effekt beim fehlgeschlagenen Map-Check).
for entry in PanelRegistry.toolbar_actions():
var btn := Button.new()
btn.text = str(entry["titel"])
btn.name = str(entry["id"])
if str(entry["id"]) == "karte_pruefen":
btn.custom_minimum_size = UIScale.v2(170, 40)
btn.tooltip_text = "Prüft, ob die Map bereit für den Export ist — sagen wir VORHER, was fehlt"
else:
btn.custom_minimum_size = UIScale.v2(190, 40)
btn.tooltip_text = "Startet die Map SOFORT als Spiel zum Durchlaufen — eigenes Fenster, der Editor bleibt offen. ESC im Spiel = zurück zum Editor."
btn.pressed.connect(main.call.bind(str(entry["action"])))
# Test-Start ist ein Umschalter: main liest/setzt seinen Zustand
# (Prüfsuite test_playtest_spawn.gd erwartet main.test_start_btn).
if str(entry["id"]) == "teststart":
btn.toggle_mode = true
main.set("test_start_btn", btn)
add_child(btn)
# Einstellungen (25.10.): Gitter, Höhenlinien, Symmetrie-Modus, UI-Größe,
# Raster-Snap … stehen jetzt in einem eigenen Fenster.
settings_btn = Button.new()
settings_btn.text = "⚙ Einstellungen"
settings_btn.name = "einstellungen_knopf"
settings_btn.custom_minimum_size = UIScale.v2(170, 40)
settings_btn.tooltip_text = "Gitter, Höhenlinien, Symmetrie, UI-Größe, Raster-Snap und Testlauf-Einstellungen"
settings_btn.pressed.connect(func() -> void: main.call("_open_settings"))
add_child(settings_btn)
var help_btn := Button.new()
help_btn.text = "❓ Hilfe"
help_btn.name = "hilfe"
help_btn.custom_minimum_size = UIScale.v2(110, 40)
help_btn.tooltip_text = "Werkzeuge, Steuerung und Tastenkürzel (H)"
help_btn.pressed.connect(func() -> void: main.call("_toggle_help_overlay"))
add_child(help_btn)
title_label = Label.new()
title_label.text = " %s" % main.APP_TITLE
title_label.add_theme_font_size_override("font_size", UIScale.heading_font_size())
# Karte t_297221b5: bei großer Stufe darf der Titel EGALISIEREN statt die
# Top-Bar aus dem Fenster zu drücken (Mindestbreite der Schrift skaliert mit).
# Mindestbreite, damit er nicht KOMPLETT verschwindet (Ellipsis macht "Scop…").
# Expand: bei Platz bekommt er seine VOLLSTÄNDIGE natürliche Breite (wie
# Vorher bei „Klein“), erst bei knappem Fenster egalisiert er mit "…".
title_label.custom_minimum_size = UIScale.v2(180, 0)
title_label.size_flags_horizontal = Control.SIZE_EXPAND_FILL
title_label.text_overrun_behavior = TextServer.OVERRUN_TRIM_ELLIPSIS
title_label.clip_text = true
add_child(title_label)
var spacer := Control.new()
spacer.size_flags_horizontal = Control.SIZE_EXPAND_FILL
add_child(spacer)
file_label = Label.new()
file_label.text = ""
# U7: Farbe über Theme (Editor/colors/title) statt modulate-Wert im Code.
file_label.add_theme_color_override("font_color",
main.theme.get_color("title", "Editor"))
# Karte t_297221b5: Map-Pfad darf bei großer Stufe egalisiert werden
# (Voller Name im Tooltip, sonst drückt die Zeile die Top-Bar aus dem Fenster).
# Expand: bekommt zusammen mit dem Spacer seinen Anteil, egalisiert mit "…".
file_label.text_overrun_behavior = TextServer.OVERRUN_TRIM_ELLIPSIS
file_label.clip_text = true
file_label.size_flags_horizontal = Control.SIZE_EXPAND_FILL
add_child(file_label)