extends PanelContainer ## Werkzeugleiste oben links in der 3D-Ansicht (25.10.): erscheint, sobald ein ## Objekt ausgewählt ist. Umschalter Verschieben / Drehen & Kippen (steuert den ## Gizmo) plus schnelle Aktionen (Auf den Boden, Duplizieren, Löschen). ## Objekte werden bewusst NIE skaliert — es gibt kein Skalieren-Werkzeug. var main var move_btn: Button var rotate_btn: Button var ground_btn: Button var dup_btn: Button var delete_btn: Button func setup(p_main) -> void: main = p_main set_anchors_preset(Control.PRESET_TOP_LEFT) offset_left = UIScale.px(12) offset_top = UIScale.px(12) mouse_filter = Control.MOUSE_FILTER_STOP visible = false var box := HBoxContainer.new() box.add_theme_constant_override("separation", UIScale.px(6)) add_child(box) var group := ButtonGroup.new() move_btn = _btn("↔ Verschieben", "Pfeile am Objekt ziehen: X rot, Y grün, Z blau", true, group) move_btn.pressed.connect(func() -> void: _set_mode("move")) box.add_child(move_btn) rotate_btn = _btn("⟳ Drehen / Kippen", "Ringe am Objekt ziehen: um alle drei Achsen, in 15°-Schritten", true, group) rotate_btn.pressed.connect(func() -> void: _set_mode("rotate")) box.add_child(rotate_btn) move_btn.set_pressed_no_signal(true) box.add_child(VSeparator.new()) ground_btn = _btn("⤓ Auf den Boden", "Auswahl aufs Terrain absetzen (Strg+Bild↑)", false, null) ground_btn.pressed.connect(func() -> void: main.interaction.snap_selection_to_floor()) box.add_child(ground_btn) dup_btn = _btn("⧉ Kopie", "Duplizieren (Strg+D)", false, null) dup_btn.pressed.connect(func() -> void: main.interaction.duplicate_selected()) box.add_child(dup_btn) delete_btn = _btn("🗑 Löschen", "Löschen (Entf) — Strg+Z holt es zurück", false, null) delete_btn.pressed.connect(func() -> void: main.interaction.delete_selected()) box.add_child(delete_btn) func _btn(text: String, tip: String, toggle: bool, group: ButtonGroup) -> Button: var b := Button.new() b.text = text b.tooltip_text = tip b.toggle_mode = toggle if group != null: b.button_group = group b.custom_minimum_size = UIScale.v2(0, 36) b.focus_mode = Control.FOCUS_NONE # Leertaste/Pfeile bleiben beim Viewport return b func _set_mode(m: String) -> void: if main.gizmo != null: main.gizmo.set_mode(m) ## Sichtbarkeit pro Frame aus der Auswahl ableiten (wie der Gizmo selbst). func _process(_delta: float) -> void: if main == null or main.get("interaction") == null: return var inter = main.interaction var mode: String = str(main.get("tool_mode")) var want: bool = mode == "objects" \ and not inter.selected_indices.is_empty() \ and not bool(inter.get("placing")) \ and main.get("playtest") == null if want != visible: visible = want if visible and main.gizmo != null: var rotate_on: bool = main.gizmo.mode == "rotate" if rotate_btn.button_pressed != rotate_on: rotate_btn.set_pressed_no_signal(rotate_on) move_btn.set_pressed_no_signal(not rotate_on)