VanguardReMaster/client/Assets/Vanguard/Runtime/UI/Overlays/CardActionMenuView.cs

155 lines
4.8 KiB
C#

using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
namespace Vanguard.UI.Overlays
{
public sealed class CardActionMenuItem
{
public CardActionMenuItem(string label, Action action, bool enabled = true)
{
Label = label;
Action = action;
Enabled = enabled;
}
public string Label { get; }
public Action Action { get; }
public bool Enabled { get; }
}
/// <summary>Экранное контекстное меню над картой.</summary>
public sealed class CardActionMenuView
{
private RectTransform _root;
private RectTransform _popup;
private Action _onClose;
public bool IsVisible => _root != null && _root.gameObject.activeSelf;
public void Build(Transform parent)
{
_root = UiKit.CreatePanel(parent, "CardActionMenu", new Color(0f, 0f, 0f, 0.01f));
var image = _root.GetComponent<Image>();
image.raycastTarget = true;
var backdrop = _root.gameObject.AddComponent<Button>();
backdrop.targetGraphic = image;
backdrop.onClick.AddListener(Hide);
_popup = UiKit.CreatePanel(_root, "Popup", new Color(0.045f, 0.06f, 0.09f, 0.98f));
_popup.anchorMin = new Vector2(0f, 1f);
_popup.anchorMax = new Vector2(0f, 1f);
_popup.pivot = new Vector2(0f, 1f);
_popup.sizeDelta = new Vector2(250f, 380f);
UiKit.AddVerticalLayout(_popup, 8, 4);
_root.gameObject.SetActive(false);
}
public void Show(
Vector2 screenPosition,
string title,
IReadOnlyList<CardActionMenuItem> items,
Action onClose)
{
if (_root == null)
return;
_onClose = onClose;
ClearChildren(_popup);
var heading = UiKit.CreateText(
_popup,
"Title",
title,
15,
new Color(0.86f, 0.91f, 1f),
TextAnchor.MiddleLeft);
heading.fontStyle = FontStyle.Bold;
UiKit.MakeLiteral(heading);
UiKit.SetPreferredHeight(heading, 26f);
if (items == null || items.Count == 0)
{
var empty = UiKit.CreateText(
_popup,
"Empty",
"Нет доступных действий",
13,
new Color(0.62f, 0.68f, 0.82f));
UiKit.SetPreferredHeight(empty, 34f);
}
else
{
foreach (var item in items)
{
var button = UiKit.CreateButton(
_popup,
"Action_" + item.Label,
item.Label,
() =>
{
var action = item.Action;
Hide();
action?.Invoke();
},
14);
button.interactable = item.Enabled;
UiKit.SetPreferredHeight(button, 36f);
}
}
_root.SetAsLastSibling();
_root.gameObject.SetActive(true);
if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(
_root,
screenPosition,
null,
out var local))
{
return;
}
var rect = _root.rect;
var fromLeft = local.x + rect.width * 0.5f;
var fromTop = rect.height * 0.5f - local.y;
var x = Mathf.Clamp(
fromLeft + 18f,
8f,
Mathf.Max(8f, rect.width - 258f));
var y = Mathf.Clamp(
-fromTop - 18f,
-Mathf.Max(8f, rect.height - 388f),
-8f);
_popup.anchoredPosition = new Vector2(x, y);
}
public void Hide()
{
if (_root == null || !_root.gameObject.activeSelf)
return;
_root.gameObject.SetActive(false);
var callback = _onClose;
_onClose = null;
callback?.Invoke();
}
private static void ClearChildren(Transform parent)
{
for (var i = parent.childCount - 1; i >= 0; i--)
{
var child = parent.GetChild(i).gameObject;
child.SetActive(false);
if (Application.isPlaying)
UnityEngine.Object.Destroy(child);
else
UnityEngine.Object.DestroyImmediate(child);
}
}
}
}