// Copyright (c) 2025 EFramework Innovation. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
using System;
using UnityEngine;
using UnityEngine.EventSystems;
namespace EFramework.Unity.UIPlugin
{
///
/// UIEventListener 封装了多种 Unity UI 事件接口,用于处理 UI 交互的各种事件,是一个 UI 事件监听器组件。
///
///
///
/// 功能特性
/// - Unity UI 事件系统接口封装
/// - 支持事件回调和事件委托绑定
///
/// 使用手册
/// 1. 组件获取
///
/// 1. 获取或添加监听器:
/// - 获取GameObject上的监听器,如果不存在则自动添加:
///
/// UIEventListener listener = UIEventListener.Get(gameObject);
///
/// - 也可以传入组件来获取其GameObject上的监听器:
///
/// UIEventListener listener = UIEventListener.Get(transform);
///
/// 2. 事件绑定
///
/// 1. 使用事件委托:
///
/// // 使用事件委托绑定点击事件
/// listener.OnPointerClickEvent += (eventData) => {
/// Debug.Log("点击了:" + gameObject.name);
/// };
///
/// 2. 使用回调函数:
///
/// // 直接指定回调函数
/// listener.OnPointerClickFunc = HandleClick;
///
/// // 回调函数定义
/// private void HandleClick(PointerEventData eventData) {
/// Debug.Log("点击了:" + eventData.pointerCurrentRaycast.gameObject.name);
/// }
///
/// 常见问题
/// 1. 如何判断一个 UI 元素当前是否被按下?
///
/// UIEventListener组件包含一个IsPressed属性,可以用来检查UI元素当前的按压状态:
///
/// UIEventListener listener = UIEventListener.Get(buttonObj);
/// if (listener.IsPressed) {
/// // 按钮当前被按下
/// Debug.Log("按钮处于按下状态");
/// }
///
/// 2. UIEventListener 支持哪些类型的事件?
///
/// UIEventListener支持以下类型的事件:
/// - 按钮选中/取消选中 (OnButtonSelectEvent/OnButtonDeselectEvent)
/// - 指针点击 (OnPointerClickEvent)
/// - 指针按下/抬起 (OnPointerDownEvent/OnPointerUpEvent)
/// - 指针进入/退出 (OnPointerEnterEvent/OnPointerExitEvent)
/// - 拖拽相关 (OnBeginDragEvent/OnDragEvent/OnEndDragEvent)
///
/// 更多信息请参考模块文档。
///
[AddComponentMenu("UI/Event Listener")]
public class UIEventListener : MonoBehaviour, ISelectHandler, IDeselectHandler,
IPointerClickHandler, IPointerDownHandler, IPointerEnterHandler, IPointerExitHandler, IPointerUpHandler,
IBeginDragHandler, IDragHandler, IEndDragHandler
{
///
/// PointEventDelegate 是指针事件委托,用于处理与指针相关的事件回调。
/// 包括点击、按下、进入、退出、抬起以及拖拽相关事件。
///
/// 指针事件数据,包含事件发生时的指针信息
public delegate void PointEventDelegate(PointerEventData data);
///
/// BaseEventDelegate 是基础事件委托,用于处理基础UI事件回调。
/// 包括选中和取消选中等非指针相关事件。
///
/// 基础事件数据,包含事件相关信息
public delegate void BaseEventDelegate(BaseEventData data);
///
/// OnButtonSelectEvent 是按钮选中事件。
/// 当UI元素被选中时触发,可通过添加事件监听器响应。
///
public event BaseEventDelegate OnButtonSelectEvent;
///
/// OnButtonSelectFunc 是按钮选中回调函数。
/// 可直接设置此属性指定回调,作为事件的替代方式。
///
public BaseEventDelegate OnButtonSelectFunc;
///
/// OnButtonDeselectEvent 是按钮取消选中事件。
/// 当UI元素失去选中状态时触发,可通过添加事件监听器响应。
///
public event BaseEventDelegate OnButtonDeselectEvent;
///
/// OnButtonDeselectFunc 是按钮取消选中回调函数。
/// 可直接设置此属性指定回调,作为事件的替代方式。
///
public BaseEventDelegate OnButtonDeselectFunc;
///
/// OnPointerClickEvent 是指针点击事件。
/// 当UI元素被点击时触发,可通过添加事件监听器响应。
///
public event PointEventDelegate OnPointerClickEvent;
///
/// OnPointerClickFunc 是指针点击回调函数。
/// 可直接设置此属性指定回调,作为事件的替代方式。
///
public PointEventDelegate OnPointerClickFunc;
///
/// OnPointerDownEvent 是指针按下事件。
/// 当指针在UI元素上按下时触发,可通过添加事件监听器响应。
///
public event PointEventDelegate OnPointerDownEvent;
///
/// OnPointerDownFunc 是指针按下回调函数。
/// 可直接设置此属性指定回调,作为事件的替代方式。
///
public PointEventDelegate OnPointerDownFunc;
///
/// OnPointerEnterEvent 是指针进入事件。
/// 当指针进入UI元素区域时触发,可通过添加事件监听器响应。
///
public event PointEventDelegate OnPointerEnterEvent;
///
/// OnPointerEnterFunc 是指针进入回调函数。
/// 可直接设置此属性指定回调,作为事件的替代方式。
///
public PointEventDelegate OnPointerEnterFunc;
///
/// OnPointerExitEvent 是指针退出事件。
/// 当指针离开UI元素区域时触发,可通过添加事件监听器响应。
///
public event PointEventDelegate OnPointerExitEvent;
///
/// OnPointerExitFunc 是指针退出回调函数。
/// 可直接设置此属性指定回调,作为事件的替代方式。
///
public PointEventDelegate OnPointerExitFunc;
///
/// OnPointerUpEvent 是指针抬起事件。
/// 当指针在UI元素上抬起时触发,可通过添加事件监听器响应。
///
public event PointEventDelegate OnPointerUpEvent;
///
/// OnPointerUpFunc 是指针抬起回调函数。
/// 可直接设置此属性指定回调,作为事件的替代方式。
///
public PointEventDelegate OnPointerUpFunc;
///
/// OnBeginDragEvent 是开始拖拽事件。
/// 当在UI元素上开始拖拽操作时触发,可通过添加事件监听器响应。
///
public event PointEventDelegate OnBeginDragEvent;
///
/// OnBeginDragFunc 是开始拖拽回调函数。
/// 可直接设置此属性指定回调,作为事件的替代方式。
///
public PointEventDelegate OnBeginDragFunc;
///
/// OnDragEvent 是拖拽中事件。
/// 当正在拖拽UI元素时触发,可通过添加事件监听器响应。
///
public event PointEventDelegate OnDragEvent;
///
/// OnDragFunc 是拖拽中回调函数。
/// 可直接设置此属性指定回调,作为事件的替代方式。
///
public PointEventDelegate OnDragFunc;
///
/// OnEndDragEvent 是结束拖拽事件。
/// 当结束拖拽UI元素时触发,可通过添加事件监听器响应。
///
public event PointEventDelegate OnEndDragEvent;
///
/// OnEndDragFunc 是结束拖拽回调函数。
/// 可直接设置此属性指定回调,作为事件的替代方式。
///
public PointEventDelegate OnEndDragFunc;
///
/// IsPressed 表示按钮是否处于按下状态。
/// 用于跟踪按钮的当前按压状态,可在外部代码中检查此状态。
///
[NonSerialized] public bool IsPressed;
///
/// OnDeselect 处理UI元素失去选中状态的事件。
/// 当UI元素失去选中状态时,调用相应的事件委托和回调函数。
///
/// 事件数据,包含选中相关信息
public void OnDeselect(BaseEventData data) { OnButtonDeselectEvent?.Invoke(data); OnButtonDeselectFunc?.Invoke(data); }
///
/// OnSelect 处理UI元素被选中的事件。
/// 当UI元素被选中时,调用相应的事件委托和回调函数。
///
/// 事件数据,包含选中相关信息
public void OnSelect(BaseEventData data) { OnButtonSelectEvent?.Invoke(data); OnButtonSelectFunc?.Invoke(data); }
///
/// OnPointerClick 处理指针点击事件。
/// 当指针点击UI元素时,调用相应的事件委托和回调函数。
///
/// 指针事件数据,包含点击相关信息
void IPointerClickHandler.OnPointerClick(PointerEventData data) { OnPointerClickEvent?.Invoke(data); OnPointerClickFunc?.Invoke(data); }
///
/// OnPointerDown 处理指针按下事件。
/// 当指针在UI元素上按下时,设置IsPressed状态并调用相应的事件委托和回调函数。
///
/// 指针事件数据,包含按下相关信息
void IPointerDownHandler.OnPointerDown(PointerEventData data) { IsPressed = true; OnPointerDownEvent?.Invoke(data); OnPointerDownFunc?.Invoke(data); }
///
/// OnPointerEnter 处理指针进入UI元素区域的事件。
/// 当指针进入UI元素区域时,调用相应的事件委托和回调函数。
///
/// 指针事件数据,包含进入相关信息
void IPointerEnterHandler.OnPointerEnter(PointerEventData data) { OnPointerEnterEvent?.Invoke(data); OnPointerEnterFunc?.Invoke(data); }
///
/// OnPointerExit 处理指针离开UI元素区域的事件。
/// 当指针离开UI元素区域时,调用相应的事件委托和回调函数。
///
/// 指针事件数据,包含离开相关信息
void IPointerExitHandler.OnPointerExit(PointerEventData data) { OnPointerExitEvent?.Invoke(data); OnPointerExitFunc?.Invoke(data); }
///
/// OnPointerUp 处理指针抬起事件。
/// 当指针在UI元素上抬起时,重置IsPressed状态并调用相应的事件委托和回调函数。
///
/// 指针事件数据,包含抬起相关信息
void IPointerUpHandler.OnPointerUp(PointerEventData data) { IsPressed = false; OnPointerUpEvent?.Invoke(data); OnPointerUpFunc?.Invoke(data); }
///
/// OnBeginDrag 处理开始拖拽事件。
/// 当在UI元素上开始拖拽操作时,调用相应的事件委托和回调函数。
///
/// 指针事件数据,包含拖拽相关信息
void IBeginDragHandler.OnBeginDrag(PointerEventData data) { OnBeginDragEvent?.Invoke(data); OnBeginDragFunc?.Invoke(data); }
///
/// OnDrag 处理拖拽过程中的事件。
/// 当正在拖拽UI元素时,调用相应的事件委托和回调函数。
///
/// 指针事件数据,包含拖拽相关信息
void IDragHandler.OnDrag(PointerEventData data) { OnDragEvent?.Invoke(data); OnDragFunc?.Invoke(data); }
///
/// OnEndDrag 处理结束拖拽事件。
/// 当结束拖拽UI元素时,调用相应的事件委托和回调函数。
///
/// 指针事件数据,包含拖拽相关信息
void IEndDragHandler.OnEndDrag(PointerEventData data) { OnEndDragEvent?.Invoke(data); OnEndDragFunc?.Invoke(data); }
///
/// Get 获取指定组件GameObject上的UIEventListener组件,若不存在则自动添加。
/// 简化获取和添加监听器的过程。
///
/// 目标组件
/// UIEventListener实例,如果组件为null则返回null
public static UIEventListener Get(Component comp)
{
if (comp) return Get(comp.gameObject);
return null;
}
///
/// Get 获取指定GameObject上的UIEventListener组件,若不存在则自动添加。
/// 简化获取和添加监听器的过程。
///
/// 目标游戏对象
/// UIEventListener实例
public static UIEventListener Get(GameObject obj)
{
var listener = obj.GetComponent();
if (listener == null) listener = obj.AddComponent();
return listener;
}
}
}