2021-05-01 20:55:27 +10:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
using UnityEngine.UI;
|
2021-05-05 21:27:09 +10:00
|
|
|
|
using UnityExplorer.UI.CacheObject;
|
|
|
|
|
using UnityExplorer.UI.CacheObject.Views;
|
|
|
|
|
using UnityExplorer.UI.Inspectors;
|
2021-05-03 21:02:01 +10:00
|
|
|
|
using UnityExplorer.UI.Panels;
|
2021-05-01 20:55:27 +10:00
|
|
|
|
using UnityExplorer.UI.Utility;
|
|
|
|
|
using UnityExplorer.UI.Widgets;
|
|
|
|
|
|
2021-05-05 21:27:09 +10:00
|
|
|
|
namespace UnityExplorer.UI.IValues
|
2021-05-01 20:55:27 +10:00
|
|
|
|
{
|
2021-05-13 23:03:30 +10:00
|
|
|
|
public class InteractiveList : InteractiveValue, ICellPoolDataSource<CacheListEntryCell>, ICacheObjectController
|
2021-05-01 20:55:27 +10:00
|
|
|
|
{
|
2021-05-03 01:29:02 +10:00
|
|
|
|
CacheObjectBase ICacheObjectController.ParentCacheObject => this.CurrentOwner;
|
|
|
|
|
object ICacheObjectController.Target => this.CurrentOwner.Value;
|
|
|
|
|
public Type TargetType { get; private set; }
|
|
|
|
|
|
2021-05-06 20:28:04 +10:00
|
|
|
|
public override bool CanWrite => base.CanWrite && RefIList != null && !RefIList.IsReadOnly;
|
2021-05-01 20:55:27 +10:00
|
|
|
|
|
2021-05-03 01:29:02 +10:00
|
|
|
|
public Type EntryType;
|
2021-05-15 18:00:16 +10:00
|
|
|
|
//public IEnumerable RefIEnumerable;
|
2021-05-01 20:55:27 +10:00
|
|
|
|
public IList RefIList;
|
|
|
|
|
|
|
|
|
|
public int ItemCount => values.Count;
|
|
|
|
|
private readonly List<object> values = new List<object>();
|
|
|
|
|
private readonly List<CacheListEntry> cachedEntries = new List<CacheListEntry>();
|
|
|
|
|
|
|
|
|
|
public ScrollPool<CacheListEntryCell> ListScrollPool { get; private set; }
|
|
|
|
|
|
|
|
|
|
public Text TopLabel;
|
|
|
|
|
|
2021-05-03 01:29:02 +10:00
|
|
|
|
public override void OnBorrowed(CacheObjectBase owner)
|
|
|
|
|
{
|
|
|
|
|
base.OnBorrowed(owner);
|
2021-05-04 20:10:46 +10:00
|
|
|
|
|
|
|
|
|
ListScrollPool.Refresh(true, true);
|
2021-05-03 01:29:02 +10:00
|
|
|
|
}
|
|
|
|
|
|
2021-05-01 20:55:27 +10:00
|
|
|
|
public override void ReleaseFromOwner()
|
|
|
|
|
{
|
|
|
|
|
base.ReleaseFromOwner();
|
|
|
|
|
|
|
|
|
|
ClearAndRelease();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void ClearAndRelease()
|
|
|
|
|
{
|
2021-05-15 18:00:16 +10:00
|
|
|
|
//RefIEnumerable = null;
|
|
|
|
|
RefIList = null;
|
2021-05-01 20:55:27 +10:00
|
|
|
|
values.Clear();
|
|
|
|
|
|
|
|
|
|
foreach (var entry in cachedEntries)
|
2021-05-05 21:27:09 +10:00
|
|
|
|
{
|
|
|
|
|
entry.UnlinkFromView();
|
2021-05-01 20:55:27 +10:00
|
|
|
|
entry.ReleasePooledObjects();
|
2021-05-05 21:27:09 +10:00
|
|
|
|
}
|
2021-05-01 20:55:27 +10:00
|
|
|
|
|
|
|
|
|
cachedEntries.Clear();
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-06 20:28:04 +10:00
|
|
|
|
// Setting the List value itself to this model
|
2021-05-01 20:55:27 +10:00
|
|
|
|
public override void SetValue(object value)
|
|
|
|
|
{
|
|
|
|
|
if (value == null)
|
|
|
|
|
{
|
2021-05-03 01:29:02 +10:00
|
|
|
|
// should never be null
|
2021-05-01 20:55:27 +10:00
|
|
|
|
if (values.Any())
|
|
|
|
|
ClearAndRelease();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
var type = value.GetActualType();
|
|
|
|
|
if (type.IsGenericType)
|
2021-05-03 01:29:02 +10:00
|
|
|
|
EntryType = type.GetGenericArguments()[0];
|
2021-05-08 20:54:16 +10:00
|
|
|
|
else if (type.HasElementType)
|
|
|
|
|
EntryType = type.GetElementType();
|
2021-05-01 20:55:27 +10:00
|
|
|
|
else
|
2021-05-03 01:29:02 +10:00
|
|
|
|
EntryType = typeof(object);
|
2021-05-01 20:55:27 +10:00
|
|
|
|
|
|
|
|
|
CacheEntries(value);
|
|
|
|
|
|
2021-05-06 04:02:42 +10:00
|
|
|
|
TopLabel.text = $"[{cachedEntries.Count}] {SignatureHighlighter.Parse(type, false)}";
|
2021-05-03 01:29:02 +10:00
|
|
|
|
}
|
2021-05-01 20:55:27 +10:00
|
|
|
|
|
2021-05-03 01:29:02 +10:00
|
|
|
|
//this.ScrollPoolLayout.minHeight = Math.Min(400f, 35f * values.Count);
|
2021-05-01 20:55:27 +10:00
|
|
|
|
this.ListScrollPool.Refresh(true, false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void CacheEntries(object value)
|
|
|
|
|
{
|
|
|
|
|
RefIList = value as IList;
|
|
|
|
|
|
2021-05-15 18:00:16 +10:00
|
|
|
|
IEnumerator enumerator = (value as IEnumerable).GetEnumerator();
|
|
|
|
|
|
|
|
|
|
//if (value is IEnumerable enumerable)
|
|
|
|
|
// enumerator = enumerable.GetEnumerator();
|
|
|
|
|
//else
|
|
|
|
|
// enumerator = Il2CppReflection.EnumerateCppList(value);
|
2021-05-01 20:55:27 +10:00
|
|
|
|
|
|
|
|
|
values.Clear();
|
|
|
|
|
int idx = 0;
|
2021-05-15 18:00:16 +10:00
|
|
|
|
while (enumerator.MoveNext())
|
2021-05-01 20:55:27 +10:00
|
|
|
|
{
|
2021-05-15 18:00:16 +10:00
|
|
|
|
var entry = enumerator.Current;
|
2021-05-06 20:28:04 +10:00
|
|
|
|
|
2021-05-01 20:55:27 +10:00
|
|
|
|
values.Add(entry);
|
|
|
|
|
|
|
|
|
|
// If list count increased, create new cache entries
|
|
|
|
|
CacheListEntry cache;
|
|
|
|
|
if (idx >= cachedEntries.Count)
|
|
|
|
|
{
|
|
|
|
|
cache = new CacheListEntry();
|
|
|
|
|
cache.SetListOwner(this, idx);
|
|
|
|
|
cachedEntries.Add(cache);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
cache = cachedEntries[idx];
|
|
|
|
|
|
2021-05-03 01:29:02 +10:00
|
|
|
|
cache.SetFallbackType(this.EntryType);
|
2021-05-01 20:55:27 +10:00
|
|
|
|
cache.SetValueFromSource(entry);
|
|
|
|
|
idx++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Remove excess cached entries if list count decreased
|
|
|
|
|
if (cachedEntries.Count > values.Count)
|
|
|
|
|
{
|
|
|
|
|
for (int i = cachedEntries.Count - 1; i >= values.Count; i--)
|
|
|
|
|
{
|
|
|
|
|
var cache = cachedEntries[i];
|
|
|
|
|
if (cache.CellView != null)
|
2021-05-05 21:27:09 +10:00
|
|
|
|
cache.UnlinkFromView();
|
|
|
|
|
|
2021-05-01 20:55:27 +10:00
|
|
|
|
cache.ReleasePooledObjects();
|
|
|
|
|
cachedEntries.RemoveAt(i);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-06 20:28:04 +10:00
|
|
|
|
// Setting the value of an index to the list
|
|
|
|
|
|
|
|
|
|
public void TrySetValueToIndex(object value, int index)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2021-05-07 06:27:44 +10:00
|
|
|
|
//value = value.TryCast(this.EntryType);
|
2021-05-06 20:28:04 +10:00
|
|
|
|
RefIList[index] = value;
|
|
|
|
|
|
|
|
|
|
var entry = cachedEntries[index];
|
|
|
|
|
entry.SetValueFromSource(value);
|
2021-05-09 02:22:03 +10:00
|
|
|
|
|
|
|
|
|
if (entry.CellView != null)
|
|
|
|
|
entry.SetDataToCell(entry.CellView);
|
2021-05-06 20:28:04 +10:00
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
ExplorerCore.LogWarning($"Exception setting IList value: {ex}");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-01 20:55:27 +10:00
|
|
|
|
// List entry scroll pool
|
|
|
|
|
|
2021-05-03 21:02:01 +10:00
|
|
|
|
public override void SetLayout()
|
|
|
|
|
{
|
|
|
|
|
var minHeight = 5f;
|
|
|
|
|
|
|
|
|
|
foreach (var cell in ListScrollPool.CellPool)
|
|
|
|
|
{
|
|
|
|
|
if (cell.Enabled)
|
|
|
|
|
minHeight += cell.Rect.rect.height;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.scrollLayout.minHeight = Math.Min(InspectorPanel.CurrentPanelHeight - 400f, minHeight);
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-05 21:27:09 +10:00
|
|
|
|
public void OnCellBorrowed(CacheListEntryCell cell) { } // not needed
|
2021-05-01 20:55:27 +10:00
|
|
|
|
|
|
|
|
|
public void SetCell(CacheListEntryCell cell, int index)
|
|
|
|
|
{
|
2021-05-07 06:27:44 +10:00
|
|
|
|
CacheObjectControllerHelper.SetCell(cell, index, cachedEntries, null);
|
2021-05-01 20:55:27 +10:00
|
|
|
|
}
|
|
|
|
|
|
2021-05-03 01:29:02 +10:00
|
|
|
|
private LayoutElement scrollLayout;
|
|
|
|
|
|
2021-05-01 20:55:27 +10:00
|
|
|
|
public override GameObject CreateContent(GameObject parent)
|
|
|
|
|
{
|
2021-05-03 01:29:02 +10:00
|
|
|
|
UIRoot = UIFactory.CreateVerticalGroup(parent, "InteractiveList", true, true, true, true, 6, new Vector4(10, 3, 15, 4),
|
2021-05-01 20:55:27 +10:00
|
|
|
|
new Color(0.05f, 0.05f, 0.05f));
|
|
|
|
|
UIFactory.SetLayoutElement(UIRoot, flexibleWidth: 9999, minHeight: 25, flexibleHeight: 600);
|
2021-05-03 01:29:02 +10:00
|
|
|
|
UIRoot.AddComponent<ContentSizeFitter>().verticalFit = ContentSizeFitter.FitMode.PreferredSize;
|
2021-05-01 20:55:27 +10:00
|
|
|
|
|
|
|
|
|
// Entries label
|
|
|
|
|
|
2021-05-03 01:29:02 +10:00
|
|
|
|
TopLabel = UIFactory.CreateLabel(UIRoot, "EntryLabel", "not set", TextAnchor.MiddleLeft, fontSize: 16);
|
|
|
|
|
TopLabel.horizontalOverflow = HorizontalWrapMode.Overflow;
|
2021-05-01 20:55:27 +10:00
|
|
|
|
|
|
|
|
|
// entry scroll pool
|
|
|
|
|
|
|
|
|
|
ListScrollPool = UIFactory.CreateScrollPool<CacheListEntryCell>(UIRoot, "EntryList", out GameObject scrollObj,
|
|
|
|
|
out GameObject _, new Color(0.09f, 0.09f, 0.09f));
|
2021-05-03 01:29:02 +10:00
|
|
|
|
UIFactory.SetLayoutElement(scrollObj, minHeight: 400, flexibleHeight: 0);
|
|
|
|
|
ListScrollPool.Initialize(this, SetLayout);
|
|
|
|
|
scrollLayout = scrollObj.GetComponent<LayoutElement>();
|
2021-05-01 20:55:27 +10:00
|
|
|
|
|
|
|
|
|
return UIRoot;
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-05-03 01:29:02 +10:00
|
|
|
|
}
|