130 lines
3.1 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|
|
}
|