Files
2026-02-21 16:45:37 +08:00

130 lines
3.1 KiB
C#

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
namespace UIWidgets
{
public abstract class DragSupport<T> : BaseDragSupport, IBeginDragHandler, IEndDragHandler, IDragHandler, IEventSystemHandler
{
[SerializeField]
public Texture2D AllowDropCursor;
[SerializeField]
public Vector2 AllowDropCursorHotSpot = new Vector2(4f, 2f);
[SerializeField]
public Texture2D DeniedDropCursor;
[SerializeField]
public Vector2 DeniedDropCursorHotSpot = new Vector2(4f, 2f);
[SerializeField]
public Texture2D DefaultCursorTexture;
[SerializeField]
public Vector2 DefaultCursorHotSpot;
protected bool IsDragged;
protected IDropSupport<T> oldTarget;
protected IDropSupport<T> currentTarget;
private List<RaycastResult> raycastResults = new List<RaycastResult>();
public T Data { get; protected set; }
public virtual bool CanDrag(PointerEventData eventData)
{
return true;
}
protected abstract void InitDrag(PointerEventData eventData);
public virtual void Dropped(bool success)
{
Data = default(T);
}
public virtual void OnBeginDrag(PointerEventData eventData)
{
if (CanDrag(eventData))
{
IsDragged = true;
InitDrag(eventData);
}
}
public virtual void OnDrag(PointerEventData eventData)
{
if (IsDragged)
{
oldTarget = currentTarget;
currentTarget = FindTarget(eventData);
if (oldTarget != null && currentTarget != oldTarget)
{
oldTarget.DropCanceled(Data, eventData);
}
if (currentTarget != null)
{
Cursor.SetCursor(AllowDropCursor, AllowDropCursorHotSpot, Utilites.GetCursorMode());
}
else
{
Cursor.SetCursor(DeniedDropCursor, DeniedDropCursorHotSpot, Utilites.GetCursorMode());
}
Vector2 localPoint;
if (RectTransformUtility.ScreenPointToLocalPointInRectangle(base.CanvasTransform as RectTransform, Input.mousePosition, eventData.pressEventCamera, out localPoint))
{
base.DragPoint.localPosition = localPoint;
}
}
}
protected IDropSupport<T> FindTarget(PointerEventData eventData)
{
raycastResults.Clear();
EventSystem.current.RaycastAll(eventData, raycastResults);
foreach (RaycastResult raycastResult in raycastResults)
{
if (raycastResult.isValid)
{
IDropSupport<T> component = raycastResult.gameObject.GetComponent<IDropSupport<T>>();
if (component != null)
{
return (!component.CanReceiveDrop(Data, eventData)) ? null : component;
}
}
}
return null;
}
public virtual void OnEndDrag(PointerEventData eventData)
{
if (IsDragged)
{
IDropSupport<T> dropSupport = FindTarget(eventData);
if (dropSupport != null)
{
dropSupport.Drop(Data, eventData);
Dropped(true);
}
else
{
Dropped(false);
}
IsDragged = false;
Cursor.SetCursor(DefaultCursorTexture, DefaultCursorHotSpot, Utilites.GetCursorMode());
}
}
protected virtual void OnDestroy()
{
if (BaseDragSupport.DragPoints != null && base.CanvasTransform != null && BaseDragSupport.DragPoints.ContainsKey(base.CanvasTransform))
{
BaseDragSupport.DragPoints.Remove(base.CanvasTransform);
}
}
}
}