NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/Framework/UI/UIWindow.ButtonBinding.cs

237 lines
13 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System;
using Cysharp.Threading.Tasks;
using Framework;
using PhxhSDK;
using UnityEngine;
using UnityEngine.UI;
/*
╔═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗
║ UIWindow 按钮绑定模块 (Button Binding) ║
╠═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╣
║ ║
║ 【模块功能】 ║
║ 本模块提供按钮绑定的核心功能: ║
║ • 手动按钮绑定 API - 在OnInit()中手动绑定自定义按钮 ║
║ ║
║ 注意:默认按钮的处理已移至独立的 partial 文件: ║
║ • UIWindow.DefaultCloseButton.cs - 处理默认关闭按钮BgClose、BtnClose
║ • UIWindow.DefaultHomeButton.cs - 处理默认回主界面按钮BtnHome、BtnBackHome、HomeButton
║ • UIWindow.DefaultBackButton.cs - 处理默认返回按钮BtnBack、BackButton、BtnReturn
║ ║
║ 【使用方式】 ║
║ ║
║ 在 OnInit() 中使用 BindButton() API 手动绑定: ║
║ ║
║ 示例: ║
║ protected override void OnInit() ║
║ { ║
║ // 通过路径绑定 ║
║ BindButton("BtnStart", OnStartClick); ║
║ ║
║ // 通过Button组件绑定 ║
║ BindButton(myButton, OnMyButtonClick); ║
║ ║
║ // 带参数绑定 ║
║ BindButton(itemButton, OnItemClick, itemData); ║
║ ║
║ // 静音绑定(不播放音效) ║
║ BindButton(silentButton, OnSilentClick, playAudio: false); ║
║ } ║
║ ║
║ 【更多信息】 ║
║ • 关闭按钮UIWindow.DefaultCloseButton.cs ║
║ • 回主界面按钮UIWindow.DefaultHomeButton.cs ║
║ • 返回按钮UIWindow.DefaultBackButton.cs ║
║ ║
╚═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝
*/
/// <summary>
/// UI窗口基类 - 按钮绑定部分
/// 提供按钮绑定API和默认按钮自动绑定功能
/// </summary>
public abstract partial class UIWindow
{
#region Button Binding Core - 按钮绑定核心逻辑
/// <summary>
/// 处理按钮点击的音频逻辑
/// </summary>
private void HandleButtonAudio(Button button, bool playAudio)
{
if (!playAudio) return;
var clickAudio = button.GetComponent<ClickAudio>();
if (clickAudio)
{
if (clickAudio.IsPlayAudio && !string.IsNullOrEmpty(clickAudio.AudioKey))
{
AudioManager.Instance.PlayAudio(clickAudio.AudioKey);
}
}
else
{
// do nothing, must use ClickAudio
DebugUtil.LogError("按钮未添加ClickAudio组件请检查按钮绑定参数!");
}
}
/// <summary>
/// 绑定按钮点击事件的核心逻辑(无参数)
/// </summary>
private void BindButtonCore(Button button, Action action, bool playAudio = true)
{
if (button is null)
{
DebugUtil.LogError("传入按钮为空,无法绑定点击事件!");
return;
}
button.onClick.RemoveAllListeners();
button.onClick.AddListener(() =>
{
DebugUtil.Log("按钮被点击: {0}", button.gameObject.name);
if (UIManager.IsUIInputBlocked) return;
UIManager.Instance.BlockUIForNormalOperation();
HandleButtonAudio(button, playAudio);
action?.Invoke();
});
DebugUtil.Log("按钮绑定完成: {0}", button.gameObject.name);
}
/// <summary>
/// 绑定按钮点击事件的核心逻辑(带参数)
/// </summary>
private void BindButtonCore<T>(Button button, Action<T> action, T parameter, bool playAudio = true)
{
if (button is null) return;
button.onClick.RemoveAllListeners();
button.onClick.AddListener(() =>
{
if (UIManager.IsUIInputBlocked) return;
UIManager.Instance.BlockUIForNormalOperation();
HandleButtonAudio(button, playAudio);
if (parameter == null)
{
DebugUtil.LogError("=== 传入参数为空! ===");
}
action?.Invoke(parameter);
});
}
#endregion
#region Button Binding Public API - 手动绑定按钮的公共API
/// <summary>
/// 通过路径绑定按钮
/// </summary>
/// <param name="target">按钮节点路径(相对于窗口根节点)</param>
/// <param name="action">点击回调</param>
/// <param name="playAudio">是否播放点击音效默认true</param>
/// <returns>Button组件</returns>
/// <example>
/// BindButton("TopBar/BtnSettings", OnSettingsClick);
/// </example>
public Button BindButton(string target, Action action, bool playAudio = true)
{
GameObject obj = transform.Find(target)?.gameObject;
if (obj is not null)
{
Button button = obj.GetComponent<Button>();
BindButtonCore(button, action, playAudio);
return button;
}
else
{
DebugUtil.LogError("未找到按钮节点: {0}/{1}", gameObject.name, target);
}
return null;
}
/// <summary>
/// 直接绑定Button组件
/// </summary>
/// <param name="button">Button组件</param>
/// <param name="action">点击回调</param>
/// <param name="playAudio">是否播放点击音效默认true</param>
/// <returns>Button组件</returns>
/// <example>
/// BindButton(myButton, OnMyButtonClick);
/// </example>
public Button BindButton(Button button, Action action, bool playAudio = true)
{
if (button is not null)
{
BindButtonCore(button, action, playAudio);
return button;
}
else
{
DebugUtil.LogError("传入按钮为空,请检查按钮绑定参数!");
}
return button;
}
/// <summary>
/// 通过GameObject绑定按钮带参数
/// </summary>
/// <typeparam name="T">参数类型</typeparam>
/// <param name="obj">按钮GameObject</param>
/// <param name="action">点击回调</param>
/// <param name="parameter">回调参数</param>
/// <param name="playAudio">是否播放点击音效默认true</param>
/// <returns>Button组件</returns>
/// <example>
/// BindButton(itemObj, OnItemClick, itemData);
/// </example>
public Button BindButton<T>(GameObject obj, Action<T> action, T parameter, bool playAudio = true)
{
if (obj is not null)
{
Button button = obj.GetComponent<Button>();
BindButtonCore(button, action, parameter, playAudio);
return button;
}
else
{
DebugUtil.LogError("传入GameObject为空请检查按钮绑定参数!");
}
return null;
}
/// <summary>
/// 直接绑定Button组件带参数
/// </summary>
/// <typeparam name="T">参数类型</typeparam>
/// <param name="button">Button组件</param>
/// <param name="action">点击回调</param>
/// <param name="parameter">回调参数</param>
/// <param name="playAudio">是否播放点击音效默认true</param>
/// <returns>Button组件</returns>
/// <example>
/// BindButton(itemButton, OnItemClick, itemData);
/// </example>
public Button BindButton<T>(Button button, Action<T> action, T parameter, bool playAudio = true)
{
if (button is not null)
{
BindButtonCore(button, action, parameter, playAudio);
return button;
}
else
{
DebugUtil.LogError("传入按钮为空,请检查按钮绑定参数!");
}
return button;
}
#endregion
}