Add generated UI button surfaces
This commit is contained in:
@@ -93,6 +93,7 @@ func _init() -> void:
|
||||
_check_battle_visual_data(failures)
|
||||
_check_generated_toolbar_icons(failures)
|
||||
_check_generated_panel_textures(failures)
|
||||
_check_generated_button_textures(failures)
|
||||
_check_generated_terrain_textures(failures)
|
||||
_check_scene_texture_loading(failures)
|
||||
_check_hud_focus_text(failures)
|
||||
@@ -2984,6 +2985,12 @@ func _check_generated_panel_textures(failures: Array[String]) -> void:
|
||||
_check_panel_texture_path(failures, "res://art/ui/panels/panel_%s.png" % panel_key, "panel texture %s" % panel_key)
|
||||
|
||||
|
||||
func _check_generated_button_textures(failures: Array[String]) -> void:
|
||||
var button_keys := ["normal", "hover", "pressed", "disabled"]
|
||||
for button_key in button_keys:
|
||||
_check_button_texture_path(failures, "res://art/ui/buttons/button_%s.png" % button_key, "button texture %s" % button_key)
|
||||
|
||||
|
||||
func _check_generated_terrain_textures(failures: Array[String]) -> void:
|
||||
var terrain_keys := ["g", "f", "h", "d", "r", "w", "t", "c"]
|
||||
for terrain_key in terrain_keys:
|
||||
@@ -3814,6 +3821,26 @@ func _check_button_uses_generated_toolbar_icon(failures: Array[String], button:
|
||||
failures.append("%s should use generated high-resolution toolbar art, got %dx%d" % [context, button.icon.get_width(), button.icon.get_height()])
|
||||
|
||||
|
||||
func _check_button_uses_generated_surface(failures: Array[String], button: Button, context: String) -> void:
|
||||
if button == null:
|
||||
failures.append("%s button missing" % context)
|
||||
return
|
||||
var stylebox := button.get_theme_stylebox("normal")
|
||||
if not (stylebox is StyleBoxTexture):
|
||||
failures.append("%s should use a generated button texture surface" % context)
|
||||
return
|
||||
var style := stylebox as StyleBoxTexture
|
||||
if style.texture == null:
|
||||
failures.append("%s generated button style is missing its texture" % context)
|
||||
return
|
||||
if style.texture.get_width() < 512 or style.texture.get_height() < 192:
|
||||
failures.append("%s generated button texture should keep high-resolution source pixels: %dx%d" % [context, style.texture.get_width(), style.texture.get_height()])
|
||||
if style.texture_margin_left < 48 or style.texture_margin_top < 24:
|
||||
failures.append("%s generated button texture should define visible frame slice margins" % context)
|
||||
if style.content_margin_left < 8 or style.content_margin_top < 5:
|
||||
failures.append("%s generated button texture should reserve readable content margins" % context)
|
||||
|
||||
|
||||
func _check_local_command_icon_button(failures: Array[String], button: Button, expected_label: String, expected_icon: String) -> void:
|
||||
if button == null:
|
||||
failures.append("local command button missing: %s" % expected_label)
|
||||
@@ -3823,6 +3850,7 @@ func _check_local_command_icon_button(failures: Array[String], button: Button, e
|
||||
if button.icon == null or str(button.get_meta("command_icon", "")) != expected_icon:
|
||||
failures.append("local command should carry an immediate visual icon: %s icon=%s meta=%s" % [expected_label, str(button.icon), str(button.get_meta("command_icon", ""))])
|
||||
_check_button_uses_generated_toolbar_icon(failures, button, expected_label)
|
||||
_check_button_uses_generated_surface(failures, button, expected_label)
|
||||
if str(button.get_meta("command_label", "")) != expected_label:
|
||||
failures.append("local command should keep old wording in hover metadata: %s meta=%s" % [expected_label, str(button.get_meta("command_label", ""))])
|
||||
if str(button.tooltip_text).strip_edges().is_empty() or not str(button.tooltip_text).contains(expected_label):
|
||||
@@ -3860,6 +3888,7 @@ func _check_hud_command_grid_layout(failures: Array[String]) -> void:
|
||||
if button.icon == null or str(button.get_meta("command_icon", "")) != str(expectation["icon"]):
|
||||
failures.append("unit command button should carry an immediate visual icon: %s icon=%s meta=%s" % [button.text, str(button.icon), str(button.get_meta("command_icon", ""))])
|
||||
_check_button_uses_generated_toolbar_icon(failures, button, str(expectation["icon"]))
|
||||
_check_button_uses_generated_surface(failures, button, str(expectation["icon"]))
|
||||
if not bool(button.get_meta("icon_only", false)) or button.text != "":
|
||||
failures.append("unit command button should be icon-first without visible text: %s text=%s" % [str(button.name), button.text])
|
||||
if not scene.state.load_battle("res://data/scenarios/001_yellow_turbans.json"):
|
||||
@@ -3895,6 +3924,7 @@ func _check_hud_command_grid_layout(failures: Array[String]) -> void:
|
||||
if not bool(button.get_meta("icon_only", false)) or button.text != "" or button.icon == null:
|
||||
failures.append("top tool button should be icon-only with tooltip detail: %s text=%s icon=%s" % [str(button.name), button.text, str(button.icon)])
|
||||
_check_button_uses_generated_toolbar_icon(failures, button, str(button.name))
|
||||
_check_button_uses_generated_surface(failures, button, str(button.name))
|
||||
if button.custom_minimum_size.x < BattleSceneScript.TOP_TOOL_BUTTON_SIZE.x or button.custom_minimum_size.y < BattleSceneScript.TOP_TOOL_BUTTON_SIZE.y:
|
||||
failures.append("top tool button should reserve stable icon space: %s" % str(button.custom_minimum_size))
|
||||
scene.free()
|
||||
@@ -4005,6 +4035,7 @@ func _check_prep_menu_icon_button(failures: Array[String], button: Button, expec
|
||||
if button.icon == null or str(button.get_meta("command_icon", "")) != expected_icon:
|
||||
failures.append("pre-battle prep button should carry a distinct icon: %s icon=%s meta=%s" % [expected_label, str(button.icon), str(button.get_meta("command_icon", ""))])
|
||||
_check_button_uses_generated_toolbar_icon(failures, button, expected_label)
|
||||
_check_button_uses_generated_surface(failures, button, expected_label)
|
||||
if str(button.get_meta("command_label", "")) != expected_label:
|
||||
failures.append("pre-battle prep button should preserve Korean label in metadata: %s meta=%s" % [expected_label, str(button.get_meta("command_label", ""))])
|
||||
if str(button.tooltip_text).strip_edges().is_empty() or not str(button.tooltip_text).contains(expected_label):
|
||||
@@ -4949,6 +4980,61 @@ func _check_panel_texture_path(failures: Array[String], path: String, context: S
|
||||
failures.append("%s should contain visible material contrast: %s" % [context, path])
|
||||
|
||||
|
||||
func _check_button_texture_path(failures: Array[String], path: String, context: String) -> void:
|
||||
if path.is_empty():
|
||||
failures.append("%s has an empty button path" % context)
|
||||
return
|
||||
if not path.begins_with("res://"):
|
||||
failures.append("%s must use a res:// path: %s" % [context, path])
|
||||
return
|
||||
if not FileAccess.file_exists(path):
|
||||
failures.append("%s references missing button texture: %s" % [context, path])
|
||||
return
|
||||
var image := Image.new()
|
||||
var err := image.load(path)
|
||||
if err != OK:
|
||||
failures.append("%s references unreadable button texture: %s" % [context, path])
|
||||
return
|
||||
if image.get_width() < 512 or image.get_height() < 192:
|
||||
failures.append("%s should keep high-resolution source pixels: %s (%dx%d)" % [context, path, image.get_width(), image.get_height()])
|
||||
return
|
||||
if image.get_width() <= image.get_height():
|
||||
failures.append("%s should be a wide button surface: %s (%dx%d)" % [context, path, image.get_width(), image.get_height()])
|
||||
return
|
||||
for corner in [Vector2i(0, 0), Vector2i(image.get_width() - 1, 0), Vector2i(0, image.get_height() - 1), Vector2i(image.get_width() - 1, image.get_height() - 1)]:
|
||||
if image.get_pixelv(corner).a > 0.01:
|
||||
failures.append("%s should have transparent corners: %s" % [context, path])
|
||||
return
|
||||
var opaque_samples := 0
|
||||
var transparent_samples := 0
|
||||
var green_fringe_samples := 0
|
||||
var luma_min := 999.0
|
||||
var luma_max := -999.0
|
||||
var total_samples := 0
|
||||
for y in range(0, image.get_height(), 8):
|
||||
for x in range(0, image.get_width(), 8):
|
||||
total_samples += 1
|
||||
var pixel := image.get_pixel(x, y)
|
||||
if pixel.a <= 0.01:
|
||||
transparent_samples += 1
|
||||
continue
|
||||
if pixel.a >= 0.80:
|
||||
opaque_samples += 1
|
||||
if pixel.g > 0.80 and pixel.r < 0.18 and pixel.b < 0.18:
|
||||
green_fringe_samples += 1
|
||||
var luma := pixel.r * 0.299 + pixel.g * 0.587 + pixel.b * 0.114
|
||||
luma_min = minf(luma_min, luma)
|
||||
luma_max = maxf(luma_max, luma)
|
||||
if transparent_samples < int(total_samples * 0.08):
|
||||
failures.append("%s should retain transparent button padding: %s (%d/%d sampled pixels)" % [context, path, transparent_samples, total_samples])
|
||||
if opaque_samples < int(total_samples * 0.45):
|
||||
failures.append("%s should contain substantial generated button artwork: %s (%d/%d sampled pixels)" % [context, path, opaque_samples, total_samples])
|
||||
if green_fringe_samples > 0:
|
||||
failures.append("%s should not keep chroma-key green pixels: %s (%d sampled)" % [context, path, green_fringe_samples])
|
||||
if luma_max - luma_min < 0.08:
|
||||
failures.append("%s should contain visible material contrast: %s" % [context, path])
|
||||
|
||||
|
||||
func _check_terrain_texture_path(failures: Array[String], path: String, context: String) -> void:
|
||||
if path.is_empty():
|
||||
failures.append("%s has an empty texture path" % context)
|
||||
|
||||
Reference in New Issue
Block a user