Files
Studio/Assets/Scripts/Studio/UI/TreeView/HierarchyScrollItemUI.cs
2025-06-24 16:57:39 +09:00

229 lines
7.9 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using System;
using XRLib;
using Studio.Util;
using Studio.AssetTool;
namespace Studio.HierarchyTree
{
public class HierarchyScrollItemUI : UnityEngine.MonoBehaviour, IPointerClickHandler, IPointerEnterHandler, IPointerExitHandler//, IBeginDragHandler, IEndDragHandler,
{
public TMP_Text nameText;
public Image iconImage;
public Image loadProgress;
public Button expandButton;
public RectTransform paddingRT;
public Sprite spriteExpanded;
public Sprite spriteCollapsed;
public UnityEvent<HierarchyItem> onClickSingle;
public UnityEvent<HierarchyItem> onClickAddSingle;
public UnityEvent<HierarchyItem> onClickMultiple;
public UnityEvent<HierarchyItem> onHover;
public UnityEvent onToggleExpand;
public UnityEvent<HierarchyItem> onDragStart;
public UnityEvent<HierarchyItem> onDragEnd;
public UnityEvent<PointerEventData> onScroll;
public Color selectedColor;
public Color hoverColor;
public HierarchyItem currentItem;
public Image upperLine;
public Image lowerLine;
public Color lineColor;
public GameObject highLight;
public List<HierarchyItemSprite> itemSprites;
private Image backgroundImage;
public bool isSelected;
private void Awake()
{
backgroundImage = transform.Find("Hover").GetComponent<Image>();
}
public int SetItemData(HierarchyItem item)
{
currentItem = item;
SetName();
currentItem.isExpanded = item.isExpanded;
item.onLoadProgress.RemoveAllListeners();
item.onLoadProgress.AddListener(OnLoadProgress);
loadProgress.gameObject.SetActive(false);
HierarchyItemSprite itemSprite = itemSprites.Find((x) => x.type == item.type);
if (itemSprite != null) iconImage.sprite = itemSprite.sprite;
expandButton.image.sprite = currentItem.isExpanded == true ? spriteExpanded : spriteCollapsed;
float width = nameText.GetComponent<RectTransform>().sizeDelta.x + iconImage.GetComponent<RectTransform>().sizeDelta.x;
float paddingSize = item.layerNum * expandButton.GetComponent<RectTransform>().sizeDelta.x;
if (item.children.Count > 0)
{
expandButton.gameObject.SetActive(true);
width += expandButton.GetComponent<RectTransform>().sizeDelta.x;
}
else
{
expandButton.gameObject.SetActive(false);
paddingSize += expandButton.GetComponent<RectTransform>().sizeDelta.x;
}
width += paddingSize;
paddingRT.sizeDelta = new Vector2(paddingSize, paddingRT.sizeDelta.y);
upperLine.GetComponent<RectTransform>().offsetMin = new Vector2(paddingSize, 0);
lowerLine.GetComponent<RectTransform>().offsetMin = new Vector2(paddingSize, 0);
return Mathf.RoundToInt(width);
}
public void SetSelected(bool selected)
{
isSelected = selected;
SetName();
if (isSelected)
{
backgroundImage.color = selectedColor;
}
else
{
backgroundImage.color = Color.clear;
}
}
private void SetName()
{
nameText.text = currentItem.name;
CustomAssetRenderObject connectObj = currentItem.linkedObject.GetComponent<CustomAssetRenderObject>();
if (connectObj != null && !string.IsNullOrEmpty(connectObj.code))
{
nameText.text += $" ({connectObj.code})";
}
}
public void SetSelected(List<HierarchyItem> selectedItems)
{
isSelected = selectedItems.Contains(currentItem);
SetName();
if (isSelected)
{
backgroundImage.color = selectedColor;
}
else
{
backgroundImage.color = Color.clear;
}
}
public void ToggleExpandCollapse()
{
currentItem.isExpanded = !currentItem.isExpanded;
expandButton.image.sprite = currentItem.isExpanded == true ? spriteExpanded : spriteCollapsed;
onToggleExpand?.Invoke();
}
public void OnPointerClick(PointerEventData eventData)
{
if (eventData.button == PointerEventData.InputButton.Left)
{
if (Input.GetKey(KeyCode.LeftControl))
{
onClickAddSingle?.Invoke(currentItem);
}
else if (Input.GetKey(KeyCode.LeftShift))
{
onClickMultiple?.Invoke(currentItem);
}
else
{
onClickSingle?.Invoke(currentItem);
}
}
}
public void OnPointerEnter(PointerEventData eventData)
{
backgroundImage.color = isSelected? selectedColor : hoverColor;
onHover?.Invoke(currentItem);
}
public void OnPointerExit(PointerEventData eventData)
{
backgroundImage.color = isSelected? selectedColor : Color.clear;
}
public void OnBeginDrag(BaseEventData data)
{
Debug.Log("DragStart " + currentItem.name);
onDragStart?.Invoke(currentItem);
}
public void OnEndDrag()
{
Debug.Log("DragEnd " + currentItem.name);
onDragEnd?.Invoke(currentItem);
}
public void OnEndDrag(BaseEventData data)
{
HierarchyScrollItemUI itemUI = GetDropTarget(data);
if (itemUI != null)
itemUI.OnEndDrag();
}
private HierarchyScrollItemUI GetDropTarget(BaseEventData data)
{
PointerEventData eventData = (PointerEventData)data;
PointerEventData pointerData = new PointerEventData(EventSystem.current)
{
position = eventData.position
};
var results = new System.Collections.Generic.List<RaycastResult>();
EventSystem.current.RaycastAll(pointerData, results);
foreach (var result in results)
{
HierarchyScrollItemUI itemUI = result.gameObject.GetComponent<HierarchyScrollItemUI>();
if (itemUI != null)
{
return itemUI;
}
}
return null;
}
public void OnScroll(BaseEventData data)
{
PointerEventData eventData = (PointerEventData)data;
onScroll?.Invoke(eventData);
}
public void ActivateUpperHighlight()
{
upperLine.color = lineColor;
}
public void ActivateLowerHighlight()
{
lowerLine.color = lineColor;
}
public void ActivateMidHighlight()
{
highLight.SetActive(true);
}
public void DeactivateAllHighlights()
{
upperLine.color = Color.clear;
lowerLine.color = Color.clear;
highLight.SetActive(false);
}
public void OnLoadProgress(float ratio)
{
if (ratio == 1.0f)
{
loadProgress.gameObject.SetActive(false);
return;
}
if (loadProgress.gameObject.activeSelf == false)
{
loadProgress.gameObject.SetActive(true);
}
loadProgress.fillAmount = ratio;
}
}
[Serializable]
public class HierarchyItemSprite
{
public HierarchyItemType type;
public Sprite sprite;
}
}