using System;
using UnityEngine;
using UnityEngine.UI;
using Vanguard.App;
using Vanguard.State;
namespace Vanguard.UI
{
///
/// Верхняя панель игрока, общая для Lobby и DeckBuilder: аватар-инициалы,
/// ник, MMR, сезон, Rating/Community и гамбургер-меню.
///
public sealed class PlayerTopBar : IDisposable
{
public const string RootName = "PlayerTopBar";
private const float Margin = 24f;
private const float Height = 96f;
private static readonly Color Border = new Color(0.18f, 0.49f, 1f, 0.55f);
private static readonly Color BorderStrong = new Color(0.34f, 0.72f, 1f, 0.9f);
private static readonly Color TextPrimary = new Color(0.88f, 0.93f, 1f);
private static readonly Color TextMuted = new Color(0.58f, 0.69f, 0.88f);
private static readonly Color TextDim = new Color(0.44f, 0.55f, 0.75f);
private static readonly Color Accent = new Color(0.37f, 0.69f, 1f);
private readonly PlayerState _player;
private readonly HamburgerMenu _menu;
private Text _avatar;
private Text _playerName;
private Text _mmr;
private bool _disposed;
public PlayerTopBar(
Transform parent,
AppConfig config,
PlayerState player,
Action onLoggedOut,
Action onHistory,
Action onRating,
Action onCommunity,
Action onLobby = null)
{
_player = player;
var top = Surface(parent, RootName, new Color(0.012f, 0.03f, 0.08f, 0.94f), 0);
top.anchorMin = new Vector2(0f, 1f);
top.anchorMax = new Vector2(1f, 1f);
top.pivot = new Vector2(0.5f, 1f);
top.offsetMin = new Vector2(Margin, -Height);
top.offsetMax = new Vector2(-Margin, 0f);
var avatarRect = Surface(
top,
"Avatar",
new Color(0.05f, 0.13f, 0.3f, 0.95f),
14);
avatarRect.anchorMin = new Vector2(0f, 0.5f);
avatarRect.anchorMax = new Vector2(0f, 0.5f);
avatarRect.pivot = new Vector2(0f, 0.5f);
avatarRect.sizeDelta = new Vector2(64f, 64f);
avatarRect.anchoredPosition = new Vector2(20f, 0f);
_avatar = UiKit.CreateText(avatarRect, "Initials", "?", 26, TextPrimary);
_avatar.fontStyle = FontStyle.Bold;
UiKit.Stretch(_avatar.rectTransform);
UiKit.MakeLiteral(_avatar);
_playerName = UiKit.CreateText(
top,
"PlayerName",
"…",
22,
TextPrimary,
TextAnchor.MiddleLeft);
_playerName.fontStyle = FontStyle.Bold;
var nameRect = _playerName.rectTransform;
nameRect.anchorMin = new Vector2(0f, 0.5f);
nameRect.anchorMax = new Vector2(0f, 0.5f);
nameRect.pivot = new Vector2(0f, 0.5f);
nameRect.sizeDelta = new Vector2(420f, 30f);
nameRect.anchoredPosition = new Vector2(104f, 14f);
UiKit.MakeLiteral(_playerName);
_mmr = UiKit.CreateText(
top,
"Mmr",
string.Empty,
14,
TextMuted,
TextAnchor.MiddleLeft);
var mmrRect = _mmr.rectTransform;
mmrRect.anchorMin = new Vector2(0f, 0.5f);
mmrRect.anchorMax = new Vector2(0f, 0.5f);
mmrRect.pivot = new Vector2(0f, 0.5f);
mmrRect.sizeDelta = new Vector2(460f, 22f);
mmrRect.anchoredPosition = new Vector2(104f, -16f);
UiKit.MakeLiteral(_mmr);
var season = UiKit.CreateText(
top,
"Season",
"Сезон — скоро",
14,
TextDim,
TextAnchor.MiddleCenter);
var seasonRect = season.rectTransform;
seasonRect.anchorMin = new Vector2(0.5f, 0.5f);
seasonRect.anchorMax = new Vector2(0.5f, 0.5f);
seasonRect.sizeDelta = new Vector2(280f, 30f);
seasonRect.anchoredPosition = Vector2.zero;
AddAction(top, "Rating", "Рейтинг", -312f, 180f, onRating, LobbyIcon.Chart);
AddAction(top, "Community", "Сообщество", -96f, 200f, onCommunity, LobbyIcon.Friends);
_menu = new HamburgerMenu(parent, config, onLoggedOut, onHistory, onLobby);
_player.Changed += UpdateTexts;
Loc.LanguageChanged += UpdateTexts;
UpdateTexts();
}
public bool IsMenuOpen => _menu != null && _menu.IsOpen;
public void CloseMenu()
{
if (_menu != null)
_menu.Close();
}
public void Dispose()
{
if (_disposed)
return;
_disposed = true;
_player.Changed -= UpdateTexts;
Loc.LanguageChanged -= UpdateTexts;
}
private void UpdateTexts()
{
if (_disposed)
return;
var name = string.IsNullOrEmpty(_player.UserName) ? "…" : _player.UserName;
_playerName.text = name;
_avatar.text = Initial(name);
_mmr.text = "MMR " + _player.RankedMmr
+ " · " + Loc.Translate("матчей") + " " + _player.Matches
+ " · " + Loc.Translate("побед") + " " + WinsPercent();
}
private string WinsPercent()
{
if (_player.Matches <= 0)
return "0%";
return Mathf.RoundToInt(_player.Wins * 100f / _player.Matches) + "%";
}
private static string Initial(string name)
{
foreach (var character in name)
{
if (char.IsLetterOrDigit(character))
return char.ToUpperInvariant(character).ToString();
}
return "?";
}
private static void AddAction(
RectTransform parent,
string name,
string label,
float rightOffset,
float width,
Action onClick,
Action icon)
{
var buttonRect = Surface(parent, name, new Color(0.035f, 0.09f, 0.21f, 0.85f), 12);
buttonRect.anchorMin = new Vector2(1f, 0.5f);
buttonRect.anchorMax = new Vector2(1f, 0.5f);
buttonRect.pivot = new Vector2(1f, 0.5f);
buttonRect.sizeDelta = new Vector2(width, 52f);
buttonRect.anchoredPosition = new Vector2(rightOffset, 0f);
var image = buttonRect.GetComponent();
image.raycastTarget = true;
var button = buttonRect.gameObject.AddComponent