UI-Nachbesserung: Statuszeile eine Zeile, Ring-Drehen (Variablen-Schatten im Gizmo), Tab-Klick aktiviert Werkzeug, Panels offen
This commit is contained in:
parent
35a047cc2a
commit
e3a6b2ad21
12 changed files with 104 additions and 24 deletions
|
|
@ -1237,7 +1237,14 @@ func _on_left_press(mb: InputEventMouseButton) -> void:
|
||||||
|
|
||||||
|
|
||||||
## Zieh-Menge festlegen: Mehrfachauswahl oder komplette Gruppe ziehen GEMEINSAM.
|
## Zieh-Menge festlegen: Mehrfachauswahl oder komplette Gruppe ziehen GEMEINSAM.
|
||||||
|
## Vom Gizmo im Drehen-Modus gesetzt: ein Klick auf das gewählte Objekt zieht
|
||||||
|
## es NICHT mehr weg (nur die Ringe drehen).
|
||||||
|
var no_drag_move := false
|
||||||
|
|
||||||
|
|
||||||
func _begin_drag(hit: int, viewport_pos: Vector2) -> void:
|
func _begin_drag(hit: int, viewport_pos: Vector2) -> void:
|
||||||
|
if no_drag_move and hit == selected_index:
|
||||||
|
return
|
||||||
var objects: Array = main.doc.get("objects", [])
|
var objects: Array = main.doc.get("objects", [])
|
||||||
_drag_members = []
|
_drag_members = []
|
||||||
_grab_offsets = {}
|
_grab_offsets = {}
|
||||||
|
|
|
||||||
|
|
@ -274,6 +274,7 @@ func _build_ui() -> void:
|
||||||
var right_tabs := _build_group_tabs("rechts")
|
var right_tabs := _build_group_tabs("rechts")
|
||||||
right_tabs.name = "RightTabs"
|
right_tabs.name = "RightTabs"
|
||||||
ui_right_panel = right_tabs
|
ui_right_panel = right_tabs
|
||||||
|
right_tabs.tab_changed.connect(_on_right_tab_changed)
|
||||||
split.add_child(right_tabs)
|
split.add_child(right_tabs)
|
||||||
|
|
||||||
# --- Assets unten (Registry-Gruppe "unten", U1 Auftragspunkt 4) ---
|
# --- Assets unten (Registry-Gruppe "unten", U1 Auftragspunkt 4) ---
|
||||||
|
|
@ -1774,6 +1775,28 @@ func _base_tool_status() -> void:
|
||||||
## _refresh_spawn_status, _mark_tree_selection…), bleiben unter denselben
|
## _refresh_spawn_status, _mark_tree_selection…), bleiben unter denselben
|
||||||
## Namen hier (dünne Weiterleitung) — der Werkzeug-Vertrag ist unverändert.
|
## Namen hier (dünne Weiterleitung) — der Werkzeug-Vertrag ist unverändert.
|
||||||
|
|
||||||
|
## Tab Terrain/Malen/Bauen angeklickt → das Werkzeug ist sofort aktiv, kein
|
||||||
|
## zweiter Klick auf einen Start-Knopf nötig (Befund 25.10.).
|
||||||
|
func _on_right_tab_changed(idx: int) -> void:
|
||||||
|
if terrain_mod == null or malen_mod == null or bauen_mod == null or doc.is_empty():
|
||||||
|
return
|
||||||
|
var tab: Node = (ui_right_panel as TabContainer).get_child(idx)
|
||||||
|
if tab == terrain_mod:
|
||||||
|
if tool_mode == "terrain" and not terrain_mod.terrain_mode_paint.button_pressed:
|
||||||
|
return
|
||||||
|
if terrain_mod.terrain_mode_paint.button_pressed:
|
||||||
|
terrain_mod.terrain_mode_raise.button_pressed = true
|
||||||
|
_set_tool_mode("terrain")
|
||||||
|
elif tab == malen_mod:
|
||||||
|
if tool_mode == "terrain" and terrain_mod.terrain_mode_paint.button_pressed:
|
||||||
|
return
|
||||||
|
terrain_mod.terrain_mode_paint.button_pressed = true
|
||||||
|
_set_tool_mode("terrain")
|
||||||
|
elif tab == bauen_mod:
|
||||||
|
if tool_mode != "bauen":
|
||||||
|
_set_tool_mode("bauen")
|
||||||
|
|
||||||
|
|
||||||
func _on_terrain_btn_pressed() -> void:
|
func _on_terrain_btn_pressed() -> void:
|
||||||
if tool_mode != "terrain":
|
if tool_mode != "terrain":
|
||||||
if terrain_mod.terrain_mode_paint.button_pressed:
|
if terrain_mod.terrain_mode_paint.button_pressed:
|
||||||
|
|
@ -1844,9 +1867,6 @@ func _enter_terrain_mode() -> void:
|
||||||
func _leave_terrain_mode() -> void:
|
func _leave_terrain_mode() -> void:
|
||||||
if terrain_tool != null:
|
if terrain_tool != null:
|
||||||
terrain_tool.call("deactivate")
|
terrain_tool.call("deactivate")
|
||||||
if terrain_mod != null:
|
|
||||||
terrain_mod.terrain_panel.visible = false
|
|
||||||
malen_mod.malen_panel.visible = false
|
|
||||||
_sync_terrain_button()
|
_sync_terrain_button()
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1906,7 +1926,6 @@ func _enter_build_mode() -> void:
|
||||||
interaction.call("cancel_placement")
|
interaction.call("cancel_placement")
|
||||||
interaction.call("clear_selection", true)
|
interaction.call("clear_selection", true)
|
||||||
tool_mode = "bauen"
|
tool_mode = "bauen"
|
||||||
build_panel.visible = true
|
|
||||||
help_label.text = "Linksklick: Bauteil setzen · R: drehen · Entf: löschen · H: Hilfe"
|
help_label.text = "Linksklick: Bauteil setzen · R: drehen · Entf: löschen · H: Hilfe"
|
||||||
build_edit_btn.button_pressed = true
|
build_edit_btn.button_pressed = true
|
||||||
if ui_right_panel is TabContainer and bauen_mod != null:
|
if ui_right_panel is TabContainer and bauen_mod != null:
|
||||||
|
|
@ -1918,8 +1937,6 @@ func _enter_build_mode() -> void:
|
||||||
func _leave_build_mode() -> void:
|
func _leave_build_mode() -> void:
|
||||||
if build_tool != null:
|
if build_tool != null:
|
||||||
build_tool.call("deactivate")
|
build_tool.call("deactivate")
|
||||||
if build_panel != null:
|
|
||||||
build_panel.visible = false
|
|
||||||
_sync_build_button()
|
_sync_build_button()
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1981,8 +1998,6 @@ func _recheck_terrain_mode() -> void:
|
||||||
if not terrain_tool.call("refresh_from_doc"):
|
if not terrain_tool.call("refresh_from_doc"):
|
||||||
terrain_tool.call("deactivate")
|
terrain_tool.call("deactivate")
|
||||||
tool_mode = "objects"
|
tool_mode = "objects"
|
||||||
terrain_mod.terrain_panel.visible = false
|
|
||||||
malen_mod.malen_panel.visible = false
|
|
||||||
_sync_terrain_button()
|
_sync_terrain_button()
|
||||||
_update_tool_label()
|
_update_tool_label()
|
||||||
# Karte t_89c0ec95: Dezenter Terrain-Rückschalter = ebenfalls ein
|
# Karte t_89c0ec95: Dezenter Terrain-Rückschalter = ebenfalls ein
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,6 @@ func build() -> void:
|
||||||
|
|
||||||
build_panel = VBoxContainer.new()
|
build_panel = VBoxContainer.new()
|
||||||
build_panel.add_theme_constant_override("separation", UIScale.px(8))
|
build_panel.add_theme_constant_override("separation", UIScale.px(8))
|
||||||
build_panel.visible = false
|
|
||||||
add_child(build_panel)
|
add_child(build_panel)
|
||||||
|
|
||||||
build_panel.add_child(_field_label("Bauteil:"))
|
build_panel.add_child(_field_label("Bauteil:"))
|
||||||
|
|
|
||||||
1
src/ui/panels/bauen_panel.gd.uid
Normal file
1
src/ui/panels/bauen_panel.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
uid://ctxc87eisoda6
|
||||||
|
|
@ -43,7 +43,6 @@ func build() -> void:
|
||||||
|
|
||||||
malen_panel = VBoxContainer.new()
|
malen_panel = VBoxContainer.new()
|
||||||
malen_panel.add_theme_constant_override("separation", UIScale.px(8))
|
malen_panel.add_theme_constant_override("separation", UIScale.px(8))
|
||||||
malen_panel.visible = false
|
|
||||||
add_child(malen_panel)
|
add_child(malen_panel)
|
||||||
|
|
||||||
palette = VBoxContainer.new()
|
palette = VBoxContainer.new()
|
||||||
|
|
|
||||||
1
src/ui/panels/malen_panel.gd.uid
Normal file
1
src/ui/panels/malen_panel.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
uid://1cuxg4r1bmls
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
extends "res://src/ui/panels/editor_panel.gd"
|
extends HBoxContainer
|
||||||
## Statusleiste (aus main.gd ausgezogen, Karte t_eaccbfed U1 — Logik
|
## Statusleiste (aus main.gd ausgezogen, Karte t_eaccbfed U1 — Logik
|
||||||
## unverändert): Hilfs-Meldungen + permanente Werkzeug-Anzeige +
|
## unverändert): Hilfs-Meldungen + permanente Werkzeug-Anzeige +
|
||||||
## Symmetrie-Anzeige + Objekt-/Terrain-Zähler + FPS-Timer.
|
## Symmetrie-Anzeige + Objekt-/Terrain-Zähler + FPS-Timer.
|
||||||
|
|
||||||
|
var main # src/ui/main.gd
|
||||||
var status_label: Label
|
var status_label: Label
|
||||||
var tool_label: Label # permanenter Werkzeugmodus + Flug-Hint
|
var tool_label: Label # permanenter Werkzeugmodus + Flug-Hint
|
||||||
var sym_label: Label
|
var sym_label: Label
|
||||||
|
|
@ -14,6 +15,20 @@ static func spec() -> Dictionary:
|
||||||
return {"titel": "Statuszeile", "gruppe": "status", "order": 0}
|
return {"titel": "Statuszeile", "gruppe": "status", "order": 0}
|
||||||
|
|
||||||
|
|
||||||
|
func setup(p_main) -> void:
|
||||||
|
main = p_main
|
||||||
|
# Eine Leiste ist EINE Zeile (VBox-Erbe stapelte alle Labels senkrecht →
|
||||||
|
# riesiger Balken, Befund 25.10.).
|
||||||
|
size_flags_vertical = Control.SIZE_SHRINK_END
|
||||||
|
size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||||
|
|
||||||
|
|
||||||
|
func theme_color(cname: String) -> Color:
|
||||||
|
if main != null and main.theme != null and main.theme.has_color(cname, "Editor"):
|
||||||
|
return main.theme.get_color(cname, "Editor")
|
||||||
|
return get_theme_color(cname, "Editor")
|
||||||
|
|
||||||
|
|
||||||
func build() -> void:
|
func build() -> void:
|
||||||
add_theme_constant_override("separation", UIScale.px(16))
|
add_theme_constant_override("separation", UIScale.px(16))
|
||||||
status_label = Label.new()
|
status_label = Label.new()
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,6 @@ func build() -> void:
|
||||||
|
|
||||||
terrain_panel = VBoxContainer.new()
|
terrain_panel = VBoxContainer.new()
|
||||||
terrain_panel.add_theme_constant_override("separation", UIScale.px(8)) # U7-Raster
|
terrain_panel.add_theme_constant_override("separation", UIScale.px(8)) # U7-Raster
|
||||||
terrain_panel.visible = false
|
|
||||||
add_child(terrain_panel)
|
add_child(terrain_panel)
|
||||||
|
|
||||||
terrain_panel.add_child(_field_label("Pinsel:"))
|
terrain_panel.add_child(_field_label("Pinsel:"))
|
||||||
|
|
@ -191,11 +190,9 @@ func refresh_panels() -> void:
|
||||||
return
|
return
|
||||||
var aktiv: bool = str(main.get("tool_mode")) == "terrain"
|
var aktiv: bool = str(main.get("tool_mode")) == "terrain"
|
||||||
var paint := _selected_terrain_mode() == TerrainField.Mode.PAINT
|
var paint := _selected_terrain_mode() == TerrainField.Mode.PAINT
|
||||||
terrain_panel.visible = aktiv and not paint
|
|
||||||
terrain_edit_btn.set_pressed_no_signal(aktiv and not paint)
|
terrain_edit_btn.set_pressed_no_signal(aktiv and not paint)
|
||||||
var malen = main.get("malen_mod")
|
var malen = main.get("malen_mod")
|
||||||
if malen != null:
|
if malen != null:
|
||||||
malen.malen_panel.visible = aktiv and paint
|
|
||||||
malen.malen_edit_btn.set_pressed_no_signal(aktiv and paint)
|
malen.malen_edit_btn.set_pressed_no_signal(aktiv and paint)
|
||||||
if aktiv:
|
if aktiv:
|
||||||
_show_own_tab(malen if paint else self)
|
_show_own_tab(malen if paint else self)
|
||||||
|
|
|
||||||
1
src/ui/viewport_toolbar.gd.uid
Normal file
1
src/ui/viewport_toolbar.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
uid://jjp1jooped0q
|
||||||
|
|
@ -173,6 +173,9 @@ func set_mode(m: String) -> void:
|
||||||
if _rot_dragging:
|
if _rot_dragging:
|
||||||
_finish_rotate(false)
|
_finish_rotate(false)
|
||||||
mode = m
|
mode = m
|
||||||
|
var inter = main.get("interaction") if main != null else null
|
||||||
|
if inter != null:
|
||||||
|
inter.no_drag_move = (m == "rotate")
|
||||||
_apply_mode_visibility()
|
_apply_mode_visibility()
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -222,8 +225,8 @@ func _unhandled_input(event: InputEvent) -> void:
|
||||||
var doc: Dictionary = main.get("doc")
|
var doc: Dictionary = main.get("doc")
|
||||||
if doc == null or doc.is_empty():
|
if doc == null or doc.is_empty():
|
||||||
return
|
return
|
||||||
var mode: String = str(main.get("tool_mode"))
|
var tool_mode: String = str(main.get("tool_mode"))
|
||||||
if mode == "terrain" or mode == "spawns":
|
if tool_mode == "terrain" or tool_mode == "spawns":
|
||||||
return # Terrain-Pinsel / Spawn-Zonen haben das Zepter
|
return # Terrain-Pinsel / Spawn-Zonen haben das Zepter
|
||||||
if event is InputEventMouseButton:
|
if event is InputEventMouseButton:
|
||||||
var mb := event as InputEventMouseButton
|
var mb := event as InputEventMouseButton
|
||||||
|
|
@ -301,7 +304,7 @@ func pick_ring(screen_pos: Vector2) -> String:
|
||||||
if not visible or mode != "rotate":
|
if not visible or mode != "rotate":
|
||||||
return ""
|
return ""
|
||||||
var best := ""
|
var best := ""
|
||||||
var best_d := HIT_PX
|
var best_d := HIT_PX * 1.6
|
||||||
for a in AXES:
|
for a in AXES:
|
||||||
var pts := _ring_screen_points(a)
|
var pts := _ring_screen_points(a)
|
||||||
for i in pts.size() - 1:
|
for i in pts.size() - 1:
|
||||||
|
|
|
||||||
|
|
@ -35,16 +35,25 @@ func _run() -> void:
|
||||||
_check(main.build_edit_btn.get_parent() == main.bauen_mod, "Bauen-Knopf wohnt im Bauen-Tab")
|
_check(main.build_edit_btn.get_parent() == main.bauen_mod, "Bauen-Knopf wohnt im Bauen-Tab")
|
||||||
_check(main.malen_mod.mat_buttons.size() == SvmapIO.MATERIAL_IDS.size(), "Malen: eine Kachel je Material")
|
_check(main.malen_mod.mat_buttons.size() == SvmapIO.MATERIAL_IDS.size(), "Malen: eine Kachel je Material")
|
||||||
|
|
||||||
print("== Malen-Tab ==")
|
print("== Tab-Klick aktiviert das Werkzeug direkt ==")
|
||||||
main.call("_set_tool_mode", "terrain")
|
tabs.current_tab = main.terrain_mod.get_index()
|
||||||
_check(main.terrain_mod.terrain_panel.visible and not main.malen_mod.malen_panel.visible, "Terrain aktiv: nur Terrain-Panel")
|
_check(str(main.tool_mode) == "terrain" and not main.terrain_mod.terrain_mode_paint.button_pressed,
|
||||||
main.terrain_mod.terrain_mode_paint.button_pressed = true
|
"Tab Terrain: Terrain-Werkzeug sofort an (Heben)")
|
||||||
_check(main.malen_mod.malen_panel.visible and main.malen_mod.palette.visible and not main.terrain_mod.terrain_panel.visible,
|
_check(main.terrain_mod.terrain_panel.visible, "Terrain-Regler stehen offen")
|
||||||
"Malen aktiv: Malen-Panel statt Terrain-Panel")
|
tabs.current_tab = main.malen_mod.get_index()
|
||||||
_check(tabs.current_tab == main.malen_mod.get_index(), "Tab springt auf Malen")
|
_check(str(main.tool_mode) == "terrain" and main.terrain_mod.terrain_mode_paint.button_pressed,
|
||||||
|
"Tab Malen: Malen sofort an")
|
||||||
|
_check(main.malen_mod.malen_panel.visible and main.malen_mod.palette.visible, "Malen: Palette offen")
|
||||||
main.malen_mod.radius_slider.value = 20.0
|
main.malen_mod.radius_slider.value = 20.0
|
||||||
_check(int(main.terrain_mod.terrain_radius_slider.value) == 20, "Malen-Radius steuert den Pinsel")
|
_check(int(main.terrain_mod.terrain_radius_slider.value) == 20, "Malen-Radius steuert den Pinsel")
|
||||||
|
tabs.current_tab = main.bauen_mod.get_index()
|
||||||
|
_check(str(main.tool_mode) == "bauen" and main.build_panel.visible, "Tab Bauen: Bauen sofort an, Bauteile offen")
|
||||||
main.call("_set_tool_mode", "objects")
|
main.call("_set_tool_mode", "objects")
|
||||||
|
tabs.current_tab = 0
|
||||||
|
|
||||||
|
print("== Statuszeile = eine Zeile ==")
|
||||||
|
_check(main.status_mod is HBoxContainer, "Statuszeile ist waagerecht")
|
||||||
|
_check(main.status_mod.size.y < 80, "Statuszeile niedrig (%.0f px)" % main.status_mod.size.y)
|
||||||
|
|
||||||
print("== Lesbarkeit ==")
|
print("== Lesbarkeit ==")
|
||||||
var muted: Color = main.malen_mod.theme_color("muted")
|
var muted: Color = main.malen_mod.theme_color("muted")
|
||||||
|
|
@ -76,7 +85,39 @@ func _run() -> void:
|
||||||
main.call("_do_undo")
|
main.call("_do_undo")
|
||||||
obj = main.doc["objects"][0]
|
obj = main.doc["objects"][0]
|
||||||
_check(SvmapIO.objekt_rotation(obj).is_equal_approx(Vector3.ZERO), "dreimal Undo = Ausgangslage")
|
_check(SvmapIO.objekt_rotation(obj).is_equal_approx(Vector3.ZERO), "dreimal Undo = Ausgangslage")
|
||||||
|
print("== Ring per Maus ziehen ==")
|
||||||
|
obj = main.doc["objects"][0]
|
||||||
|
var rot0 := SvmapIO.objekt_rotation(obj)
|
||||||
|
var pos0 := Vector3(float(obj["pos"][0]), float(obj["pos"][1]), float(obj["pos"][2]))
|
||||||
|
main.camera.set("distance", 9.0)
|
||||||
|
main.camera.call("focus_on", pos0)
|
||||||
|
main.interaction.call("select_object", 0)
|
||||||
|
for i in 4:
|
||||||
|
await process_frame
|
||||||
|
var pts: Array = main.gizmo._ring_screen_points("y")
|
||||||
|
var p1: Vector2 = pts[3]
|
||||||
|
var p2: Vector2 = pts[9]
|
||||||
|
_check(p1 != Vector2.INF and main.gizmo.pick_ring(p1) == "y", "Ring Y unter dem Cursor gefunden")
|
||||||
|
var press := InputEventMouseButton.new()
|
||||||
|
press.button_index = MOUSE_BUTTON_LEFT
|
||||||
|
press.pressed = true
|
||||||
|
press.position = p1
|
||||||
|
main.gizmo._unhandled_input(press)
|
||||||
|
var mv := InputEventMouseMotion.new()
|
||||||
|
mv.position = p2
|
||||||
|
main.gizmo._unhandled_input(mv)
|
||||||
|
var rel := InputEventMouseButton.new()
|
||||||
|
rel.button_index = MOUSE_BUTTON_LEFT
|
||||||
|
rel.pressed = false
|
||||||
|
rel.position = p2
|
||||||
|
main.gizmo._unhandled_input(rel)
|
||||||
|
obj = main.doc["objects"][0]
|
||||||
|
var rot1 := SvmapIO.objekt_rotation(obj)
|
||||||
|
_check(absf(rot1.y - rot0.y) > 1.0, "Ring ziehen dreht das Objekt (%.0f° → %.0f°)" % [rot0.y, rot1.y])
|
||||||
|
_check(Vector3(float(obj["pos"][0]), float(obj["pos"][1]), float(obj["pos"][2])).is_equal_approx(pos0), "Position bleibt")
|
||||||
|
_check(main.interaction.no_drag_move, "Drehen-Modus: Klick auf Objekt zieht es nicht weg")
|
||||||
main.viewport_toolbar.move_btn.pressed.emit()
|
main.viewport_toolbar.move_btn.pressed.emit()
|
||||||
|
_check(not main.interaction.no_drag_move, "Verschieben-Modus: Ziehen wieder erlaubt")
|
||||||
_check(main.gizmo.mode == "move", "Verschieben schaltet zurück")
|
_check(main.gizmo.mode == "move", "Verschieben schaltet zurück")
|
||||||
var scale_btns := 0
|
var scale_btns := 0
|
||||||
for c in main.viewport_toolbar.find_children("*", "Button", true, false):
|
for c in main.viewport_toolbar.find_children("*", "Button", true, false):
|
||||||
|
|
|
||||||
1
tests/test_ui_aufraeumen.gd.uid
Normal file
1
tests/test_ui_aufraeumen.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
uid://cj7lbm6uebrs0
|
||||||
Loading…
Reference in a new issue