2026-07-30 23:16:28 -04:00
|
|
|
extends SceneTree
|
|
|
|
|
|
|
|
|
|
const FishCatchType = preload("res://fish/fish_catch.gd")
|
|
|
|
|
const FishInventoryType = preload("res://inventory/fish_inventory.gd")
|
|
|
|
|
const FishPoolType = preload("res://fish/fish_pool.gd")
|
|
|
|
|
const CollectionLogType = preload("res://collection/collection_log.gd")
|
2026-07-31 00:03:47 -04:00
|
|
|
const FishDataType = preload("res://fish/fish_data.gd")
|
2026-08-02 09:57:05 -04:00
|
|
|
const LogbookPortraitType = preload(
|
|
|
|
|
"res://ui/components/logbook_portrait.gd"
|
|
|
|
|
)
|
|
|
|
|
const InventoryNotepadType = preload(
|
|
|
|
|
"res://ui/components/inventory_notepad.gd"
|
|
|
|
|
)
|
2026-07-30 23:16:28 -04:00
|
|
|
const LogbookPageScene = preload("res://ui/logbook_page.tscn")
|
|
|
|
|
const CatalogResource: FishPoolType = preload(
|
2026-07-30 23:46:53 -04:00
|
|
|
"res://fish/pools/fish_catalog.tres"
|
2026-07-30 23:16:28 -04:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func _initialize() -> void:
|
|
|
|
|
call_deferred("_run")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func _run() -> void:
|
|
|
|
|
if OS.has_environment("NETFISHING_TEST_CREATE_ROOT"):
|
|
|
|
|
var data_root := PlayerDataRoot.new()
|
|
|
|
|
root.add_child(data_root)
|
|
|
|
|
var result: Dictionary = data_root.create_unbound_root(
|
|
|
|
|
OS.get_environment("NETFISHING_TEST_CREATE_ROOT")
|
|
|
|
|
)
|
|
|
|
|
assert(bool(result.get("ok", false)))
|
|
|
|
|
data_root.queue_free()
|
|
|
|
|
print("Logbook portable test root: PASS")
|
|
|
|
|
quit()
|
|
|
|
|
return
|
|
|
|
|
_validate_catalog()
|
|
|
|
|
await _validate_page()
|
|
|
|
|
print("Logbook validation: PASS")
|
|
|
|
|
quit()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func _validate_catalog() -> void:
|
|
|
|
|
var expected_ids: Array[StringName] = [
|
2026-07-30 23:46:53 -04:00
|
|
|
&"bluegill",
|
|
|
|
|
&"bass",
|
|
|
|
|
&"carp",
|
|
|
|
|
&"sunfish",
|
|
|
|
|
&"catfish_blue",
|
|
|
|
|
&"catfish_channel",
|
|
|
|
|
&"catfish_flathead",
|
|
|
|
|
&"catfish_white",
|
2026-08-03 15:44:45 -04:00
|
|
|
&"tuna_albacore",
|
|
|
|
|
&"tuna_bigeye",
|
|
|
|
|
&"tuna_bluefin",
|
|
|
|
|
&"tuna_skipjack",
|
|
|
|
|
&"tuna_yellowfin",
|
|
|
|
|
&"goby_round",
|
|
|
|
|
&"salmon_atlantic",
|
|
|
|
|
&"salmon_chum",
|
|
|
|
|
&"salmon_coho",
|
|
|
|
|
&"salmon_pink",
|
|
|
|
|
&"salmon_sockeye",
|
2026-08-06 01:00:52 -04:00
|
|
|
&"anchovy_european",
|
|
|
|
|
&"anchovy_northern",
|
|
|
|
|
&"chub_european",
|
|
|
|
|
&"chub_flame",
|
|
|
|
|
&"chub_lake",
|
|
|
|
|
&"goldfish",
|
|
|
|
|
&"goldfish_bubbleeye",
|
|
|
|
|
&"grouper_gulf",
|
|
|
|
|
&"grouper_red",
|
|
|
|
|
&"mackerel_atlantic",
|
|
|
|
|
&"mackerel_cero",
|
|
|
|
|
&"mackerel_chub",
|
|
|
|
|
&"mackerel_king",
|
|
|
|
|
&"mackerel_spanish",
|
|
|
|
|
&"marlin_black",
|
|
|
|
|
&"marlin_blue",
|
|
|
|
|
&"marlin_white",
|
|
|
|
|
&"pomfret_black",
|
|
|
|
|
&"pomfret_chinese",
|
|
|
|
|
&"pomfret_golden",
|
|
|
|
|
&"pomfret_white",
|
|
|
|
|
&"sailfish",
|
|
|
|
|
&"sauger",
|
|
|
|
|
&"saugeye",
|
|
|
|
|
&"snapper_lane",
|
|
|
|
|
&"snapper_mangrove",
|
|
|
|
|
&"snapper_mutton",
|
|
|
|
|
&"snapper_red",
|
|
|
|
|
&"swordfish",
|
|
|
|
|
&"trout_cutthroat",
|
|
|
|
|
&"trout_golden",
|
|
|
|
|
&"trout_rainbow",
|
|
|
|
|
&"trout_steelhead",
|
|
|
|
|
&"walleye",
|
2026-07-30 23:16:28 -04:00
|
|
|
]
|
|
|
|
|
assert(LogbookCatalog.CATALOG_ORDER == expected_ids)
|
|
|
|
|
for index: int in expected_ids.size():
|
|
|
|
|
var fish := CatalogResource.get_fish_by_id(expected_ids[index])
|
|
|
|
|
assert(fish != null)
|
2026-08-02 09:57:05 -04:00
|
|
|
assert(not LogbookCatalog.facts_for(fish.id).is_empty())
|
|
|
|
|
assert(
|
|
|
|
|
LogbookCatalog.facts_for(fish.id)
|
|
|
|
|
== LogbookCatalog.facts_for(fish.id).to_lower()
|
|
|
|
|
)
|
2026-08-06 01:00:52 -04:00
|
|
|
if LogbookCatalog.FISH_FACTS.has(fish.id):
|
|
|
|
|
assert(LogbookCatalog.facts_for(fish.id) != "unknown")
|
|
|
|
|
else:
|
|
|
|
|
assert(LogbookCatalog.facts_for(fish.id) == "unknown")
|
2026-07-31 16:05:44 -04:00
|
|
|
var expected_category: WaterType.Type = (
|
|
|
|
|
WaterType.Type.SALT_WATER
|
2026-08-03 15:44:45 -04:00
|
|
|
if expected_ids[index] in [
|
|
|
|
|
&"bass",
|
|
|
|
|
&"sunfish",
|
|
|
|
|
&"tuna_albacore",
|
|
|
|
|
&"tuna_bigeye",
|
|
|
|
|
&"tuna_bluefin",
|
|
|
|
|
&"tuna_skipjack",
|
|
|
|
|
&"tuna_yellowfin",
|
|
|
|
|
&"salmon_atlantic",
|
|
|
|
|
&"salmon_chum",
|
|
|
|
|
&"salmon_coho",
|
|
|
|
|
&"salmon_pink",
|
|
|
|
|
&"salmon_sockeye",
|
2026-08-06 01:00:52 -04:00
|
|
|
&"anchovy_european",
|
|
|
|
|
&"anchovy_northern",
|
|
|
|
|
&"grouper_gulf",
|
|
|
|
|
&"grouper_red",
|
|
|
|
|
&"mackerel_atlantic",
|
|
|
|
|
&"mackerel_cero",
|
|
|
|
|
&"mackerel_chub",
|
|
|
|
|
&"mackerel_king",
|
|
|
|
|
&"mackerel_spanish",
|
|
|
|
|
&"marlin_black",
|
|
|
|
|
&"marlin_blue",
|
|
|
|
|
&"marlin_white",
|
|
|
|
|
&"pomfret_black",
|
|
|
|
|
&"pomfret_chinese",
|
|
|
|
|
&"pomfret_golden",
|
|
|
|
|
&"pomfret_white",
|
|
|
|
|
&"sailfish",
|
|
|
|
|
&"snapper_lane",
|
|
|
|
|
&"snapper_mangrove",
|
|
|
|
|
&"snapper_mutton",
|
|
|
|
|
&"snapper_red",
|
|
|
|
|
&"swordfish",
|
2026-08-03 15:44:45 -04:00
|
|
|
]
|
2026-07-31 16:05:44 -04:00
|
|
|
else WaterType.Type.FRESH_WATER
|
2026-07-30 23:46:53 -04:00
|
|
|
)
|
2026-07-30 23:16:28 -04:00
|
|
|
assert(
|
|
|
|
|
LogbookCatalog.category_for(fish)
|
2026-07-30 23:46:53 -04:00
|
|
|
== expected_category
|
2026-07-30 23:16:28 -04:00
|
|
|
)
|
|
|
|
|
assert(LogbookCatalog.catalog_number(fish.id) == index + 1)
|
|
|
|
|
assert(
|
2026-07-31 16:05:44 -04:00
|
|
|
LogbookCatalog.empty_state(WaterType.Type.SALT_WATER)
|
2026-07-30 23:16:28 -04:00
|
|
|
== "No saltwater catches cataloged yet."
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func _validate_page() -> void:
|
|
|
|
|
var collection := CollectionLogType.new()
|
|
|
|
|
var inventory := FishInventoryType.new()
|
|
|
|
|
root.add_child(collection)
|
|
|
|
|
root.add_child(inventory)
|
|
|
|
|
var page := LogbookPageScene.instantiate() as LogbookPage
|
|
|
|
|
root.add_child(page)
|
|
|
|
|
await process_frame
|
|
|
|
|
page.setup(collection, inventory, CatalogResource)
|
|
|
|
|
page.activate()
|
|
|
|
|
await process_frame
|
2026-08-02 09:57:05 -04:00
|
|
|
assert(page.get("_category") == WaterType.Type.FRESH_WATER)
|
2026-08-11 20:02:54 -04:00
|
|
|
assert((page.get("_catalog_grid") as GridContainer).columns == 4)
|
2026-08-02 09:57:05 -04:00
|
|
|
var initial_detail_body := page.get("_detail_body") as VBoxContainer
|
|
|
|
|
assert(not initial_detail_body.get_parent() is ScrollContainer)
|
|
|
|
|
assert(
|
|
|
|
|
page.call("_entry_label_text", "flathead catfish")
|
|
|
|
|
== "flathead\ncatfish"
|
|
|
|
|
)
|
2026-07-30 23:16:28 -04:00
|
|
|
|
2026-07-31 00:03:47 -04:00
|
|
|
var shared_material: Material
|
|
|
|
|
var silhouette_count: int = 0
|
2026-07-31 16:05:44 -04:00
|
|
|
for category: WaterType.Type in [
|
|
|
|
|
WaterType.Type.FRESH_WATER,
|
|
|
|
|
WaterType.Type.SALT_WATER,
|
2026-07-31 00:03:47 -04:00
|
|
|
]:
|
|
|
|
|
page.call("_select_category", category)
|
|
|
|
|
await create_timer(0.25).timeout
|
|
|
|
|
var entries: Dictionary = page.get("_entry_buttons")
|
2026-08-06 01:00:52 -04:00
|
|
|
assert(entries.size() == (19 if category == WaterType.Type.FRESH_WATER else 34))
|
2026-07-31 00:03:47 -04:00
|
|
|
for fish: FishDataType in LogbookCatalog.ordered_species(
|
|
|
|
|
CatalogResource.candidates
|
|
|
|
|
):
|
|
|
|
|
if LogbookCatalog.category_for(fish) != category:
|
|
|
|
|
continue
|
|
|
|
|
var unknown_key := StringName(
|
|
|
|
|
"unknown_%d" % LogbookCatalog.catalog_number(fish.id)
|
|
|
|
|
)
|
|
|
|
|
var entry := entries.get(unknown_key) as Button
|
|
|
|
|
assert(entry != null)
|
|
|
|
|
assert(entry.text.is_empty())
|
|
|
|
|
assert(entry.tooltip_text.is_empty())
|
|
|
|
|
assert(entry.icon == null)
|
|
|
|
|
assert(entry.accessibility_name == "Unknown catalog entry")
|
|
|
|
|
assert(_has_visible_unknown_name(entry))
|
2026-08-02 09:57:05 -04:00
|
|
|
var portrait: LogbookPortraitType = _find_portrait(entry)
|
2026-07-31 00:03:47 -04:00
|
|
|
assert(portrait != null)
|
2026-08-02 09:57:05 -04:00
|
|
|
assert(portrait.source_texture == fish.display_texture)
|
|
|
|
|
assert(
|
|
|
|
|
portrait.custom_minimum_size
|
2026-08-11 20:02:54 -04:00
|
|
|
== LogbookPage.CATALOG_PORTRAIT_SIZE
|
2026-08-02 09:57:05 -04:00
|
|
|
)
|
2026-07-31 00:03:47 -04:00
|
|
|
assert(
|
|
|
|
|
portrait.expand_mode
|
|
|
|
|
== TextureRect.EXPAND_IGNORE_SIZE
|
|
|
|
|
)
|
|
|
|
|
assert(
|
|
|
|
|
portrait.stretch_mode
|
|
|
|
|
== TextureRect.STRETCH_KEEP_ASPECT_CENTERED
|
|
|
|
|
)
|
|
|
|
|
assert(portrait.material is ShaderMaterial)
|
|
|
|
|
if shared_material == null:
|
|
|
|
|
shared_material = portrait.material
|
|
|
|
|
else:
|
|
|
|
|
assert(portrait.material == shared_material)
|
|
|
|
|
assert(_texture_has_transparency(portrait.texture))
|
|
|
|
|
silhouette_count += 1
|
|
|
|
|
for candidate: FishDataType in CatalogResource.candidates:
|
|
|
|
|
assert(not entry.text.contains(candidate.display_name))
|
|
|
|
|
assert(
|
|
|
|
|
not entry.tooltip_text.contains(
|
|
|
|
|
candidate.display_name
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
assert(
|
|
|
|
|
not entry.accessibility_name.contains(
|
|
|
|
|
candidate.display_name
|
|
|
|
|
)
|
|
|
|
|
)
|
2026-08-06 01:00:52 -04:00
|
|
|
assert(silhouette_count == 53)
|
2026-07-31 00:03:47 -04:00
|
|
|
|
2026-07-31 16:05:44 -04:00
|
|
|
page.call("_select_category", WaterType.Type.OTHER)
|
2026-07-30 23:16:28 -04:00
|
|
|
await create_timer(0.25).timeout
|
|
|
|
|
assert((page.get("_entry_buttons") as Dictionary).is_empty())
|
|
|
|
|
assert(
|
|
|
|
|
(page.get("_empty_state") as Label).text
|
2026-07-31 16:05:44 -04:00
|
|
|
== "No entries available."
|
2026-07-30 23:16:28 -04:00
|
|
|
)
|
2026-07-31 16:05:44 -04:00
|
|
|
page.call("_select_category", WaterType.Type.FRESH_WATER)
|
2026-07-30 23:16:28 -04:00
|
|
|
await create_timer(0.25).timeout
|
|
|
|
|
|
|
|
|
|
var bluegill = CatalogResource.get_fish_by_id(&"bluegill")
|
2026-07-31 00:03:47 -04:00
|
|
|
page.call("_select_entry", &"unknown_1", StringName())
|
|
|
|
|
assert(
|
|
|
|
|
(page.get("_entry_buttons") as Dictionary)
|
|
|
|
|
.get(&"unknown_1") != null
|
|
|
|
|
)
|
2026-07-30 23:16:28 -04:00
|
|
|
collection.mark_discovered(&"bluegill")
|
|
|
|
|
await process_frame
|
2026-07-31 00:03:47 -04:00
|
|
|
var entries: Dictionary = page.get("_entry_buttons")
|
2026-07-30 23:16:28 -04:00
|
|
|
var known := entries.get(&"bluegill") as Button
|
|
|
|
|
assert(known != null)
|
2026-08-02 09:57:05 -04:00
|
|
|
assert(known.custom_minimum_size.x == known.custom_minimum_size.y)
|
|
|
|
|
_validate_entry_bubble_styles(known)
|
|
|
|
|
assert(known.text.is_empty())
|
|
|
|
|
assert(known.icon == null)
|
|
|
|
|
assert(_has_visible_name(known, bluegill.display_name))
|
|
|
|
|
var known_portrait: LogbookPortraitType = _find_portrait(known)
|
|
|
|
|
assert(known_portrait != null)
|
|
|
|
|
assert(known_portrait.source_texture == bluegill.display_texture)
|
|
|
|
|
assert(known_portrait.material == null)
|
2026-07-31 00:03:47 -04:00
|
|
|
assert(known.button_pressed)
|
2026-08-02 09:57:05 -04:00
|
|
|
_validate_handwritten_logbook_font(page)
|
2026-07-30 23:16:28 -04:00
|
|
|
|
|
|
|
|
var fish_catch := FishCatchType.new()
|
|
|
|
|
fish_catch.fish = bluegill
|
|
|
|
|
fish_catch.fish_id = bluegill.id
|
|
|
|
|
fish_catch.weight_lb = bluegill.get_minimum_weight()
|
|
|
|
|
fish_catch.display_scale = bluegill.get_display_scale_for_weight(
|
|
|
|
|
fish_catch.weight_lb
|
|
|
|
|
)
|
|
|
|
|
fish_catch.sale_value = bluegill.get_sale_value_for_weight(
|
|
|
|
|
fish_catch.weight_lb
|
|
|
|
|
)
|
|
|
|
|
fish_catch.ensure_identity()
|
|
|
|
|
inventory.add_catch(fish_catch)
|
|
|
|
|
page.call("_select_entry", &"bluegill", &"bluegill")
|
|
|
|
|
await process_frame
|
|
|
|
|
assert(_detail_text(page).contains("number owned\n1"))
|
2026-08-02 09:57:05 -04:00
|
|
|
assert(_detail_text(page).contains("number caught\nunknown"))
|
|
|
|
|
assert(_detail_text(page).contains("body of water\nfresh water"))
|
2026-07-30 23:16:28 -04:00
|
|
|
assert(_detail_text(page).contains("catalog number\n#001"))
|
2026-08-02 09:57:05 -04:00
|
|
|
assert(_detail_text(page).contains("fish facts\n"))
|
|
|
|
|
assert(_detail_text(page).contains(LogbookCatalog.facts_for(&"bluegill")))
|
|
|
|
|
_validate_detail_field_fonts(page)
|
|
|
|
|
_validate_handwritten_numeric_scale(page)
|
|
|
|
|
var portrait_button := page.get("_detail_portrait_button") as Button
|
|
|
|
|
assert(portrait_button != null)
|
|
|
|
|
portrait_button.pressed.emit()
|
|
|
|
|
await process_frame
|
|
|
|
|
var portrait_overlay := page.get("_portrait_overlay") as Control
|
|
|
|
|
assert(portrait_overlay.visible)
|
|
|
|
|
var overlay_artwork := (
|
|
|
|
|
page.get("_portrait_overlay_artwork") as LogbookPortraitType
|
|
|
|
|
)
|
|
|
|
|
assert(overlay_artwork.source_texture == bluegill.display_texture)
|
|
|
|
|
assert(
|
|
|
|
|
overlay_artwork.custom_minimum_size.x <= 860.0
|
|
|
|
|
and overlay_artwork.custom_minimum_size.y <= 480.0
|
|
|
|
|
)
|
|
|
|
|
(page.get("_portrait_overlay_backdrop") as Button).pressed.emit()
|
|
|
|
|
await process_frame
|
|
|
|
|
assert(not portrait_overlay.visible)
|
2026-07-30 23:16:28 -04:00
|
|
|
|
|
|
|
|
inventory.remove_catch_by_id(fish_catch.catch_id)
|
|
|
|
|
await process_frame
|
|
|
|
|
assert(_detail_text(page).contains("number owned\n0"))
|
|
|
|
|
page.queue_free()
|
|
|
|
|
collection.queue_free()
|
|
|
|
|
inventory.queue_free()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func _detail_text(page: LogbookPage) -> String:
|
|
|
|
|
var values: PackedStringArray = []
|
|
|
|
|
var detail_body := page.get("_detail_body") as VBoxContainer
|
|
|
|
|
for node: Node in detail_body.find_children("*", "Label", true, false):
|
|
|
|
|
values.append((node as Label).text)
|
|
|
|
|
return "\n".join(values)
|
2026-07-31 00:03:47 -04:00
|
|
|
|
|
|
|
|
|
2026-08-02 09:57:05 -04:00
|
|
|
func _find_portrait(entry: Button) -> LogbookPortraitType:
|
2026-07-31 00:03:47 -04:00
|
|
|
var pending: Array[Node] = [entry]
|
|
|
|
|
while not pending.is_empty():
|
|
|
|
|
var node: Node = pending.pop_back()
|
2026-08-02 09:57:05 -04:00
|
|
|
if node is LogbookPortraitType:
|
|
|
|
|
return node as LogbookPortraitType
|
2026-07-31 00:03:47 -04:00
|
|
|
pending.append_array(node.get_children())
|
|
|
|
|
return null
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func _has_visible_unknown_name(entry: Button) -> bool:
|
2026-08-02 09:57:05 -04:00
|
|
|
return _has_visible_name(entry, "???")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func _has_visible_name(entry: Button, expected_name: String) -> bool:
|
2026-07-31 00:03:47 -04:00
|
|
|
var pending: Array[Node] = [entry]
|
|
|
|
|
while not pending.is_empty():
|
|
|
|
|
var node: Node = pending.pop_back()
|
2026-08-02 09:57:05 -04:00
|
|
|
if node is Label and (node as Label).text == expected_name:
|
2026-07-31 00:03:47 -04:00
|
|
|
return true
|
|
|
|
|
pending.append_array(node.get_children())
|
|
|
|
|
return false
|
|
|
|
|
|
|
|
|
|
|
2026-08-02 09:57:05 -04:00
|
|
|
func _validate_handwritten_logbook_font(page: LogbookPage) -> void:
|
|
|
|
|
var detail_body := page.get("_detail_body") as VBoxContainer
|
|
|
|
|
for node: Node in detail_body.find_children("*", "Label", true, false):
|
|
|
|
|
var label := node as Label
|
2026-08-02 17:44:11 -04:00
|
|
|
if label.text.begins_with("quality collection"):
|
|
|
|
|
continue
|
2026-08-02 09:57:05 -04:00
|
|
|
if label.text in [
|
|
|
|
|
"fish facts",
|
|
|
|
|
"catalog number",
|
|
|
|
|
"rarity",
|
|
|
|
|
"body of water",
|
|
|
|
|
"time of day",
|
|
|
|
|
"weight range",
|
|
|
|
|
"value range",
|
|
|
|
|
"number caught",
|
|
|
|
|
"number owned",
|
|
|
|
|
]:
|
|
|
|
|
continue
|
|
|
|
|
assert(
|
|
|
|
|
label.get_theme_font("font")
|
|
|
|
|
== InventoryNotepadType.HANDWRITTEN_FONT
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func _validate_detail_field_fonts(page: LogbookPage) -> void:
|
|
|
|
|
var detail_body := page.get("_detail_body") as VBoxContainer
|
|
|
|
|
var field_names: Array[String] = [
|
|
|
|
|
"fish facts",
|
|
|
|
|
"catalog number",
|
|
|
|
|
"rarity",
|
|
|
|
|
"body of water",
|
|
|
|
|
"time of day",
|
|
|
|
|
"weight range",
|
|
|
|
|
"value range",
|
|
|
|
|
"number caught",
|
|
|
|
|
"number owned",
|
|
|
|
|
]
|
|
|
|
|
for node: Node in detail_body.find_children("*", "Label", true, false):
|
|
|
|
|
var label := node as Label
|
2026-08-02 17:44:11 -04:00
|
|
|
if label.text.begins_with("quality collection"):
|
|
|
|
|
assert(label.get_theme_font("font") == UtilityPageStyle.TuffyFont)
|
|
|
|
|
continue
|
2026-08-02 09:57:05 -04:00
|
|
|
if label.text not in field_names:
|
|
|
|
|
continue
|
|
|
|
|
assert(label.get_theme_font("font") == UtilityPageStyle.TuffyFont)
|
|
|
|
|
if label.text != "fish facts":
|
|
|
|
|
assert(
|
|
|
|
|
label.horizontal_alignment
|
|
|
|
|
== HORIZONTAL_ALIGNMENT_CENTER
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func _validate_handwritten_numeric_scale(page: LogbookPage) -> void:
|
|
|
|
|
var detail_body := page.get("_detail_body") as VBoxContainer
|
|
|
|
|
var text_value: Label
|
|
|
|
|
var numeric_value: Label
|
|
|
|
|
for node: Node in detail_body.find_children("*", "Label", true, false):
|
|
|
|
|
var label := node as Label
|
|
|
|
|
if label.text == "common":
|
|
|
|
|
text_value = label
|
|
|
|
|
elif label.text == "#001":
|
|
|
|
|
numeric_value = label
|
|
|
|
|
assert(text_value != null)
|
|
|
|
|
assert(numeric_value != null)
|
|
|
|
|
assert(
|
|
|
|
|
numeric_value.get_theme_font_size("font_size")
|
|
|
|
|
< text_value.get_theme_font_size("font_size")
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func _validate_entry_bubble_styles(entry: Button) -> void:
|
|
|
|
|
var normal := entry.get_theme_stylebox("normal") as StyleBoxFlat
|
|
|
|
|
var hover := entry.get_theme_stylebox("hover") as StyleBoxFlat
|
|
|
|
|
var pressed := entry.get_theme_stylebox("pressed") as StyleBoxFlat
|
|
|
|
|
assert(normal != null)
|
|
|
|
|
assert(hover != null)
|
|
|
|
|
assert(pressed != null)
|
|
|
|
|
assert(is_zero_approx(normal.bg_color.a))
|
|
|
|
|
assert(hover.bg_color.a > 0.0)
|
|
|
|
|
assert(pressed.bg_color.a > 0.0)
|
|
|
|
|
assert(hover.border_width_left == 0)
|
|
|
|
|
assert(pressed.border_width_left == 0)
|
|
|
|
|
assert(hover.corner_radius_top_left == 51)
|
|
|
|
|
|
|
|
|
|
|
2026-07-31 00:03:47 -04:00
|
|
|
func _texture_has_transparency(texture: Texture2D) -> bool:
|
|
|
|
|
var image: Image = texture.get_image()
|
|
|
|
|
return image != null and image.detect_alpha() != Image.ALPHA_NONE
|