218 lines
7.8 KiB
C#
218 lines
7.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
using Vanguard.Api.Contracts;
|
|
using Vanguard.Shared.Protocol;
|
|
|
|
namespace Vanguard.UI.Overlays
|
|
{
|
|
/// <summary>
|
|
/// Единый горизонтальный список карт для Deck/Drop/Soul/Damage/Trigger/Hand.
|
|
/// Порядок задаёт адаптер: первой идёт карта, лежащая сверху зоны.
|
|
/// </summary>
|
|
public sealed class CardListView
|
|
{
|
|
private readonly RectTransform _root;
|
|
private readonly RectTransform _content;
|
|
private readonly Text _title;
|
|
private readonly Func<string, CardCatalogItemDto> _catalog;
|
|
private Action<CardListEntry> _onEntry;
|
|
private Action _onClose;
|
|
|
|
public CardListView(
|
|
Transform parent,
|
|
Func<string, CardCatalogItemDto> catalog)
|
|
{
|
|
_catalog = catalog;
|
|
|
|
var prefabRoot = OverlayPrefabs.Instantiate("CardListView", parent);
|
|
if (prefabRoot != null)
|
|
{
|
|
_root = prefabRoot;
|
|
_title = _root.Find("CardListPanel/Header/Title").GetComponent<Text>();
|
|
_content = (RectTransform)_root.Find(
|
|
"CardListPanel/CardScroll/Viewport/Content");
|
|
WireClose(_root.Find("CardListPanel/Header/Close").GetComponent<Button>());
|
|
_root.gameObject.SetActive(false);
|
|
return;
|
|
}
|
|
|
|
_root = UiKit.CreatePanel(parent, "CardListView", new Color(0f, 0f, 0f, 0.78f));
|
|
var panel = UiKit.CreateCenteredCard(
|
|
_root,
|
|
"CardListPanel",
|
|
new Vector2(980f, 560f),
|
|
new Color(0.045f, 0.06f, 0.09f, 1f));
|
|
UiKit.AddVerticalLayout(panel, 16, 10);
|
|
|
|
var header = UiKit.CreatePanel(panel, "Header", Color.clear);
|
|
UiKit.AddHorizontalLayout(header, 0, 10);
|
|
UiKit.SetPreferredHeight(header, 44f);
|
|
|
|
_title = UiKit.CreateText(
|
|
header,
|
|
"Title",
|
|
"Карты",
|
|
24,
|
|
Color.white,
|
|
TextAnchor.MiddleLeft);
|
|
_title.fontStyle = FontStyle.Bold;
|
|
UiKit.SetPreferredHeight(_title, 44f);
|
|
|
|
var close = UiKit.CreateButton(header, "Close", "Закрыть", null, 16);
|
|
var closeElement = UiKit.SetPreferredHeight(close, 40f, 0f);
|
|
closeElement.preferredWidth = 120f;
|
|
WireClose(close);
|
|
|
|
var scroll = UiKit.CreateHorizontalScrollView(panel, "CardScroll", out _content, 10f);
|
|
var scrollElement = scroll.gameObject.AddComponent<LayoutElement>();
|
|
scrollElement.flexibleHeight = 1f;
|
|
scrollElement.minHeight = 400f;
|
|
|
|
_root.gameObject.SetActive(false);
|
|
}
|
|
|
|
public RectTransform Root => _root;
|
|
|
|
private void WireClose(Button close)
|
|
{
|
|
if (close != null)
|
|
close.onClick.AddListener(() => _onClose?.Invoke());
|
|
}
|
|
|
|
public bool IsVisible => _root.gameObject.activeSelf;
|
|
|
|
public void Show(
|
|
CardListRequest request,
|
|
Action<CardListEntry> onEntry,
|
|
Action onClose)
|
|
{
|
|
_onEntry = onEntry;
|
|
_onClose = onClose;
|
|
_title.text = request.Title;
|
|
ClearChildren(_content);
|
|
|
|
if (request.Entries.Count == 0)
|
|
{
|
|
var empty = UiKit.CreateText(
|
|
_content,
|
|
"Empty",
|
|
request.EmptyText,
|
|
17,
|
|
new Color(0.62f, 0.68f, 0.82f));
|
|
UiKit.SetPreferredHeight(empty, 80f);
|
|
}
|
|
else
|
|
{
|
|
foreach (var entry in request.Entries)
|
|
AddTile(entry);
|
|
}
|
|
|
|
_root.SetAsLastSibling();
|
|
_root.gameObject.SetActive(true);
|
|
}
|
|
|
|
public void Hide()
|
|
{
|
|
_root.gameObject.SetActive(false);
|
|
}
|
|
|
|
private void AddTile(CardListEntry entry)
|
|
{
|
|
var tile = UiKit.CreatePanel(
|
|
_content,
|
|
"Card_" + (entry.Card != null ? entry.Card.InstanceId.ToString() : "hidden"),
|
|
Color.white);
|
|
var layout = tile.gameObject.AddComponent<LayoutElement>();
|
|
layout.preferredWidth = 126f;
|
|
layout.preferredHeight = 178f;
|
|
layout.flexibleWidth = 0f;
|
|
|
|
var image = tile.GetComponent<Image>();
|
|
image.raycastTarget = true;
|
|
|
|
var meta = entry.Card != null
|
|
? _catalog?.Invoke(entry.Card.PrintingId)
|
|
: null;
|
|
|
|
if (entry.Hidden)
|
|
{
|
|
image.sprite = CardArt.Back;
|
|
image.color = Color.white;
|
|
}
|
|
else
|
|
{
|
|
CardImageService.Apply(
|
|
image,
|
|
meta != null ? meta.ImageKey : null,
|
|
CardArt.ForCard(
|
|
meta != null ? meta.NameId : entry.Card.PrintingId,
|
|
meta != null ? meta.Clan : "None"));
|
|
}
|
|
|
|
var shade = UiKit.CreatePanel(tile, "Shade", new Color(0f, 0f, 0f, 0.76f));
|
|
shade.anchorMin = new Vector2(0f, 0f);
|
|
shade.anchorMax = new Vector2(1f, 0f);
|
|
shade.pivot = new Vector2(0.5f, 0f);
|
|
shade.anchoredPosition = Vector2.zero;
|
|
shade.sizeDelta = new Vector2(0f, 44f);
|
|
shade.GetComponent<Image>().raycastTarget = false;
|
|
|
|
var name = UiKit.CreateText(
|
|
tile,
|
|
"Name",
|
|
entry.Hidden
|
|
? (entry.Label ?? "Закрытая карта")
|
|
: (meta != null ? Loc.CardName(meta) : entry.Card.PrintingId),
|
|
12,
|
|
Color.white,
|
|
TextAnchor.LowerCenter);
|
|
UiKit.MakeLiteral(name);
|
|
var nameRect = name.rectTransform;
|
|
nameRect.anchorMin = new Vector2(0f, 0f);
|
|
nameRect.anchorMax = new Vector2(1f, 0f);
|
|
nameRect.pivot = new Vector2(0.5f, 0f);
|
|
nameRect.anchoredPosition = new Vector2(0f, 22f);
|
|
nameRect.sizeDelta = new Vector2(-8f, 20f);
|
|
name.horizontalOverflow = HorizontalWrapMode.Wrap;
|
|
name.verticalOverflow = VerticalWrapMode.Truncate;
|
|
name.raycastTarget = false;
|
|
|
|
var stats = UiKit.CreateText(
|
|
tile,
|
|
"Stats",
|
|
entry.Hidden || entry.Card == null
|
|
? string.Empty
|
|
: "P " + entry.Card.Power + " C " + entry.Card.Critical,
|
|
10,
|
|
new Color(0.78f, 0.84f, 0.95f),
|
|
TextAnchor.LowerCenter);
|
|
UiKit.MakeLiteral(stats);
|
|
var statsRect = stats.rectTransform;
|
|
statsRect.anchorMin = new Vector2(0f, 0f);
|
|
statsRect.anchorMax = new Vector2(1f, 0f);
|
|
statsRect.pivot = new Vector2(0.5f, 0f);
|
|
statsRect.anchoredPosition = new Vector2(0f, 5f);
|
|
statsRect.sizeDelta = new Vector2(-8f, 16f);
|
|
stats.raycastTarget = false;
|
|
|
|
var button = tile.gameObject.AddComponent<Button>();
|
|
button.targetGraphic = image;
|
|
button.onClick.AddListener(() => _onEntry?.Invoke(entry));
|
|
}
|
|
|
|
private static void ClearChildren(Transform parent)
|
|
{
|
|
for (var i = parent.childCount - 1; i >= 0; i--)
|
|
{
|
|
var child = parent.GetChild(i).gameObject;
|
|
if (Application.isPlaying)
|
|
UnityEngine.Object.Destroy(child);
|
|
else
|
|
UnityEngine.Object.DestroyImmediate(child);
|
|
}
|
|
}
|
|
}
|
|
}
|