Files
Studio/Assets/Scripts/Studio/UI/TreeView/AssetLibraryScrollRect.cs

197 lines
7.1 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using Studio.UI;
namespace Studio.AssetLibraryTree
{
public class AssetLibraryScrollRect : ScrollRect, IPointerDownHandler
{
public bool passDragToChildren = true;
public UnityEvent<AssetLibraryItem, AssetLibraryItem> setToChildItem;
public UnityEvent<AssetLibraryItem, AssetLibraryItem> setToPriorSiblingItem;
public UnityEvent<AssetLibraryItem, AssetLibraryItem> setToNextSiblingItem;
//public UnityEvent onSelect;
public UnityEvent<AssetLibraryItem> onDragBegin;
public UnityEvent<AssetLibraryItem> onDragAndDrop;
public GameObject menuPopup;
public AssetLibraryItem sourceItem;
private AssetLibraryScrollItemUI hoverItemUI;
public UnityEvent<AssetLibraryItem> onExit;
public override void OnBeginDrag(PointerEventData eventData)
{
if (eventData.button != PointerEventData.InputButton.Left)
return;
AssetLibraryScrollItemUI itemUI = GetTargetItemUI(eventData);
if (itemUI != null && !itemUI.isSelected)
{
itemUI.OnPointerClick(eventData);
}
onDragBegin?.Invoke(sourceItem);
if (!passDragToChildren)
{
base.OnBeginDrag(eventData); // Allow default scrolling if needed
}
}
public override void OnDrag(PointerEventData eventData)
{
if (eventData.button == PointerEventData.InputButton.Left)
{
if (hoverItemUI != null) hoverItemUI.DeactivateAllHighlights();
AssetLibraryScrollItemUI itemUI = GetTargetItemUI(eventData);
if (itemUI != null)
{
RectTransform itemRect = itemUI.GetComponent<RectTransform>();
Vector2 localPoint;
RectTransformUtility.ScreenPointToLocalPointInRectangle(
itemRect,
eventData.position,
eventData.pressEventCamera,
out localPoint
);
float rectHeight = itemRect.rect.height;
float normalizedY = (localPoint.y + rectHeight / 2) / rectHeight;
if (normalizedY >= 0.8f) // Upper 20%
{
itemUI.ActivateUpperHighlight();
}
else if (normalizedY <= 0.2f) // Lower 20%
{
itemUI.ActivateLowerHighlight();
}
//else // Middle 60%
//{
// itemUI.ActivateMidHighlight();
//}
hoverItemUI = itemUI;
}
}
if (!passDragToChildren)
{
base.OnDrag(eventData);
}
}
public override void OnEndDrag(PointerEventData eventData)
{
if (eventData.button == PointerEventData.InputButton.Left)
{
if (hoverItemUI != null) hoverItemUI.DeactivateAllHighlights();
//Add to Other Item Hierarchy
AssetLibraryScrollItemUI itemUI = GetTargetItemUI(eventData);
if (itemUI != null && sourceItem != null)
{
RectTransform itemRect = itemUI.GetComponent<RectTransform>(); // Get RectTransform of the item
Vector2 localPoint;
// Convert screen position to local position within the item
RectTransformUtility.ScreenPointToLocalPointInRectangle(
itemRect,
eventData.position,
eventData.pressEventCamera,
out localPoint
);
float rectHeight = itemRect.rect.height; // Height of the item's RectTransform
float normalizedY = (localPoint.y + rectHeight / 2) / rectHeight; // Normalize to 0 (bottom) to 1 (top)
hoverItemUI = itemUI;
AssetLibraryItem destItem = itemUI.currentItem;
if (destItem == null)
return;
if (normalizedY >= 0.8f)
{
setToPriorSiblingItem?.Invoke(sourceItem, destItem);
}
else if (normalizedY <= 0.2f)
{
setToNextSiblingItem?.Invoke(sourceItem, destItem);
}
else
{
setToChildItem?.Invoke(sourceItem, destItem);
}
sourceItem = null;
}
onDragAndDrop?.Invoke(sourceItem);
sourceItem = null;
}
if (!passDragToChildren)
{
base.OnEndDrag(eventData);
}
}
public void OnPointerDown(PointerEventData eventData)
{
if (eventData.button == PointerEventData.InputButton.Left)
{
AssetLibraryScrollItemUI itemUI = GetTargetItemUI(eventData);
if (itemUI != null)
{
sourceItem = itemUI.currentItem;
}
}
}
public void OnPointerUp(PointerEventData eventData)
{
if (eventData.button == PointerEventData.InputButton.Right)
{
if (menuPopup != null)
{
menuPopup.SetActive(true);
}
}
}
private AssetLibraryScrollItemUI GetTargetItemUI(PointerEventData eventData)
{
PointerEventData pointerData = new PointerEventData(EventSystem.current)
{
position = eventData.position // Get mouse position at drag end
};
var results = new List<RaycastResult>();
EventSystem.current.RaycastAll(pointerData, results); // Raycast against UI elements
AssetLibraryScrollItemUI itemUI = null;
foreach (var result in results)
{
itemUI = result.gameObject.GetComponent<AssetLibraryScrollItemUI>();
if (itemUI != null) // Exclude the dragged item itself
{
break;
}
}
if (itemUI != null && itemUI.GetComponentInParent<AssetLibraryScrollRect>() == this)
return itemUI;
return null;
}
public bool IsPointerOverScrollRect()
{
return RectTransformUtility.RectangleContainsScreenPoint(
GetComponent<RectTransform>(), Input.mousePosition);
}
//public void OnPointerExit(PointerEventData eventData)
//{
// onExit?.Invoke(null);
//}
}
}