using System;
using System.Threading;
using System.Threading.Tasks;
using Febucci.UI.Core;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
using AibisDream.Framework;
using AibisDream.Utility;
namespace AibisDream
{
public class OnelineBox : MonoBehaviour, ILineView
{
[SerializeField] private TypewriterCore content;
[SerializeField] private GameObject box;
[Header("排版参数")]
[SerializeField] private int maxWidth = 800;
[SerializeField] private int minWidth = 10;
private LayoutElement _contentLayoutElement;
private TMP_Text _contentText;
private RectTransform _rectTransform;
private CancellationTokenSource _autoHideToken;
private event Action OnTextShowed;
private bool _isInitialized;
// ---------------------------- 显示逻辑 ----------------------------
public void RunLine(LineSyncToken syncToken)
{
// 先中断结束事件
_autoHideToken?.Cancel();
_autoHideToken = null;
// 注册事件
OnTextShowed += syncToken.TextShown;
syncToken.SkipTextAnima += () => content.SkipTypewriter();
syncToken.OnAdvance += AfterAdvance;
// 播放文字
content.TextAnimator.SetText(string.Empty);
var lineText = GetOneLineText(syncToken.lineInfo);
box.SetActive(true);
HandleLayout(lineText);
content.ShowText(lineText);
syncToken.TextStart();
}
private string GetOneLineText(LineInfo lineInfo)
{
if (string.IsNullOrEmpty(lineInfo.character.GetActorName()))
{
return lineInfo.lineText;
}
return $"{lineInfo.character.GetActorName()}: {lineInfo.lineText}";
}
private void HandleLayout(string line)
{
if (!_isInitialized)
{
InitRefs();
}
// 去除富文本标签后计算宽度
var width = DialogUIManager.Instance.EstimateTextWidth(line.RemoveRichTextTags(), _contentText.fontSize);
if (width > maxWidth)
{
_contentLayoutElement.preferredWidth = maxWidth;
}
else
{
_contentLayoutElement.preferredWidth = -1; // 自适应
}
_contentLayoutElement.minWidth = minWidth;
LayoutRebuilder.ForceRebuildLayoutImmediate(_rectTransform);
}
private async void AfterAdvance()
{
_autoHideToken = new CancellationTokenSource();
try
{
await Task.Delay(ConstRef.AutoHideDelay, _autoHideToken.Token);
HideDialog();
}
catch (TaskCanceledException)
{
// 忽略取消
}
}
public void HideDialog()
{
box.SetActive(false);
}
// ---------------------------- 生命周期 ----------------------------
private void Awake()
{
box.SetActive(false);
InitRefs();
}
private void InitRefs()
{
if (_isInitialized) return;
_rectTransform = box.GetComponent();
_contentText = content.GetComponent();
_contentLayoutElement = content.GetComponent();
_isInitialized = true;
}
private void Start()
{
DialogUIManager.Instance.RegisterScreenView(DialogViewType.OnelineBox, this);
RegisterEvents();
}
private void OnDestroy()
{
DialogUIManager.Instance.UnRegisterScreenView(DialogViewType.OnelineBox);
UnregisterEvents();
OnTextShowed = null;
}
private void RegisterEvents()
{
// 全局事件
EnumEventSystem.Global.Register(DialogEventEnum.OptionShow, OnOptionShow);
// 文本事件
content.onTextShowed.AddListener(TextShowed);
}
private void UnregisterEvents()
{
// 全局事件
EnumEventSystem.Global.UnRegister(DialogEventEnum.OptionShow, OnOptionShow);
// 文本事件
content.onTextShowed.RemoveListener(TextShowed);
}
private void TextShowed()
{
OnTextShowed?.Invoke();
OnTextShowed = null;
}
private void OnOptionShow()
{
_autoHideToken?.Cancel();
_autoHideToken = null;
HideDialog();
}
}
}