- Implemented `test_editor_visual_harmonization.gd` to validate the Stickman editor and prop editor UI layouts, ensuring proper functionality and visual consistency. - Created `test_editor_visual_theme.gd` to verify the loading and application of visual themes in the editor, including semantic overrides and default values. - Introduced `test_phase19_ground_finish_chooser.gd` to test the ground finish chooser's functionality, including layout responsiveness, selection behavior, and interaction with the stage. - Added new scripts for ground finish preview and chooser UI components to enhance the editor's visual representation of ground finishes.
112 lines
6.5 KiB
GDScript
112 lines
6.5 KiB
GDScript
extends SceneTree
|
|
|
|
const THEME := preload("res://scripts/editors/prop/prop_theme.gd")
|
|
const CANVAS_SCENE := preload("res://scenes/editors/prop/prop_editor.tscn")
|
|
const PREVIEW_SCENE := preload("res://scenes/editors/prop/prop_attach_preview.tscn")
|
|
const PROP_FILE := preload("res://scripts/editors/prop/prop_file.gd")
|
|
|
|
var _failed: int = 0
|
|
var _count: int = 0
|
|
|
|
func _init() -> void:
|
|
call_deferred("_run")
|
|
|
|
func _check(label: String, value: bool) -> void:
|
|
_count += 1
|
|
if value:
|
|
print("PASS: %s" % label)
|
|
else:
|
|
_failed += 1
|
|
push_error("FAIL: %s" % label)
|
|
|
|
func _run() -> void:
|
|
root.size = Vector2i(1200, 800)
|
|
var theme := THEME.new()
|
|
_check("default inspector background uses shared surface token", theme.inspector_background_color().is_equal_approx(Color("#252B38FA")))
|
|
var preview := PREVIEW_SCENE.instantiate() as Control
|
|
root.add_child(preview)
|
|
await process_frame
|
|
await process_frame
|
|
var hand := preview.find_child("HandOption", true, false) as OptionButton
|
|
var motion := preview.find_child("MotionOption", true, false) as OptionButton
|
|
_check("hand labels are kid-readable", hand != null and hand.get_item_text(0) == "Left Hand" and hand.get_item_text(1) == "Right Hand")
|
|
_check("motion selector has approved choices", motion != null and motion.item_count == 3 and motion.get_item_text(0) == "Front Pose" and motion.get_item_text(1) == "Walk Left" and motion.get_item_text(2) == "Walk Right")
|
|
_check("obsolete preview controls removed", preview.find_child("FacingOption", true, false) == null and preview.find_child("FrameOption", true, false) == null)
|
|
preview.call("set_preview_motion", 2)
|
|
_check("walk right enters active gait", int(preview.get("_motion")) == 2 and not bool(preview.get("_walk_paused")))
|
|
preview.call("toggle_walk_playback")
|
|
_check("walk toggle pauses gait", bool(preview.get("_walk_paused")))
|
|
preview.call("set_preview_motion", 0)
|
|
_check("front pose stops gait", int(preview.get("_motion")) == 0 and bool(preview.get("_walk_paused")))
|
|
preview.queue_free()
|
|
var editor := CANVAS_SCENE.instantiate() as Control
|
|
root.add_child(editor)
|
|
await process_frame
|
|
var canvas := editor.get("_canvas") as PropCanvas
|
|
var attach_tools := editor.get("_attach_tools") as FlowContainer
|
|
var marker := editor.get("_inactive_anchors_check") as CheckBox
|
|
_check("attach tools are wrapping flow controls", attach_tools != null)
|
|
_check("marker toggle is meaningful wording", marker != null and marker.text == "Show Other Markers")
|
|
canvas.set_edit_mode(PropCanvas.EditMode.ATTACH)
|
|
await process_frame
|
|
var material := editor.get("_material_section") as Control
|
|
_check("material hides in Attach", material != null and not material.visible)
|
|
canvas.set_edit_mode(PropCanvas.EditMode.TRANSFORM)
|
|
_check("material returns in Arrange", material != null and material.visible)
|
|
var anchors: Dictionary = {"grip": {"role": "grip", "position": Vector2(10.0, 20.0), "rotation_deg": 12.0, "z_index_offset": 2, "allowed_hands": "both"}}
|
|
editor.set("_anchors", anchors)
|
|
canvas.set_anchor_data(anchors)
|
|
editor.call("_select_anchor", "grip")
|
|
var roles := editor.get("_anchor_role") as OptionButton
|
|
_check("editable role list omits pivot and maps safely", roles != null and roles.item_count == 5 and roles.get_item_text(0) == "grip" and roles.get_item_text(4) == "custom")
|
|
editor.call("_on_rename_anchor_pressed")
|
|
var dialog := editor.get("_rename_anchor_dialog") as ConfirmationDialog
|
|
var rename_edit := editor.get("_rename_anchor_edit") as LineEdit
|
|
rename_edit.text = "Main Handle"
|
|
dialog.get_ok_button().emit_signal("pressed")
|
|
await process_frame
|
|
var renamed: Dictionary = editor.get("_anchors")
|
|
_check("dialog confirmation renames normalized anchor", renamed.has("main_handle") and not renamed.has("grip") and str(renamed["main_handle"].get("role")) == "grip")
|
|
renamed["other"] = {"role": "custom", "position": Vector2.ZERO, "rotation_deg": 0.0, "z_index_offset": 0, "allowed_hands": "both"}
|
|
editor.set("_anchors", renamed)
|
|
canvas.set_anchor_data(renamed)
|
|
editor.call("_select_anchor", "other")
|
|
editor.call("_on_rename_anchor_pressed")
|
|
rename_edit.text = "Main Handle"
|
|
dialog.get_ok_button().emit_signal("pressed")
|
|
await process_frame
|
|
var collision_renamed: Dictionary = editor.get("_anchors")
|
|
_check("dialog confirmation uses collision suffix", collision_renamed.has("main_handle") and collision_renamed.has("main_handle_2"))
|
|
editor.call("_select_anchor", "main_handle_2")
|
|
editor.call("_on_rename_anchor_pressed")
|
|
rename_edit.text = "Entered Name"
|
|
rename_edit.text_submitted.emit(rename_edit.text)
|
|
await process_frame
|
|
_check("Enter in rename field confirms typed name", (editor.get("_anchors") as Dictionary).has("entered_name") and not (editor.get("_anchors") as Dictionary).has("main_handle_2"))
|
|
editor.call("_select_anchor", "entered_name")
|
|
editor.call("_on_rename_anchor_pressed")
|
|
rename_edit.text = "Cancelled Name"
|
|
dialog.emit_signal("canceled")
|
|
await process_frame
|
|
_check("dialog cancel leaves anchor unchanged", (editor.get("_anchors") as Dictionary).has("entered_name") and str(editor.get("_rename_anchor_source_id")).is_empty())
|
|
var main_split := editor.get("_main_layout") as HSplitContainer
|
|
var inspector := editor.get("_inspector_column") as PanelContainer
|
|
_check("inspector starts at minimum usable width", main_split != null and inspector != null and inspector.size.x >= inspector.get_combined_minimum_size().x)
|
|
var eye_data: Dictionary = PROP_FILE.load("res://content/props/eye.prop")
|
|
_check("eye prop fixture is available", not eye_data.is_empty())
|
|
editor.call("_apply_json_data", eye_data)
|
|
root.size = Vector2i(1200, 600)
|
|
canvas.set_edit_mode(PropCanvas.EditMode.ATTACH)
|
|
await process_frame
|
|
await process_frame
|
|
var top_bar := editor.get_node("ChromeRoot/TopBar") as Control
|
|
var status_bar := editor.get_node("ChromeRoot/StatusBar") as Control
|
|
var holding_preview := editor.get("_attach_preview") as Control
|
|
_check("Attach layout stays between name and status bars", main_split.get_global_rect().position.y >= top_bar.get_global_rect().end.y - 1.0 and holding_preview.get_global_rect().end.y <= status_bar.get_global_rect().position.y + 1.0)
|
|
var preview_container := holding_preview.get("_viewport_container") as SubViewportContainer
|
|
var preview_viewport := holding_preview.get("_viewport") as SubViewport
|
|
_check("preview viewport follows flexible pane height", preview_container != null and preview_viewport != null and preview_container.size.y > 0.0 and absf(float(preview_viewport.size.y) - preview_container.size.y) <= 1.0)
|
|
editor.queue_free()
|
|
print("RESULT: %s (%d assertions)" % ["ALL PASSED" if _failed == 0 else "%d FAILED" % _failed, _count])
|
|
quit(0 if _failed == 0 else 1)
|