278 lines
9.9 KiB
C#
278 lines
9.9 KiB
C#
using System;
|
||
using UnityEngine;
|
||
using UnityEngine.UI;
|
||
using Vanguard.App;
|
||
|
||
namespace Vanguard.UI
|
||
{
|
||
/// <summary>
|
||
/// Гамбургер-меню экрана: язык, версия и адрес сервера. В Lobby добавляется
|
||
/// «Выйти». Закрывается кнопкой, кликом вне панели и по Esc (через драйвер
|
||
/// экрана).
|
||
/// </summary>
|
||
public sealed class HamburgerMenu
|
||
{
|
||
private readonly GameObject _blocker;
|
||
private readonly RectTransform _panel;
|
||
private readonly Action _onLogout;
|
||
private readonly Action _onHistory;
|
||
private readonly Action _onLobby;
|
||
|
||
public HamburgerMenu(
|
||
Transform parent,
|
||
AppConfig config,
|
||
Action onLogout = null,
|
||
Action onHistory = null,
|
||
Action onLobby = null,
|
||
string title = "Меню",
|
||
Transform overlayParent = null)
|
||
{
|
||
_onLogout = onLogout;
|
||
_onHistory = onHistory;
|
||
_onLobby = onLobby;
|
||
var overlayRoot = overlayParent != null ? overlayParent : parent;
|
||
|
||
_blocker = new GameObject(
|
||
"MenuBlocker",
|
||
typeof(RectTransform),
|
||
typeof(Image),
|
||
typeof(Button));
|
||
var blockerRect = (RectTransform)_blocker.transform;
|
||
blockerRect.SetParent(overlayRoot, false);
|
||
UiKit.Stretch(blockerRect);
|
||
|
||
var blockerImage = _blocker.GetComponent<Image>();
|
||
blockerImage.color = new Color(0f, 0f, 0f, 0.001f);
|
||
blockerImage.raycastTarget = true;
|
||
|
||
var blockerButton = _blocker.GetComponent<Button>();
|
||
blockerButton.transition = Selectable.Transition.None;
|
||
blockerButton.onClick.AddListener(Close);
|
||
_blocker.SetActive(false);
|
||
|
||
var burger = NeonUi.AddAnchored(
|
||
parent,
|
||
"MenuButton",
|
||
NeonUi.Body(
|
||
56,
|
||
56,
|
||
12,
|
||
new Color(0.027f, 0.066f, 0.17f, 0.92f),
|
||
new Color(0.18f, 0.49f, 1f, 0.85f),
|
||
1),
|
||
new Vector2(56f, 56f),
|
||
new Vector2(1f, 1f),
|
||
new Vector2(1f, 1f),
|
||
new Vector2(-28f, -28f));
|
||
|
||
var burgerImage = burger.GetComponent<Image>();
|
||
burgerImage.raycastTarget = true;
|
||
|
||
var burgerButton = burger.gameObject.AddComponent<Button>();
|
||
burgerButton.targetGraphic = burgerImage;
|
||
burgerButton.transition = Selectable.Transition.ColorTint;
|
||
burgerButton.colors = new ColorBlock
|
||
{
|
||
normalColor = Color.white,
|
||
highlightedColor = new Color(1.15f, 1.15f, 1.15f, 1f),
|
||
pressedColor = new Color(0.9f, 0.9f, 0.9f, 1f),
|
||
selectedColor = Color.white,
|
||
disabledColor = new Color(0.6f, 0.6f, 0.6f, 0.5f),
|
||
colorMultiplier = 1f,
|
||
fadeDuration = 0.08f,
|
||
};
|
||
burgerButton.onClick.AddListener(Toggle);
|
||
|
||
var barColor = new Color(0.75f, 0.88f, 1f, 0.95f);
|
||
for (var i = -1; i <= 1; i++)
|
||
{
|
||
NeonUi.AddImage(
|
||
burger,
|
||
"Bar" + i,
|
||
NeonUi.HorizontalBar(22, 2, barColor),
|
||
new Vector2(22f, 2f),
|
||
new Vector2(0f, i * 7f));
|
||
}
|
||
|
||
var height = 300f
|
||
+ (onLogout != null ? 56f : 0f)
|
||
+ (onHistory != null ? 46f : 0f)
|
||
+ (onLobby != null ? 46f : 0f);
|
||
var panelGo = new GameObject("MenuPanel", typeof(RectTransform), typeof(Image));
|
||
_panel = (RectTransform)panelGo.transform;
|
||
_panel.SetParent(overlayRoot, false);
|
||
_panel.anchorMin = new Vector2(1f, 1f);
|
||
_panel.anchorMax = new Vector2(1f, 1f);
|
||
_panel.pivot = new Vector2(1f, 1f);
|
||
_panel.anchoredPosition = new Vector2(-28f, -96f);
|
||
_panel.sizeDelta = new Vector2(340f, height);
|
||
|
||
var panelImage = panelGo.GetComponent<Image>();
|
||
panelImage.sprite = NeonUi.Body(
|
||
340,
|
||
Mathf.RoundToInt(height),
|
||
16,
|
||
new Color(0.027f, 0.066f, 0.17f, 0.96f),
|
||
new Color(0.18f, 0.49f, 1f, 0.85f),
|
||
1);
|
||
panelImage.type = Image.Type.Simple;
|
||
panelImage.raycastTarget = true;
|
||
|
||
BuildContent(config, title);
|
||
_panel.gameObject.SetActive(false);
|
||
}
|
||
|
||
public bool IsOpen => _panel != null && _panel.gameObject.activeSelf;
|
||
|
||
public void Toggle()
|
||
{
|
||
if (IsOpen)
|
||
Close();
|
||
else
|
||
Open();
|
||
}
|
||
|
||
public void Open()
|
||
{
|
||
_blocker.SetActive(true);
|
||
_blocker.transform.SetAsLastSibling();
|
||
_panel.gameObject.SetActive(true);
|
||
_panel.SetAsLastSibling();
|
||
}
|
||
|
||
public void Close()
|
||
{
|
||
_panel.gameObject.SetActive(false);
|
||
_blocker.SetActive(false);
|
||
}
|
||
|
||
private void BuildContent(AppConfig config, string title)
|
||
{
|
||
UiKit.AddVerticalLayout(_panel, 16, 10);
|
||
|
||
var header = UiKit.CreateText(
|
||
_panel,
|
||
"Title",
|
||
title,
|
||
18,
|
||
new Color(0.82f, 0.9f, 1f),
|
||
TextAnchor.MiddleLeft);
|
||
UiKit.SetPreferredHeight(header, 24f);
|
||
|
||
var row = new GameObject("LanguageRow", typeof(RectTransform));
|
||
row.transform.SetParent(_panel, false);
|
||
UiKit.SetPreferredHeight(row.transform, 36f);
|
||
|
||
var languageLabel = UiKit.CreateText(
|
||
row.transform,
|
||
"Label",
|
||
"Язык",
|
||
15,
|
||
new Color(0.66f, 0.76f, 0.9f),
|
||
TextAnchor.MiddleLeft);
|
||
var labelRect = languageLabel.rectTransform;
|
||
labelRect.anchorMin = new Vector2(0f, 0f);
|
||
labelRect.anchorMax = new Vector2(0.6f, 1f);
|
||
labelRect.offsetMin = Vector2.zero;
|
||
labelRect.offsetMax = Vector2.zero;
|
||
|
||
var language = UiKit.CreateLanguageButton(row.transform, "Language");
|
||
var languageRect = language.GetComponent<RectTransform>();
|
||
languageRect.anchorMin = new Vector2(1f, 0.5f);
|
||
languageRect.anchorMax = new Vector2(1f, 0.5f);
|
||
languageRect.pivot = new Vector2(1f, 0.5f);
|
||
languageRect.sizeDelta = new Vector2(64f, 32f);
|
||
languageRect.anchoredPosition = Vector2.zero;
|
||
|
||
var version = UiKit.CreateText(
|
||
_panel,
|
||
"Version",
|
||
"Версия " + Application.version,
|
||
13,
|
||
new Color(0.52f, 0.62f, 0.78f),
|
||
TextAnchor.MiddleLeft);
|
||
UiKit.SetPreferredHeight(version, 18f);
|
||
UiKit.MakeLiteral(version);
|
||
|
||
var caption = UiKit.CreateText(
|
||
_panel,
|
||
"ServerCaption",
|
||
"Адрес сервера",
|
||
13,
|
||
new Color(0.52f, 0.62f, 0.78f),
|
||
TextAnchor.MiddleLeft);
|
||
UiKit.SetPreferredHeight(caption, 16f);
|
||
|
||
var server = UiKit.CreateInput(_panel, "ServerUrl", "http://host:port");
|
||
UiKit.SetPreferredHeight(server, 42f);
|
||
server.text = config.ServerBaseUrl;
|
||
UiKit.MakeLiteral(server.textComponent);
|
||
server.onEndEdit.AddListener(value =>
|
||
{
|
||
config.SetServerBaseUrl(value);
|
||
server.text = config.ServerBaseUrl;
|
||
});
|
||
|
||
if (_onLobby != null)
|
||
{
|
||
var lobby = UiKit.CreateButton(
|
||
_panel,
|
||
"Lobby",
|
||
"В лобби",
|
||
() =>
|
||
{
|
||
Close();
|
||
_onLobby();
|
||
},
|
||
15);
|
||
var lobbyImage = lobby.GetComponent<Image>();
|
||
if (lobbyImage != null)
|
||
lobbyImage.color = new Color(0.06f, 0.12f, 0.24f, 0.95f);
|
||
UiKit.SetPreferredHeight(lobby, 36f);
|
||
}
|
||
|
||
if (_onHistory != null)
|
||
{
|
||
var history = UiKit.CreateButton(
|
||
_panel,
|
||
"History",
|
||
"История матчей",
|
||
() =>
|
||
{
|
||
Close();
|
||
_onHistory();
|
||
},
|
||
15);
|
||
var historyImage = history.GetComponent<Image>();
|
||
if (historyImage != null)
|
||
historyImage.color = new Color(0.06f, 0.12f, 0.24f, 0.95f);
|
||
UiKit.SetPreferredHeight(history, 36f);
|
||
}
|
||
|
||
if (_onLogout != null)
|
||
{
|
||
var logout = UiKit.CreateButton(
|
||
_panel,
|
||
"Logout",
|
||
"Выйти",
|
||
() =>
|
||
{
|
||
Close();
|
||
_onLogout();
|
||
},
|
||
15);
|
||
var logoutImage = logout.GetComponent<Image>();
|
||
if (logoutImage != null)
|
||
logoutImage.color = new Color(0.36f, 0.09f, 0.12f, 0.95f);
|
||
UiKit.SetPreferredHeight(logout, 36f);
|
||
}
|
||
|
||
var close = UiKit.CreateButton(_panel, "Close", "Закрыть", Close, 15);
|
||
var closeImage = close.GetComponent<Image>();
|
||
if (closeImage != null)
|
||
closeImage.color = new Color(0.06f, 0.12f, 0.24f, 0.95f);
|
||
UiKit.SetPreferredHeight(close, 36f);
|
||
}
|
||
}
|
||
}
|