Files
step3/scripts/ui/study_map.gd
2026-07-11 02:05:43 -05:00

86 lines
2.9 KiB
GDScript

extends VBoxContainer
const Style := preload("res://scripts/ui/ui_style.gd")
var main: Control
var zone_list: GridContainer
func _ready() -> void:
set_anchors_preset(Control.PRESET_FULL_RECT)
add_theme_constant_override("separation", 14)
if not QuestionBankService.questions_changed.is_connected(_refresh_zones):
QuestionBankService.questions_changed.connect(_refresh_zones)
var title := Label.new()
title.text = "Study Map"
Style.set_label(title, 34, Style.TEXT)
add_child(title)
var help := Label.new()
help.text = "Choose a system zone. Strong scores raise your rating and build momentum."
help.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
Style.set_label(help, 16, Style.MUTED)
add_child(help)
zone_list = GridContainer.new()
zone_list.columns = 3
zone_list.size_flags_vertical = Control.SIZE_EXPAND_FILL
add_child(zone_list)
func on_show(_payload: Variant = null) -> void:
_refresh_zones()
func _refresh_zones() -> void:
if zone_list == null:
return
for child in zone_list.get_children():
child.queue_free()
if QuestionBankService.is_loading:
var loading := Label.new()
loading.text = "Question API unavailable. Retrying in %d seconds..." % QuestionBankService.next_retry_seconds if QuestionBankService.load_state == "retrying" else "Loading question bank..."
Style.set_label(loading, 20, Style.AMBER)
zone_list.add_child(loading)
return
if not QuestionBankService.has_questions():
var empty := Label.new()
empty.text = QuestionBankService.last_error if QuestionBankService.last_error != "" else "No API questions loaded."
empty.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
Style.set_label(empty, 20, Style.RED)
zone_list.add_child(empty)
var retry := Button.new()
retry.text = "Retry Questions"
retry.custom_minimum_size = Vector2(220, 54)
Style.style_chip(retry, Style.AMBER)
retry.pressed.connect(QuestionBankService.retry_now)
zone_list.add_child(retry)
return
var systems: Array[String] = ["All Systems"]
systems.append_array(QuestionBankService.get_systems())
var stats: Dictionary = ProfileService.get_profile().get("system_stats", {})
for system_name in systems:
var button := Button.new()
button.custom_minimum_size = Vector2(260, 110)
button.text = _zone_text(system_name, stats)
Style.style_chip(button, Style.CYAN if system_name == "All Systems" else Style.MAGENTA)
button.pressed.connect(func(zone_name: String = system_name): main.show_screen("setup", zone_name))
zone_list.add_child(button)
func _zone_text(system_name: String, stats: Dictionary) -> String:
if system_name == "All Systems" or not stats.has(system_name):
return "%s\nStart block" % system_name
var seen := int(stats[system_name].get("seen", 0))
var correct := int(stats[system_name].get("correct", 0))
var accuracy := 0
if seen > 0:
accuracy = int(round(float(correct) / float(seen) * 100.0))
return "%s\n%d seen | %d%%" % [system_name, seen, accuracy]