OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-tps / scenes / test / gate_editor_e1.gd

152 lines · gd ref:
extends SceneTree
## GATE — editor redesign E1 (docs/editor-redesign.md §3): the four collapsible regions,
## the top bar (menus generated from the keymap, select modes, grid, texture lock), the
## toolbar and the generated status bar, on a REAL map_flat in build mode.
##
## Every surface runs actions through Keymap.run — the same path a key press takes — so
## the assertions click a control and then read the MAP's state, never the control's.
##
## Run: "$HYPER_TPS_GODOT" --headless --path . --script res://scenes/test/gate_editor_e1.gd

var ok := true
var checks := 0
var _frame := 0
var _map: Node
var _dock: Node
var _km: Node
var _hud: Node
var _top: Node
var _tools: Node
var _vis0 := false
var _saved_grid: Variant = 5
var _saved_snap: Variant = true


func _p(cond: bool, what: String, note: String = "") -> void:
	checks += 1
	if not cond:
		ok = false
	print("  %-62s %s  %s" % [what, "OK" if cond else "**FAIL**", note])


func _process(_d: float) -> bool:
	_frame += 1
	match _frame:
		1:
			_map = (load("res://scenes/maps/map_flat.tscn") as PackedScene).instantiate()
			root.add_child(_map)
		30:
			_dock = root.get_node("/root/BuildDock")
			# Gates share the installed game's user:// — put the player's saved grid and
			# snap back at the end (the grid steps below would otherwise persist).
			_saved_grid = _dock.pref("grid", 5)
			_saved_snap = _dock.pref("snap", true)
			_km = root.get_node("/root/Keymap")
			_hud = root.get_node("/root/BuildHud")
			root.get_node("/root/GameMode").set_mode("build")
			print("-- four regions, each collapsible --")
			for side: String in ["top", "bottom", "left", "right"]:
				_p(_dock.has_region(side), "region '%s' exists" % side)
			_p(_dock.has_panel("topbar") and String(_dock._panels["topbar"]["side"]) == "top", "the top bar is in the TOP region")
			_p(_dock.has_panel("tools") and String(_dock._panels["tools"]["side"]) == "left", "the toolbar is in the LEFT region")
			for side: String in ["top", "bottom", "left", "right"]:
				var t: Button = _dock.region_toggle(side)
				_p(t != null and t.is_visible_in_tree(), "'%s' has a visible ▸/▾ toggle" % side)
			var lt: Button = _dock.region_toggle("left")
			lt.pressed.emit()
			_p(_dock.is_region_collapsed("left") and not _dock.region_content("left").visible,
				"clicking the left toggle collapses the left region")
			_p(lt.is_visible_in_tree(), "and the toggle stays reachable")
			_p(FileAccess.get_file_as_string(_dock.LAYOUT_PATH).contains("left"), "collapse state saved per player")
			lt.pressed.emit()
			_p(not _dock.is_region_collapsed("left") and _dock.region_content("left").visible, "clicking again restores it")
			# NARROW WINDOWS: the bands must fit between the two columns of a 1280-px
			# window, or the bottom one runs under the right column (it did: the status
			# line and the strip's top row refused to shrink below ~1350 px).
			var cols: float = _dock._column_width("left") + _dock._column_width("right") + 48.0
			for side: String in ["top", "bottom"]:
				var col: Control = _dock._sides[side]["column"]
				var need: float = col.get_combined_minimum_size().x + 32.0   # + the toggle
				_p(cols + need <= 1280.0, "the %s band fits a 1280-px window" % side,
					"needs %d px between columns of %d" % [int(need), int(cols)])
			var sb_need: float = (_dock._status_left as Control).get_combined_minimum_size().x
			_p(cols + sb_need + 120.0 <= 1280.0, "and so does the status bar", "%d px" % int(sb_need))

			print("\n-- the top bar's menus come from the keymap --")
			_top = _map.get("_top_bar")
			_p(_top != null, "the map keeps its top bar")
			var items := 0
			var bad: Array[String] = []
			for pm: PopupMenu in _top.menus():
				for i in pm.item_count:
					if pm.is_item_separator(i):
						continue
					items += 1
					var action: String = String(pm.get_item_metadata(i))
					if _km.binding_of(action).is_empty():
						bad.append(action)
					elif pm.get_item_accelerator(i) != _top.accel_of(action):
						bad.append(action + " (accel)")
			_p(items >= 18 and bad.is_empty(), "every menu item names a bound action with its live key",
				"%d items, bad %s" % [items, str(bad)])
			# Since keymap step 6.5 V is the "Brush outlines" OVERLAY: its own switch, and the
			# level-outline layer (the BrushView node itself is build mode).
			_vis0 = bool(_map.overlay_on("outlines"))
			_top.activate("builder.brush_view")      # what clicking View > Brush outlines does
		34:
			var bv: Node = _map.get("_brush_view")
			_p(bv != null and bool(_map.overlay_on("outlines")) != _vis0 and bool(bv.show_outlines) == bool(_map.overlay_shown("outlines")),
				"View > Brush outlines toggled the outlines overlay")
			_map.set_overlay("outlines", _vis0)      # back as it was
			print("\n-- select modes, grid, texture lock --")
			_top.select_mode_button("brush").pressed.emit()
		38:
			_p(String(_map.get("_sel_mode")) == "brush", "the 'brush' select-mode button set the map's mode",
				String(_map.get("_sel_mode")))
			_top.grid_option().select(1)
			_top.grid_option().item_selected.emit(1)
			_p(int(_map.get("_grid_idx")) == 1, "choosing grid 2u set the map's grid", str(_map.get("_grid_idx")))
			_km.run("builder.grid_coarser")          # 2u -> 4u (index 1 -> 2)
		42:
			_p(int(_map.get("_grid_idx")) == 2 and _top.grid_option().selected == 2,
				"the key changed the grid AND the dropdown follows", "%d / %d" % [int(_map.get("_grid_idx")), _top.grid_option().selected])
			_top.tex_lock_button().button_pressed = false
			_top.tex_lock_button().toggled.emit(false)
			_p(not bool(_map.get("tex_lock")), "the Texture Lock toggle sets the map's tex_lock")
			_top.tex_lock_button().button_pressed = true
			_top.tex_lock_button().toggled.emit(true)

			print("\n-- the toolbar --")
			_tools = _map.get("_tool_bar")
			_p(_tools != null and _tools.buttons().size() >= 8, "the toolbar has the tools", str(_tools.buttons().size() if _tools else 0))
			var tip_bad := PackedStringArray()
			for a: String in _tools.buttons():
				var b: Button = _tools.buttons()[a]
				var lbl := String(_km.binding_of(a).get("label", ""))
				# key_text: the live key, or how a key-less tool is reached (keymap step 3).
				if not (b.tooltip_text.contains(lbl) and b.tooltip_text.contains(String(_tools.key_text(a)))):
					tip_bad.append("%s: %s" % [a, b.tooltip_text.left(60)])
			_p(tip_bad.is_empty(), "every tool tooltip shows its label AND its live key", " | ".join(tip_bad))
			_p(not (_tools.buttons().values()[0] as Button).tooltip_text.contains("Physical"), "no 'Physical' noise in tooltips")

			print("\n-- the status bar is generated --")
			var idle: String = _hud.status_text()
			_p(idle.contains("F1") and idle.contains(String(_km.describe("builder.add_menu"))), "idle: hints include F1 and the add-menu key", idle.left(90))
			_p(_hud.status_right().contains("%du" % int(_map.GRID_UNITS[int(_map.get("_grid_idx"))])), "right side shows the grid", _hud.status_right())
			var stack: Node = _map.call("_ensure_ops")
			var op := LevelOperator.new()
			_map.add_child(op)
			stack.activate(op)
			_map.call("_update_op_hud")
		46:
			var busy: String = _hud.status_text()
			_p(busy.contains("Esc") and busy.contains("RMB"), "a tool is up: Enter/Esc and 'hold RMB fly' are shown", busy.left(90))
			if checks < 25:
				_p(false, "only %d checks ran" % checks)
			_dock.set_pref("grid", _saved_grid)
			_dock.set_pref("snap", _saved_snap)
			print("GATE editor_e1: %s (%d checks)" % ["PASS" if ok else "FAIL", checks])
			quit(0 if ok else 1)
			return true
	return false