157 lines
7 KiB
GDScript
157 lines
7 KiB
GDScript
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)
|