186 lines
5.7 KiB
C#
186 lines
5.7 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 RectTransform Root => _root;
|
|
|
|
public void Build(Transform parent)
|
|
{
|
|
var prefabRoot = OverlayPrefabs.Instantiate("CardActionMenu", parent);
|
|
if (prefabRoot != null)
|
|
{
|
|
_root = prefabRoot;
|
|
_popup = (RectTransform)_root.Find("Popup");
|
|
WireBackdrop();
|
|
_root.gameObject.SetActive(false);
|
|
return;
|
|
}
|
|
|
|
_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;
|
|
|
|
_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);
|
|
|
|
WireBackdrop();
|
|
_root.gameObject.SetActive(false);
|
|
}
|
|
|
|
private void WireBackdrop()
|
|
{
|
|
if (_root == null)
|
|
return;
|
|
|
|
var image = _root.GetComponent<Image>();
|
|
if (image != null)
|
|
image.raycastTarget = true;
|
|
|
|
var backdrop = _root.GetComponent<Button>();
|
|
if (backdrop == null)
|
|
{
|
|
backdrop = _root.gameObject.AddComponent<Button>();
|
|
backdrop.targetGraphic = image;
|
|
}
|
|
|
|
backdrop.onClick.AddListener(Hide);
|
|
}
|
|
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
}
|