Files
Cielonos/Assets/Scripts/MainGame/UI/PlayerUI/MainGamePages/Common/Item/ItemDetailPanel.cs
SoulliesOfficial 6d7ebc5825 Passion & UI
2026-06-12 17:11:39 -04:00

178 lines
6.0 KiB
C#

using System.Collections.Generic;
using Cielonos.MainGame.Inventory;
using Cielonos.MainGame.UI;
using Sirenix.OdinInspector;
using SLSUtilities.General;
using TMPro;
using UniRx;
using UnityEngine;
using UnityEngine.Localization.Settings;
using UnityEngine.Serialization;
using UnityEngine.UI;
namespace SLSUtilities.UI
{
/// <summary>
/// 通用物品详情面板,显示物品图标、名称、类型、描述条目、标签等信息。
/// 可被不同的 UIPage 复用(机械台、商店、背包检视等)。
/// </summary>
public class ItemDetailPanel : UIElementBase
{
[Title("Detail Panel References")]
public TMP_Text selectionHintText;
//public Image itemIcon;
public TMP_Text nameText;
public TMP_Text typeRarityText;
public TMP_Text institutionText;
public RectTransform tagContainer;
public GameObject tagPrefab;
// ─────────────────── 描述条目 ───────────────────
[Title("Description Entries")]
[Tooltip("描述条目的容器,应挂载 VerticalLayoutGroup 以实现垂直排列。")]
public RectTransform descriptionContainer;
[Tooltip("描述条目预制体,需挂载 ItemDescriptionEntry 组件。")]
public GameObject descriptionEntryPrefab;
// ─────────────────── 运行时数据 ───────────────────
private ItemBase currentItem;
private readonly List<ItemDescriptionEntry> activeEntries = new List<ItemDescriptionEntry>();
/// <summary>当前显示的物品。</summary>
public ItemBase CurrentItem => currentItem;
/// <summary>
/// 使用指定物品的数据填充详情面板并显示。
/// </summary>
public void SetItem(ItemBase item)
{
currentItem = item;
if (item == null || item.contentData == null)
{
ClearPanel();
return;
}
ContentData data = item.contentData;
// 图标
/*Sprite icon = data.itemIcon;
if (itemIcon != null)
{
itemIcon.sprite = icon;
itemIcon.enabled = icon != null;
}*/
// 名称(本地化)
nameText.text = data.displayNameKey.Localize("Items");
// 类型
typeRarityText.text = data.itemType.ToString() + " - " + data.itemRarity.ToString();
//机构
institutionText.text = string.Empty;
for (var index = 0; index < data.institutions.Count; index++)
{
var institution = data.institutions[index];
string comma = LocalizationSettings.SelectedLocale.Identifier.Code.StartsWith("zh") ? "、" : ", ";
if(index < data.institutions.Count - 1)
institutionText.text += institution.Localize("Items") + comma;
else
institutionText.text += institution.Localize("Items");
}
// 描述条目
RefreshDescriptions(data);
// 标签
RefreshTags(data);
selectionHintText.gameObject.SetActive(false);
}
/// <summary>清空面板内容并隐藏。</summary>
public void ClearPanel()
{
currentItem = null;
//if (itemIcon != null) itemIcon.enabled = false;
if (nameText != null) nameText.text = string.Empty;
if (typeRarityText != null) typeRarityText.text = string.Empty;
ClearDescriptions();
ClearTags();
selectionHintText.gameObject.SetActive(true);
}
// ================================================================
// 描述条目
// ================================================================
private void RefreshDescriptions(ContentData data)
{
ClearDescriptions();
if (descriptionContainer == null || descriptionEntryPrefab == null) return;
if (data.descriptions == null || data.descriptions.Count == 0) return;
Dictionary<string, string> descriptionArgs = currentItem?.GetDescriptionArgs();
foreach (ItemDescription desc in data.descriptions)
{
ItemDescriptionEntry entry = Instantiate(descriptionEntryPrefab, descriptionContainer).GetComponent<ItemDescriptionEntry>();
entry.SetDescription(desc, descriptionArgs);
activeEntries.Add(entry);
}
LayoutRebuilder.ForceRebuildLayoutImmediate(descriptionContainer);
}
private void ClearDescriptions()
{
foreach (ItemDescriptionEntry entry in activeEntries)
{
if (entry != null)
{
Destroy(entry.gameObject);
}
}
activeEntries.Clear();
}
// ================================================================
// 标签
// ================================================================
private void RefreshTags(ContentData data)
{
ClearTags();
if (tagContainer == null || tagPrefab == null || data.tags == null) return;
foreach (string tag in data.tags)
{
GameObject tagObj = Instantiate(tagPrefab, tagContainer);
TMP_Text tagText = tagObj.GetComponentInChildren<TMP_Text>();
if (tagText != null)
{
tagText.text = tag;
}
}
}
private void ClearTags()
{
if (tagContainer == null) return;
for (int i = tagContainer.childCount - 1; i >= 0; i--)
{
Destroy(tagContainer.GetChild(i).gameObject);
}
}
}
}