2021-04-15 20:18:03 +10:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections;
|
|
|
|
|
using System.Collections.Generic;
|
2021-05-05 21:27:09 +10:00
|
|
|
|
using System.Collections.Specialized;
|
2022-03-10 04:35:06 +11:00
|
|
|
|
using System.Diagnostics;
|
2021-04-15 20:18:03 +10:00
|
|
|
|
using UnityEngine;
|
2021-12-02 18:35:46 +11:00
|
|
|
|
using UniverseLib;
|
2022-01-31 21:24:01 +11:00
|
|
|
|
using UniverseLib.UI.Widgets.ScrollView;
|
|
|
|
|
using UniverseLib.Utility;
|
2021-04-15 20:18:03 +10:00
|
|
|
|
|
|
|
|
|
namespace UnityExplorer.UI.Widgets
|
|
|
|
|
{
|
2021-05-13 23:03:30 +10:00
|
|
|
|
public class TransformTree : ICellPoolDataSource<TransformCell>
|
2021-04-15 20:18:03 +10:00
|
|
|
|
{
|
|
|
|
|
public Func<IEnumerable<GameObject>> GetRootEntriesMethod;
|
2021-05-16 21:46:19 +10:00
|
|
|
|
public Action<GameObject> OnClickOverrideHandler;
|
2021-04-15 20:18:03 +10:00
|
|
|
|
|
2021-05-16 21:46:19 +10:00
|
|
|
|
public ScrollPool<TransformCell> ScrollPool;
|
2021-05-05 21:27:09 +10:00
|
|
|
|
|
2022-03-10 17:56:21 +11:00
|
|
|
|
// IMPORTANT CAVEAT WITH OrderedDictionary:
|
|
|
|
|
// While the performance is mostly good, there are two methods we should NEVER use:
|
|
|
|
|
// - Remove(object)
|
|
|
|
|
// - set_Item[object]
|
|
|
|
|
// These two methods have extremely bad performance due to using IndexOfKey(), which iterates the whole dictionary.
|
|
|
|
|
// Currently we do not use either of these methods, so everything should be constant time hash lookups.
|
|
|
|
|
// We DO make use of get_Item[object], get_Item[index], Add, Insert and RemoveAt, which OrderedDictionary perfectly meets our needs for.
|
2021-05-05 21:27:09 +10:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Key: UnityEngine.Transform instance ID<br/>
|
|
|
|
|
/// Value: CachedTransform
|
|
|
|
|
/// </summary>
|
2022-03-10 04:35:06 +11:00
|
|
|
|
internal readonly OrderedDictionary cachedTransforms = new();
|
2021-05-05 21:27:09 +10:00
|
|
|
|
|
|
|
|
|
// for keeping track of which actual transforms are expanded or not, outside of the cache data.
|
2022-03-10 04:35:06 +11:00
|
|
|
|
private readonly HashSet<int> expandedInstanceIDs = new();
|
|
|
|
|
private readonly HashSet<int> autoExpandedIDs = new();
|
2021-05-05 21:27:09 +10:00
|
|
|
|
|
2022-03-10 17:56:21 +11:00
|
|
|
|
// state for Traverse parse
|
2022-03-10 04:35:06 +11:00
|
|
|
|
private readonly HashSet<int> visited = new();
|
2022-03-10 17:56:21 +11:00
|
|
|
|
private bool needRefreshUI;
|
2021-05-26 17:42:31 +10:00
|
|
|
|
private int displayIndex;
|
2022-03-10 04:35:06 +11:00
|
|
|
|
int prevDisplayIndex;
|
2021-05-26 17:42:31 +10:00
|
|
|
|
|
2022-03-10 17:56:21 +11:00
|
|
|
|
private Coroutine refreshCoroutine;
|
|
|
|
|
private readonly Stopwatch traversedThisFrame = new();
|
|
|
|
|
|
|
|
|
|
// ScrollPool item count. PrevDisplayIndex is the highest index + 1 from our last traverse.
|
2022-03-10 04:35:06 +11:00
|
|
|
|
public int ItemCount => prevDisplayIndex;
|
2021-05-26 17:42:31 +10:00
|
|
|
|
|
2022-03-10 17:56:21 +11:00
|
|
|
|
// Search filter
|
2021-04-16 02:52:54 +10:00
|
|
|
|
public bool Filtering => !string.IsNullOrEmpty(currentFilter);
|
|
|
|
|
private bool wasFiltering;
|
|
|
|
|
|
2021-04-15 20:18:03 +10:00
|
|
|
|
public string CurrentFilter
|
|
|
|
|
{
|
|
|
|
|
get => currentFilter;
|
2021-04-16 02:52:54 +10:00
|
|
|
|
set
|
|
|
|
|
{
|
2021-04-30 23:43:27 +10:00
|
|
|
|
currentFilter = value ?? "";
|
2021-04-16 02:52:54 +10:00
|
|
|
|
if (!wasFiltering && Filtering)
|
|
|
|
|
wasFiltering = true;
|
|
|
|
|
else if (wasFiltering && !Filtering)
|
|
|
|
|
{
|
|
|
|
|
wasFiltering = false;
|
|
|
|
|
autoExpandedIDs.Clear();
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-04-15 20:18:03 +10:00
|
|
|
|
}
|
|
|
|
|
private string currentFilter;
|
|
|
|
|
|
2021-05-26 17:42:31 +10:00
|
|
|
|
public TransformTree(ScrollPool<TransformCell> scrollPool, Func<IEnumerable<GameObject>> getRootEntriesMethod)
|
|
|
|
|
{
|
|
|
|
|
ScrollPool = scrollPool;
|
|
|
|
|
GetRootEntriesMethod = getRootEntriesMethod;
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-10 17:56:21 +11:00
|
|
|
|
// Initialize and reset
|
|
|
|
|
|
|
|
|
|
// Must be called externally from owner of this TransformTree
|
2021-05-17 21:48:39 +10:00
|
|
|
|
public void Init()
|
|
|
|
|
{
|
|
|
|
|
ScrollPool.Initialize(this);
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-10 17:56:21 +11:00
|
|
|
|
// Called to completely reset the tree, ie. switching inspected GameObject
|
|
|
|
|
public void Rebuild()
|
|
|
|
|
{
|
|
|
|
|
autoExpandedIDs.Clear();
|
|
|
|
|
expandedInstanceIDs.Clear();
|
|
|
|
|
|
|
|
|
|
RefreshData(true, true, true, false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Called to completely wipe our data (ie, GameObject inspector returning to pool)
|
2021-05-17 21:48:39 +10:00
|
|
|
|
public void Clear()
|
|
|
|
|
{
|
2021-05-26 17:42:31 +10:00
|
|
|
|
this.cachedTransforms.Clear();
|
2021-05-17 21:48:39 +10:00
|
|
|
|
displayIndex = 0;
|
|
|
|
|
autoExpandedIDs.Clear();
|
|
|
|
|
expandedInstanceIDs.Clear();
|
2021-05-27 19:29:00 +10:00
|
|
|
|
this.ScrollPool.Refresh(true, true);
|
2022-03-10 17:56:21 +11:00
|
|
|
|
if (refreshCoroutine != null)
|
|
|
|
|
{
|
|
|
|
|
RuntimeHelper.StopCoroutine(refreshCoroutine);
|
|
|
|
|
refreshCoroutine = null;
|
|
|
|
|
}
|
2021-05-17 21:48:39 +10:00
|
|
|
|
}
|
|
|
|
|
|
2022-03-10 17:56:21 +11:00
|
|
|
|
// Checks if the given Instance ID is expanded or not
|
|
|
|
|
public bool IsTransformExpanded(int instanceID)
|
2021-05-26 17:42:31 +10:00
|
|
|
|
{
|
|
|
|
|
return Filtering ? autoExpandedIDs.Contains(instanceID)
|
|
|
|
|
: expandedInstanceIDs.Contains(instanceID);
|
|
|
|
|
}
|
2021-05-17 21:48:39 +10:00
|
|
|
|
|
2022-03-10 17:56:21 +11:00
|
|
|
|
// Jumps to a specific Transform in the tree and highlights it.
|
2021-05-26 17:42:31 +10:00
|
|
|
|
public void JumpAndExpandToTransform(Transform transform)
|
2021-05-16 21:46:19 +10:00
|
|
|
|
{
|
2021-05-26 17:42:31 +10:00
|
|
|
|
// make sure all parents of the object are expanded
|
|
|
|
|
var parent = transform.parent;
|
|
|
|
|
while (parent)
|
2021-05-16 21:46:19 +10:00
|
|
|
|
{
|
2021-05-26 17:42:31 +10:00
|
|
|
|
int pid = parent.GetInstanceID();
|
|
|
|
|
if (!expandedInstanceIDs.Contains(pid))
|
|
|
|
|
expandedInstanceIDs.Add(pid);
|
|
|
|
|
|
|
|
|
|
parent = parent.parent;
|
2021-05-16 21:46:19 +10:00
|
|
|
|
}
|
2021-05-26 17:42:31 +10:00
|
|
|
|
|
2022-03-10 17:56:21 +11:00
|
|
|
|
// Refresh cached transforms (no UI rebuild yet).
|
|
|
|
|
// Stop existing coroutine and do it oneshot.
|
|
|
|
|
RefreshData(false, false, true, true);
|
2021-05-26 17:42:31 +10:00
|
|
|
|
|
|
|
|
|
int transformID = transform.GetInstanceID();
|
|
|
|
|
|
|
|
|
|
// find the index of our transform in the list and jump to it
|
|
|
|
|
int idx;
|
|
|
|
|
for (idx = 0; idx < cachedTransforms.Count; idx++)
|
2021-05-16 21:46:19 +10:00
|
|
|
|
{
|
2021-05-26 17:42:31 +10:00
|
|
|
|
var cache = (CachedTransform)cachedTransforms[idx];
|
|
|
|
|
if (cache.InstanceID == transformID)
|
|
|
|
|
break;
|
2021-05-16 21:46:19 +10:00
|
|
|
|
}
|
2021-05-26 17:42:31 +10:00
|
|
|
|
|
2021-05-26 18:32:47 +10:00
|
|
|
|
ScrollPool.JumpToIndex(idx, OnCellJumpedTo);
|
2021-04-16 02:52:54 +10:00
|
|
|
|
}
|
|
|
|
|
|
2021-05-26 18:32:47 +10:00
|
|
|
|
private void OnCellJumpedTo(TransformCell cell)
|
2021-04-16 02:52:54 +10:00
|
|
|
|
{
|
2022-01-31 21:24:01 +11:00
|
|
|
|
RuntimeHelper.StartCoroutine(HighlightCellCoroutine(cell));
|
2021-05-26 18:32:47 +10:00
|
|
|
|
}
|
2021-05-26 17:42:31 +10:00
|
|
|
|
|
2021-05-26 18:32:47 +10:00
|
|
|
|
private IEnumerator HighlightCellCoroutine(TransformCell cell)
|
|
|
|
|
{
|
2021-05-26 17:42:31 +10:00
|
|
|
|
var button = cell.NameButton.Component;
|
|
|
|
|
button.StartColorTween(new Color(0.2f, 0.3f, 0.2f), false);
|
|
|
|
|
|
|
|
|
|
float start = Time.realtimeSinceStartup;
|
|
|
|
|
while (Time.realtimeSinceStartup - start < 1.5f)
|
|
|
|
|
yield return null;
|
|
|
|
|
|
|
|
|
|
button.OnDeselect(null);
|
2021-04-15 20:18:03 +10:00
|
|
|
|
}
|
|
|
|
|
|
2022-03-10 17:56:21 +11:00
|
|
|
|
// Perform a Traverse and optionally refresh the ScrollPool as well.
|
|
|
|
|
// If oneShot, then this happens instantly with no yield.
|
|
|
|
|
public void RefreshData(bool andRefreshUI, bool jumpToTop, bool stopExistingCoroutine, bool oneShot)
|
2021-04-15 20:18:03 +10:00
|
|
|
|
{
|
2022-03-10 04:35:06 +11:00
|
|
|
|
if (refreshCoroutine != null)
|
|
|
|
|
{
|
|
|
|
|
if (stopExistingCoroutine)
|
|
|
|
|
{
|
|
|
|
|
RuntimeHelper.StopCoroutine(refreshCoroutine);
|
|
|
|
|
refreshCoroutine = null;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-05 21:27:09 +10:00
|
|
|
|
visited.Clear();
|
|
|
|
|
displayIndex = 0;
|
2022-03-10 17:56:21 +11:00
|
|
|
|
needRefreshUI = false;
|
2022-03-10 04:35:06 +11:00
|
|
|
|
traversedThisFrame.Reset();
|
|
|
|
|
traversedThisFrame.Start();
|
2021-04-15 20:18:03 +10:00
|
|
|
|
|
2022-03-10 04:35:06 +11:00
|
|
|
|
IEnumerable<GameObject> rootObjects = GetRootEntriesMethod.Invoke();
|
2021-04-15 20:18:03 +10:00
|
|
|
|
|
2022-03-10 17:56:21 +11:00
|
|
|
|
refreshCoroutine = RuntimeHelper.StartCoroutine(RefreshCoroutine(rootObjects, andRefreshUI, jumpToTop, oneShot));
|
2022-03-10 04:35:06 +11:00
|
|
|
|
}
|
|
|
|
|
|
2022-03-10 17:56:21 +11:00
|
|
|
|
// Coroutine for batched updates, max 2000 gameobjects per frame so FPS doesn't get tanked when there is like 100k gameobjects.
|
|
|
|
|
// if "oneShot", then this will NOT be batched (if we need an immediate full update).
|
|
|
|
|
IEnumerator RefreshCoroutine(IEnumerable<GameObject> rootObjects, bool andRefreshUI, bool jumpToTop, bool oneShot)
|
2022-03-10 04:35:06 +11:00
|
|
|
|
{
|
|
|
|
|
foreach (var gameObj in rootObjects)
|
|
|
|
|
{
|
|
|
|
|
if (gameObj)
|
|
|
|
|
{
|
2022-03-10 17:56:21 +11:00
|
|
|
|
var enumerator = Traverse(gameObj.transform, null, 0, oneShot);
|
2022-03-10 04:35:06 +11:00
|
|
|
|
while (enumerator.MoveNext())
|
2022-03-10 17:56:21 +11:00
|
|
|
|
{
|
|
|
|
|
if (!oneShot)
|
|
|
|
|
yield return enumerator.Current;
|
|
|
|
|
}
|
2022-03-10 04:35:06 +11:00
|
|
|
|
}
|
|
|
|
|
}
|
2021-05-05 21:27:09 +10:00
|
|
|
|
|
|
|
|
|
// Prune displayed transforms that we didnt visit in that traverse
|
2021-05-26 17:42:31 +10:00
|
|
|
|
for (int i = cachedTransforms.Count - 1; i >= 0; i--)
|
2021-04-16 17:49:05 +10:00
|
|
|
|
{
|
2022-03-10 04:35:06 +11:00
|
|
|
|
var cached = (CachedTransform)cachedTransforms[i];
|
|
|
|
|
if (!visited.Contains(cached.InstanceID))
|
2021-05-05 21:27:09 +10:00
|
|
|
|
{
|
2022-03-10 04:35:06 +11:00
|
|
|
|
cachedTransforms.RemoveAt(i);
|
2022-03-10 17:56:21 +11:00
|
|
|
|
needRefreshUI = true;
|
2021-05-05 21:27:09 +10:00
|
|
|
|
}
|
2021-04-16 17:49:05 +10:00
|
|
|
|
}
|
2021-04-15 20:18:03 +10:00
|
|
|
|
|
2022-03-10 17:56:21 +11:00
|
|
|
|
if (andRefreshUI && needRefreshUI)
|
2022-03-10 04:35:06 +11:00
|
|
|
|
ScrollPool.Refresh(true, jumpToTop);
|
2021-05-05 21:27:09 +10:00
|
|
|
|
|
2022-03-10 04:35:06 +11:00
|
|
|
|
prevDisplayIndex = displayIndex;
|
2022-03-10 17:56:21 +11:00
|
|
|
|
refreshCoroutine = null;
|
|
|
|
|
}
|
2021-05-05 21:27:09 +10:00
|
|
|
|
|
2022-03-10 17:56:21 +11:00
|
|
|
|
// Recursive method to check a Transform and its children (if expanded).
|
|
|
|
|
// Parent and depth can be null/default.
|
|
|
|
|
private IEnumerator Traverse(Transform transform, CachedTransform parent, int depth, bool oneShot)
|
2022-03-10 04:35:06 +11:00
|
|
|
|
{
|
|
|
|
|
// Let's only tank 2ms of each frame (60->53fps)
|
|
|
|
|
if (traversedThisFrame.ElapsedMilliseconds > 2)
|
2021-04-22 17:53:29 +10:00
|
|
|
|
{
|
2022-03-10 04:35:06 +11:00
|
|
|
|
yield return null;
|
|
|
|
|
traversedThisFrame.Reset();
|
|
|
|
|
traversedThisFrame.Start();
|
2021-04-22 17:53:29 +10:00
|
|
|
|
}
|
2021-04-15 20:18:03 +10:00
|
|
|
|
|
2021-04-16 02:52:54 +10:00
|
|
|
|
int instanceID = transform.GetInstanceID();
|
|
|
|
|
|
2021-05-05 21:27:09 +10:00
|
|
|
|
if (visited.Contains(instanceID))
|
2022-03-10 04:35:06 +11:00
|
|
|
|
yield break;
|
2021-05-05 21:27:09 +10:00
|
|
|
|
|
2021-04-16 02:52:54 +10:00
|
|
|
|
if (Filtering)
|
|
|
|
|
{
|
2021-05-05 21:27:09 +10:00
|
|
|
|
if (!FilterHierarchy(transform))
|
2022-03-10 04:35:06 +11:00
|
|
|
|
yield break;
|
2021-05-05 21:27:09 +10:00
|
|
|
|
|
2021-05-16 21:46:19 +10:00
|
|
|
|
visited.Add(instanceID);
|
|
|
|
|
|
2021-05-05 21:27:09 +10:00
|
|
|
|
if (!autoExpandedIDs.Contains(instanceID))
|
|
|
|
|
autoExpandedIDs.Add(instanceID);
|
2021-04-16 02:52:54 +10:00
|
|
|
|
}
|
2021-05-16 21:46:19 +10:00
|
|
|
|
else
|
|
|
|
|
visited.Add(instanceID);
|
2021-04-16 02:52:54 +10:00
|
|
|
|
|
2021-04-15 20:18:03 +10:00
|
|
|
|
CachedTransform cached;
|
2021-05-26 17:42:31 +10:00
|
|
|
|
if (cachedTransforms.Contains(instanceID))
|
2021-04-15 20:18:03 +10:00
|
|
|
|
{
|
2021-05-26 17:42:31 +10:00
|
|
|
|
cached = (CachedTransform)cachedTransforms[(object)instanceID];
|
2022-03-10 04:35:06 +11:00
|
|
|
|
int prevSiblingIdx = cached.SiblingIndex;
|
2021-05-08 06:18:28 +10:00
|
|
|
|
if (cached.Update(transform, depth))
|
2022-03-10 04:35:06 +11:00
|
|
|
|
{
|
2022-03-10 17:56:21 +11:00
|
|
|
|
needRefreshUI = true;
|
2022-03-10 04:35:06 +11:00
|
|
|
|
|
|
|
|
|
// If the sibling index changed, we need to shuffle it in our cached transforms list.
|
|
|
|
|
if (prevSiblingIdx != cached.SiblingIndex)
|
|
|
|
|
{
|
|
|
|
|
cachedTransforms.Remove(instanceID);
|
|
|
|
|
if (cachedTransforms.Count <= displayIndex)
|
|
|
|
|
cachedTransforms.Add(instanceID, cached);
|
|
|
|
|
else
|
|
|
|
|
cachedTransforms.Insert(displayIndex, instanceID, cached);
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-04-15 20:18:03 +10:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2022-03-10 17:56:21 +11:00
|
|
|
|
needRefreshUI = true;
|
2021-04-26 19:56:21 +10:00
|
|
|
|
cached = new CachedTransform(this, transform, depth, parent);
|
2021-05-26 17:42:31 +10:00
|
|
|
|
if (cachedTransforms.Count <= displayIndex)
|
|
|
|
|
cachedTransforms.Add(instanceID, cached);
|
2021-05-05 21:27:09 +10:00
|
|
|
|
else
|
2021-05-26 17:42:31 +10:00
|
|
|
|
cachedTransforms.Insert(displayIndex, instanceID, cached);
|
2021-04-15 20:18:03 +10:00
|
|
|
|
}
|
|
|
|
|
|
2021-05-05 21:27:09 +10:00
|
|
|
|
displayIndex++;
|
2021-04-15 20:18:03 +10:00
|
|
|
|
|
2022-03-10 17:56:21 +11:00
|
|
|
|
if (IsTransformExpanded(instanceID) && cached.Value.childCount > 0)
|
2021-04-15 20:18:03 +10:00
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < transform.childCount; i++)
|
2022-03-10 04:35:06 +11:00
|
|
|
|
{
|
2022-03-10 17:56:21 +11:00
|
|
|
|
var enumerator = Traverse(transform.GetChild(i), cached, depth + 1, oneShot);
|
2022-03-10 04:35:06 +11:00
|
|
|
|
while (enumerator.MoveNext())
|
2022-03-10 17:56:21 +11:00
|
|
|
|
{
|
|
|
|
|
if (!oneShot)
|
|
|
|
|
yield return enumerator.Current;
|
|
|
|
|
}
|
2022-03-10 04:35:06 +11:00
|
|
|
|
}
|
2021-04-15 20:18:03 +10:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private bool FilterHierarchy(Transform obj)
|
|
|
|
|
{
|
2021-04-30 23:43:27 +10:00
|
|
|
|
if (obj.name.ContainsIgnoreCase(currentFilter))
|
2021-04-15 20:18:03 +10:00
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
if (obj.childCount <= 0)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < obj.childCount; i++)
|
|
|
|
|
if (FilterHierarchy(obj.GetChild(i)))
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-30 23:43:27 +10:00
|
|
|
|
public void SetCell(TransformCell cell, int index)
|
2021-04-15 20:18:03 +10:00
|
|
|
|
{
|
2021-05-26 17:42:31 +10:00
|
|
|
|
if (index < cachedTransforms.Count)
|
2021-05-16 21:46:19 +10:00
|
|
|
|
{
|
2021-05-26 17:42:31 +10:00
|
|
|
|
cell.ConfigureCell((CachedTransform)cachedTransforms[index], index);
|
2021-05-16 21:46:19 +10:00
|
|
|
|
if (Filtering)
|
|
|
|
|
{
|
|
|
|
|
if (cell.cachedTransform.Name.ContainsIgnoreCase(currentFilter))
|
|
|
|
|
cell.NameButton.ButtonText.color = Color.green;
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-04-15 20:18:03 +10:00
|
|
|
|
else
|
|
|
|
|
cell.Disable();
|
|
|
|
|
}
|
2022-03-10 04:35:06 +11:00
|
|
|
|
|
|
|
|
|
public void OnCellBorrowed(TransformCell cell)
|
|
|
|
|
{
|
|
|
|
|
cell.OnExpandToggled += OnCellExpandToggled;
|
|
|
|
|
cell.OnGameObjectClicked += OnGameObjectClicked;
|
|
|
|
|
cell.OnEnableToggled += OnCellEnableToggled;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void OnGameObjectClicked(GameObject obj)
|
|
|
|
|
{
|
|
|
|
|
if (OnClickOverrideHandler != null)
|
|
|
|
|
OnClickOverrideHandler.Invoke(obj);
|
|
|
|
|
else
|
|
|
|
|
InspectorManager.Inspect(obj);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void OnCellExpandToggled(CachedTransform cache)
|
|
|
|
|
{
|
|
|
|
|
var instanceID = cache.InstanceID;
|
|
|
|
|
if (expandedInstanceIDs.Contains(instanceID))
|
|
|
|
|
expandedInstanceIDs.Remove(instanceID);
|
|
|
|
|
else
|
|
|
|
|
expandedInstanceIDs.Add(instanceID);
|
|
|
|
|
|
2022-03-12 20:16:37 +11:00
|
|
|
|
RefreshData(true, false, true, true);
|
2022-03-10 04:35:06 +11:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void OnCellEnableToggled(CachedTransform cache)
|
|
|
|
|
{
|
|
|
|
|
cache.Value.gameObject.SetActive(!cache.Value.gameObject.activeSelf);
|
|
|
|
|
|
2022-03-12 20:16:37 +11:00
|
|
|
|
RefreshData(true, false, true, true);
|
2022-03-10 04:35:06 +11:00
|
|
|
|
}
|
2021-04-15 20:18:03 +10:00
|
|
|
|
}
|
|
|
|
|
}
|