Files
whale-town-front-v2/scenes/ui/PlayerHud.gd
2026-07-22 12:16:31 +08:00

608 lines
24 KiB
GDScript

extends Control
# ============================================================================
# PlayerHud.gd - 右上角玩家头像与快捷入口
# ============================================================================
# 展示当前玩家头像入口,以及地图/任务/背包/好友/设置入口。
# 好友入口只负责打开或收起右下角好友列表。
# ============================================================================
const HUD_MARGIN: Vector2 = Vector2(16, 16)
const SHORTCUT_BAR_SIZE: Vector2 = Vector2(476, 86)
const PLAYER_PROFILE_BUTTON_SIZE: Vector2 = Vector2(210, 78)
const PLAYER_AVATAR_SIZE: Vector2 = Vector2(58, 58)
const HUD_SEPARATION: int = 18
const HUD_TOTAL_WIDTH: float = SHORTCUT_BAR_SIZE.x + PLAYER_PROFILE_BUTTON_SIZE.x + HUD_SEPARATION
const TEXT_COLOR: Color = Color(0.188, 0.294, 0.424)
const MUTED_COLOR: Color = Color(0.560, 0.639, 0.733)
const ACCENT_COLOR: Color = Color(0.258824, 0.627451, 0.913725)
const WALLET_REFRESH_INTERVAL: float = 15.0
const HUD_SHORTCUT_ICON_SCRIPT: Script = preload("res://scenes/ui/HudShortcutIcon.gd")
var _usernameLabel: Label
var _walletLabel: Label
var _avatarLabel: Label
var _avatarPanel: PanelContainer
var _walletRefreshTimer: Timer
var _taskShortcutButton: Button
var _taskRewardBadge: Label
var _shortcutRow: HBoxContainer
var _adminShortcutButton: Button
var _currentUsername: String = "玩家"
var _walletBalance: int = 0
var _walletLoaded: bool = false
var _walletLoading: bool = false
func _ready() -> void:
mouse_filter = Control.MOUSE_FILTER_IGNORE
_build_ui()
_build_wallet_refresh_timer()
_subscribe_to_events()
_load_current_user()
_refresh_wallet()
call_deferred("_refresh_admin_shortcut")
func _exit_tree() -> void:
var eventSystem := _get_event_system()
if eventSystem != null:
eventSystem.call("disconnect_event", EventNames.CHAT_LOGIN_SUCCESS, _on_chat_login_success, self)
eventSystem.call("disconnect_event", EventNames.AUTH_LOGIN_SUCCESS, _on_auth_login_success, self)
eventSystem.call("disconnect_event", EventNames.AUTH_REGISTER_SUCCESS, _on_auth_register_success, self)
eventSystem.call("disconnect_event", EventNames.AUTH_LOGOUT, _on_auth_logout, self)
eventSystem.call("disconnect_event", EventNames.APPEARANCE_AVATAR_CHANGED, _on_appearance_avatar_changed, self)
eventSystem.call("disconnect_event", EventNames.MALL_PURCHASE_SUCCEEDED, _on_wallet_mutation_event, self)
eventSystem.call("disconnect_event", EventNames.CAFE_COMPANION_CHAT_TIME_PURCHASED, _on_wallet_mutation_event, self)
eventSystem.call("disconnect_event", EventNames.CAFE_COMPANION_EMPLOYMENT_RESIGNED, _on_wallet_mutation_event, self)
var playerStateManager := get_node_or_null("/root/PlayerStateManager")
if playerStateManager != null and playerStateManager.has_signal("wallet_changed"):
var walletCallback := Callable(self, "_on_player_wallet_changed")
if playerStateManager.is_connected("wallet_changed", walletCallback):
playerStateManager.disconnect("wallet_changed", walletCallback)
var authManager := get_node_or_null("/root/AuthManager")
if authManager != null and authManager.has_signal("auth_state_changed"):
var callback := Callable(self, "_on_auth_state_changed")
if authManager.is_connected("auth_state_changed", callback):
authManager.disconnect("auth_state_changed", callback)
var taskManager := get_node_or_null("/root/TaskManager")
if taskManager != null and taskManager.has_signal("board_changed"):
var taskCallback := Callable(self, "_on_task_board_changed")
if taskManager.is_connected("board_changed", taskCallback):
taskManager.disconnect("board_changed", taskCallback)
func _build_ui() -> void:
var rootRow := HBoxContainer.new()
rootRow.name = "HudRoot"
rootRow.set_anchors_preset(Control.PRESET_TOP_RIGHT)
rootRow.offset_left = -HUD_TOTAL_WIDTH - HUD_MARGIN.x
rootRow.offset_top = HUD_MARGIN.y
rootRow.offset_right = -HUD_MARGIN.x
rootRow.add_theme_constant_override("separation", HUD_SEPARATION)
add_child(rootRow)
rootRow.add_child(_build_shortcut_bar())
rootRow.add_child(_build_player_avatar_button())
func _build_shortcut_bar() -> PanelContainer:
var panel := PanelContainer.new()
panel.custom_minimum_size = SHORTCUT_BAR_SIZE
panel.mouse_filter = Control.MOUSE_FILTER_STOP
panel.add_theme_stylebox_override("panel", _create_panel_style(32))
var margin := MarginContainer.new()
margin.add_theme_constant_override("margin_left", 18)
margin.add_theme_constant_override("margin_top", 12)
margin.add_theme_constant_override("margin_right", 18)
margin.add_theme_constant_override("margin_bottom", 12)
panel.add_child(margin)
var row := HBoxContainer.new()
_shortcutRow = row
row.alignment = BoxContainer.ALIGNMENT_CENTER
row.add_theme_constant_override("separation", 8)
margin.add_child(row)
row.add_child(_create_shortcut_button("map", "地图", _on_map_pressed))
_taskShortcutButton = _create_shortcut_button("task", "任务", _on_task_pressed)
_taskShortcutButton.tooltip_text = "打开任务书"
_taskRewardBadge = Label.new()
_taskRewardBadge.mouse_filter = Control.MOUSE_FILTER_IGNORE
_taskRewardBadge.visible = false
_taskRewardBadge.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
_taskRewardBadge.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
_taskRewardBadge.add_theme_color_override("font_color", Color.WHITE)
_taskRewardBadge.add_theme_font_size_override("font_size", 12)
_taskRewardBadge.add_theme_stylebox_override("normal", _create_pill_style(Color(0.92, 0.30, 0.24), 12))
_taskRewardBadge.set_anchors_preset(Control.PRESET_TOP_RIGHT)
_taskRewardBadge.offset_left = -20
_taskRewardBadge.offset_top = 1
_taskRewardBadge.offset_right = 4
_taskRewardBadge.offset_bottom = 25
_taskRewardBadge.z_index = 1
_taskShortcutButton.add_child(_taskRewardBadge)
row.add_child(_taskShortcutButton)
row.add_child(_create_shortcut_button("backpack", "背包", _on_backpack_pressed))
row.add_child(_create_shortcut_button("friends", "好友", _on_friends_pressed))
row.add_child(_create_shortcut_button("activity", "通知", _on_notifications_pressed))
row.add_child(_create_shortcut_button("settings", "设置", _on_settings_pressed))
_refresh_admin_shortcut()
return panel
func _build_player_avatar_button() -> Button:
var button := Button.new()
button.custom_minimum_size = PLAYER_PROFILE_BUTTON_SIZE
button.tooltip_text = "角色设置"
button.focus_mode = Control.FOCUS_NONE
button.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND
button.text = ""
button.add_theme_stylebox_override("normal", _create_avatar_button_style(Color(1, 1, 1, 0.94), 39))
button.add_theme_stylebox_override("hover", _create_avatar_button_style(Color(0.918, 0.961, 0.992, 0.98), 39))
button.add_theme_stylebox_override("pressed", _create_avatar_button_style(Color(0.858, 0.925, 0.980, 1.0), 39))
button.add_theme_stylebox_override("focus", _create_empty_style())
button.pressed.connect(_on_avatar_pressed)
var margin := MarginContainer.new()
margin.mouse_filter = Control.MOUSE_FILTER_IGNORE
margin.set_anchors_preset(Control.PRESET_FULL_RECT)
margin.add_theme_constant_override("margin_left", 10)
margin.add_theme_constant_override("margin_top", 10)
margin.add_theme_constant_override("margin_right", 14)
margin.add_theme_constant_override("margin_bottom", 10)
button.add_child(margin)
var row := HBoxContainer.new()
row.mouse_filter = Control.MOUSE_FILTER_IGNORE
row.alignment = BoxContainer.ALIGNMENT_CENTER
row.add_theme_constant_override("separation", 10)
margin.add_child(row)
var avatar := PanelContainer.new()
_avatarPanel = avatar
avatar.custom_minimum_size = PLAYER_AVATAR_SIZE
avatar.mouse_filter = Control.MOUSE_FILTER_IGNORE
avatar.clip_contents = true
row.add_child(avatar)
_avatarLabel = Label.new()
_avatarLabel.mouse_filter = Control.MOUSE_FILTER_IGNORE
_avatarLabel.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
_avatarLabel.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
_avatarLabel.add_theme_color_override("font_color", Color.WHITE)
_avatarLabel.add_theme_font_size_override("font_size", 22)
avatar.add_child(_avatarLabel)
_apply_current_avatar()
_usernameLabel = Label.new()
_usernameLabel.mouse_filter = Control.MOUSE_FILTER_IGNORE
_usernameLabel.text = _currentUsername
_usernameLabel.custom_minimum_size = Vector2(96, 0)
_usernameLabel.size_flags_horizontal = Control.SIZE_EXPAND_FILL
_usernameLabel.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
_usernameLabel.text_overrun_behavior = TextServer.OVERRUN_TRIM_ELLIPSIS
_usernameLabel.add_theme_color_override("font_color", TEXT_COLOR)
_usernameLabel.add_theme_font_size_override("font_size", 18)
var info := VBoxContainer.new()
info.mouse_filter = Control.MOUSE_FILTER_IGNORE
info.size_flags_horizontal = Control.SIZE_EXPAND_FILL
info.alignment = BoxContainer.ALIGNMENT_CENTER
info.add_theme_constant_override("separation", 2)
row.add_child(info)
info.add_child(_usernameLabel)
_walletLabel = Label.new()
_walletLabel.mouse_filter = Control.MOUSE_FILTER_IGNORE
_walletLabel.text = "鲸币 --"
_walletLabel.custom_minimum_size = Vector2(112, 0)
_walletLabel.size_flags_horizontal = Control.SIZE_EXPAND_FILL
_walletLabel.text_overrun_behavior = TextServer.OVERRUN_TRIM_ELLIPSIS
_walletLabel.add_theme_color_override("font_color", ACCENT_COLOR)
_walletLabel.add_theme_font_size_override("font_size", 14)
info.add_child(_walletLabel)
return button
func _create_shortcut_button(iconName: String, text: String, callback: Callable) -> Button:
var button := Button.new()
button.custom_minimum_size = Vector2(56, 60)
button.focus_mode = Control.FOCUS_NONE
button.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND
button.text = ""
button.add_theme_stylebox_override("normal", _create_empty_style())
button.add_theme_stylebox_override("hover", _create_pill_style(Color(0.918, 0.961, 0.992, 0.86), 18))
button.add_theme_stylebox_override("pressed", _create_pill_style(Color(0.858, 0.925, 0.980, 0.98), 18))
button.add_theme_stylebox_override("focus", _create_empty_style())
button.pressed.connect(callback)
var content := VBoxContainer.new()
content.mouse_filter = Control.MOUSE_FILTER_IGNORE
content.set_anchors_preset(Control.PRESET_FULL_RECT)
content.alignment = BoxContainer.ALIGNMENT_CENTER
content.add_theme_constant_override("separation", 1)
button.add_child(content)
var icon := HUD_SHORTCUT_ICON_SCRIPT.new() as Control
icon.set("iconName", iconName)
icon.custom_minimum_size = Vector2(31, 31)
content.add_child(icon)
var label := Label.new()
label.mouse_filter = Control.MOUSE_FILTER_IGNORE
label.text = text
label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
label.add_theme_color_override("font_color", MUTED_COLOR)
label.add_theme_font_size_override("font_size", 14)
content.add_child(label)
button.mouse_entered.connect(func() -> void:
if is_instance_valid(label):
label.add_theme_color_override("font_color", ACCENT_COLOR)
)
button.mouse_exited.connect(func() -> void:
if is_instance_valid(label):
label.add_theme_color_override("font_color", MUTED_COLOR)
)
return button
func _subscribe_to_events() -> void:
var eventSystem := _get_event_system()
if eventSystem == null:
push_warning("PlayerHud: EventSystem autoload is not available.")
return
eventSystem.call("connect_event", EventNames.CHAT_LOGIN_SUCCESS, _on_chat_login_success, self)
eventSystem.call("connect_event", EventNames.AUTH_LOGIN_SUCCESS, _on_auth_login_success, self)
eventSystem.call("connect_event", EventNames.AUTH_REGISTER_SUCCESS, _on_auth_register_success, self)
eventSystem.call("connect_event", EventNames.AUTH_LOGOUT, _on_auth_logout, self)
eventSystem.call("connect_event", EventNames.APPEARANCE_AVATAR_CHANGED, _on_appearance_avatar_changed, self)
eventSystem.call("connect_event", EventNames.MALL_PURCHASE_SUCCEEDED, _on_wallet_mutation_event, self)
eventSystem.call("connect_event", EventNames.CAFE_COMPANION_CHAT_TIME_PURCHASED, _on_wallet_mutation_event, self)
eventSystem.call("connect_event", EventNames.CAFE_COMPANION_EMPLOYMENT_RESIGNED, _on_wallet_mutation_event, self)
var playerStateManager := get_node_or_null("/root/PlayerStateManager")
if playerStateManager != null and playerStateManager.has_signal("wallet_changed"):
var walletCallback := Callable(self, "_on_player_wallet_changed")
if not playerStateManager.is_connected("wallet_changed", walletCallback):
playerStateManager.connect("wallet_changed", walletCallback)
var authManager := get_node_or_null("/root/AuthManager")
if authManager != null and authManager.has_signal("auth_state_changed"):
var callback := Callable(self, "_on_auth_state_changed")
if not authManager.is_connected("auth_state_changed", callback):
authManager.connect("auth_state_changed", callback)
var taskManager := get_node_or_null("/root/TaskManager")
if taskManager != null and taskManager.has_signal("board_changed"):
var taskCallback := Callable(self, "_on_task_board_changed")
if not taskManager.is_connected("board_changed", taskCallback):
taskManager.connect("board_changed", taskCallback)
if taskManager.has_method("get_board"):
var boardVariant: Variant = taskManager.call("get_board")
if boardVariant is Dictionary:
_on_task_board_changed(boardVariant as Dictionary)
func _load_current_user() -> void:
var authManager := get_node_or_null("/root/AuthManager")
if authManager != null and authManager.has_method("get_current_username"):
var username := str(authManager.call("get_current_username")).strip_edges()
if not username.is_empty():
_set_username(username)
func _on_chat_login_success(data: Dictionary) -> void:
var username := str(data.get("username", "")).strip_edges()
if not username.is_empty():
_set_username(username)
func _on_auth_login_success(data: Dictionary) -> void:
_apply_auth_user_payload(data)
func _on_auth_register_success(data: Dictionary) -> void:
_apply_auth_user_payload(data)
func _on_auth_state_changed(isAuthenticated: bool, user: Dictionary) -> void:
if not isAuthenticated:
_set_username("玩家")
_reset_wallet()
_refresh_admin_shortcut()
return
_apply_auth_user_payload({"user": user})
_refresh_wallet()
_refresh_admin_shortcut()
func _apply_auth_user_payload(data: Dictionary) -> void:
var userVariant: Variant = data.get("user", {})
if userVariant is Dictionary:
var username := str((userVariant as Dictionary).get("username", "")).strip_edges()
if not username.is_empty():
_set_username(username)
_refresh_admin_shortcut()
func _on_auth_logout(_data: Variant = null) -> void:
_set_username("玩家")
_reset_wallet()
_on_task_board_changed({})
_refresh_admin_shortcut()
func _on_task_board_changed(board: Dictionary) -> void:
if not is_instance_valid(_taskShortcutButton):
return
var claimableCount: int = _count_claimable_task_rewards(board)
if claimableCount > 0:
_taskShortcutButton.tooltip_text = "任务书:有 %d 项奖励可领取" % claimableCount
_taskShortcutButton.modulate = Color(1.0, 0.855, 0.470, 1.0)
if is_instance_valid(_taskRewardBadge):
_taskRewardBadge.text = str(mini(claimableCount, 9)) if claimableCount < 10 else "9+"
_taskRewardBadge.visible = true
return
_taskShortcutButton.tooltip_text = "打开任务书"
_taskShortcutButton.modulate = Color.WHITE
if is_instance_valid(_taskRewardBadge):
_taskRewardBadge.visible = false
func _count_claimable_task_rewards(board: Dictionary) -> int:
var claimableCount: int = 0
claimableCount += _count_claimable_tasks(board.get("newbie_tasks", []))
claimableCount += _count_claimable_tasks(board.get("weekly_tasks", []))
var weeklyBonusVariant: Variant = board.get("weekly_bonus", {})
if weeklyBonusVariant is Dictionary:
var weeklyBonus: Dictionary = weeklyBonusVariant as Dictionary
if bool(weeklyBonus.get("claimable", false)):
claimableCount += 1
return claimableCount
func _count_claimable_tasks(tasksVariant: Variant) -> int:
if not (tasksVariant is Array):
return 0
var claimableCount: int = 0
for taskVariant: Variant in tasksVariant as Array:
if taskVariant is Dictionary:
var task: Dictionary = taskVariant as Dictionary
if bool(task.get("claimable", false)):
claimableCount += 1
return claimableCount
func _on_appearance_avatar_changed(_data: Dictionary) -> void:
_apply_current_avatar()
func _set_username(username: String) -> void:
_currentUsername = username.strip_edges()
if _currentUsername.is_empty():
_currentUsername = "玩家"
if is_instance_valid(_usernameLabel):
_usernameLabel.text = _currentUsername
_apply_current_avatar()
func _on_wallet_mutation_event(data: Dictionary) -> void:
var balanceVariant: Variant = data.get("balance", null)
if balanceVariant != null and (balanceVariant is int or balanceVariant is float):
_apply_wallet_balance(int(balanceVariant))
return
_refresh_wallet()
func _build_wallet_refresh_timer() -> void:
_walletRefreshTimer = Timer.new()
_walletRefreshTimer.name = "HudWalletRefreshTimer"
_walletRefreshTimer.wait_time = WALLET_REFRESH_INTERVAL
_walletRefreshTimer.autostart = true
_walletRefreshTimer.timeout.connect(_on_wallet_refresh_timer_timeout)
add_child(_walletRefreshTimer)
func _on_wallet_refresh_timer_timeout() -> void:
_refresh_wallet()
func _refresh_wallet() -> void:
if not _is_wallet_available():
_reset_wallet()
return
var playerStateManager := get_node_or_null("/root/PlayerStateManager")
if playerStateManager == null:
_reset_wallet()
return
if playerStateManager.has_method("get_wallet"):
var walletVariant: Variant = playerStateManager.call("get_wallet")
if walletVariant is Dictionary and not (walletVariant as Dictionary).is_empty():
_on_player_wallet_changed(walletVariant as Dictionary)
return
if _walletLoading:
return
_walletLoading = true
_update_wallet_label()
if playerStateManager.has_method("refresh_snapshot"):
playerStateManager.call("refresh_snapshot")
func _on_player_wallet_changed(wallet: Dictionary) -> void:
if wallet.is_empty():
_reset_wallet()
return
_apply_wallet_balance(int(wallet.get("balance", 0)))
func _apply_wallet_balance(balance: int) -> void:
_walletBalance = max(0, balance)
_walletLoaded = true
_walletLoading = false
_update_wallet_label()
func _reset_wallet() -> void:
_walletBalance = 0
_walletLoaded = false
_walletLoading = false
_update_wallet_label()
func _update_wallet_label(overrideText: String = "") -> void:
if not is_instance_valid(_walletLabel):
return
if not overrideText.is_empty():
_walletLabel.text = "鲸币 %s" % overrideText
_walletLabel.tooltip_text = "鲸币余额"
return
if _walletLoading:
_walletLabel.text = "鲸币 读取中"
elif _walletLoaded:
_walletLabel.text = "鲸币 %s" % _format_number(_walletBalance)
else:
_walletLabel.text = "鲸币 --"
_walletLabel.tooltip_text = "鲸币余额"
func _format_number(value: int) -> String:
var text := str(value)
var result := ""
var count := 0
for i in range(text.length() - 1, -1, -1):
if count > 0 and count % 3 == 0:
result = "," + result
result = text[i] + result
count += 1
return result
func _is_wallet_available() -> bool:
var authManager := get_node_or_null("/root/AuthManager")
return authManager != null and authManager.has_method("is_authenticated") and bool(authManager.call("is_authenticated")) and authManager.has_method("get_access_token")
func _on_map_pressed() -> void:
var eventSystem := _get_event_system()
if eventSystem != null:
eventSystem.call("emit_event", EventNames.HUD_MAP_TOGGLE, {})
func _on_notifications_pressed() -> void:
var socialManager := get_node_or_null("/root/SocialManager")
if socialManager != null and socialManager.has_method("toggle_notifications"):
socialManager.call("toggle_notifications")
func _on_task_pressed() -> void:
var eventSystem := _get_event_system()
if eventSystem != null:
eventSystem.call("emit_event", EventNames.HUD_TASK_BOOK_REQUESTED, {})
func _on_backpack_pressed() -> void:
var eventSystem := _get_event_system()
if eventSystem != null:
eventSystem.call("emit_event", EventNames.HUD_BACKPACK_TOGGLE, {})
func _on_friends_pressed() -> void:
var eventSystem := _get_event_system()
if eventSystem != null:
eventSystem.call("emit_event", EventNames.HUD_FRIEND_LIST_TOGGLE, {})
func _on_settings_pressed() -> void:
var eventSystem := _get_event_system()
if eventSystem != null:
eventSystem.call("emit_event", EventNames.HUD_SETTINGS_REQUESTED, {})
func _on_avatar_pressed() -> void:
var eventSystem := _get_event_system()
if eventSystem != null:
eventSystem.call("emit_event", EventNames.HUD_SETTINGS_REQUESTED, {})
func _on_admin_test_lab_pressed() -> void:
var eventSystem := _get_event_system()
if eventSystem != null:
eventSystem.call("emit_event", EventNames.HUD_ADMIN_TEST_LAB_REQUESTED, {})
func _refresh_admin_shortcut() -> void:
if not is_instance_valid(_shortcutRow):
return
var shouldShow: bool = _is_current_user_admin()
if shouldShow and not is_instance_valid(_adminShortcutButton):
_adminShortcutButton = _create_shortcut_button("admin", "管理", _on_admin_test_lab_pressed)
_adminShortcutButton.tooltip_text = "管理员测试实验室"
_shortcutRow.add_child(_adminShortcutButton)
elif not shouldShow and is_instance_valid(_adminShortcutButton):
_adminShortcutButton.queue_free()
_adminShortcutButton = null
func _is_current_user_admin() -> bool:
var authManager := get_node_or_null("/root/AuthManager")
if authManager == null or not authManager.has_method("is_authenticated") or not bool(authManager.call("is_authenticated")):
return false
if not authManager.has_method("get_current_user"):
return false
var userVariant: Variant = authManager.call("get_current_user")
if not (userVariant is Dictionary):
return false
var user: Dictionary = userVariant as Dictionary
return int(user.get("role", 0)) == 9
func _emit_status_message(message: String) -> void:
var eventSystem := _get_event_system()
if eventSystem != null:
eventSystem.call("emit_event", EventNames.CHAT_MESSAGE_RECEIVED, {
"from_user": "系统",
"content": message,
"timestamp": Time.get_unix_time_from_system(),
"is_self": false,
"scope": "system",
"tab": "world"
})
func _create_panel_style(radius: int) -> StyleBoxFlat:
var style := StyleBoxFlat.new()
style.bg_color = Color(1, 1, 1, 0.925)
style.corner_radius_top_left = radius
style.corner_radius_top_right = radius
style.corner_radius_bottom_left = radius
style.corner_radius_bottom_right = radius
style.shadow_color = Color(0.12549, 0.282353, 0.407843, 0.15)
style.shadow_size = 18
style.shadow_offset = Vector2(0, 7)
return style
func _create_avatar_style() -> StyleBoxFlat:
var style := StyleBoxFlat.new()
style.bg_color = Color(0.361, 0.690, 0.914)
style.corner_radius_top_left = 32
style.corner_radius_top_right = 32
style.corner_radius_bottom_left = 32
style.corner_radius_bottom_right = 32
return style
func _apply_current_avatar() -> void:
if not is_instance_valid(_avatarPanel) or not is_instance_valid(_avatarLabel):
return
var appearanceManager := get_node_or_null("/root/AppearanceManager")
if appearanceManager != null and appearanceManager.has_method("apply_avatar_to_panel"):
appearanceManager.call("apply_avatar_to_panel", _avatarPanel, _avatarLabel, "", _currentUsername)
_avatarPanel.add_theme_stylebox_override("panel", _create_round_avatar_style(_avatarPanel))
return
_avatarPanel.add_theme_stylebox_override("panel", _create_avatar_style())
_avatarLabel.visible = true
_avatarLabel.text = _currentUsername.substr(0, 1).to_upper()
func _create_avatar_button_style(color: Color, radius: int) -> StyleBoxFlat:
var style := _create_pill_style(color, radius)
style.shadow_color = Color(0.12549, 0.282353, 0.407843, 0.14)
style.shadow_size = 16
style.shadow_offset = Vector2(0, 6)
return style
func _create_round_avatar_style(panel: PanelContainer) -> StyleBoxFlat:
var style := StyleBoxFlat.new()
style.bg_color = Color(0.361, 0.690, 0.914)
var radius := int(round(minf(panel.custom_minimum_size.x, panel.custom_minimum_size.y) * 0.5))
style.corner_radius_top_left = radius
style.corner_radius_top_right = radius
style.corner_radius_bottom_left = radius
style.corner_radius_bottom_right = radius
style.border_width_left = 2
style.border_width_top = 2
style.border_width_right = 2
style.border_width_bottom = 2
style.border_color = Color(1, 1, 1, 0.78)
return style
func _create_pill_style(color: Color, radius: int) -> StyleBoxFlat:
var style := StyleBoxFlat.new()
style.bg_color = color
style.corner_radius_top_left = radius
style.corner_radius_top_right = radius
style.corner_radius_bottom_left = radius
style.corner_radius_bottom_right = radius
style.content_margin_left = 8
style.content_margin_right = 8
style.content_margin_top = 5
style.content_margin_bottom = 5
return style
func _create_empty_style() -> StyleBoxEmpty:
return StyleBoxEmpty.new()
func _get_event_system() -> Node:
return get_node_or_null("/root/EventSystem")