mirror of
https://github.com/sinai-dev/UnityExplorer.git
synced 2025-01-06 01:23:31 +08:00
Some UI cleanups, improving caching and reduce image allocation
This commit is contained in:
parent
fda5afae46
commit
f3cd84804d
@ -106,7 +106,7 @@ namespace UnityExplorer.UI.Inspectors
|
||||
var closeBtn = UIFactory.CreateButton(tabGroupObj,
|
||||
"CloseButton",
|
||||
"X",
|
||||
parent.Destroy,
|
||||
() => { InspectorManager.DestroyInspector(parent); },
|
||||
new Color(0.2f, 0.2f, 0.2f, 1));
|
||||
|
||||
UIFactory.SetLayoutElement(closeBtn.gameObject, minWidth: 20, flexibleWidth: 0);
|
||||
|
@ -30,6 +30,14 @@ namespace UnityExplorer.UI.Inspectors
|
||||
}
|
||||
}
|
||||
|
||||
public static void DestroyInspector(InspectorBase inspector)
|
||||
{
|
||||
if (inspector is ReflectionInspector ri)
|
||||
ri.Destroy();
|
||||
else
|
||||
inspector.Destroy();
|
||||
}
|
||||
|
||||
public static void Inspect(object obj, CacheObjectBase parentMember = null)
|
||||
{
|
||||
var type = ReflectionProvider.Instance.GetActualType(obj);
|
||||
@ -70,7 +78,7 @@ namespace UnityExplorer.UI.Inspectors
|
||||
SetInspectorTab(inspector);
|
||||
}
|
||||
|
||||
public static void InspectType(Type type)
|
||||
public static void Inspect(Type type)
|
||||
{
|
||||
if (type == null)
|
||||
{
|
||||
|
@ -29,48 +29,33 @@ namespace UnityExplorer.UI.Inspectors.Reflection
|
||||
|
||||
public ICell CreateCell(RectTransform cellTransform) => new CellViewHolder(cellTransform.gameObject);
|
||||
|
||||
public void DisableCell(ICell cell, int index)
|
||||
{
|
||||
var root = (cell as CellViewHolder).UIRoot;
|
||||
DisableContent(root);
|
||||
cell.Disable();
|
||||
}
|
||||
|
||||
public void SetCell(ICell icell, int index)
|
||||
{
|
||||
var root = (icell as CellViewHolder).UIRoot;
|
||||
var cell = icell as CellViewHolder;
|
||||
|
||||
if (index < 0 || index >= ItemCount)
|
||||
{
|
||||
DisableContent(root);
|
||||
icell.Disable();
|
||||
var existing = cell.DisableContent();
|
||||
if (existing)
|
||||
existing.transform.SetParent(Inspector.InactiveHolder.transform, false);
|
||||
return;
|
||||
}
|
||||
|
||||
float start = Time.realtimeSinceStartup;
|
||||
index = GetRealIndexOfTempIndex(index);
|
||||
|
||||
var cache = Inspector.allMembers[index];
|
||||
cache.Enable();
|
||||
|
||||
var content = cache.UIRoot;
|
||||
|
||||
if (content.transform.parent.ReferenceEqual(root.transform))
|
||||
return;
|
||||
|
||||
var orig = content.transform.parent;
|
||||
|
||||
DisableContent(root);
|
||||
|
||||
content.transform.SetParent(root.transform, false);
|
||||
//ExplorerCore.Log("Set cell " + index + ", took " + (Time.realtimeSinceStartup - start) + " secs");
|
||||
//ExplorerCore.Log("orig parent was " + (orig?.name ?? " <null>"));
|
||||
var prev = cell.SetContent(cache.UIRoot);
|
||||
if (prev)
|
||||
prev.transform.SetParent(Inspector.InactiveHolder.transform, false);
|
||||
}
|
||||
|
||||
private void DisableContent(GameObject cellRoot)
|
||||
public void DisableCell(ICell cell, int index)
|
||||
{
|
||||
if (cellRoot.transform.childCount > 0 && cellRoot.transform.GetChild(0) is Transform existing)
|
||||
existing.transform.SetParent(Inspector.InactiveHolder.transform, false);
|
||||
var content = (cell as CellViewHolder).DisableContent();
|
||||
if (content)
|
||||
content.transform.SetParent(Inspector.InactiveHolder.transform, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ namespace UnityExplorer.UI.Inspectors.Reflection
|
||||
|
||||
FilterMembers(null, true);
|
||||
|
||||
ScrollPool.EnableTempCache();
|
||||
ScrollPool.RecreateHeightCache();
|
||||
ScrollPool.RefreshAndJumpToTop();
|
||||
//RefreshDisplay();
|
||||
//m_sliderScroller.m_slider.value = 1f;
|
||||
@ -134,23 +134,21 @@ namespace UnityExplorer.UI.Inspectors.Reflection
|
||||
|
||||
internal void ConstructTextureHelper()
|
||||
{
|
||||
var rowObj = UIFactory.CreateHorizontalGroup(Content, "TextureHelper", true, false, true, true, 5, new Vector4(3, 3, 3, 3),
|
||||
var rowObj = UIFactory.CreateHorizontalGroup(Content, "TextureHelper", false, false, true, true, 5, new Vector4(3, 3, 3, 3),
|
||||
new Color(0.1f, 0.1f, 0.1f));
|
||||
UIFactory.SetLayoutElement(rowObj, minHeight: 25, flexibleHeight: 0);
|
||||
|
||||
var showBtn = UIFactory.CreateButton(rowObj, "ShowButton", "Show", null, new Color(0.2f, 0.6f, 0.2f));
|
||||
UIFactory.SetLayoutElement(showBtn.gameObject, minWidth: 50, flexibleWidth: 0);
|
||||
var showBtn = UIFactory.CreateButton(rowObj, "ShowButton", "Show", null, new Color(0.2f, 0.3f, 0.2f));
|
||||
UIFactory.SetLayoutElement(showBtn.gameObject, minWidth: 50, flexibleWidth: 0, minHeight: 20);
|
||||
|
||||
UIFactory.CreateLabel(rowObj, "TextureViewerLabel", "Texture Viewer", TextAnchor.MiddleLeft);
|
||||
|
||||
var textureViewerObj = UIFactory.CreateScrollView(Content, "TextureViewerContent", out GameObject scrollContent, out _,
|
||||
m_textureViewerObj = UIFactory.CreateScrollView(Content, "TextureViewerContent", out GameObject scrollContent, out _,
|
||||
new Color(0.1f, 0.1f, 0.1f));
|
||||
UIFactory.SetLayoutGroup<VerticalLayoutGroup>(textureViewerObj, false, false, true, true);
|
||||
UIFactory.SetLayoutElement(textureViewerObj, minHeight: 100, flexibleHeight: 9999, flexibleWidth: 9999);
|
||||
UIFactory.SetLayoutGroup<VerticalLayoutGroup>(scrollContent, false, false, true, true);
|
||||
UIFactory.SetLayoutElement(m_textureViewerObj, minHeight: 100, flexibleHeight: 9999, flexibleWidth: 9999);
|
||||
|
||||
textureViewerObj.SetActive(false);
|
||||
|
||||
m_textureViewerObj = textureViewerObj;
|
||||
m_textureViewerObj.SetActive(false);
|
||||
|
||||
var showText = showBtn.GetComponentInChildren<Text>();
|
||||
showBtn.onClick.AddListener(() =>
|
||||
@ -249,7 +247,7 @@ namespace UnityExplorer.UI.Inspectors.Reflection
|
||||
m_textureViewerObj.SetActive(enabled);
|
||||
|
||||
m_filterAreaObj.SetActive(!enabled);
|
||||
//m_memberListObj.SetActive(!enabled);
|
||||
this.ScrollPool.UIRoot.SetActive(!enabled);
|
||||
m_updateRowObj.SetActive(!enabled);
|
||||
}
|
||||
}
|
||||
|
@ -125,7 +125,10 @@ namespace UnityExplorer.UI.Inspectors.Reflection
|
||||
base.Destroy();
|
||||
|
||||
if (this.Content)
|
||||
{
|
||||
GameObject.Destroy(this.InactiveHolder);
|
||||
GameObject.Destroy(this.Content);
|
||||
}
|
||||
}
|
||||
|
||||
internal bool IsBlacklisted(string sig) => bl_typeAndMember.Any(it => sig.Contains(it));
|
||||
@ -262,7 +265,7 @@ namespace UnityExplorer.UI.Inspectors.Reflection
|
||||
RuntimeProvider.Instance.SetColorBlock(m_lastActiveMemButton, new Color(0.2f, 0.6f, 0.2f));
|
||||
|
||||
FilterMembers(null, true);
|
||||
ScrollPool.EnableTempCache();
|
||||
ScrollPool.RecreateHeightCache();
|
||||
ScrollPool.Rebuild();
|
||||
}
|
||||
|
||||
@ -332,7 +335,7 @@ namespace UnityExplorer.UI.Inspectors.Reflection
|
||||
new Color(0.15f, 0.15f, 0.15f));
|
||||
|
||||
this.m_inactiveHolder = new GameObject("InactiveContentHolder");
|
||||
m_inactiveHolder.transform.SetParent(parent.transform, false);
|
||||
m_inactiveHolder.transform.SetParent(Content.transform, false);
|
||||
m_inactiveHolder.SetActive(false);
|
||||
|
||||
ConstructTopArea();
|
||||
@ -389,7 +392,7 @@ namespace UnityExplorer.UI.Inspectors.Reflection
|
||||
nameInput.onValueChanged.AddListener((string val) =>
|
||||
{
|
||||
FilterMembers(val, true);
|
||||
ScrollPool.EnableTempCache();
|
||||
ScrollPool.RecreateHeightCache();
|
||||
ScrollPool.Rebuild();
|
||||
});
|
||||
m_nameFilterText = nameInput.textComponent;
|
||||
|
@ -22,7 +22,6 @@ namespace UnityExplorer.UI.Models
|
||||
var instance = Instances[i];
|
||||
if (instance == null || !instance.UIRoot)
|
||||
{
|
||||
ExplorerCore.Log($"Instance {instance?.GetType().Name ?? "<null>"} has no UIRoot or it was destroyed!");
|
||||
Instances.RemoveAt(i);
|
||||
continue;
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ namespace UnityExplorer.UI.Panels
|
||||
UIFactory.SetLayoutGroup<VerticalLayoutGroup>(this.content, forceHeight: true, spacing: 10, padLeft: 5, padRight: 5);
|
||||
|
||||
this.NavbarHolder = UIFactory.CreateGridGroup(this.content, "Navbar", new Vector2(200, 22), new Vector2(4, 2),
|
||||
new Color(0.18f, 0.18f, 0.18f));
|
||||
new Color(0.12f, 0.12f, 0.12f));
|
||||
//UIFactory.SetLayoutElement(NavbarHolder, flexibleWidth: 9999, minHeight: 0, preferredHeight: 0, flexibleHeight: 9999);
|
||||
NavbarHolder.AddComponent<ContentSizeFitter>().verticalFit = ContentSizeFitter.FitMode.PreferredSize;
|
||||
|
||||
@ -81,267 +81,4 @@ namespace UnityExplorer.UI.Panels
|
||||
UIManager.SetPanelActive(PanelType, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//using System;
|
||||
//using System.Collections;
|
||||
//using System.Collections.Generic;
|
||||
//using System.Linq;
|
||||
//using System.Text;
|
||||
//using UnityEngine;
|
||||
//using UnityEngine.UI;
|
||||
//using UnityExplorer.Core.Config;
|
||||
//using UnityExplorer.Core.Runtime;
|
||||
//using UnityExplorer.UI.Models;
|
||||
//using UnityExplorer.UI.Utility;
|
||||
//using UnityExplorer.UI.Widgets;
|
||||
|
||||
//namespace UnityExplorer.UI.Panels
|
||||
//{
|
||||
// public class InspectorPanel : UIPanel
|
||||
// {
|
||||
// public static InspectorPanel Instance { get; private set; }
|
||||
|
||||
// public GameObject NavbarHolder;
|
||||
// public GameObject ContentHolder;
|
||||
|
||||
// public override string Name => "Inspector";
|
||||
// public override UIManager.Panels PanelType => UIManager.Panels.Inspector;
|
||||
// public override bool ShouldSaveActiveState => false;
|
||||
|
||||
// public InspectorPanel() { Instance = this; }
|
||||
|
||||
// public override void Update()
|
||||
// {
|
||||
|
||||
// }
|
||||
|
||||
// public override void LoadSaveData()
|
||||
// {
|
||||
// ApplySaveData(ConfigManager.GameObjectInspectorData.Value);
|
||||
// }
|
||||
|
||||
// public override void SaveToConfigManager()
|
||||
// {
|
||||
// ConfigManager.GameObjectInspectorData.Value = this.ToSaveData();
|
||||
// }
|
||||
|
||||
// public override void SetDefaultPosAndAnchors()
|
||||
// {
|
||||
// mainPanelRect.localPosition = Vector2.zero;
|
||||
// mainPanelRect.pivot = new Vector2(0.5f, 0.5f);
|
||||
// mainPanelRect.anchorMin = new Vector2(0.5f, 0);
|
||||
// mainPanelRect.anchorMax = new Vector2(0.5f, 1);
|
||||
// mainPanelRect.offsetMin = new Vector2(mainPanelRect.offsetMin.x, 100); // bottom
|
||||
// mainPanelRect.offsetMax = new Vector2(mainPanelRect.offsetMax.x, -50); // top
|
||||
// mainPanelRect.sizeDelta = new Vector2(700f, mainPanelRect.sizeDelta.y);
|
||||
// mainPanelRect.anchoredPosition = new Vector2(-150, 0);
|
||||
// }
|
||||
|
||||
// internal static DynamicListTest listInstance;
|
||||
|
||||
// private ScrollPool scrollPool;
|
||||
|
||||
// public override void ConstructPanelContent()
|
||||
// {
|
||||
// // temp test
|
||||
// scrollPool = UIFactory.CreateScrollPool(content, "Test", out GameObject scrollObj,
|
||||
// out GameObject scrollContent, new Color(0.15f, 0.15f, 0.15f));
|
||||
// UIFactory.SetLayoutElement(scrollObj, flexibleHeight: 9999);
|
||||
// UIFactory.SetLayoutElement(scrollContent, flexibleHeight: 9999);
|
||||
|
||||
// // disable masks for debug
|
||||
// UIRoot.GetComponent<Mask>().enabled = false;
|
||||
// scrollPool.Viewport.GetComponent<Mask>().enabled = false;
|
||||
// scrollPool.Content.gameObject.AddComponent<Image>().color = new Color(1f, 0f, 1f, 0.3f);
|
||||
|
||||
// listInstance = new DynamicListTest(scrollPool, this);
|
||||
// listInstance.Init();
|
||||
|
||||
// //var prototype = DynamicCell.CreatePrototypeCell(scrollContent);
|
||||
// //scrollPool.PrototypeCell = prototype.GetComponent<RectTransform>();
|
||||
|
||||
// contentHolder = new GameObject("DummyHolder");
|
||||
// contentHolder.SetActive(false);
|
||||
// contentHolder.transform.SetParent(this.content.transform, false);
|
||||
|
||||
// ExplorerCore.Log("Creating dummy objects");
|
||||
// for (int i = 0; i < 150; i++)
|
||||
// {
|
||||
// dummyContents.Add(CreateDummyContent());
|
||||
// }
|
||||
// ExplorerCore.Log("Done");
|
||||
|
||||
// //previousRectHeight = mainPanelRect.rect.height;
|
||||
|
||||
// UIManager.SetPanelActive(PanelType, false);
|
||||
// }
|
||||
|
||||
// internal GameObject contentHolder;
|
||||
// internal readonly List<GameObject> dummyContents = new List<GameObject>();
|
||||
|
||||
// private GameObject CreateDummyContent()
|
||||
// {
|
||||
// var obj = UIFactory.CreateVerticalGroup(contentHolder, "Content", true, true, true, true, 2, new Vector4(2, 2, 2, 2));
|
||||
// obj.AddComponent<ContentSizeFitter>().verticalFit = ContentSizeFitter.FitMode.PreferredSize;
|
||||
|
||||
// var horiGroup = UIFactory.CreateHorizontalGroup(obj, "topGroup", true, true, true, true);
|
||||
// UIFactory.SetLayoutElement(horiGroup, minHeight: 25, flexibleHeight: 0);
|
||||
|
||||
// var mainLabel = UIFactory.CreateLabel(horiGroup, "label", "Dummy " + dummyContents.Count, TextAnchor.MiddleCenter);
|
||||
// UIFactory.SetLayoutElement(mainLabel.gameObject, minHeight: 25, flexibleHeight: 0);
|
||||
|
||||
// var expandButton = UIFactory.CreateButton(horiGroup, "Expand", "V");
|
||||
// UIFactory.SetLayoutElement(expandButton.gameObject, minWidth: 25, flexibleWidth: 0);
|
||||
|
||||
// var subContent = UIFactory.CreateVerticalGroup(obj, "SubContent", true, true, true, true);
|
||||
|
||||
// var inputObj = UIFactory.CreateInputField(subContent, "input", "...", out var inputField);
|
||||
// UIFactory.SetLayoutElement(inputObj, minHeight: 25, flexibleHeight: 9999);
|
||||
// inputObj.AddComponent<ContentSizeFitter>().verticalFit = ContentSizeFitter.FitMode.PreferredSize;
|
||||
// inputField.lineType = InputField.LineType.MultiLineNewline;
|
||||
|
||||
// int numLines = UnityEngine.Random.Range(0, 10);
|
||||
// inputField.text = "This field has " + numLines + " lines";
|
||||
// for (int i = 0; i < numLines; i++)
|
||||
// inputField.text += "\r\n";
|
||||
|
||||
// //subContent.SetActive(false);
|
||||
|
||||
// var btnLabel = expandButton.GetComponentInChildren<Text>();
|
||||
// expandButton.onClick.AddListener(OnExpand);
|
||||
// void OnExpand()
|
||||
// {
|
||||
// bool active = !subContent.activeSelf;
|
||||
// if (active)
|
||||
// {
|
||||
// subContent.SetActive(true);
|
||||
// btnLabel.text = "^";
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// subContent.SetActive(false);
|
||||
// btnLabel.text = "V";
|
||||
// }
|
||||
// }
|
||||
|
||||
// return obj;
|
||||
// }
|
||||
// }
|
||||
|
||||
// public class DynamicListTest : IPoolDataSource
|
||||
// {
|
||||
// internal ScrollPool ScrollPool;
|
||||
// internal InspectorPanel Inspector;
|
||||
|
||||
// public DynamicListTest(ScrollPool scroller, InspectorPanel inspector)
|
||||
// {
|
||||
// ScrollPool = scroller;
|
||||
// Inspector = inspector;
|
||||
// }
|
||||
|
||||
// public int ItemCount => filtering ? filteredIndices.Count : Inspector.dummyContents.Count;
|
||||
|
||||
// private bool filtering;
|
||||
// private readonly List<int> filteredIndices = new List<int>();
|
||||
|
||||
// public int GetRealIndexOfTempIndex(int index)
|
||||
// {
|
||||
// if (index < 0 || index >= filteredIndices.Count)
|
||||
// return -1;
|
||||
// return filteredIndices[index];
|
||||
// }
|
||||
|
||||
// public void ToggleFilter()
|
||||
// {
|
||||
// if (filtering)
|
||||
// {
|
||||
// DisableFilter();
|
||||
// ScrollPool.DisableTempCache();
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// EnableRandomFilter();
|
||||
// ScrollPool.EnableTempCache();
|
||||
// }
|
||||
|
||||
// ExplorerCore.Log("Filter toggled, new count: " + ItemCount);
|
||||
// ScrollPool.Rebuild();
|
||||
// }
|
||||
|
||||
// public void EnableRandomFilter()
|
||||
// {
|
||||
// filteredIndices.Clear();
|
||||
// filtering = true;
|
||||
|
||||
// int counter = UnityEngine.Random.Range(0, Inspector.dummyContents.Count);
|
||||
// while (filteredIndices.Count < counter)
|
||||
// {
|
||||
// var i = UnityEngine.Random.Range(0, Inspector.dummyContents.Count);
|
||||
// if (!filteredIndices.Contains(i))
|
||||
// filteredIndices.Add(i);
|
||||
// }
|
||||
// filteredIndices.Sort();
|
||||
// }
|
||||
|
||||
// public void DisableFilter()
|
||||
// {
|
||||
// filtering = false;
|
||||
// }
|
||||
|
||||
// public void OnDisableCell(CellViewHolder cell, int dataIndex)
|
||||
// {
|
||||
// if (cell.UIRoot.transform.Find("Content") is Transform existing)
|
||||
// existing.transform.SetParent(Inspector.contentHolder.transform, false);
|
||||
// }
|
||||
|
||||
// public void Init()
|
||||
// {
|
||||
// var prototype = CellViewHolder.CreatePrototypeCell(ScrollPool.UIRoot);
|
||||
|
||||
// ScrollPool.DataSource = this;
|
||||
// ScrollPool.Initialize(this, prototype);
|
||||
// }
|
||||
|
||||
// public ICell CreateCell(RectTransform cellTransform) => new CellViewHolder(cellTransform.gameObject);
|
||||
|
||||
// public void DisableCell(ICell icell, int index)
|
||||
// {
|
||||
// var root = (icell as CellViewHolder).UIRoot;
|
||||
// DisableContent(root);
|
||||
// icell.Disable();
|
||||
// }
|
||||
|
||||
// public void SetCell(ICell icell, int index)
|
||||
// {
|
||||
// var root = (icell as CellViewHolder).UIRoot;
|
||||
|
||||
// if (index < 0 || index >= ItemCount)
|
||||
// {
|
||||
// DisableContent(root);
|
||||
// icell.Disable();
|
||||
// return;
|
||||
// }
|
||||
|
||||
// if (filtering)
|
||||
// index = GetRealIndexOfTempIndex(index);
|
||||
|
||||
// var content = Inspector.dummyContents[index];
|
||||
|
||||
// if (content.transform.parent.ReferenceEqual(root.transform))
|
||||
// return;
|
||||
|
||||
// ExplorerCore.Log("Setting index " + index + " to cell " + root.transform.name);
|
||||
|
||||
// DisableContent(root);
|
||||
|
||||
// content.transform.SetParent(root.transform, false);
|
||||
// }
|
||||
|
||||
// private void DisableContent(GameObject cellRoot)
|
||||
// {
|
||||
// if (cellRoot.transform.Find("Content") is Transform existing)
|
||||
// existing.transform.SetParent(Inspector.contentHolder.transform, false);
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
}
|
@ -33,7 +33,7 @@ namespace UnityExplorer.UI
|
||||
var obj = new GameObject(name)
|
||||
{
|
||||
layer = 5,
|
||||
hideFlags = HideFlags.HideAndDontSave
|
||||
hideFlags = HideFlags.HideAndDontSave,
|
||||
};
|
||||
|
||||
obj.transform.SetParent(parent.transform, false);
|
||||
@ -752,6 +752,7 @@ namespace UnityExplorer.UI
|
||||
|
||||
var scrollRect = mainObj.AddComponent<ScrollRect>();
|
||||
scrollRect.movementType = ScrollRect.MovementType.Clamped;
|
||||
//scrollRect.inertia = false;
|
||||
scrollRect.inertia = true;
|
||||
scrollRect.elasticity = 0.125f;
|
||||
scrollRect.scrollSensitivity = 25;
|
||||
|
@ -16,7 +16,7 @@ namespace UnityExplorer.UI.Widgets
|
||||
internal ScrollPool Scroller;
|
||||
|
||||
public int ItemCount => currentEntries.Count;
|
||||
public List<T> currentEntries;
|
||||
public readonly List<T> currentEntries = new List<T>();
|
||||
|
||||
public Func<List<T>> GetEntries;
|
||||
public Action<ButtonCell<T>, int> SetICell;
|
||||
@ -54,7 +54,7 @@ namespace UnityExplorer.UI.Widgets
|
||||
public void RefreshData()
|
||||
{
|
||||
var allEntries = GetEntries.Invoke();
|
||||
var list = new List<T>();
|
||||
currentEntries.Clear();
|
||||
|
||||
foreach (var entry in allEntries)
|
||||
{
|
||||
@ -63,13 +63,11 @@ namespace UnityExplorer.UI.Widgets
|
||||
if (!ShouldDisplay.Invoke(entry, currentFilter))
|
||||
continue;
|
||||
|
||||
list.Add(entry);
|
||||
currentEntries.Add(entry);
|
||||
}
|
||||
else
|
||||
list.Add(entry);
|
||||
currentEntries.Add(entry);
|
||||
}
|
||||
|
||||
currentEntries = list;
|
||||
}
|
||||
|
||||
public ICell CreateCell(RectTransform rect)
|
||||
|
@ -31,9 +31,6 @@ namespace UnityExplorer.UI.CacheObject
|
||||
ConstructUI();
|
||||
UpdateValue();
|
||||
}
|
||||
|
||||
//if (!m_mainContent.activeSelf)
|
||||
// m_mainContent.SetActive(true);
|
||||
}
|
||||
|
||||
public virtual void Disable()
|
||||
@ -79,33 +76,44 @@ namespace UnityExplorer.UI.CacheObject
|
||||
internal GameObject m_parentContent;
|
||||
internal RectTransform m_mainRect;
|
||||
internal GameObject UIRoot;
|
||||
|
||||
internal GameObject SubContentGroup;
|
||||
internal bool constructedSubcontent;
|
||||
|
||||
// Make base UI holder for CacheObject, this doesnt actually display anything.
|
||||
internal virtual void ConstructUI()
|
||||
{
|
||||
m_constructedUI = true;
|
||||
|
||||
UIRoot = UIFactory.CreateVerticalGroup(m_parentContent, $"{this.GetType().Name}.MainContent", true, true, true, true, 2,
|
||||
new Vector4(0, 5, 0, 0), new Color(0.1f, 0.1f, 0.1f), TextAnchor.UpperLeft);
|
||||
//UIRoot = UIFactory.CreateVerticalGroup(m_parentContent, $"{this.GetType().Name}.MainContent", true, true, true, true, 2,
|
||||
// new Vector4(0, 5, 0, 0), new Color(0.1f, 0.1f, 0.1f), TextAnchor.UpperLeft);
|
||||
|
||||
UIRoot = UIFactory.CreateUIObject($"{this.GetType().Name}.MainContent", m_parentContent);
|
||||
UIFactory.SetLayoutGroup<VerticalLayoutGroup>(UIRoot, true, true, true, true, 2, 0, 5, 0, 0, TextAnchor.UpperLeft);
|
||||
m_mainRect = UIRoot.GetComponent<RectTransform>();
|
||||
m_mainRect.pivot = new Vector2(0, 1);
|
||||
m_mainRect.anchorMin = Vector2.zero;
|
||||
m_mainRect.anchorMax = Vector2.one;
|
||||
UIFactory.SetLayoutElement(UIRoot, minHeight: 30, flexibleHeight: 9999, minWidth: 200, flexibleWidth: 5000);
|
||||
//UIRoot.AddComponent<ContentSizeFitter>().verticalFit = ContentSizeFitter.FitMode.PreferredSize;
|
||||
|
||||
// subcontent
|
||||
|
||||
SubContentGroup = UIFactory.CreateVerticalGroup(UIRoot, $"{this.GetType().Name}.SubContent", true, false, true, true, 0, default,
|
||||
new Color(0.085f, 0.085f, 0.085f));
|
||||
SubContentGroup = new GameObject("SubContent");
|
||||
SubContentGroup.transform.parent = UIRoot.transform;
|
||||
UIFactory.SetLayoutElement(SubContentGroup, minHeight: 30, flexibleHeight: 9999, minWidth: 125, flexibleWidth: 9000);
|
||||
|
||||
UIFactory.SetLayoutGroup<VerticalLayoutGroup>(SubContentGroup, true, false, true, true);
|
||||
SubContentGroup.SetActive(false);
|
||||
|
||||
IValue.m_subContentParent = SubContentGroup;
|
||||
}
|
||||
|
||||
public virtual void CheckSubcontentCreation()
|
||||
{
|
||||
if (!constructedSubcontent)
|
||||
{
|
||||
SubContentGroup.AddComponent<Image>().color = new Color(0.08f, 0.08f, 0.08f);
|
||||
constructedSubcontent = true;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ namespace UnityExplorer.UI.InteractiveValues
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_recacheWanted)
|
||||
if (m_recacheWanted && Value != null)
|
||||
return true;
|
||||
else return m_entries.Count > 0;
|
||||
}
|
||||
|
@ -11,11 +11,90 @@ using UnityExplorer.Core.Config;
|
||||
using UnityExplorer.UI;
|
||||
using UnityExplorer.UI.CacheObject;
|
||||
using UnityExplorer.UI.Utility;
|
||||
using UnityExplorer.UI.Widgets;
|
||||
|
||||
namespace UnityExplorer.UI.InteractiveValues
|
||||
{
|
||||
public class InteractiveEnumerable : InteractiveValue
|
||||
public class InteractiveEnumerable : InteractiveValue, IPoolDataSource
|
||||
{
|
||||
// IPoolDataSource
|
||||
|
||||
public ScrollPool ScrollPool;
|
||||
public GameObject InactiveHolder;
|
||||
internal LayoutElement listLayout;
|
||||
|
||||
public int ItemCount => m_entries?.Count ?? 0;
|
||||
|
||||
public void SetCell(ICell icell, int index)
|
||||
{
|
||||
var cell = icell as CellViewHolder;
|
||||
|
||||
if (index < 0 || index >= ItemCount)
|
||||
{
|
||||
var existing = cell.DisableContent();
|
||||
if (existing)
|
||||
existing.transform.SetParent(InactiveHolder.transform, false);
|
||||
return;
|
||||
}
|
||||
|
||||
var cache = m_entries[index];
|
||||
cache.Enable();
|
||||
|
||||
var prev = cell.SetContent(cache.UIRoot);
|
||||
if (prev)
|
||||
prev.transform.SetParent(InactiveHolder.transform, false);
|
||||
}
|
||||
|
||||
public void DisableCell(ICell cell, int index)
|
||||
{
|
||||
var content = (cell as CellViewHolder).DisableContent();
|
||||
if (content)
|
||||
content.transform.SetParent(InactiveHolder.transform, false);
|
||||
}
|
||||
|
||||
//public void SetCell(ICell cell, int index)
|
||||
//{
|
||||
// var root = (cell as CellViewHolder).UIRoot;
|
||||
|
||||
// if (index < 0 || index >= ItemCount)
|
||||
// {
|
||||
// DisableContent(root);
|
||||
// cell.Disable();
|
||||
// return;
|
||||
// }
|
||||
|
||||
// var cache = m_entries[index];
|
||||
// cache.Enable();
|
||||
|
||||
// var content = cache.UIRoot;
|
||||
|
||||
// if (content.transform.parent.ReferenceEqual(root.transform))
|
||||
// return;
|
||||
|
||||
// DisableContent(root);
|
||||
|
||||
// content.transform.SetParent(root.transform, false);
|
||||
//}
|
||||
|
||||
//public void DisableCell(ICell cell, int index)
|
||||
//{
|
||||
// var root = (cell as CellViewHolder).UIRoot;
|
||||
// DisableContent(root);
|
||||
// cell.Disable();
|
||||
//}
|
||||
|
||||
//private void DisableContent(GameObject cellRoot)
|
||||
//{
|
||||
// if (cellRoot.transform.childCount > 0 && cellRoot.transform.GetChild(0) is Transform existing)
|
||||
// existing.transform.SetParent(InactiveHolder.transform, false);
|
||||
//}
|
||||
|
||||
public ICell CreateCell(RectTransform cellTransform) => new CellViewHolder(cellTransform.gameObject);
|
||||
|
||||
public int GetRealIndexOfTempIndex(int tempIndex) => throw new NotImplementedException("Filtering not supported");
|
||||
|
||||
// InteractiveEnumerable
|
||||
|
||||
public InteractiveEnumerable(object value, Type valueType) : base(value, valueType)
|
||||
{
|
||||
if (valueType.IsGenericType)
|
||||
@ -30,12 +109,13 @@ namespace UnityExplorer.UI.InteractiveValues
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_recacheWanted)
|
||||
if (m_recacheWanted && Value != null)
|
||||
return true;
|
||||
else return m_entries.Count > 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
internal IEnumerable RefIEnumerable;
|
||||
internal IList RefIList;
|
||||
|
||||
@ -50,13 +130,14 @@ namespace UnityExplorer.UI.InteractiveValues
|
||||
RefIEnumerable = Value as IEnumerable;
|
||||
RefIList = Value as IList;
|
||||
|
||||
if (m_subContentParent.activeSelf)
|
||||
if (m_subContentParent && m_subContentParent.activeSelf)
|
||||
{
|
||||
GetCacheEntries();
|
||||
RefreshDisplay();
|
||||
ToggleSubcontent();
|
||||
//GetCacheEntries();
|
||||
//RefreshDisplay();
|
||||
}
|
||||
else
|
||||
m_recacheWanted = true;
|
||||
|
||||
m_recacheWanted = true;
|
||||
|
||||
base.OnValueUpdated();
|
||||
}
|
||||
@ -66,11 +147,6 @@ namespace UnityExplorer.UI.InteractiveValues
|
||||
base.OnException(member);
|
||||
}
|
||||
|
||||
private void OnPageTurned()
|
||||
{
|
||||
RefreshDisplay();
|
||||
}
|
||||
|
||||
public override void RefreshUIForValue()
|
||||
{
|
||||
GetDefaultLabel();
|
||||
@ -95,8 +171,6 @@ namespace UnityExplorer.UI.InteractiveValues
|
||||
{
|
||||
if (m_entries.Any())
|
||||
{
|
||||
// maybe improve this, probably could be more efficient i guess
|
||||
|
||||
foreach (var entry in m_entries)
|
||||
entry.Destroy();
|
||||
|
||||
@ -111,7 +185,7 @@ namespace UnityExplorer.UI.InteractiveValues
|
||||
int index = 0;
|
||||
foreach (var entry in RefIEnumerable)
|
||||
{
|
||||
var cache = new CacheEnumerated(index, this, RefIList, this.m_listContent);
|
||||
var cache = new CacheEnumerated(index, this, RefIList, this.InactiveHolder);
|
||||
cache.CreateIValue(entry, m_baseEntryType);
|
||||
m_entries.Add(cache);
|
||||
|
||||
@ -126,32 +200,9 @@ namespace UnityExplorer.UI.InteractiveValues
|
||||
|
||||
public void RefreshDisplay()
|
||||
{
|
||||
//var entries = m_entries;
|
||||
//m_pageHandler.ListCount = entries.Count;
|
||||
//
|
||||
//for (int i = 0; i < m_displayedEntries.Length; i++)
|
||||
//{
|
||||
// var entry = m_displayedEntries[i];
|
||||
// if (entry != null)
|
||||
// entry.Disable();
|
||||
// else
|
||||
// break;
|
||||
//}
|
||||
//
|
||||
//if (entries.Count < 1)
|
||||
// return;
|
||||
//
|
||||
//foreach (var itemIndex in m_pageHandler)
|
||||
//{
|
||||
// if (itemIndex >= entries.Count)
|
||||
// break;
|
||||
//
|
||||
// CacheEnumerated entry = entries[itemIndex];
|
||||
// m_displayedEntries[itemIndex - m_pageHandler.StartIndex] = entry;
|
||||
// entry.Enable();
|
||||
//}
|
||||
//
|
||||
////UpdateSubcontentHeight();
|
||||
ScrollPool.RefreshCells(true);
|
||||
|
||||
listLayout.minHeight = Math.Min(500f, m_entries.Count * 32f);
|
||||
}
|
||||
|
||||
internal override void OnToggleSubcontent(bool active)
|
||||
@ -168,39 +219,27 @@ namespace UnityExplorer.UI.InteractiveValues
|
||||
RefreshDisplay();
|
||||
}
|
||||
|
||||
|
||||
internal GameObject m_listContent;
|
||||
internal LayoutElement m_listLayout;
|
||||
|
||||
//internal PageHandler m_pageHandler;
|
||||
|
||||
public override void ConstructUI(GameObject parent, GameObject subGroup)
|
||||
{
|
||||
base.ConstructUI(parent, subGroup);
|
||||
|
||||
InactiveHolder = new GameObject("InactiveHolder");
|
||||
InactiveHolder.transform.SetParent(parent.transform, false);
|
||||
InactiveHolder.SetActive(false);
|
||||
}
|
||||
|
||||
public override void ConstructSubcontent()
|
||||
{
|
||||
base.ConstructSubcontent();
|
||||
|
||||
//m_pageHandler = new PageHandler(null);
|
||||
//m_pageHandler.ConstructUI(m_subContentParent);
|
||||
//m_pageHandler.OnPageChanged += OnPageTurned;
|
||||
ScrollPool = UIFactory.CreateScrollPool(m_subContentParent, "ListEntries", out GameObject scrollRoot, out GameObject scrollContent,
|
||||
new Color(0.05f, 0.05f, 0.05f));
|
||||
|
||||
m_listContent = UIFactory.CreateVerticalGroup(this.m_subContentParent, "EnumerableContent", true, true, true, true, 2, new Vector4(5,5,5,5),
|
||||
new Color(0.08f, 0.08f, 0.08f));
|
||||
listLayout = scrollRoot.AddComponent<LayoutElement>();
|
||||
|
||||
var scrollRect = m_listContent.GetComponent<RectTransform>();
|
||||
scrollRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 0);
|
||||
|
||||
m_listLayout = Owner.UIRoot.GetComponent<LayoutElement>();
|
||||
m_listLayout.minHeight = 25;
|
||||
m_listLayout.flexibleHeight = 0;
|
||||
Owner.m_mainRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 25);
|
||||
|
||||
var contentFitter = m_listContent.AddComponent<ContentSizeFitter>();
|
||||
contentFitter.horizontalFit = ContentSizeFitter.FitMode.Unconstrained;
|
||||
contentFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
|
||||
var proto = CellViewHolder.CreatePrototypeCell(scrollRoot);
|
||||
proto.sizeDelta = new Vector2(100, 30);
|
||||
ScrollPool.Initialize(this, proto);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -67,6 +67,9 @@ namespace UnityExplorer.UI.InteractiveValues
|
||||
if (_typeSupportCache.TryGetValue(type.AssemblyQualifiedName, out bool ret))
|
||||
return ret;
|
||||
|
||||
if (type.FullName == "System.Void")
|
||||
return false;
|
||||
|
||||
ret = true;
|
||||
var fields = type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
|
||||
foreach (var field in fields)
|
||||
|
@ -172,6 +172,8 @@ namespace UnityExplorer.UI.InteractiveValues
|
||||
|
||||
public virtual void ConstructSubcontent()
|
||||
{
|
||||
Owner.CheckSubcontentCreation();
|
||||
|
||||
m_subContentConstructed = true;
|
||||
}
|
||||
|
||||
@ -305,8 +307,11 @@ namespace UnityExplorer.UI.InteractiveValues
|
||||
{
|
||||
m_UIConstructed = true;
|
||||
|
||||
m_mainContent = UIFactory.CreateHorizontalGroup(parent, $"InteractiveValue_{this.GetType().Name}", false, false, true, true, 4, default,
|
||||
new Color(1, 1, 1, 0), TextAnchor.UpperLeft);
|
||||
//m_mainContent = UIFactory.CreateHorizontalGroup(parent, $"InteractiveValue_{this.GetType().Name}", false, false, true, true, 4, default,
|
||||
// new Color(1, 1, 1, 0), TextAnchor.UpperLeft);
|
||||
|
||||
m_mainContent = UIFactory.CreateUIObject($"InteractiveValue_{this.GetType().Name}", parent);
|
||||
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(m_mainContent, false, false, true, true, 4, 0, 0, 0, 0, TextAnchor.UpperLeft);
|
||||
|
||||
var mainRect = m_mainContent.GetComponent<RectTransform>();
|
||||
mainRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 25);
|
||||
@ -316,7 +321,7 @@ namespace UnityExplorer.UI.InteractiveValues
|
||||
// subcontent expand button
|
||||
if (HasSubContent)
|
||||
{
|
||||
m_subExpandBtn = UIFactory.CreateButton(m_mainContent, "ExpandSubcontentButton", "▲", ToggleSubcontent, new Color(0.3f, 0.3f, 0.3f));
|
||||
m_subExpandBtn = UIFactory.CreateButton(m_mainContent, "ExpandSubcontentButton", "▲", ToggleSubcontent, new Color(1,1,1,0));
|
||||
UIFactory.SetLayoutElement(m_subExpandBtn.gameObject, minHeight: 25, minWidth: 25, flexibleWidth: 0, flexibleHeight: 0);
|
||||
}
|
||||
|
||||
|
@ -66,6 +66,8 @@ namespace UnityExplorer.UI.Widgets
|
||||
|
||||
public void DoSearch()
|
||||
{
|
||||
cachedCellTexts.Clear();
|
||||
|
||||
if (m_context == SearchContext.Singleton)
|
||||
currentResults = SearchProvider.SingletonSearch(nameInputField.text);
|
||||
else if (m_context == SearchContext.StaticClass)
|
||||
@ -85,20 +87,29 @@ namespace UnityExplorer.UI.Widgets
|
||||
resultsLabel.text = $"{currentResults.Count} results";
|
||||
}
|
||||
|
||||
// Cache the syntax-highlighted text for each search result to reduce allocs.
|
||||
private static readonly Dictionary<int, string> cachedCellTexts = new Dictionary<int, string>();
|
||||
|
||||
public void SetCell(ButtonCell<object> cell, int index)
|
||||
{
|
||||
if (m_context == SearchContext.StaticClass)
|
||||
if (!cachedCellTexts.ContainsKey(index))
|
||||
{
|
||||
cell.buttonText.text = SignatureHighlighter.HighlightTypeName(currentResults[index].GetActualType());
|
||||
string text;
|
||||
if (m_context == SearchContext.StaticClass)
|
||||
text = SignatureHighlighter.HighlightTypeName(currentResults[index].GetActualType());
|
||||
else
|
||||
text = ToStringUtility.ToString(currentResults[index], currentResults[index].GetActualType());
|
||||
|
||||
cachedCellTexts.Add(index, text);
|
||||
}
|
||||
else
|
||||
cell.buttonText.text = ToStringUtility.ToString(currentResults[index], currentResults[index].GetActualType());
|
||||
|
||||
cell.buttonText.text = cachedCellTexts[index];
|
||||
}
|
||||
|
||||
private void OnCellClicked(int dataIndex)
|
||||
{
|
||||
if (m_context == SearchContext.StaticClass)
|
||||
InspectorManager.InspectType(currentResults[dataIndex] as Type);
|
||||
InspectorManager.Inspect(currentResults[dataIndex] as Type);
|
||||
else
|
||||
InspectorManager.Inspect(currentResults[dataIndex]);
|
||||
}
|
||||
|
@ -12,33 +12,57 @@ namespace UnityExplorer.UI.Widgets
|
||||
public CellViewHolder(GameObject uiRoot)
|
||||
{
|
||||
this.UIRoot = uiRoot;
|
||||
this.m_rect = uiRoot.GetComponent<RectTransform>();
|
||||
this.Rect = uiRoot.GetComponent<RectTransform>();
|
||||
m_enabled = uiRoot.activeSelf;
|
||||
}
|
||||
|
||||
public bool Enabled => m_enabled;
|
||||
private bool m_enabled;
|
||||
|
||||
public GameObject UIRoot;
|
||||
public RectTransform Rect => m_rect;
|
||||
private RectTransform m_rect;
|
||||
public GameObject UIRoot { get; }
|
||||
public RectTransform Rect { get; }
|
||||
|
||||
public void Disable()
|
||||
private GameObject m_content;
|
||||
|
||||
public GameObject SetContent(GameObject newContent)
|
||||
{
|
||||
m_enabled = false;
|
||||
UIRoot.SetActive(false);
|
||||
var ret = m_content;
|
||||
|
||||
if (ret && newContent && ret.ReferenceEqual(newContent))
|
||||
return null;
|
||||
|
||||
newContent.transform.SetParent(this.UIRoot.transform, false);
|
||||
(this as ICell).Enable();
|
||||
|
||||
m_content = newContent;
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void Enable()
|
||||
public GameObject DisableContent()
|
||||
{
|
||||
var ret = m_content;
|
||||
(this as ICell).Disable();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ICell.Enable()
|
||||
{
|
||||
m_enabled = true;
|
||||
UIRoot.SetActive(true);
|
||||
}
|
||||
|
||||
void ICell.Disable()
|
||||
{
|
||||
m_enabled = false;
|
||||
UIRoot.SetActive(false);
|
||||
}
|
||||
|
||||
public static RectTransform CreatePrototypeCell(GameObject parent)
|
||||
{
|
||||
var prototype = UIFactory.CreateVerticalGroup(parent, "PrototypeCell", true, true, true, true, 0, new Vector4(1, 0, 0, 0),
|
||||
new Color(0.15f, 0.15f, 0.15f), TextAnchor.MiddleCenter);
|
||||
// using an image on the cell view holder is fine, we only need to make about 20-50 of these per pool.
|
||||
var prototype = UIFactory.CreateVerticalGroup(parent, "PrototypeCell", true, true, true, true, 0, new Vector4(0, 0, 0, 0),
|
||||
new Color(0.11f, 0.11f, 0.11f), TextAnchor.MiddleCenter);
|
||||
|
||||
var rect = prototype.GetComponent<RectTransform>();
|
||||
rect.anchorMin = new Vector2(0, 1);
|
||||
rect.anchorMax = new Vector2(0, 1);
|
||||
@ -47,6 +71,10 @@ namespace UnityExplorer.UI.Widgets
|
||||
|
||||
prototype.AddComponent<ContentSizeFitter>().verticalFit = ContentSizeFitter.FitMode.PreferredSize;
|
||||
|
||||
var sepObj = UIFactory.CreateUIObject("separator", prototype);
|
||||
sepObj.AddComponent<Image>().color = Color.black;
|
||||
UIFactory.SetLayoutElement(sepObj, minHeight: 1, preferredHeight: 1, flexibleHeight: 0);
|
||||
|
||||
prototype.SetActive(false);
|
||||
|
||||
return rect;
|
||||
|
@ -18,22 +18,14 @@ namespace UnityExplorer.UI.Widgets
|
||||
public class DataHeightCache
|
||||
{
|
||||
private ScrollPool ScrollPool { get; }
|
||||
//private DataHeightCache SisterCache { get; }
|
||||
|
||||
public DataHeightCache(ScrollPool scrollPool)
|
||||
{
|
||||
ScrollPool = scrollPool;
|
||||
}
|
||||
|
||||
public DataHeightCache(ScrollPool scrollPool, DataHeightCache sisterCache) : this(scrollPool)
|
||||
{
|
||||
//this.SisterCache = sisterCache;
|
||||
|
||||
//for (int i = 0; i < scrollPool.DataSource.ItemCount; i++)
|
||||
// Add(sisterCache[ScrollPool.DataSource.GetRealIndexOfTempIndex(i)]);
|
||||
}
|
||||
|
||||
private readonly List<DataViewInfo> heightCache = new List<DataViewInfo>();
|
||||
// initialize with a reasonably sized pool, most caches will allocate a fair bit.
|
||||
private readonly List<DataViewInfo> heightCache = new List<DataViewInfo>(16384);
|
||||
|
||||
public DataViewInfo this[int index]
|
||||
{
|
||||
@ -118,14 +110,23 @@ namespace UnityExplorer.UI.Widgets
|
||||
/// <summary>Get the data index at the specific position of the total height cache.</summary>
|
||||
public int GetDataIndexAtPosition(float desiredHeight, out DataViewInfo cache)
|
||||
{
|
||||
cache = null;
|
||||
cache = default;
|
||||
int rangeIndex = GetRangeIndexOfPosition(desiredHeight);
|
||||
|
||||
if (rangeIndex < 0)
|
||||
throw new Exception("Range index (" + rangeIndex + ") is below 0");
|
||||
{
|
||||
ExplorerCore.LogWarning("RangeIndex < 0? " + rangeIndex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (rangeCache.Count <= rangeIndex)
|
||||
throw new Exception("Range index (" + rangeIndex + ") exceeded rangeCache count (" + rangeCache.Count + ")");
|
||||
{
|
||||
ExplorerCore.LogWarning("Want range index " + rangeIndex + " but count is " + rangeCache.Count);
|
||||
RebuildCache();
|
||||
rangeIndex = GetRangeIndexOfPosition(desiredHeight);
|
||||
if (rangeCache.Count <= rangeIndex)
|
||||
throw new Exception("Range index (" + rangeIndex + ") exceeded rangeCache count (" + rangeCache.Count + ")");
|
||||
}
|
||||
|
||||
int dataIndex = rangeCache[rangeIndex];
|
||||
cache = heightCache[dataIndex];
|
||||
@ -134,16 +135,13 @@ namespace UnityExplorer.UI.Widgets
|
||||
}
|
||||
|
||||
/// <summary>Set a given data index with the specified value.</summary>
|
||||
public void SetIndex(int dataIndex, float height, bool ignoreDataCount = false)
|
||||
public void SetIndex(int dataIndex, float height)
|
||||
{
|
||||
if (!ignoreDataCount)
|
||||
if (dataIndex >= ScrollPool.DataSource.ItemCount)
|
||||
{
|
||||
if (dataIndex >= ScrollPool.DataSource.ItemCount)
|
||||
{
|
||||
while (heightCache.Count > dataIndex)
|
||||
RemoveLast();
|
||||
return;
|
||||
}
|
||||
while (heightCache.Count > dataIndex)
|
||||
RemoveLast();
|
||||
return;
|
||||
}
|
||||
|
||||
if (dataIndex >= heightCache.Count)
|
||||
@ -175,14 +173,10 @@ namespace UnityExplorer.UI.Widgets
|
||||
int rangeIndex = GetRangeCeilingOfPosition(cache.startPosition);
|
||||
int spread = GetRangeSpread(cache.startPosition, height);
|
||||
|
||||
// check if our range cache is "corrupt" or not. If so we need to do a quick rebuild,
|
||||
// so that each cell's start position is correct again.
|
||||
if (rangeCache.Count <= rangeIndex || rangeCache[rangeIndex] != dataIndex)
|
||||
if (rangeCache.Count <= rangeIndex)
|
||||
{
|
||||
RebuildStartPositions(ignoreDataCount);
|
||||
// get these values again after rebuilding
|
||||
rangeIndex = GetRangeCeilingOfPosition(cache.startPosition);
|
||||
spread = GetRangeSpread(cache.startPosition, height);
|
||||
RebuildCache();
|
||||
return;
|
||||
}
|
||||
|
||||
if (spread != cache.normalizedSpread)
|
||||
@ -196,7 +190,7 @@ namespace UnityExplorer.UI.Widgets
|
||||
{
|
||||
// In some rare cases we may not find our data index at the expected range index.
|
||||
// We can make some educated guesses and find the real index pretty quickly.
|
||||
int minStart = rangeCache[dataIndex];
|
||||
int minStart = GetRangeIndexOfPosition(dataIndex * DefaultHeight);
|
||||
for (int i = minStart; i < rangeCache.Count; i++)
|
||||
{
|
||||
if (rangeCache[i] == dataIndex)
|
||||
@ -211,16 +205,16 @@ namespace UnityExplorer.UI.Widgets
|
||||
// This should never happen. We might be in a rebuild right now so don't
|
||||
// rebuild again, we could overflow the stack. Just log it.
|
||||
ExplorerCore.LogWarning($"DataHeightCache: Looking for range index of data {dataIndex} but reached the end and didn't find it.");
|
||||
ExplorerCore.Log($"startPos: {cache.startPosition}, rangeIndex: {rangeIndex}, total height: {TotalHeight}");
|
||||
return;
|
||||
}
|
||||
|
||||
// our data index is further down. add the min difference and try again.
|
||||
// the iterator will add 1 on the next loop so account for that.
|
||||
// also, add the (spread - 1) of the cell we found at this index to skip it.
|
||||
var spreadCurr = heightCache[rangeCache[i]].normalizedSpread;
|
||||
int jmp = dataIndex - rangeCache[i] - 1;
|
||||
jmp += heightCache[rangeCache[i]].normalizedSpread - 1;
|
||||
i += jmp < 1 ? 0 : jmp;
|
||||
jmp += spreadCurr - 2;
|
||||
i = (jmp < 1 ? i : i + jmp);
|
||||
}
|
||||
}
|
||||
|
||||
@ -232,19 +226,19 @@ namespace UnityExplorer.UI.Widgets
|
||||
if (rangeCache[rangeIndex] == dataIndex)
|
||||
rangeCache.Insert(rangeIndex, dataIndex);
|
||||
else
|
||||
ExplorerCore.LogWarning($"DataHeightCache error increasing spread of data {dataIndex}, " +
|
||||
$"the value at range {rangeIndex} is {rangeCache[rangeIndex]}!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// need to remove
|
||||
for (int i = 0; i < -spreadDiff; i++)
|
||||
{
|
||||
if (rangeCache[rangeIndex] == dataIndex)
|
||||
rangeCache.RemoveAt(rangeIndex);
|
||||
else
|
||||
ExplorerCore.LogWarning($"DataHeightCache error decreasing spread of data {dataIndex}, " +
|
||||
$"the value at range {rangeIndex} is {rangeCache[rangeIndex]}!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -257,11 +251,11 @@ namespace UnityExplorer.UI.Widgets
|
||||
//}
|
||||
}
|
||||
|
||||
private void RebuildStartPositions(bool ignoreDataCount)
|
||||
private void RebuildCache()
|
||||
{
|
||||
//start at 1 because 0's start pos is always 0
|
||||
for (int i = 1; i < heightCache.Count; i++)
|
||||
SetIndex(i, heightCache[i].height, ignoreDataCount);
|
||||
SetIndex(i, heightCache[i].height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,11 @@ using UnityExplorer.UI.Models;
|
||||
|
||||
namespace UnityExplorer.UI.Widgets
|
||||
{
|
||||
public struct CellInfo
|
||||
{
|
||||
public int cellIndex, dataIndex;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An object-pooled ScrollRect, attempts to support content of any size and provide a scrollbar for it.
|
||||
/// </summary>
|
||||
@ -62,7 +67,6 @@ namespace UnityExplorer.UI.Widgets
|
||||
private readonly List<ICell> CellPool = new List<ICell>();
|
||||
|
||||
internal DataHeightCache HeightCache;
|
||||
internal DataHeightCache tempHeightCache;
|
||||
|
||||
private float TotalDataHeight => HeightCache.TotalHeight + contentLayout.padding.top + contentLayout.padding.bottom;
|
||||
|
||||
@ -114,7 +118,10 @@ namespace UnityExplorer.UI.Widgets
|
||||
|
||||
public void Rebuild()
|
||||
{
|
||||
RecreateCellPool(true, true, null);
|
||||
SetRecycleViewBounds(false);
|
||||
SetScrollBounds();
|
||||
|
||||
RecreateCellPool(true, true);
|
||||
writingLocked = false;
|
||||
Content.anchoredPosition = Vector2.zero;
|
||||
UpdateSliderHandle(true);
|
||||
@ -128,22 +135,23 @@ namespace UnityExplorer.UI.Widgets
|
||||
UpdateSliderHandle(true);
|
||||
}
|
||||
|
||||
public void EnableTempCache()
|
||||
public void RecreateHeightCache()
|
||||
{
|
||||
if (tempHeightCache == null)
|
||||
tempHeightCache = HeightCache;
|
||||
//if (tempHeightCache == null)
|
||||
// tempHeightCache = HeightCache;
|
||||
|
||||
HeightCache = new DataHeightCache(this, tempHeightCache);
|
||||
HeightCache = new DataHeightCache(this);
|
||||
CheckDataSourceCountChange(out _);
|
||||
}
|
||||
|
||||
public void DisableTempCache()
|
||||
{
|
||||
if (tempHeightCache == null)
|
||||
return;
|
||||
//public void DisableTempCache()
|
||||
//{
|
||||
// if (tempHeightCache == null)
|
||||
// return;
|
||||
|
||||
HeightCache = tempHeightCache;
|
||||
tempHeightCache = null;
|
||||
}
|
||||
// HeightCache = tempHeightCache;
|
||||
// tempHeightCache = null;
|
||||
//}
|
||||
|
||||
public void RefreshCells(bool reloadData)
|
||||
{
|
||||
@ -252,23 +260,15 @@ namespace UnityExplorer.UI.Widgets
|
||||
RecycleViewBounds = new Vector2(Viewport.MinY() + HalfThreshold, Viewport.MaxY() - HalfThreshold);
|
||||
|
||||
if (checkHeightGrow && prevViewportHeight < Viewport.rect.height && prevViewportHeight != 0.0f)
|
||||
ret = RecreateCellPool(false, false, null);
|
||||
ret = RecreateCellPool(false, false);
|
||||
|
||||
prevViewportHeight = Viewport.rect.height;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private bool RecreateCellPool(bool forceRecreate, bool resetDataIndex, bool? setTempCacheEnabledTo)
|
||||
private bool RecreateCellPool(bool forceRecreate, bool resetDataIndex)
|
||||
{
|
||||
if (setTempCacheEnabledTo != null)
|
||||
{
|
||||
if (setTempCacheEnabledTo == true)
|
||||
EnableTempCache();
|
||||
else if (setTempCacheEnabledTo == false)
|
||||
DisableTempCache();
|
||||
}
|
||||
|
||||
CheckDataSourceCountChange(out _);
|
||||
|
||||
var requiredCoverage = Math.Abs(RecycleViewBounds.y - RecycleViewBounds.x);
|
||||
@ -310,7 +310,7 @@ namespace UnityExplorer.UI.Widgets
|
||||
|
||||
// Refresh methods
|
||||
|
||||
private struct CellInfo { public int cellIndex, dataIndex; }
|
||||
private CellInfo _cellInfo = new CellInfo();
|
||||
|
||||
private IEnumerator<CellInfo> GetPoolEnumerator()
|
||||
{
|
||||
@ -319,11 +319,9 @@ namespace UnityExplorer.UI.Widgets
|
||||
int iterated = 0;
|
||||
while (iterated < CellPool.Count)
|
||||
{
|
||||
yield return new CellInfo()
|
||||
{
|
||||
cellIndex = cellIdx,
|
||||
dataIndex = dataIndex
|
||||
};
|
||||
_cellInfo.cellIndex = cellIdx;
|
||||
_cellInfo.dataIndex = dataIndex;
|
||||
yield return _cellInfo;
|
||||
|
||||
cellIdx++;
|
||||
if (cellIdx >= CellPool.Count)
|
||||
@ -407,7 +405,7 @@ namespace UnityExplorer.UI.Widgets
|
||||
cachedCell.Enable();
|
||||
DataSource.SetCell(cachedCell, dataIndex);
|
||||
|
||||
//LayoutRebuilder.ForceRebuildLayoutImmediate(cachedCell.Rect);
|
||||
LayoutRebuilder.ForceRebuildLayoutImmediate(cachedCell.Rect);
|
||||
HeightCache.SetIndex(dataIndex, cachedCell.Rect.rect.height);
|
||||
}
|
||||
|
||||
@ -443,11 +441,11 @@ namespace UnityExplorer.UI.Widgets
|
||||
ScrollRect.m_ContentStartPosition += vector;
|
||||
ScrollRect.m_PrevPosition += vector;
|
||||
|
||||
// LayoutRebuilder.ForceRebuildLayoutImmediate(Content);
|
||||
prevAnchoredPos = ScrollRect.content.anchoredPosition;
|
||||
|
||||
SetScrollBounds();
|
||||
|
||||
//WritingLocked = true;
|
||||
UpdateSliderHandle();
|
||||
}
|
||||
|
||||
@ -487,6 +485,8 @@ namespace UnityExplorer.UI.Widgets
|
||||
topPoolIndex = (topPoolIndex + 1) % CellPool.Count;
|
||||
}
|
||||
|
||||
//LayoutRebuilder.ForceRebuildLayoutImmediate(Content);
|
||||
|
||||
return -recycledheight;
|
||||
}
|
||||
|
||||
@ -528,6 +528,8 @@ namespace UnityExplorer.UI.Widgets
|
||||
bottomPoolIndex = (bottomPoolIndex - 1 + CellPool.Count) % CellPool.Count;
|
||||
}
|
||||
|
||||
//LayoutRebuilder.ForceRebuildLayoutImmediate(Content);
|
||||
|
||||
return recycledheight;
|
||||
}
|
||||
|
||||
|
@ -37,8 +37,6 @@ namespace UnityExplorer.UI.Utility
|
||||
|
||||
public SliderScrollbar(Scrollbar scrollbar, Slider slider)
|
||||
{
|
||||
//Instances.Add(this);
|
||||
|
||||
this.m_scrollbar = scrollbar;
|
||||
this.m_slider = slider;
|
||||
this.m_scrollRect = scrollbar.transform.parent.GetComponent<RectTransform>();
|
||||
@ -50,17 +48,6 @@ namespace UnityExplorer.UI.Utility
|
||||
this.m_slider.Set(1f, false);
|
||||
}
|
||||
|
||||
//internal bool CheckDestroyed()
|
||||
//{
|
||||
// if (!m_slider || !m_scrollbar)
|
||||
// {
|
||||
// Instances.Remove(this);
|
||||
// return true;
|
||||
// }
|
||||
|
||||
// return false;
|
||||
//}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
this.RefreshVisibility();
|
||||
@ -75,12 +62,12 @@ namespace UnityExplorer.UI.Utility
|
||||
}
|
||||
|
||||
bool shouldShow = !Mathf.Approximately(this.m_scrollbar.size, 1);
|
||||
var obj = this.m_slider.handleRect.gameObject;
|
||||
//var obj = this.m_slider.handleRect.gameObject;
|
||||
|
||||
if (IsActive != shouldShow)
|
||||
{
|
||||
IsActive = shouldShow;
|
||||
obj.SetActive(IsActive);
|
||||
m_slider.interactable = shouldShow;
|
||||
|
||||
if (IsActive)
|
||||
this.m_slider.Set(this.m_scrollbar.value, false);
|
||||
@ -109,14 +96,12 @@ namespace UnityExplorer.UI.Utility
|
||||
GameObject sliderObj = UIFactory.CreateUIObject("SliderScrollbar", parent, UIFactory._smallElementSize);
|
||||
|
||||
GameObject bgObj = UIFactory.CreateUIObject("Background", sliderObj);
|
||||
//GameObject fillAreaObj = UIFactory.CreateUIObject("Fill Area", sliderObj);
|
||||
//GameObject fillObj = UIFactory.CreateUIObject("Fill", fillAreaObj);
|
||||
GameObject handleSlideAreaObj = UIFactory.CreateUIObject("Handle Slide Area", sliderObj);
|
||||
GameObject handleObj = UIFactory.CreateUIObject("Handle", handleSlideAreaObj);
|
||||
|
||||
Image bgImage = bgObj.AddComponent<Image>();
|
||||
bgImage.type = Image.Type.Sliced;
|
||||
bgImage.color = new Color(0.05f, 0.05f, 0.05f, 1.0f);
|
||||
bgImage.color = new Color(0.1f, 0.1f, 0.1f, 1.0f);
|
||||
|
||||
RectTransform bgRect = bgObj.GetComponent<RectTransform>();
|
||||
bgRect.anchorMin = Vector2.zero;
|
||||
@ -128,7 +113,7 @@ namespace UnityExplorer.UI.Utility
|
||||
handleSlideRect.anchorMin = new Vector2(0f, 0f);
|
||||
handleSlideRect.anchorMax = new Vector2(1f, 1f);
|
||||
handleSlideRect.pivot = new Vector2(0.5f, 0.5f);
|
||||
handleSlideRect.offsetMin = new Vector2(27f, 30f);
|
||||
handleSlideRect.offsetMin = new Vector2(25f, 30f);
|
||||
handleSlideRect.offsetMax = new Vector2(-15f, 0f);
|
||||
handleSlideRect.sizeDelta = new Vector2(-20f, -30f);
|
||||
|
||||
@ -147,14 +132,14 @@ namespace UnityExplorer.UI.Utility
|
||||
sliderBarLayout.flexibleHeight = 5000;
|
||||
|
||||
slider = sliderObj.AddComponent<Slider>();
|
||||
//slider.fillRect = fillObj.GetComponent<RectTransform>();
|
||||
slider.handleRect = handleObj.GetComponent<RectTransform>();
|
||||
slider.targetGraphic = handleImage;
|
||||
slider.direction = Slider.Direction.BottomToTop;
|
||||
|
||||
RuntimeProvider.Instance.SetColorBlock(slider,
|
||||
new Color(0.25f, 0.25f, 0.25f),
|
||||
new Color(0.3f, 0.3f, 0.3f),
|
||||
RuntimeProvider.Instance.SetColorBlock(slider,
|
||||
new Color(0.4f, 0.4f, 0.4f),
|
||||
new Color(0.5f, 0.5f, 0.5f),
|
||||
new Color(0.3f, 0.3f, 0.3f),
|
||||
new Color(0.2f, 0.2f, 0.2f));
|
||||
|
||||
return sliderObj;
|
||||
|
Loading…
x
Reference in New Issue
Block a user