using System.Collections.Generic;
using Ichni.Story.Dialogue;
using UnityEngine;
using UnityEngine.UI;
namespace Ichni.Story.UI
{
///
/// 对话记录覆盖面板。
/// 它不是独立 UIPage:打开时覆盖在 DialogUIPage 上方,并由全屏 Raycast Target 阻断底层输入;
/// 关闭后仅恢复对话画面,不推进 Yarn 对话。
///
public class DialogueHistoryPage : MonoBehaviour
{
[Header("References")]
[Tooltip("覆盖全屏的 CanvasGroup。根物体应位于 DialogCanvas 顶层,并包含可接收 Raycast 的全屏透明 Image。")]
[SerializeField] private CanvasGroup canvasGroup;
[SerializeField] private ScrollRect scrollRect;
[SerializeField] private RectTransform entryContainer;
[SerializeField] private DialogueHistoryEntryView entryPrefab;
[SerializeField] private Button closeButton;
/// 当前覆盖层是否正在显示并拦截 DialogUIPage 输入。
public bool IsOpen => _isOpen;
private readonly List _spawnedEntries = new();
private bool _isOpen;
private void Awake()
{
if (closeButton != null)
closeButton.onClick.AddListener(Close);
SetVisible(false);
}
private void OnDestroy()
{
if (closeButton != null)
closeButton.onClick.RemoveListener(Close);
}
/// 以当前一次 TextBlock 对话的内存记录刷新并打开覆盖面板。
public void Open(IReadOnlyList entries)
{
RebuildEntries(entries);
SetVisible(true);
Canvas.ForceUpdateCanvases();
// 记录按时间从上到下排列;打开后停在最早一条,玩家可向下浏览最新内容。
if (scrollRect != null)
scrollRect.verticalNormalizedPosition = 1f;
}
/// 关闭覆盖面板,不修改当前 Yarn 进度或选项状态。
public void Close() => SetVisible(false);
private void RebuildEntries(IReadOnlyList entries)
{
foreach (DialogueHistoryEntryView view in _spawnedEntries)
if (view != null)
Destroy(view.gameObject);
_spawnedEntries.Clear();
if (entries == null || entryPrefab == null || entryContainer == null)
return;
foreach (DialogueHistoryEntry entry in entries)
{
DialogueHistoryEntryView view = Instantiate(entryPrefab, entryContainer);
view.SetUp(entry);
_spawnedEntries.Add(view);
}
}
private void SetVisible(bool visible)
{
_isOpen = visible;
if (canvasGroup == null)
return;
canvasGroup.alpha = visible ? 1f : 0f;
canvasGroup.interactable = visible;
canvasGroup.blocksRaycasts = visible;
}
}
}