Implement jumping to index in TransformTree

This commit is contained in:
Sinai 2021-05-26 17:42:31 +10:00
parent 9e7bb1a625
commit 041f2938f7
4 changed files with 166 additions and 81 deletions

View File

@ -232,6 +232,15 @@ namespace UnityExplorer.UI.Inspectors
}
}
private void OnExploreButtonClicked()
{
var panel = UIManager.GetPanel<Panels.ObjectExplorerPanel>(UIManager.Panels.ObjectExplorer);
UIManager.SetPanelActive(panel, true);
panel.SetTab(0);
panel.SceneExplorer.JumpToTransform(this.Parent.GOTarget.transform);
}
private void OnLayerDropdownChanged(int value)
{
GOTarget.layer = value;
@ -533,6 +542,12 @@ namespace UnityExplorer.UI.Inspectors
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(thirdrow, false, false, true, true, 5, 0, 0, 0, 0, default);
UIFactory.SetLayoutElement(thirdrow, minHeight: 25, flexibleWidth: 9999);
// Inspect in Explorer button
var explorerBtn = UIFactory.CreateButton(thirdrow, "ExploreBtn", "Show in Explorer", new Color(0.15f, 0.15f, 0.15f));
UIFactory.SetLayoutElement(explorerBtn.Component.gameObject, minHeight: 25, minWidth: 100);
explorerBtn.ButtonText.fontSize = 12;
explorerBtn.OnClick += OnExploreButtonClicked;
// Scene
var sceneLabel = UIFactory.CreateLabel(thirdrow, "SceneLabel", "Scene:", TextAnchor.MiddleLeft, Color.grey);
UIFactory.SetLayoutElement(sceneLabel.gameObject, minHeight: 25, minWidth: 50);
@ -547,7 +562,7 @@ namespace UnityExplorer.UI.Inspectors
UIFactory.SetLayoutElement(layerLabel.gameObject, minHeight: 25, minWidth: 50);
var layerDrop = UIFactory.CreateDropdown(thirdrow, out LayerDropdown, "0", 14, OnLayerDropdownChanged);
UIFactory.SetLayoutElement(layerDrop, minHeight: 25, minWidth: 120, flexibleWidth: 999);
UIFactory.SetLayoutElement(layerDrop, minHeight: 25, minWidth: 110, flexibleWidth: 999);
LayerDropdown.captionText.color = SignatureHighlighter.EnumGreen;
if (layerToNames == null)
GetLayerNames();

View File

@ -58,6 +58,23 @@ namespace UnityExplorer.UI.ObjectExplorer
Tree.RefreshData(true);
}
public void JumpToTransform(Transform transform)
{
if (!transform)
return;
// select the transform's scene
var go = transform.gameObject;
if (SceneHandler.SelectedScene != go.scene)
{
int idx = sceneDropdown.options.IndexOf(sceneToDropdownOption[go.scene.handle]);
sceneDropdown.value = idx;
}
// Let the TransformTree handle the rest
Tree.JumpAndExpandToTransform(transform);
}
private void OnDropdownChanged(int value)
{
if (value < 0 || SceneHandler.LoadedScenes.Count <= value)
@ -122,7 +139,7 @@ namespace UnityExplorer.UI.ObjectExplorer
{
if ((!string.IsNullOrEmpty(input) && !Tree.Filtering) || (string.IsNullOrEmpty(input) && Tree.Filtering))
{
Tree.displayedObjects.Clear();
Tree.cachedTransforms.Clear();
}
Tree.CurrentFilter = input;

View File

@ -7,7 +7,6 @@ using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.Core.Input;
using UnityExplorer.UI.Models;
using UnityExplorer.UI.ObjectPool;
using UnityExplorer.UI.Panels;
namespace UnityExplorer.UI.Widgets
@ -20,7 +19,7 @@ namespace UnityExplorer.UI.Widgets
/// <summary>
/// An object-pooled ScrollRect, attempts to support content of any size and provide a scrollbar for it.
/// </summary>
public class ScrollPool<T> : UIBehaviourModel where T : ICell
public class ScrollPool<T> : UIBehaviourModel, IEnumerable<CellInfo> where T : ICell
{
public ScrollPool(ScrollRect scrollRect)
{
@ -138,9 +137,23 @@ namespace UnityExplorer.UI.Widgets
RefreshCells(setCellData, true);
}
// Initialize
public void JumpToIndex(int index)
{
RefreshCells(true, true);
//private bool Initialized;
float normalized = HeightCache[index].startPosition / HeightCache.TotalHeight;
// Slide to the normalized position
OnSliderValueChanged(normalized);
}
// IEnumerable
public IEnumerator<CellInfo> GetEnumerator() => EnumerateCellPool();
IEnumerator IEnumerable.GetEnumerator() => EnumerateCellPool();
// Initialize
/// <summary>Should be called only once, when the scroll pool is created.</summary>
public void Initialize(ICellPoolDataSource<T> dataSource, Action onHeightChangedListener = null)
@ -178,9 +191,8 @@ namespace UnityExplorer.UI.Widgets
// create initial cell pool and set cells
CreateCellPool();
var enumerator = GetPoolEnumerator();
while (enumerator.MoveNext())
SetCell(CellPool[enumerator.Current.cellIndex], enumerator.Current.dataIndex);
foreach (var cell in this)
SetCell(CellPool[cell.cellIndex], cell.dataIndex);
LayoutRebuilder.ForceRebuildLayoutImmediate(Content);
prevContentHeight = Content.rect.height;
@ -217,18 +229,18 @@ namespace UnityExplorer.UI.Widgets
// Cell pool
private CellInfo _cellInfo = new CellInfo();
private CellInfo _current;
public IEnumerator<CellInfo> GetPoolEnumerator()
private IEnumerator<CellInfo> EnumerateCellPool()
{
int cellIdx = topPoolIndex;
int dataIndex = TopDataIndex;
int iterated = 0;
while (iterated < CellPool.Count)
{
_cellInfo.cellIndex = cellIdx;
_cellInfo.dataIndex = dataIndex;
yield return _cellInfo;
_current.cellIndex = cellIdx;
_current.dataIndex = dataIndex;
yield return _current;
cellIdx++;
if (cellIdx >= CellPool.Count)
@ -368,16 +380,13 @@ namespace UnityExplorer.UI.Widgets
CheckDataSourceCountChange(out bool jumpToBottom);
// update date height cache, and set cells if 'andReload'
var enumerator = GetPoolEnumerator();
while (enumerator.MoveNext())
foreach (var cellInfo in this)
{
var curr = enumerator.Current;
var cell = CellPool[curr.cellIndex];
var cell = CellPool[cellInfo.cellIndex];
if (andReloadFromDataSource)
SetCell(cell, curr.dataIndex);
SetCell(cell, cellInfo.dataIndex);
else
HeightCache.SetIndex(curr.dataIndex, cell.Rect.rect.height);
HeightCache.SetIndex(cellInfo.dataIndex, cell.Rect.rect.height);
}
// force check recycles
@ -405,12 +414,8 @@ namespace UnityExplorer.UI.Widgets
private void RefreshCellHeightsFast()
{
var enumerator = GetPoolEnumerator();
while (enumerator.MoveNext())
{
var curr = enumerator.Current;
HeightCache.SetIndex(curr.dataIndex, CellPool[curr.cellIndex].Rect.rect.height);
}
foreach (var cellInfo in this)
HeightCache.SetIndex(cellInfo.dataIndex, CellPool[cellInfo.cellIndex].Rect.rect.height);
}
private void SetCell(T cachedCell, int dataIndex)
@ -619,12 +624,10 @@ namespace UnityExplorer.UI.Widgets
else
{
bottomDataIndex = desiredBottomIndex;
var enumerator = GetPoolEnumerator();
while (enumerator.MoveNext())
foreach (var info in this)
{
var curr = enumerator.Current;
var cell = CellPool[curr.cellIndex];
SetCell(cell, curr.dataIndex);
var cell = CellPool[info.cellIndex];
SetCell(cell, info.dataIndex);
}
}

View File

@ -6,8 +6,6 @@ using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.UI.ObjectPool;
using UnityExplorer.UI.Widgets;
namespace UnityExplorer.UI.Widgets
{
@ -22,13 +20,19 @@ namespace UnityExplorer.UI.Widgets
/// Key: UnityEngine.Transform instance ID<br/>
/// Value: CachedTransform
/// </summary>
internal readonly OrderedDictionary displayedObjects = new OrderedDictionary();
internal readonly OrderedDictionary cachedTransforms = new OrderedDictionary();
// for keeping track of which actual transforms are expanded or not, outside of the cache data.
private readonly HashSet<int> expandedInstanceIDs = new HashSet<int>();
private readonly HashSet<int> autoExpandedIDs = new HashSet<int>();
public int ItemCount => displayedObjects.Count;
private readonly HashSet<int> visited = new HashSet<int>();
private bool needRefresh;
private int displayIndex;
public int ItemCount => cachedTransforms.Count;
private readonly HashSet<int> highlightedTransforms = new HashSet<int>();
public bool Filtering => !string.IsNullOrEmpty(currentFilter);
private bool wasFiltering;
@ -50,6 +54,25 @@ namespace UnityExplorer.UI.Widgets
}
private string currentFilter;
public TransformTree(ScrollPool<TransformCell> scrollPool, Func<IEnumerable<GameObject>> getRootEntriesMethod)
{
ScrollPool = scrollPool;
GetRootEntriesMethod = getRootEntriesMethod;
}
public void OnCellBorrowed(TransformCell cell)
{
cell.OnExpandToggled += ToggleExpandCell;
cell.OnGameObjectClicked += OnGameObjectClicked;
}
private void OnGameObjectClicked(GameObject obj)
{
if (OnClickOverrideHandler != null)
OnClickOverrideHandler.Invoke(obj);
else
InspectorManager.Inspect(obj);
}
public void Init()
{
@ -58,37 +81,79 @@ namespace UnityExplorer.UI.Widgets
public void Clear()
{
this.displayedObjects.Clear();
this.cachedTransforms.Clear();
displayIndex = 0;
autoExpandedIDs.Clear();
expandedInstanceIDs.Clear();
}
public void OnGameObjectClicked(GameObject obj)
{
if (OnClickOverrideHandler != null)
{
OnClickOverrideHandler.Invoke(obj);
}
else
{
InspectorManager.Inspect(obj);
}
}
public TransformTree(ScrollPool<TransformCell> scrollPool, Func<IEnumerable<GameObject>> getRootEntriesMethod)
{
ScrollPool = scrollPool;
GetRootEntriesMethod = getRootEntriesMethod;
}
public bool IsCellExpanded(int instanceID)
{
return Filtering ? autoExpandedIDs.Contains(instanceID)
: expandedInstanceIDs.Contains(instanceID);
}
public void JumpAndExpandToTransform(Transform transform)
{
// make sure all parents of the object are expanded
var parent = transform.parent;
while (parent)
{
int pid = parent.GetInstanceID();
if (!expandedInstanceIDs.Contains(pid))
expandedInstanceIDs.Add(pid);
parent = parent.parent;
}
// Refresh cached transforms (no UI rebuild yet)
RefreshData(false);
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++)
{
var cache = (CachedTransform)cachedTransforms[idx];
if (cache.InstanceID == transformID)
break;
}
ScrollPool.JumpToIndex(idx);
// 'select' (highlight) the cell containing our transform
foreach (var cellInfo in ScrollPool)
{
var cell = ScrollPool.CellPool[cellInfo.cellIndex];
if (!cell.Enabled)
continue;
if (cell.cachedTransform.InstanceID == transformID)
{
RuntimeProvider.Instance.StartCoroutine(HighlightCellCoroutine(cell, transformID));
break;
}
}
}
private IEnumerator HighlightCellCoroutine(TransformCell cell, int transformID)
{
if (highlightedTransforms.Contains(transformID))
yield break;
highlightedTransforms.Add(transformID);
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);
highlightedTransforms.Remove(transformID);
}
public void Rebuild()
{
autoExpandedIDs.Clear();
@ -97,10 +162,6 @@ namespace UnityExplorer.UI.Widgets
RefreshData(true, true);
}
private readonly HashSet<int> visited = new HashSet<int>();
private bool needRefresh;
private int displayIndex;
public void RefreshData(bool andReload = false, bool jumpToTop = false)
{
visited.Clear();
@ -114,12 +175,12 @@ namespace UnityExplorer.UI.Widgets
if (obj) Traverse(obj.transform);
// Prune displayed transforms that we didnt visit in that traverse
for (int i = displayedObjects.Count - 1; i >= 0; i--)
for (int i = cachedTransforms.Count - 1; i >= 0; i--)
{
var obj = (CachedTransform)displayedObjects[i];
var obj = (CachedTransform)cachedTransforms[i];
if (!visited.Contains(obj.InstanceID))
{
displayedObjects.Remove(obj.InstanceID);
cachedTransforms.Remove(obj.InstanceID);
needRefresh = true;
}
}
@ -159,9 +220,9 @@ namespace UnityExplorer.UI.Widgets
visited.Add(instanceID);
CachedTransform cached;
if (displayedObjects.Contains(instanceID))
if (cachedTransforms.Contains(instanceID))
{
cached = (CachedTransform)displayedObjects[(object)instanceID];
cached = (CachedTransform)cachedTransforms[(object)instanceID];
if (cached.Update(transform, depth))
needRefresh = true;
}
@ -169,10 +230,10 @@ namespace UnityExplorer.UI.Widgets
{
needRefresh = true;
cached = new CachedTransform(this, transform, depth, parent);
if (displayedObjects.Count <= displayIndex)
displayedObjects.Add(instanceID, cached);
if (cachedTransforms.Count <= displayIndex)
cachedTransforms.Add(instanceID, cached);
else
displayedObjects.Insert(displayIndex, instanceID, cached);
cachedTransforms.Insert(displayIndex, instanceID, cached);
}
displayIndex++;
@ -201,9 +262,9 @@ namespace UnityExplorer.UI.Widgets
public void SetCell(TransformCell cell, int index)
{
if (index < displayedObjects.Count)
if (index < cachedTransforms.Count)
{
cell.ConfigureCell((CachedTransform)displayedObjects[index], index);
cell.ConfigureCell((CachedTransform)cachedTransforms[index], index);
if (Filtering)
{
if (cell.cachedTransform.Name.ContainsIgnoreCase(currentFilter))
@ -226,16 +287,5 @@ namespace UnityExplorer.UI.Widgets
RefreshData(true);
}
public void OnCellBorrowed(TransformCell cell)
{
cell.OnExpandToggled += ToggleExpandCell;
cell.OnGameObjectClicked += OnGameObjectClicked;
}
//public void ReleaseCell(TransformCell cell)
//{
// cell.OnExpandToggled -= ToggleExpandCell;
//}
}
}