extends Control const Style := preload("res://scripts/ui/ui_style.gd") var screens := {} var header_stats: Label var header_panel: PanelContainer var user_label: Label func _ready() -> void: Style.apply_app_theme(self) _build_ui() show_screen("menu" if AuthState.is_logged_in else "login") func show_screen(screen_name: String, payload: Variant = null) -> void: for child in $Root/Screens.get_children(): child.visible = false var screen = screens.get(screen_name) if screen == null: return screen.visible = true if header_panel != null: header_panel.visible = screen_name != "login" if screen.has_method("on_show"): screen.on_show(payload) func _build_ui() -> void: var background := ColorRect.new() background.color = Style.BACKGROUND background.set_anchors_preset(Control.PRESET_FULL_RECT) add_child(background) var root := VBoxContainer.new() root.name = "Root" root.set_anchors_preset(Control.PRESET_FULL_RECT) root.add_theme_constant_override("separation", 0) add_child(root) header_panel = PanelContainer.new() header_panel.name = "Header" header_panel.add_theme_stylebox_override("panel", Style.panel_box(Style.SURFACE_DARK, Color("263752"))) root.add_child(header_panel) var header := HBoxContainer.new() header.custom_minimum_size = Vector2(0, 78) header.add_theme_constant_override("separation", 14) header_panel.add_child(header) var title := Label.new() title.text = "STEP 3 Arcade" Style.set_label(title, 31, Style.TEXT) title.size_flags_horizontal = Control.SIZE_EXPAND_FILL header.add_child(title) header_stats = Label.new() header_stats.name = "HeaderStats" Style.set_label(header_stats, 15, Style.MUTED) header_stats.size_flags_horizontal = Control.SIZE_EXPAND_FILL header_stats.horizontal_alignment = HORIZONTAL_ALIGNMENT_RIGHT header.add_child(header_stats) user_label = Label.new() Style.set_label(user_label, 15, Style.CYAN) user_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_RIGHT header.add_child(user_label) var profile_button := Button.new() profile_button.text = "Profile" profile_button.pressed.connect(func(): show_screen("profile")) header.add_child(profile_button) var map_button := Button.new() map_button.text = "Study Map" map_button.pressed.connect(func(): show_screen("map")) header.add_child(map_button) var logout_button := Button.new() logout_button.text = "Log Out" logout_button.pressed.connect(_logout) header.add_child(logout_button) var screens_container := MarginContainer.new() screens_container.name = "Screens" screens_container.size_flags_vertical = Control.SIZE_EXPAND_FILL screens_container.add_theme_constant_override("margin_left", 24) screens_container.add_theme_constant_override("margin_right", 24) screens_container.add_theme_constant_override("margin_top", 18) screens_container.add_theme_constant_override("margin_bottom", 22) root.add_child(screens_container) var menu := preload("res://scripts/ui/main_menu.gd").new() menu.name = "MainMenu" menu.main = self screens_container.add_child(menu) screens["menu"] = menu var login := preload("res://scripts/ui/login_screen.gd").new() login.name = "LoginScreen" login.main = self screens_container.add_child(login) screens["login"] = login var map := preload("res://scripts/ui/study_map.gd").new() map.name = "StudyMap" map.main = self screens_container.add_child(map) screens["map"] = map var setup := preload("res://scripts/ui/block_setup.gd").new() setup.name = "BlockSetup" setup.main = self screens_container.add_child(setup) screens["setup"] = setup var player := preload("res://scripts/ui/question_player.gd").new() player.name = "QuestionPlayer" player.main = self screens_container.add_child(player) screens["player"] = player var review := preload("res://scripts/ui/review_results.gd").new() review.name = "ReviewResults" review.main = self screens_container.add_child(review) screens["review"] = review var profile := preload("res://scripts/ui/progress_profile.gd").new() profile.name = "ProgressProfile" profile.main = self screens_container.add_child(profile) screens["profile"] = profile ProfileService.profile_changed.connect(_refresh_header_stats) AuthState.auth_changed.connect(_refresh_header_stats) _refresh_header_stats() func _refresh_header_stats() -> void: if header_stats == null: return var profile := ProfileService.get_profile() header_stats.text = "LV %d | %d XP | Streak %d" % [ profile.get("level", 1), profile.get("xp", 0), profile.get("current_streak", 0) ] if user_label != null: user_label.text = AuthState.username if AuthState.is_logged_in else "" func _logout() -> void: AuthState.clear_session() show_screen("login")