202 lines
6.6 KiB
C#
202 lines
6.6 KiB
C#
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
|
|
namespace BrewMonster.Scripts.Task.UI
|
|
{
|
|
public class TaskTreeView : MonoBehaviour, IRefreshLayout
|
|
{
|
|
[SerializeField] private TaskTreeViewHolder m_pTreeViewHolder;
|
|
|
|
[Header("DEBUG")]
|
|
[SerializeField] private TaskTreeViewHolder _currentSelectedItem = null;
|
|
[SerializeField] private TaskTreeViewHolder[] m_aTreeViewItems;
|
|
|
|
private RectTransform _rectTransform;
|
|
private void Awake()
|
|
{
|
|
_rectTransform = GetComponent<RectTransform>();
|
|
}
|
|
|
|
private void Start()
|
|
{
|
|
EventBus.Subscribe<TaskItemClickEvent>(evt =>
|
|
{
|
|
SetSelectedItem(evt.Data);
|
|
});
|
|
}
|
|
|
|
public void SetItemData(TaskTreeViewHolder item, uint taskType)
|
|
{
|
|
item.SetItemData(taskType);
|
|
}
|
|
|
|
public uint GetItemData(TaskTreeViewHolder item)
|
|
{
|
|
if (item == null)
|
|
return 0;
|
|
return item.GetItemData();
|
|
}
|
|
|
|
public TaskTreeViewHolder GetNextSiblingItem(TaskTreeViewHolder item)
|
|
{
|
|
|
|
if (m_aTreeViewItems == null)
|
|
{
|
|
m_aTreeViewItems = GetComponentsInChildren<TaskTreeViewHolder>(true);
|
|
}
|
|
|
|
for (int i = 0; i < m_aTreeViewItems.Length - 1; i++)
|
|
{
|
|
if (m_aTreeViewItems[i] == item)
|
|
{
|
|
return m_aTreeViewItems[i + 1];
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public TaskTreeViewHolder InsertItem(string text, TaskTreeViewHolder pParent, TaskTreeViewHolder pAfter)
|
|
{
|
|
//caculate treelevel first
|
|
int treeLevel = pParent != null ? pParent.GetTreeLevel() + 1 : 0;
|
|
// Create a new item GameObject and component
|
|
TaskTreeViewHolder pItem = Instantiate(m_pTreeViewHolder);
|
|
|
|
if(pParent != null)
|
|
{
|
|
pParent.SetLastItem(false);
|
|
}
|
|
pItem.SetLastItem(true);
|
|
GameObject go = pItem.gameObject;
|
|
// go.name = $"Task_{}";
|
|
if (pItem == null) return null;
|
|
|
|
// Parent: root (this) if null; otherwise under given parent item
|
|
var parentTransform = (pParent != null ? pParent.transform : this.transform);
|
|
go.transform.SetParent(parentTransform, false);
|
|
|
|
// Set sibling position: after specific item if provided; otherwise append to end
|
|
if (pAfter != null && pAfter.transform.parent == parentTransform)
|
|
{
|
|
int afterIndex = pAfter.transform.GetSiblingIndex();
|
|
go.transform.SetSiblingIndex(afterIndex + 1);
|
|
}
|
|
else
|
|
{
|
|
go.transform.SetAsLastSibling();
|
|
}
|
|
|
|
// Optionally set label text if a TMP_Text is attached under the item (not required here)
|
|
// var label = go.GetComponentInChildren<TMPro.TMP_Text>(true);
|
|
// if (label != null) label.text = text ?? string.Empty;
|
|
pItem.SetItemText(text);
|
|
pItem.SetTreeLevel(treeLevel);
|
|
|
|
// Refresh local cache of items
|
|
m_aTreeViewItems = GetComponentsInChildren<TaskTreeViewHolder>(true);
|
|
|
|
// pParent.RefreshLayout();
|
|
if(pParent) pParent.OnExpand(false); // Collapse parent to show new item only when expanded
|
|
|
|
return pItem;
|
|
}
|
|
|
|
public void DeleteAllItems()
|
|
{
|
|
List<Transform> childrenCopy = new();
|
|
foreach (Transform child in transform)
|
|
{
|
|
// Destroy(child.GetComponent<TaskTreeViewHolder>());
|
|
childrenCopy.Add(child);
|
|
}
|
|
|
|
foreach (var child in childrenCopy)
|
|
{
|
|
child.SetParent(null);
|
|
Destroy(child.gameObject);
|
|
}
|
|
|
|
m_aTreeViewItems = null;
|
|
// m_aTreeViewItems = GetComponentsInChildren<TaskTreeViewHolder>(true);
|
|
_currentSelectedItem = null;
|
|
}
|
|
|
|
|
|
public TaskTreeViewHolder GetItemByData(uint taskType)
|
|
{
|
|
//This is work around to avoid the null proplem.
|
|
//TODO: Refine Logic.
|
|
if(this == null)
|
|
return null;
|
|
if (m_aTreeViewItems == null)
|
|
{
|
|
m_aTreeViewItems = new TaskTreeViewHolder[this.transform.childCount];
|
|
m_aTreeViewItems = GetComponentsInChildren<TaskTreeViewHolder>(true);
|
|
}
|
|
|
|
foreach (var item in m_aTreeViewItems)
|
|
{
|
|
if (item.GetItemData() == taskType)
|
|
{
|
|
return item;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public TaskTreeViewHolder GetFirstChild()
|
|
{
|
|
return transform.childCount == 0 ? null : transform.GetChild(0).GetComponent<TaskTreeViewHolder>();
|
|
}
|
|
|
|
public TaskTreeViewHolder GetSelectedItem()
|
|
{
|
|
return _currentSelectedItem;
|
|
}
|
|
|
|
void SetSelectedItem(uint idItem)
|
|
{
|
|
_currentSelectedItem = GetItemByData(idItem);
|
|
}
|
|
|
|
public void RefreshLayout()
|
|
{
|
|
var parent = _rectTransform;
|
|
foreach(var child in GetComponentsInChildren<TaskTreeViewHolder>(true))
|
|
{
|
|
child.RefreshSelf();
|
|
}
|
|
// Force Unity to rebuild layout immediately
|
|
parent.ForceUpdateRectTransforms();
|
|
LayoutRebuilder.ForceRebuildLayoutImmediate(parent);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Resolve all prefabs after quest loading is complete
|
|
/// This should be called after all items are added and SetLastItem() calls are done
|
|
/// 在任务加载完成后解析所有预制体
|
|
/// 这应该在所有项目添加完成且SetLastItem()调用完成后调用
|
|
/// </summary>
|
|
public void ResolveAllPrefabs()
|
|
{
|
|
// Refresh cache to get all items
|
|
m_aTreeViewItems = GetComponentsInChildren<TaskTreeViewHolder>(true);
|
|
|
|
if (m_aTreeViewItems == null) return;
|
|
|
|
// Resolve prefab for each item
|
|
foreach (var item in m_aTreeViewItems)
|
|
{
|
|
if (item != null)
|
|
{
|
|
item.ResolvePrefab();
|
|
item.RefreshSelf();
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
} |