using AppUI.Manager.View;
using DG.Tweening;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
namespace AppUI.View.Component
{
///
/// 横版 ModuleView:节点在预制体 Inspector 中拖拽绑定。
/// 弹出与关闭参考 的 Tip:Frame 缩放进入,按钮点击后缩放消失再销毁。
///
public class ModuleViewHorizontal : MonoBehaviour
{
const float PopInDuration = 0.25f;
const float PopOutDuration = 0.3f;
[Header("布局节点")]
[SerializeField]
RectTransform frame;
[Header("正文")]
[SerializeField]
TMP_Text contentTextTmp;
[SerializeField]
Text contentTextLegacy;
[Header("按钮")]
[SerializeField]
Button btnReject;
[SerializeField]
TMP_Text btnRejectLabel;
[SerializeField]
Button btnAgree;
[SerializeField]
TMP_Text btnAgreeLabel;
public string text;
public string textKey;
public object[] textFormatArgs = { };
public UnityAction onAgree;
public string onAgreeTextKey;
public UnityAction onReject;
public string onRejectTextKey;
/// 为 true(默认)时,点击按钮会先播放收起动画再销毁自身。
public bool willDestroyAfterClick = true;
bool _dismissing;
Tween _popTween;
public static ModuleViewHorizontal Show()
{
ViewConfig viewConfig = ViewManager.GetConfig(UIPrefabType.ModuleViewHorizontal);
GameObject o = Instantiate(Resources.Load(viewConfig.path));
var view = o.GetComponent();
if (view == null)
view = o.AddComponent();
return view;
}
void OnDestroy()
{
_popTween?.Kill();
transform.DOKill(true);
}
void Start()
{
SetupRejectButton();
BindContentText();
BindAgreeButton();
TrySetButtonLabelKey(btnAgreeLabel, onAgreeTextKey);
TrySetButtonLabelKey(btnRejectLabel, onRejectTextKey);
if (frame != null)
LayoutRebuilder.ForceRebuildLayoutImmediate(frame);
PlayPopIn();
}
/// 未设置拒绝回调且无拒绝文案 key 时隐藏拒绝按钮。
void SetupRejectButton()
{
if (btnReject == null)
return;
bool showReject = onReject != null || !string.IsNullOrEmpty(onRejectTextKey);
btnReject.gameObject.SetActive(showReject);
if (!showReject)
return;
btnReject.onClick.AddListener(OnRejectClicked);
}
void PlayPopIn()
{
if (frame == null)
return;
frame.DOKill();
frame.localScale = Vector3.zero;
_popTween = frame
.DOScale(1f, PopInDuration)
.SetEase(Ease.OutBack)
.SetUpdate(true);
}
/// 缩放 Frame 后销毁(不再次触发按钮回调)。
public void CloseWithTween()
{
if (_dismissing)
return;
if (!willDestroyAfterClick)
return;
_dismissing = true;
PlayPopOutAndDestroy();
}
void BindAgreeButton()
{
if (btnAgree == null)
return;
btnAgree.onClick.AddListener(OnAgreeClicked);
}
void OnAgreeClicked()
{
if (_dismissing)
return;
onAgree?.Invoke();
if (!willDestroyAfterClick)
return;
_dismissing = true;
PlayPopOutAndDestroy();
}
void OnRejectClicked()
{
if (_dismissing)
return;
onReject?.Invoke();
if (!willDestroyAfterClick)
return;
_dismissing = true;
PlayPopOutAndDestroy();
}
void PlayPopOutAndDestroy()
{
SetButtonsInteractable(false);
if (frame == null)
{
Destroy(gameObject);
return;
}
_popTween?.Kill();
frame.DOKill();
_popTween = frame
.DOScale(0f, PopOutDuration)
.SetEase(Ease.InBack)
.SetUpdate(true)
.OnComplete(() => Destroy(gameObject));
}
void SetButtonsInteractable(bool interactable)
{
if (btnAgree != null)
btnAgree.interactable = interactable;
if (btnReject != null)
btnReject.interactable = interactable;
}
void BindContentText()
{
if (contentTextTmp != null)
{
if (!string.IsNullOrEmpty(textKey))
{
var t2 = contentTextTmp.GetComponent();
if (t2 == null)
t2 = contentTextTmp.gameObject.AddComponent();
t2.textFormatArgs = textFormatArgs;
t2.SetTextKey(textKey);
}
else
{
contentTextTmp.text = text ?? string.Empty;
}
return;
}
if (contentTextLegacy == null)
return;
if (!string.IsNullOrEmpty(textKey))
{
var t2 = contentTextLegacy.GetComponent();
if (t2 == null)
t2 = contentTextLegacy.gameObject.AddComponent();
t2.textFormatArgs = textFormatArgs;
t2.SetTextKey(textKey);
}
else
{
contentTextLegacy.text = text ?? string.Empty;
}
}
static void TrySetButtonLabelKey(TMP_Text label, string key)
{
if (label == null || string.IsNullOrEmpty(key))
return;
var t2 = label.GetComponent();
if (t2 == null)
t2 = label.gameObject.AddComponent();
t2.SetTextKey(key);
}
}
}