122 lines
4.9 KiB
C#
122 lines
4.9 KiB
C#
using System;
|
||
using UnityEngine;
|
||
using UnityEngine.UI;
|
||
using UnityEngine.EventSystems;
|
||
using TMPro;
|
||
using BaseGames.Localization;
|
||
|
||
namespace BaseGames.UI.Menus
|
||
{
|
||
/// <summary>
|
||
/// 通用模态确认对话框(是/否):用于删除 / 覆盖 / 退出等确认场景。
|
||
///
|
||
/// 设计:
|
||
/// · 自包含、场景无关——通过本地 SetActive 显隐 + 回调 API 工作,不依赖 UIManager 面板栈,
|
||
/// 因此既能用于主菜单场景(不走 UIManager),也能在游戏内复用。
|
||
/// · 标题 / 正文 / 按钮文案均走本地化键(LocalizationManager.Get);传 null 则保留 Inspector 原文。
|
||
/// · 默认焦点置于"取消"按钮,防止手柄连按误触确认(破坏性操作安全默认)。
|
||
///
|
||
/// 用法:
|
||
/// _confirmDialog.Show("CONFIRM_DELETE_TITLE", "CONFIRM_DELETE_BODY",
|
||
/// onConfirm: () => DoDelete(),
|
||
/// onCancel: () => {});
|
||
/// </summary>
|
||
public class ConfirmDialogController : MonoBehaviour
|
||
{
|
||
[Header("根节点(显隐用,留空则用本 GameObject)")]
|
||
[SerializeField] private GameObject _root;
|
||
|
||
[Header("文本")]
|
||
[SerializeField] private TMP_Text _titleText;
|
||
[SerializeField] private TMP_Text _bodyText;
|
||
[Tooltip("确认按钮标签(可选,传 confirmKey 时覆盖)")]
|
||
[SerializeField] private TMP_Text _confirmLabel;
|
||
[Tooltip("取消按钮标签(可选,传 cancelKey 时覆盖)")]
|
||
[SerializeField] private TMP_Text _cancelLabel;
|
||
|
||
[Header("按钮")]
|
||
[SerializeField] private Button _btnConfirm;
|
||
[SerializeField] private Button _btnCancel;
|
||
|
||
private Action _onConfirm;
|
||
private Action _onCancel;
|
||
|
||
private void Awake()
|
||
{
|
||
_btnConfirm?.onClick.AddListener(HandleConfirm);
|
||
_btnCancel? .onClick.AddListener(HandleCancel);
|
||
SetVisible(false);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 弹出确认框。
|
||
/// </summary>
|
||
/// <param name="titleKey">标题本地化键;null 保留原文。</param>
|
||
/// <param name="bodyKey">正文本地化键;null 保留原文。</param>
|
||
/// <param name="onConfirm">点击确认后回调(确认框已自动关闭)。</param>
|
||
/// <param name="onCancel">点击取消后回调(可选)。</param>
|
||
/// <param name="confirmKey">确认按钮文案本地化键(可选)。</param>
|
||
/// <param name="cancelKey">取消按钮文案本地化键(可选)。</param>
|
||
public void Show(string titleKey, string bodyKey, Action onConfirm, Action onCancel = null,
|
||
string confirmKey = null, string cancelKey = null)
|
||
{
|
||
_onConfirm = onConfirm;
|
||
_onCancel = onCancel;
|
||
|
||
if (_titleText != null && titleKey != null) _titleText.text = Loc(titleKey);
|
||
if (_bodyText != null && bodyKey != null) _bodyText.text = Loc(bodyKey);
|
||
if (_confirmLabel != null && confirmKey != null) _confirmLabel.text = Loc(confirmKey);
|
||
if (_cancelLabel != null && cancelKey != null) _cancelLabel.text = Loc(cancelKey);
|
||
|
||
SetVisible(true);
|
||
|
||
// 安全默认:焦点置于取消,避免手柄/键盘连按直接确认破坏性操作
|
||
EventSystem.current?.SetSelectedGameObject(_btnCancel != null
|
||
? _btnCancel.gameObject
|
||
: _btnConfirm?.gameObject);
|
||
}
|
||
|
||
/// <summary>外部强制关闭(如父面板被关闭时)。不触发任何回调。</summary>
|
||
public void Close()
|
||
{
|
||
_onConfirm = null;
|
||
_onCancel = null;
|
||
SetVisible(false);
|
||
}
|
||
|
||
// ── 按钮回调 ──────────────────────────────────────────────────────────
|
||
|
||
private void HandleConfirm()
|
||
{
|
||
var cb = _onConfirm;
|
||
SetVisible(false);
|
||
_onConfirm = null;
|
||
_onCancel = null;
|
||
cb?.Invoke();
|
||
}
|
||
|
||
private void HandleCancel()
|
||
{
|
||
var cb = _onCancel;
|
||
SetVisible(false);
|
||
_onConfirm = null;
|
||
_onCancel = null;
|
||
cb?.Invoke();
|
||
}
|
||
|
||
// ── 工具 ──────────────────────────────────────────────────────────────
|
||
|
||
private void SetVisible(bool visible)
|
||
{
|
||
var go = _root != null ? _root : gameObject;
|
||
go.SetActive(visible);
|
||
}
|
||
|
||
private static string Loc(string key)
|
||
{
|
||
string s = LocalizationManager.Get(key, LocalizationTable.UI);
|
||
return string.IsNullOrEmpty(s) ? key : s;
|
||
}
|
||
}
|
||
}
|