Files
step3/scripts/ui/block_setup.gd
T

110 lines
3.9 KiB
GDScript

extends VBoxContainer
const Style := preload("res://scripts/ui/ui_style.gd")
var main: Control
var selected_system := "All Systems"
var system_label: Label
var size_spin: SpinBox
var mode_option: OptionButton
var status_label: Label
var start_button: Button
var requested_count := 10
var targeted_setup := false
func _ready() -> void:
set_anchors_preset(Control.PRESET_FULL_RECT)
add_theme_constant_override("separation", 16)
if not QuestionBankService.questions_changed.is_connected(_refresh_setup):
QuestionBankService.questions_changed.connect(_refresh_setup)
var title := Label.new()
title.text = "Block Setup"
Style.set_label(title, 34, Style.TEXT)
add_child(title)
system_label = Label.new()
Style.set_label(system_label, 22, Style.CYAN)
add_child(system_label)
var size_row := HBoxContainer.new()
size_row.add_child(Label.new())
size_row.get_child(0).text = "Question count"
size_spin = SpinBox.new()
size_spin.min_value = 1
size_spin.max_value = 40
size_spin.value = 6
size_spin.custom_minimum_size = Vector2(110, 44)
size_row.add_child(size_spin)
add_child(size_row)
var mode_row := HBoxContainer.new()
var mode_label := Label.new()
mode_label.text = "Mode"
mode_row.add_child(mode_label)
mode_option = OptionButton.new()
mode_option.add_item("Tutor")
mode_option.add_item("Timed")
mode_option.custom_minimum_size = Vector2(180, 44)
mode_row.add_child(mode_option)
add_child(mode_row)
var note := Label.new()
note.text = "Tutor mode shows explanations after each answer. Timed mode scores the block at the end."
note.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
Style.set_label(note, 16, Style.MUTED)
add_child(note)
status_label = Label.new()
status_label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
Style.set_label(status_label, 16, Style.RED)
add_child(status_label)
start_button = Button.new()
start_button.text = "Launch Block"
start_button.custom_minimum_size = Vector2(220, 54)
Style.style_primary_button(start_button)
start_button.pressed.connect(_start_block)
add_child(start_button)
func on_show(payload: Variant = null) -> void:
if typeof(payload) == TYPE_DICTIONARY:
targeted_setup = true
selected_system = str(payload.get("step3_system", "All Systems"))
requested_count = int(payload.get("question_count", 10))
size_spin.value = requested_count
QuestionBankService.load_targeted_questions(selected_system, requested_count,
int(payload.get("difficulty_min", 0)), int(payload.get("difficulty_max", 0)))
else:
targeted_setup = false
selected_system = str(payload) if payload != null else "All Systems"
_refresh_setup()
func _refresh_setup() -> void:
if system_label == null:
return
system_label.text = "Zone: %s" % selected_system
var available := QuestionBankService.get_questions_for_system(selected_system).size()
size_spin.max_value = max(1, available)
if not QuestionBankService.is_loading and available > 0:
size_spin.value = min(requested_count, available) if targeted_setup else min(size_spin.value, available)
targeted_setup = false
start_button.disabled = available == 0 or QuestionBankService.is_loading
if QuestionBankService.is_loading:
status_label.text = "Question API unavailable. Retrying in %d seconds..." % QuestionBankService.next_retry_seconds if QuestionBankService.load_state == "retrying" else "Loading question bank..."
elif available == 0:
status_label.text = QuestionBankService.last_error if QuestionBankService.last_error != "" else "No questions are available for this zone yet."
else:
status_label.text = "%d questions available.%s" % [available,
" The requested difficulty range was broadened." if QuestionBankService.targeted_fallback_used else ""]
func _start_block() -> void:
if not QuestionBankService.has_questions():
status_label.text = "Questions have not loaded from the API yet."
return
BlockSessionService.start_block(selected_system, int(size_spin.value), mode_option.get_item_text(mode_option.selected))
main.show_screen("player")