feat: overhaul UI main and profile

This commit is contained in:
2026-04-15 16:26:49 +08:00
parent 01661a56ba
commit f10d777c90
16 changed files with 1888 additions and 710 deletions
+118 -25
View File
@@ -2,22 +2,33 @@ extends Control
# UI References - Main Menu
@onready var main_menu_panel = $MainMenuPanel
@onready var main_title = $MainMenuPanel/HiddenLogic/Title
@onready var username_label = $MainMenuPanel/MainContainer/MarginContainer/LeftPanel/ProfileBox/VBoxContainer/Username
@onready var main_subtitle = $MainMenuPanel/MainContainer/MarginContainer/LeftPanel/ProfileBox/VBoxContainer/Subtitle
@onready var create_room_btn = $MainMenuPanel/MainContainer/MarginContainer/BottomRightPanel/CreateRoomBtn
@onready var browse_rooms_btn = $MainMenuPanel/MainContainer/MarginContainer/BottomRightPanel/BrowseRoomsBtn
@onready var tutorial_btn = $MainMenuPanel/MainContainer/MarginContainer/BottomRightPanel/TutorialBtn
@onready var main_menu_profile_btn = $MainMenuPanel/MainContainer/MarginContainer/LeftPanel/ProfileBox/ProfileBtn
@onready var lobby_settings_btn = $MainMenuPanel/MainContainer/MarginContainer/TopRightPanel/SettingsBtn
@onready var quit_btn = $MainMenuPanel/MainContainer/MarginContainer/LeftPanel/HBoxContainer/QuitBtn
@onready var main_title = %Title
@onready var username_label = %Username
@onready var main_subtitle = %Subtitle
@onready var create_room_btn = %CreateRoomBtn
@onready var browse_rooms_btn = %BrowseRoomsBtn
@onready var tutorial_btn = %TutorialBtn
@onready var main_menu_profile_btn = %MainProfileBtn
@onready var avatar_display = %AvatarDisplay
@onready var lobby_settings_btn = %SettingsBtn
@onready var quit_btn = %QuitBtn
# Main Menu 3D Preview
@onready var character_root = %CharacterRoot
@onready var anim_player = %AnimationPlayer
# UI References - Currencies
@onready var gold_label = %GoldLabel
@onready var star_label = %StarLabel
# UI References - Server Selection
@onready var server_option = $MainMenuPanel/HiddenLogic/ServerOption
@onready var server_ip_input = $MainMenuPanel/HiddenLogic/ServerIPInput
@onready var server_option = %ServerOption
@onready var server_ip_input = %ServerIPInput
# Leaderboard Reference
@onready var leaderboard_btn = $MainMenuPanel/MainContainer/MarginContainer/TopRightPanel/LeaderboardBtn
@onready var leaderboard_btn = %LeaderboardBtn
@onready var shop_btn = %CartBtn
@onready var top_right_profile_btn = %ProfileBtn
# UI References - Room List
@onready var room_list_panel = $RoomListPanel
@@ -108,9 +119,9 @@ const GLOBAL_CHAT_ROOM := "global_lobby"
var _chat_channel = null
var _chat_messages: Array = []
@onready var chat_display: RichTextLabel = $MainMenuPanel/MainContainer/MarginContainer/LeftPanel/ChatPanel/MarginContainer/RichTextLabel
@onready var chat_input: LineEdit = $MainMenuPanel/MainContainer/MarginContainer/LeftPanel/HBoxContainer/ChatInput
@onready var chat_send_btn: Button = $MainMenuPanel/MainContainer/MarginContainer/LeftPanel/HBoxContainer/SendBtn
@onready var chat_display: RichTextLabel = %RichTextLabel
@onready var chat_input: LineEdit = %ChatInput
@onready var chat_send_btn: Button = %SendBtn
# Server Selection Controls (Now in tscn)
# var server_option: OptionButton
@@ -142,8 +153,15 @@ func _ready():
tutorial_btn.pressed.connect(_on_tutorial_pressed)
if main_menu_profile_btn:
main_menu_profile_btn.pressed.connect(_on_profile_btn_pressed)
if top_right_profile_btn:
top_right_profile_btn.pressed.connect(_on_profile_btn_pressed)
if lobby_settings_btn:
lobby_settings_btn.pressed.connect(_on_settings_pressed)
# Shop Button
if shop_btn:
shop_btn.pressed.connect(_on_shop_pressed)
if leaderboard_btn:
leaderboard_btn.pressed.connect(_on_leaderboard_pressed)
if quit_btn:
@@ -252,6 +270,33 @@ func _ready():
# Setup
# =============================================================================
const CHAR_NODE_MAP: Dictionary = {
"Copper": "Oldpop",
"Dabro": "Masbro",
"Gatot": "Gatot",
"Pip": "Bob"
}
func _setup_3d_preview() -> void:
"""Swaps out the active character inside the 3D MainMenu SubViewport."""
if not character_root:
return
var target_character = UserProfileManager.profile.get("loadout_character", "Copper")
var node_name = CHAR_NODE_MAP.get(target_character, "Bob")
for child in character_root.get_children():
if child is Node3D:
child.visible = (child.name == node_name)
if anim_player:
var new_root: Node3D = character_root.get_node_or_null(node_name) as Node3D
if new_root:
anim_player.root_node = new_root.get_path()
if anim_player.has_animation("animation-pack/idle"):
anim_player.play("animation-pack/idle")
elif anim_player.get_animation_list().size() > 0:
anim_player.play(anim_player.get_animation_list()[0])
func _load_character_textures() -> void:
"""Load character preview textures."""
var characters = {
@@ -672,12 +717,19 @@ func _on_profile_btn_pressed() -> void:
if not profile_panel_instance:
var profile_panel_scene := load("res://scenes/ui/profile_panel.tscn")
profile_panel_instance = profile_panel_scene.instantiate()
profile_panel_instance.closed.connect(func(): profile_panel_instance.hide())
profile_panel_instance.closed.connect(func():
profile_panel_instance.hide()
if main_menu_panel:
main_menu_panel.show()
)
# Full-screen overlay — fill the entire lobby viewport
profile_panel_instance.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
add_child(profile_panel_instance)
profile_panel_instance.show_panel()
if profile_panel_instance:
if main_menu_panel:
main_menu_panel.hide()
profile_panel_instance.show_panel()
func _on_logout_pressed() -> void:
AuthManager.logout()
@@ -696,26 +748,60 @@ func _on_settings_pressed():
settings_menu.name = "SettingsMenu"
add_child(settings_menu)
# Connect close button
# Connect close button — restore whichever panel was visible before
var close_btn = settings_menu.get_node_or_null("PanelContainer/VBoxContainer/Header/CloseButton")
if close_btn:
# settings_menu.gd handles basic visibility, but we can override or add to it
pass
close_btn.pressed.connect(func():
if lobby_panel and lobby_panel.visible:
pass # lobby_panel restored below via _restore_panel
_restore_after_settings()
)
if settings_menu:
# Remember what is currently active
settings_menu.set_meta("from_lobby", lobby_panel.visible if lobby_panel else false)
main_menu_panel.hide()
if lobby_panel: lobby_panel.hide()
settings_menu.open()
func _restore_after_settings() -> void:
var settings_menu = get_node_or_null("SettingsMenu")
var from_lobby: bool = settings_menu.get_meta("from_lobby", false) if settings_menu else false
if from_lobby:
if lobby_panel: lobby_panel.show()
else:
if main_menu_panel: main_menu_panel.show()
func _on_shop_pressed() -> void:
if not NakamaManager.session:
connection_status.text = "Must be logged in"
return
var shop_scene = load("res://scenes/ui/shop_panel.tscn")
if shop_scene:
var shop = shop_scene.instantiate()
add_child(shop)
if main_menu_panel: main_menu_panel.hide()
shop.closed.connect(func(): if main_menu_panel: main_menu_panel.show())
shop.show_panel()
func _on_leaderboard_pressed() -> void:
if not leaderboard_panel_instance:
var leaderboard_panel_scene := load("res://scenes/ui/leaderboard_panel.tscn")
if leaderboard_panel_scene:
leaderboard_panel_instance = leaderboard_panel_scene.instantiate()
leaderboard_panel_instance.closed.connect(func(): leaderboard_panel_instance.hide())
leaderboard_panel_instance.closed.connect(func():
leaderboard_panel_instance.hide()
if main_menu_panel:
main_menu_panel.show()
)
# Full-screen overlay
leaderboard_panel_instance.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
add_child(leaderboard_panel_instance)
if leaderboard_panel_instance:
if main_menu_panel:
main_menu_panel.hide()
leaderboard_panel_instance.show_panel()
func _go_to_login() -> void:
@@ -873,15 +959,22 @@ func _on_profile_updated() -> void:
if username_label:
username_label.text = display_name
if main_menu_profile_btn:
if avatar_display:
var avatar_url = UserProfileManager.get_avatar_url()
if ResourceLoader.exists(avatar_url):
main_menu_profile_btn.icon = load(avatar_url)
main_menu_profile_btn.expand_icon = true
main_menu_profile_btn.text = ""
avatar_display.texture = load(avatar_url)
if main_menu_profile_btn:
main_menu_profile_btn.text = ""
if gold_label and UserProfileManager.is_profile_loaded:
gold_label.text = str(UserProfileManager.wallet.get("gold", 0))
if star_label and UserProfileManager.is_profile_loaded:
star_label.text = str(UserProfileManager.wallet.get("star", 0))
# Sync to LobbyManager
LobbyManager.set_player_name(display_name)
_setup_3d_preview()
# =============================================================================
# Player Slot Updates