extends SceneTree
## GATE — THE EDITOR'S THEME (hyper-games #124 spacing audit, item 1: "our widgets are
## ~1.5x Blender's" — Blender's widget unit is 20 px, its UI font 11 pt). One Theme on the
## editor's areas; the game's HUD and menus keep Godot's defaults.
## T1 in a dock panel: Button, OptionButton, LineEdit, SpinBox, CheckBox are <= 22 px tall
## T2 a Tree row is <= 22 px tall
## T3 the panel's text is 12 px
## T4 a Control OUTSIDE the dock keeps the default (16 px text): the theme is scoped
## T5–T10 the audit's spacing items: area gap 2 (grab 6), panel gap 2, header <= 22 px / 12 px,
## status bar <= 24, no border on the areas (T9, the top band, is gate_areas_layout's)
##
## RUN: CI=true HYPERTPS_DAEMON_TCP=127.0.0.1:1 "$GODOT" --headless --path . --script res://scenes/test/gate_editor_theme.gd
var _frame := 0
var _dock: Node = null
var _w: Dictionary = {}
var _outside: Button = null
var fails := 0
var checks := 0
func _p(c: bool, m: String, got: Variant = "") -> void:
checks += 1
if not c:
fails += 1
print(" %-62s %s %s" % [m, "OK" if c else "**FAIL**", str(got)])
func _process(_d: float) -> bool:
_frame += 1
if _frame == 1:
root.size = Vector2i(1920, 1080)
root.get_node("/root/GameMode").set_mode("build")
_dock = root.get_node("/root/BuildDock")
var box := VBoxContainer.new()
_w["button"] = Button.new()
(_w["button"] as Button).text = "Button"
var ob := OptionButton.new()
ob.add_item("Option")
_w["option"] = ob
_w["line"] = LineEdit.new()
_w["spin"] = SpinBox.new()
var cb := CheckBox.new()
cb.text = "Check"
_w["check"] = cb
var t := Tree.new()
t.custom_minimum_size = Vector2(0, 120)
var tr := t.create_item()
tr.set_text(0, "root")
var leaf := t.create_item(tr)
leaf.set_text(0, "row")
_w["tree"] = t
_w["leaf"] = leaf
for k: String in ["button", "option", "line", "spin", "check", "tree"]:
box.add_child(_w[k] as Control)
_dock.register("gate_theme", "Theme", box, true, _dock.SIDE_LEFT)
_outside = Button.new()
_outside.text = "outside"
var layer := CanvasLayer.new()
root.add_child(layer)
layer.add_child(_outside)
return false
if _frame < 10:
return false
for k: String in ["button", "option", "line", "spin", "check"]:
var h: float = (_w[k] as Control).size.y
_p(h <= 22.0, "T1 a dock %s is <= 22 px tall" % k, h)
var rr: Rect2 = (_w["tree"] as Tree).get_item_area_rect(_w["leaf"] as TreeItem)
_p(rr.size.y <= 22.0, "T2 a dock Tree row is <= 22 px tall", rr.size.y)
var fs: int = (_w["button"] as Control).get_theme_font_size("font_size")
_p(fs == 12, "T3 dock text is 12 px", fs)
var fo: int = _outside.get_theme_font_size("font_size")
_p(fo == 16, "T4 a control outside the dock keeps 16 px (the theme is scoped)", fo)
# ---- the audit's spacing items 3, 5, 6, 8, 9, 10 (Blender values) ----
var hs: SplitContainer = _dock.get("_hsplit")
_p(hs.get_theme_constant("separation") <= 2 and hs.get_theme_constant("minimum_grab_thickness") >= 6,
"T5 the gap between areas is 2 px (Blender's border_width), still 6 px to grab",
[hs.get_theme_constant("separation"), hs.get_theme_constant("minimum_grab_thickness")])
var col: Control = _dock._sides["left"]["column"]
_p(col.get_theme_constant("separation") <= 2, "T6 the gap between panels is 2 px", col.get_theme_constant("separation"))
var hdr: Button = (_dock._panels["gate_theme"] as Dictionary)["header"]
_p(hdr.size.y <= 22.0 and hdr.get_theme_font_size("font_size") <= 12, "T7 a panel header is <= 22 px, 12 px text",
[hdr.size.y, hdr.get_theme_font_size("font_size")])
var bar: Control = (_dock._status_left as Control).get_parent().get_parent() as Control
_p(bar.size.y <= 24.0, "T8 the status bar is <= 24 px (Blender ~22)", bar.size.y)
# (T9, the top band's height, is gate_areas_layout's: it needs a map's real top bar.)
var fsb: StyleBox = (_dock._sides["left"]["frame"] as Control).get_theme_stylebox("panel")
_p(fsb is StyleBoxFlat and (fsb as StyleBoxFlat).border_width_left == 0,
"T10 no orange border on the areas (the 2 px gap separates them)", (fsb as StyleBoxFlat).border_width_left if fsb is StyleBoxFlat else fsb)
_dock.unregister("gate_theme")
print("\nGATE editor_theme: %s (%d checks, %d failed)" % ["PASS" if fails == 0 else "FAIL", checks, fails])
quit(0 if fails == 0 else 1)
return true