using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices.Expando; using System.Security.Cryptography; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; using XRLib.UI; namespace Studio { public class HierarchyPanel : PanelBase,IDropHandler { public ScrollRect scrollrect_hierarchycontent; public UI_HierarchyItem prf_hierarchyitem; internal Action onClickItem; internal Action onItemDrop; internal Action OnItemDropOnItem; private Dictionary itemToView = new(); private Dictionary viewToItem = new(); HashSet tempHashSet = new(); public float tap = 30f; public override void AfterAwake() { prf_hierarchyitem = Resources.Load("Prefabs/UI/PRF_TreeItem"); } public void OnDrop(PointerEventData eventData) { if (eventData.pointerDrag != null) { UI_HierarchyItem draggeditem = eventData.pointerDrag.GetComponent(); if (draggeditem) { var item = viewToItem[draggeditem]; onItemDrop(item); } } } public void AddItem(TreeItem item) { UI_HierarchyItem itemView = Instantiate(prf_hierarchyitem, scrollrect_hierarchycontent.content); item.onExpand += Expand; item.onFold += Fold; itemView.Set(item); itemView.onDestroy += RemoveItem; itemView.onClick += OnClickItem; UI_DragDrop_ ui_DragDrop = itemView.transform.GetComponent(); ui_DragDrop.OnDropItem += ItemDrop; viewToItem.Add(itemView, item); itemToView.Add(item, itemView); } void ItemDrop(UIBase parent, UIBase child) { if(parent is UI_HierarchyItem parentItem && child is UI_HierarchyItem childItem) { var pi = viewToItem[parentItem]; var ci = viewToItem[childItem]; OnItemDropOnItem(pi, ci); } } void Expand(TreeItem item) { var rootChildren = item.children; for (int i = 0; i < rootChildren.Count; ++i) { var rootChild = item.children[i]; tempHashSet.Add(rootChild); if (!rootChild.expanded) { continue; } var rootChildItem = rootChild; for (int j = 0; j < rootChildItem.children.Count; ++j) { var leafChild = rootChildItem.children[j]; GetExpandTargets(leafChild); } } foreach (var r in tempHashSet) { itemToView[r].gameObject.SetActive(true); } tempHashSet.Clear(); } void GetExpandTargets(TreeItem i) { tempHashSet.Add(i); if (!i.expanded) { return; } var children = i.children; foreach (var item in children) { tempHashSet.Add(item); GetExpandTargets(item); } } void Fold(TreeItem item) { GetFoldTargets(item); foreach (var r in tempHashSet) { var view = itemToView[r]; view.SetActive(false); } tempHashSet.Clear(); } void GetFoldTargets(TreeItem i) { var children = i.children; foreach (var item in children) { if (itemToView[i].gameObject.activeSelf) { tempHashSet.Add(item); GetFoldTargets(item); } } } public void UpdateIndex(List data) { for(int i = 0; i < data.Count; i++) { var item = data[i]; var view = itemToView[item]; var depth = data[i].depth; view.transform.SetSiblingIndex(i); var TapRectTransform = view.transform.GetChild(0).GetComponentInChildren(true); TapRectTransform.offsetMin = new Vector2(depth * tap, TapRectTransform.offsetMin.y); } } void OnClickItem(UI_HierarchyItem view) { var item = viewToItem[view]; onClickItem?.Invoke(item.ToItem); } public void RemoveItem(UI_HierarchyItem to) { itemToView.Remove(viewToItem[to]); viewToItem.Remove(to); } } }