Files
aibis-dream/Assets/Scripts/UI/Terminal/TerminalRecordPanel.cs
T

215 lines
5.9 KiB
C#

using System;
using System.Collections.Generic;
using AibisDream.Utility;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
namespace AibisDream.UI
{
/// <summary>
/// 终端 Record Page(遗留类名 Panel)。挂在局内 InGameTerminalPanel 壳下。
/// </summary>
public class TerminalRecordPanel : MonoBehaviour
{
[SerializeField] private TerminalPanelAnimator panelAnimator;
[SerializeField] private Button backButton;
[SerializeField] private ScrollRect scrollRect;
[SerializeField] private Transform recordRoot;
[SerializeField] private TerminalRecordItemView recordItemPrefab;
[SerializeField] private TMP_Text emptyText;
private readonly List<LineInfo> _recordDataList = new List<LineInfo>();
private InGameTerminalPanel _owner;
public bool IsOpen => gameObject.activeSelf;
public void SetOwner(InGameTerminalPanel owner)
{
_owner = owner;
}
private void Awake()
{
backButton?.onClick.AddListener(ReturnGame);
EnsureScrollViewportMask();
}
private void EnsureScrollViewportMask()
{
if (scrollRect == null)
{
return;
}
var legacyMask = scrollRect.GetComponent<Mask>();
if (legacyMask != null)
{
legacyMask.enabled = false;
}
if (scrollRect.TryGetComponent<Image>(out var scrollImage))
{
var color = scrollImage.color;
color.a = 0f;
scrollImage.color = color;
scrollImage.raycastTarget = true;
}
if (scrollRect.viewport == null)
{
return;
}
if (scrollRect.viewport.GetComponent<RectMask2D>() == null)
{
scrollRect.viewport.gameObject.AddComponent<RectMask2D>();
}
}
private void OnDestroy()
{
backButton?.onClick.RemoveListener(ReturnGame);
}
public void Show()
{
_owner?.SetHeader("termnial_header_record", "REPAIR_STATION_07 - AUTH_VERIFIED");
if (panelAnimator != null)
{
panelAnimator.Show(onComplete: () => StartCoroutine(DrawRecordsWhenReady()));
}
else
{
gameObject.SetActive(true);
StartCoroutine(DrawRecordsWhenReady());
}
}
public void Hide(Action onComplete = null)
{
if (panelAnimator != null)
{
panelAnimator.Hide(() =>
{
ClearRecordItems();
onComplete?.Invoke();
});
}
else
{
ClearRecordItems();
gameObject.SetActive(false);
onComplete?.Invoke();
}
}
public void AppendDialogLine(LineInfo lineInfo)
{
_recordDataList.Add(lineInfo);
}
public void ClearDialog()
{
_recordDataList.Clear();
}
private System.Collections.IEnumerator DrawRecordsWhenReady()
{
DrawRecords();
yield return null;
ScrollToBottom();
}
private void ConfigureContentRect()
{
if (recordRoot is not RectTransform content)
{
return;
}
content.anchorMin = new Vector2(0f, 1f);
content.anchorMax = new Vector2(1f, 1f);
content.pivot = new Vector2(0.5f, 1f);
content.anchoredPosition = Vector2.zero;
content.sizeDelta = Vector2.zero;
}
private static void ConfigureRecordItemRect(RectTransform itemRect)
{
itemRect.anchorMin = new Vector2(0f, 1f);
itemRect.anchorMax = new Vector2(1f, 1f);
itemRect.pivot = new Vector2(0.5f, 1f);
itemRect.sizeDelta = Vector2.zero;
}
private static void SyncUiLayer(GameObject target, int layer)
{
target.layer = layer;
for (var i = 0; i < target.transform.childCount; i++)
{
SyncUiLayer(target.transform.GetChild(i).gameObject, layer);
}
}
private void DrawRecords()
{
ClearRecordItems();
ConfigureContentRect();
var hasRecords = _recordDataList.Count > 0;
if (emptyText != null)
{
emptyText.gameObject.SetActive(!hasRecords);
}
foreach (var recordData in _recordDataList)
{
var item = Instantiate(recordItemPrefab, recordRoot);
SyncUiLayer(item.gameObject, recordRoot.gameObject.layer);
item.Init(recordData);
if (item.transform is RectTransform itemRect)
{
ConfigureRecordItemRect(itemRect);
}
}
if (recordRoot is RectTransform contentRect)
{
LayoutRebuilder.ForceRebuildLayoutImmediate(contentRect);
}
}
private void ScrollToBottom()
{
if (scrollRect == null)
{
return;
}
if (recordRoot is RectTransform contentRect)
{
LayoutRebuilder.ForceRebuildLayoutImmediate(contentRect);
}
Canvas.ForceUpdateCanvases();
scrollRect.verticalNormalizedPosition = 0f;
}
private void ClearRecordItems()
{
if (recordRoot != null)
{
recordRoot.DestroyAllChildren();
}
}
private void ReturnGame()
{
_owner?.Back();
}
}
}