mirror of
https://github.com/sinai-dev/UnityExplorer.git
synced 2025-01-07 18:13:35 +08:00
Added Search page and AutoCompleter
This commit is contained in:
parent
eb58ab5327
commit
f509a985e7
@ -1,69 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
|
||||||
using UnityEngine;
|
|
||||||
using UnityExplorer.Core;
|
|
||||||
|
|
||||||
namespace UnityExplorer.Core.CSharp
|
|
||||||
{
|
|
||||||
public struct Suggestion
|
|
||||||
{
|
|
||||||
public enum Contexts
|
|
||||||
{
|
|
||||||
Namespace,
|
|
||||||
Keyword,
|
|
||||||
Other
|
|
||||||
}
|
|
||||||
|
|
||||||
// ~~~~ Instance ~~~~
|
|
||||||
|
|
||||||
public readonly string Prefix;
|
|
||||||
public readonly string Addition;
|
|
||||||
public readonly Contexts Context;
|
|
||||||
|
|
||||||
public string Full => Prefix + Addition;
|
|
||||||
|
|
||||||
public Color TextColor => GetTextColor();
|
|
||||||
|
|
||||||
public Suggestion(string addition, string prefix, Contexts type)
|
|
||||||
{
|
|
||||||
Addition = addition;
|
|
||||||
Prefix = prefix;
|
|
||||||
Context = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Color GetTextColor()
|
|
||||||
{
|
|
||||||
switch (Context)
|
|
||||||
{
|
|
||||||
case Contexts.Namespace: return Color.grey;
|
|
||||||
case Contexts.Keyword: return keywordColor;
|
|
||||||
default: return Color.white;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ~~~~ Static ~~~~
|
|
||||||
|
|
||||||
public static HashSet<string> Namespaces => m_namespaces ?? GetNamespaces();
|
|
||||||
private static HashSet<string> m_namespaces;
|
|
||||||
|
|
||||||
public static HashSet<string> Keywords => throw new NotImplementedException("TODO!"); // m_keywords ?? (m_keywords = new HashSet<string>(CSLexerHighlighter.validKeywordMatcher.Keywords));
|
|
||||||
//private static HashSet<string> m_keywords;
|
|
||||||
|
|
||||||
private static readonly Color keywordColor = new Color(80f / 255f, 150f / 255f, 215f / 255f);
|
|
||||||
|
|
||||||
private static HashSet<string> GetNamespaces()
|
|
||||||
{
|
|
||||||
HashSet<string> set = new HashSet<string>(
|
|
||||||
AppDomain.CurrentDomain.GetAssemblies()
|
|
||||||
.SelectMany(GetTypes)
|
|
||||||
.Where(x => x.IsPublic && !string.IsNullOrEmpty(x.Namespace))
|
|
||||||
.Select(x => x.Namespace));
|
|
||||||
|
|
||||||
return m_namespaces = set;
|
|
||||||
|
|
||||||
IEnumerable<Type> GetTypes(Assembly asm) => asm.TryGetTypes();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -120,7 +120,7 @@ namespace UnityExplorer
|
|||||||
}
|
}
|
||||||
|
|
||||||
// cache for GetBaseTypes
|
// cache for GetBaseTypes
|
||||||
internal static readonly Dictionary<string, Type[]> s_cachedTypeInheritance = new Dictionary<string, Type[]>();
|
internal static readonly Dictionary<string, Type[]> s_cachedBaseTypes = new Dictionary<string, Type[]>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get all base types of the provided Type, including itself.
|
/// Get all base types of the provided Type, including itself.
|
||||||
@ -137,7 +137,7 @@ namespace UnityExplorer
|
|||||||
|
|
||||||
var name = type.AssemblyQualifiedName;
|
var name = type.AssemblyQualifiedName;
|
||||||
|
|
||||||
if (s_cachedTypeInheritance.TryGetValue(name, out Type[] ret))
|
if (s_cachedBaseTypes.TryGetValue(name, out Type[] ret))
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
List<Type> list = new List<Type>();
|
List<Type> list = new List<Type>();
|
||||||
@ -150,11 +150,52 @@ namespace UnityExplorer
|
|||||||
|
|
||||||
ret = list.ToArray();
|
ret = list.ToArray();
|
||||||
|
|
||||||
s_cachedTypeInheritance.Add(name, ret);
|
s_cachedBaseTypes.Add(name, ret);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// cache for GetImplementationsOf
|
||||||
|
internal static readonly Dictionary<Type, HashSet<Type>> s_cachedTypeInheritance = new Dictionary<Type, HashSet<Type>>();
|
||||||
|
internal static int s_lastAssemblyCount;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get all non-abstract implementations of the provided type (include itself, if not abstract) in the current AppDomain.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="baseType">The base type, which can optionally be abstract / interface.</param>
|
||||||
|
/// <returns>All implementations of the type in the current AppDomain.</returns>
|
||||||
|
public static HashSet<Type> GetImplementationsOf(this Type baseType, bool allowAbstract)
|
||||||
|
{
|
||||||
|
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
|
||||||
|
|
||||||
|
if (!s_cachedTypeInheritance.ContainsKey(baseType) || assemblies.Length != s_lastAssemblyCount)
|
||||||
|
{
|
||||||
|
if (assemblies.Length != s_lastAssemblyCount)
|
||||||
|
{
|
||||||
|
s_cachedTypeInheritance.Clear();
|
||||||
|
s_lastAssemblyCount = assemblies.Length;
|
||||||
|
}
|
||||||
|
|
||||||
|
var set = new HashSet<Type>();
|
||||||
|
|
||||||
|
if (!baseType.IsAbstract && !baseType.IsInterface)
|
||||||
|
set.Add(baseType);
|
||||||
|
|
||||||
|
foreach (var asm in assemblies)
|
||||||
|
{
|
||||||
|
foreach (var t in asm.TryGetTypes().Where(t => allowAbstract || (!t.IsAbstract && !t.IsInterface)))
|
||||||
|
{
|
||||||
|
if (baseType.IsAssignableFrom(t) && !set.Contains(t))
|
||||||
|
set.Add(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
s_cachedTypeInheritance.Add(baseType, set);
|
||||||
|
}
|
||||||
|
|
||||||
|
return s_cachedTypeInheritance[baseType];
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Safely get all valid Types inside an Assembly.
|
/// Safely get all valid Types inside an Assembly.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -5,7 +5,7 @@ using System.Text;
|
|||||||
|
|
||||||
namespace UnityExplorer.Core.Search
|
namespace UnityExplorer.Core.Search
|
||||||
{
|
{
|
||||||
internal enum ChildFilter
|
public enum ChildFilter
|
||||||
{
|
{
|
||||||
Any,
|
Any,
|
||||||
RootObject,
|
RootObject,
|
||||||
|
@ -5,11 +5,11 @@ using System.Text;
|
|||||||
|
|
||||||
namespace UnityExplorer.Core.Search
|
namespace UnityExplorer.Core.Search
|
||||||
{
|
{
|
||||||
internal enum SceneFilter
|
public enum SceneFilter
|
||||||
{
|
{
|
||||||
Any,
|
Any,
|
||||||
Asset,
|
ActivelyLoaded,
|
||||||
DontDestroyOnLoad,
|
DontDestroyOnLoad,
|
||||||
Explicit,
|
HideAndDontSave,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ using System.Text;
|
|||||||
|
|
||||||
namespace UnityExplorer.Core.Search
|
namespace UnityExplorer.Core.Search
|
||||||
{
|
{
|
||||||
internal enum SearchContext
|
public enum SearchContext
|
||||||
{
|
{
|
||||||
UnityObject,
|
UnityObject,
|
||||||
GameObject,
|
GameObject,
|
||||||
|
@ -4,15 +4,16 @@ using System.Linq;
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using UnityEngine.SceneManagement;
|
||||||
using UnityExplorer.Core.Runtime;
|
using UnityExplorer.Core.Runtime;
|
||||||
|
|
||||||
namespace UnityExplorer.Core.Search
|
namespace UnityExplorer.Core.Search
|
||||||
{
|
{
|
||||||
public static class SearchProvider
|
public static class SearchProvider
|
||||||
{
|
{
|
||||||
internal static object[] StaticClassSearch(string input)
|
internal static List<object> StaticClassSearch(string input)
|
||||||
{
|
{
|
||||||
var list = new List<Type>();
|
var list = new List<object>();
|
||||||
|
|
||||||
var nameFilter = "";
|
var nameFilter = "";
|
||||||
if (!string.IsNullOrEmpty(input))
|
if (!string.IsNullOrEmpty(input))
|
||||||
@ -29,7 +30,7 @@ namespace UnityExplorer.Core.Search
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return list.ToArray();
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static string[] s_instanceNames = new string[]
|
internal static string[] s_instanceNames = new string[]
|
||||||
@ -46,7 +47,7 @@ namespace UnityExplorer.Core.Search
|
|||||||
"<instance>k__BackingField",
|
"<instance>k__BackingField",
|
||||||
};
|
};
|
||||||
|
|
||||||
internal static object[] SingletonSearch(string input)
|
internal static List<object> SingletonSearch(string input)
|
||||||
{
|
{
|
||||||
var instances = new List<object>();
|
var instances = new List<object>();
|
||||||
|
|
||||||
@ -72,12 +73,31 @@ namespace UnityExplorer.Core.Search
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return instances.ToArray();
|
return instances;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static object[] UnityObjectSearch(string input, string customTypeInput, SearchContext context,
|
private static bool Filter(Scene scene, SceneFilter filter)
|
||||||
ChildFilter childFilter, SceneFilter sceneFilter, string sceneName = null)
|
|
||||||
{
|
{
|
||||||
|
switch (filter)
|
||||||
|
{
|
||||||
|
case SceneFilter.Any:
|
||||||
|
return true;
|
||||||
|
case SceneFilter.DontDestroyOnLoad:
|
||||||
|
return scene == SceneHandler.DontDestroyScene;
|
||||||
|
case SceneFilter.HideAndDontSave:
|
||||||
|
return scene == SceneHandler.AssetScene;
|
||||||
|
case SceneFilter.ActivelyLoaded:
|
||||||
|
return scene != SceneHandler.DontDestroyScene && scene != SceneHandler.AssetScene;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static List<object> UnityObjectSearch(string input, string customTypeInput, SearchContext context,
|
||||||
|
ChildFilter childFilter, SceneFilter sceneFilter)
|
||||||
|
{
|
||||||
|
var results = new List<object>();
|
||||||
|
|
||||||
Type searchType = null;
|
Type searchType = null;
|
||||||
switch (context)
|
switch (context)
|
||||||
{
|
{
|
||||||
@ -91,13 +111,15 @@ namespace UnityExplorer.Core.Search
|
|||||||
if (string.IsNullOrEmpty(customTypeInput))
|
if (string.IsNullOrEmpty(customTypeInput))
|
||||||
{
|
{
|
||||||
ExplorerCore.LogWarning("Custom Type input must not be empty!");
|
ExplorerCore.LogWarning("Custom Type input must not be empty!");
|
||||||
return null;
|
return results;
|
||||||
}
|
}
|
||||||
if (ReflectionUtility.GetTypeByName(customTypeInput) is Type customType)
|
if (ReflectionUtility.GetTypeByName(customTypeInput) is Type customType)
|
||||||
|
{
|
||||||
if (typeof(UnityEngine.Object).IsAssignableFrom(customType))
|
if (typeof(UnityEngine.Object).IsAssignableFrom(customType))
|
||||||
searchType = customType;
|
searchType = customType;
|
||||||
else
|
else
|
||||||
ExplorerCore.LogWarning($"Custom type '{customType.FullName}' is not assignable from UnityEngine.Object!");
|
ExplorerCore.LogWarning($"Custom type '{customType.FullName}' is not assignable from UnityEngine.Object!");
|
||||||
|
}
|
||||||
else
|
else
|
||||||
ExplorerCore.LogWarning($"Could not find a type by the name '{customTypeInput}'!");
|
ExplorerCore.LogWarning($"Could not find a type by the name '{customTypeInput}'!");
|
||||||
break;
|
break;
|
||||||
@ -106,11 +128,11 @@ namespace UnityExplorer.Core.Search
|
|||||||
searchType = typeof(UnityEngine.Object); break;
|
searchType = typeof(UnityEngine.Object); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (searchType == null)
|
if (searchType == null)
|
||||||
return null;
|
return results;
|
||||||
|
|
||||||
var allObjects = RuntimeProvider.Instance.FindObjectsOfTypeAll(searchType);
|
var allObjects = RuntimeProvider.Instance.FindObjectsOfTypeAll(searchType);
|
||||||
var results = new List<object>();
|
|
||||||
|
|
||||||
// perform filter comparers
|
// perform filter comparers
|
||||||
|
|
||||||
@ -121,20 +143,11 @@ namespace UnityExplorer.Core.Search
|
|||||||
bool canGetGameObject = (sceneFilter != SceneFilter.Any || childFilter != ChildFilter.Any)
|
bool canGetGameObject = (sceneFilter != SceneFilter.Any || childFilter != ChildFilter.Any)
|
||||||
&& (context == SearchContext.GameObject || typeof(Component).IsAssignableFrom(searchType));
|
&& (context == SearchContext.GameObject || typeof(Component).IsAssignableFrom(searchType));
|
||||||
|
|
||||||
string sceneFilterString = null;
|
|
||||||
if (!canGetGameObject)
|
if (!canGetGameObject)
|
||||||
{
|
{
|
||||||
if (context != SearchContext.UnityObject && (sceneFilter != SceneFilter.Any || childFilter != ChildFilter.Any))
|
if (context != SearchContext.UnityObject && (sceneFilter != SceneFilter.Any || childFilter != ChildFilter.Any))
|
||||||
ExplorerCore.LogWarning($"Type '{searchType}' cannot have Scene or Child filters applied to it");
|
ExplorerCore.LogWarning($"Type '{searchType}' cannot have Scene or Child filters applied to it");
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
if (sceneFilter == SceneFilter.DontDestroyOnLoad)
|
|
||||||
sceneFilterString = "DontDestroyOnLoad";
|
|
||||||
else if (sceneFilter == SceneFilter.Explicit)
|
|
||||||
//sceneFilterString = SearchPage.Instance.m_sceneDropdown.options[SearchPage.Instance.m_sceneDropdown.value].text;
|
|
||||||
sceneFilterString = sceneName;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var obj in allObjects)
|
foreach (var obj in allObjects)
|
||||||
{
|
{
|
||||||
@ -157,12 +170,9 @@ namespace UnityExplorer.Core.Search
|
|||||||
switch (context)
|
switch (context)
|
||||||
{
|
{
|
||||||
case SearchContext.GameObject:
|
case SearchContext.GameObject:
|
||||||
if (go.scene.name != sceneFilterString)
|
|
||||||
continue;
|
|
||||||
break;
|
|
||||||
case SearchContext.Custom:
|
case SearchContext.Custom:
|
||||||
case SearchContext.Component:
|
case SearchContext.Component:
|
||||||
if (go.scene.name != sceneFilterString)
|
if (!Filter(go.scene, sceneFilter))
|
||||||
continue;
|
continue;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -184,7 +194,7 @@ namespace UnityExplorer.Core.Search
|
|||||||
results.Add(obj);
|
results.Add(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
return results.ToArray();
|
return results;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,13 @@ namespace UnityExplorer.UI.Models
|
|||||||
|
|
||||||
public abstract void ConstructUI(GameObject parent);
|
public abstract void ConstructUI(GameObject parent);
|
||||||
|
|
||||||
|
public virtual void Toggle() => SetActive(!Enabled);
|
||||||
|
|
||||||
|
public virtual void SetActive(bool active)
|
||||||
|
{
|
||||||
|
UIRoot?.SetActive(active);
|
||||||
|
}
|
||||||
|
|
||||||
public virtual void Destroy()
|
public virtual void Destroy()
|
||||||
{
|
{
|
||||||
if (UIRoot)
|
if (UIRoot)
|
||||||
|
@ -13,17 +13,19 @@ namespace UnityExplorer.UI.Models
|
|||||||
{
|
{
|
||||||
public abstract class UIPanel : UIBehaviourModel
|
public abstract class UIPanel : UIBehaviourModel
|
||||||
{
|
{
|
||||||
|
// STATIC
|
||||||
|
|
||||||
public static event Action OnPanelsReordered;
|
public static event Action OnPanelsReordered;
|
||||||
|
|
||||||
public static void UpdateFocus()
|
public static void UpdateFocus()
|
||||||
{
|
{
|
||||||
if (InputManager.GetMouseButtonDown(0) || InputManager.GetMouseButtonDown(1))
|
if (InputManager.GetMouseButtonDown(0) || InputManager.GetMouseButtonDown(1))
|
||||||
{
|
{
|
||||||
int count = UIManager.CanvasRoot.transform.childCount;
|
int count = UIManager.PanelHolder.transform.childCount;
|
||||||
var mousePos = InputManager.MousePosition;
|
var mousePos = InputManager.MousePosition;
|
||||||
for (int i = count - 1; i >= 0; i--)
|
for (int i = count - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
var transform = UIManager.CanvasRoot.transform.GetChild(i);
|
var transform = UIManager.PanelHolder.transform.GetChild(i);
|
||||||
if (transformToPanelDict.TryGetValue(transform.GetInstanceID(), out UIPanel panel))
|
if (transformToPanelDict.TryGetValue(transform.GetInstanceID(), out UIPanel panel))
|
||||||
{
|
{
|
||||||
var pos = panel.mainPanelRect.InverseTransformPoint(mousePos);
|
var pos = panel.mainPanelRect.InverseTransformPoint(mousePos);
|
||||||
@ -44,16 +46,18 @@ namespace UnityExplorer.UI.Models
|
|||||||
private static readonly List<UIPanel> instances = new List<UIPanel>();
|
private static readonly List<UIPanel> instances = new List<UIPanel>();
|
||||||
private static readonly Dictionary<int, UIPanel> transformToPanelDict = new Dictionary<int, UIPanel>();
|
private static readonly Dictionary<int, UIPanel> transformToPanelDict = new Dictionary<int, UIPanel>();
|
||||||
|
|
||||||
|
// INSTANCE
|
||||||
|
|
||||||
public UIPanel()
|
public UIPanel()
|
||||||
{
|
{
|
||||||
instances.Add(this);
|
instances.Add(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Destroy()
|
public abstract UIManager.Panels PanelType { get; }
|
||||||
{
|
|
||||||
instances.Remove(this);
|
public abstract string Name { get; }
|
||||||
base.Destroy();
|
|
||||||
}
|
public virtual bool ShouldSaveActiveState => true;
|
||||||
|
|
||||||
public override GameObject UIRoot => uiRoot;
|
public override GameObject UIRoot => uiRoot;
|
||||||
protected GameObject uiRoot;
|
protected GameObject uiRoot;
|
||||||
@ -61,7 +65,23 @@ namespace UnityExplorer.UI.Models
|
|||||||
public GameObject content;
|
public GameObject content;
|
||||||
public PanelDragger dragger;
|
public PanelDragger dragger;
|
||||||
|
|
||||||
public abstract string Name { get; }
|
public abstract void ConstructPanelContent();
|
||||||
|
|
||||||
|
public virtual void OnFinishResize(RectTransform panel)
|
||||||
|
{
|
||||||
|
SaveToConfigManager();
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void OnFinishDrag(RectTransform panel)
|
||||||
|
{
|
||||||
|
SaveToConfigManager();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Destroy()
|
||||||
|
{
|
||||||
|
instances.Remove(this);
|
||||||
|
base.Destroy();
|
||||||
|
}
|
||||||
|
|
||||||
public override void ConstructUI(GameObject parent)
|
public override void ConstructUI(GameObject parent)
|
||||||
{
|
{
|
||||||
@ -79,11 +99,28 @@ namespace UnityExplorer.UI.Models
|
|||||||
SetDefaultPosAndAnchors();
|
SetDefaultPosAndAnchors();
|
||||||
|
|
||||||
// Title bar
|
// Title bar
|
||||||
|
var titleGroup = UIFactory.CreateHorizontalGroup(content, "TitleBar", false, true, true, true, 2,
|
||||||
|
new Vector4(2, 2, 2, 2), new Color(0.09f, 0.09f, 0.09f));
|
||||||
|
UIFactory.SetLayoutElement(titleGroup, minHeight: 25, flexibleHeight: 0);
|
||||||
|
|
||||||
var titleBar = UIFactory.CreateLabel(content, "TitleBar", Name, TextAnchor.MiddleLeft);
|
// Title text
|
||||||
UIFactory.SetLayoutElement(titleBar.gameObject, minHeight: 25, flexibleHeight: 0);
|
|
||||||
|
|
||||||
dragger = new PanelDragger(titleBar.GetComponent<RectTransform>(), mainPanelRect);
|
var titleTxt = UIFactory.CreateLabel(titleGroup, "TitleBar", Name, TextAnchor.MiddleLeft);
|
||||||
|
UIFactory.SetLayoutElement(titleTxt.gameObject, minHeight: 25, flexibleHeight: 0, flexibleWidth: 9999);
|
||||||
|
|
||||||
|
// close button
|
||||||
|
|
||||||
|
var closeBtn = UIFactory.CreateButton(titleGroup, "CloseButton", "X", () =>
|
||||||
|
{
|
||||||
|
UIManager.SetPanelActive(this.PanelType, false);
|
||||||
|
});
|
||||||
|
UIFactory.SetLayoutElement(closeBtn.gameObject, minHeight: 25, minWidth: 25, flexibleWidth: 0);
|
||||||
|
RuntimeProvider.Instance.SetColorBlock(closeBtn, new Color(0.63f, 0.32f, 0.31f),
|
||||||
|
new Color(0.81f, 0.25f, 0.2f), new Color(0.6f, 0.18f, 0.16f));
|
||||||
|
|
||||||
|
// Panel dragger
|
||||||
|
|
||||||
|
dragger = new PanelDragger(titleTxt.GetComponent<RectTransform>(), mainPanelRect);
|
||||||
dragger.OnFinishResize += OnFinishResize;
|
dragger.OnFinishResize += OnFinishResize;
|
||||||
dragger.OnFinishDrag += OnFinishDrag;
|
dragger.OnFinishDrag += OnFinishDrag;
|
||||||
|
|
||||||
@ -97,8 +134,9 @@ namespace UnityExplorer.UI.Models
|
|||||||
LoadSaveData();
|
LoadSaveData();
|
||||||
dragger.OnEndResize();
|
dragger.OnEndResize();
|
||||||
}
|
}
|
||||||
catch
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
ExplorerCore.Log($"Exception loading panel save data: {ex}");
|
||||||
SetDefaultPosAndAnchors();
|
SetDefaultPosAndAnchors();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,18 +146,8 @@ namespace UnityExplorer.UI.Models
|
|||||||
SaveToConfigManager();
|
SaveToConfigManager();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void ConstructPanelContent();
|
// SAVE DATA
|
||||||
|
|
||||||
public virtual void OnFinishResize(RectTransform panel)
|
|
||||||
{
|
|
||||||
SaveToConfigManager();
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void OnFinishDrag(RectTransform panel)
|
|
||||||
{
|
|
||||||
SaveToConfigManager();
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract void SaveToConfigManager();
|
public abstract void SaveToConfigManager();
|
||||||
|
|
||||||
@ -127,11 +155,11 @@ namespace UnityExplorer.UI.Models
|
|||||||
|
|
||||||
public abstract void LoadSaveData();
|
public abstract void LoadSaveData();
|
||||||
|
|
||||||
public string ToSaveData()
|
public virtual string ToSaveData()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return $"{Enabled}" +
|
return $"{(ShouldSaveActiveState ? Enabled : false)}" +
|
||||||
$"|{mainPanelRect.RectAnchorsToString()}" +
|
$"|{mainPanelRect.RectAnchorsToString()}" +
|
||||||
$"|{mainPanelRect.RectPositionToString()}";
|
$"|{mainPanelRect.RectPositionToString()}";
|
||||||
}
|
}
|
||||||
@ -141,7 +169,7 @@ namespace UnityExplorer.UI.Models
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ApplySaveData(string data)
|
public virtual void ApplySaveData(string data)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(data))
|
if (string.IsNullOrEmpty(data))
|
||||||
return;
|
return;
|
||||||
@ -150,11 +178,15 @@ namespace UnityExplorer.UI.Models
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
uiRoot.SetActive(bool.Parse(split[0]));
|
|
||||||
mainPanelRect.SetAnchorsFromString(split[1]);
|
mainPanelRect.SetAnchorsFromString(split[1]);
|
||||||
mainPanelRect.SetPositionFromString(split[2]);
|
mainPanelRect.SetPositionFromString(split[2]);
|
||||||
|
UIManager.SetPanelActive(this.PanelType, bool.Parse(split[0]));
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
ExplorerCore.LogWarning("Invalid or corrupt panel save data! Restoring to default.");
|
||||||
|
SetDefaultPosAndAnchors();
|
||||||
}
|
}
|
||||||
catch { }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,9 +196,6 @@ namespace UnityExplorer.UI.Models
|
|||||||
|
|
||||||
// Window Anchors helpers
|
// Window Anchors helpers
|
||||||
|
|
||||||
//private const string DEFAULT_WINDOW_ANCHORS = "0.25,0.10,0.78,0.95";
|
|
||||||
//private const string DEFAULT_WINDOW_POSITION = "0,0";
|
|
||||||
|
|
||||||
internal static CultureInfo _enCulture = new CultureInfo("en-US");
|
internal static CultureInfo _enCulture = new CultureInfo("en-US");
|
||||||
|
|
||||||
internal static string RectAnchorsToString(this RectTransform rect)
|
internal static string RectAnchorsToString(this RectTransform rect)
|
||||||
|
@ -16,6 +16,8 @@ namespace UnityExplorer.UI.Panels
|
|||||||
public class InspectorTest : UIPanel
|
public class InspectorTest : UIPanel
|
||||||
{
|
{
|
||||||
public override string Name => "Inspector";
|
public override string Name => "Inspector";
|
||||||
|
public override UIManager.Panels PanelType => UIManager.Panels.Inspector;
|
||||||
|
public override bool ShouldSaveActiveState => false;
|
||||||
|
|
||||||
//public SimpleListSource<Component> ComponentList;
|
//public SimpleListSource<Component> ComponentList;
|
||||||
|
|
||||||
@ -81,6 +83,8 @@ namespace UnityExplorer.UI.Panels
|
|||||||
ExplorerCore.Log("Done");
|
ExplorerCore.Log("Done");
|
||||||
|
|
||||||
//previousRectHeight = mainPanelRect.rect.height;
|
//previousRectHeight = mainPanelRect.rect.height;
|
||||||
|
|
||||||
|
UIManager.SetPanelActive(PanelType, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal GameObject contentHolder;
|
internal GameObject contentHolder;
|
||||||
|
139
src/UI/Panels/ObjectExplorer.cs
Normal file
139
src/UI/Panels/ObjectExplorer.cs
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.SceneManagement;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
using UnityExplorer.Core;
|
||||||
|
using UnityExplorer.Core.Config;
|
||||||
|
using UnityExplorer.UI.Models;
|
||||||
|
using UnityExplorer.UI.Utility;
|
||||||
|
using UnityExplorer.UI.Widgets;
|
||||||
|
|
||||||
|
namespace UnityExplorer.UI.Panels
|
||||||
|
{
|
||||||
|
public class ObjectExplorer : UIPanel
|
||||||
|
{
|
||||||
|
public override string Name => "Object Explorer";
|
||||||
|
public override UIManager.Panels PanelType => UIManager.Panels.ObjectExplorer;
|
||||||
|
|
||||||
|
public SceneExplorer SceneExplorer;
|
||||||
|
public ObjectSearch ObjectSearch;
|
||||||
|
|
||||||
|
public int SelectedTab = -1;
|
||||||
|
private readonly List<UIModel> tabPages = new List<UIModel>();
|
||||||
|
private readonly List<Button> tabButtons = new List<Button>();
|
||||||
|
|
||||||
|
public void SetTab(int tabIndex)
|
||||||
|
{
|
||||||
|
if (SelectedTab != -1)
|
||||||
|
DisableTab(SelectedTab);
|
||||||
|
|
||||||
|
var content = tabPages[tabIndex];
|
||||||
|
content.SetActive(true);
|
||||||
|
|
||||||
|
var button = tabButtons[tabIndex];
|
||||||
|
RuntimeProvider.Instance.SetColorBlock(button, UIManager.navButtonEnabledColor, UIManager.navButtonEnabledColor * 1.2f);
|
||||||
|
|
||||||
|
SelectedTab = tabIndex;
|
||||||
|
SaveToConfigManager();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DisableTab(int tabIndex)
|
||||||
|
{
|
||||||
|
tabPages[tabIndex].SetActive(false);
|
||||||
|
RuntimeProvider.Instance.SetColorBlock(tabButtons[tabIndex], UIManager.navButtonDisabledColor, UIManager.navButtonDisabledColor * 1.2f);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Update()
|
||||||
|
{
|
||||||
|
SceneExplorer.Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SaveToConfigManager()
|
||||||
|
{
|
||||||
|
ConfigManager.SceneExplorerData.Value = this.ToSaveData();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void LoadSaveData()
|
||||||
|
{
|
||||||
|
ApplySaveData(ConfigManager.SceneExplorerData.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToSaveData()
|
||||||
|
{
|
||||||
|
string ret = base.ToSaveData();
|
||||||
|
ret += "|" + SelectedTab;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void ApplySaveData(string data)
|
||||||
|
{
|
||||||
|
base.ApplySaveData(data);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
int tab = int.Parse(data.Split('|').Last());
|
||||||
|
SelectedTab = tab;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
SelectedTab = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetTab(SelectedTab);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SetDefaultPosAndAnchors()
|
||||||
|
{
|
||||||
|
mainPanelRect.localPosition = Vector2.zero;
|
||||||
|
mainPanelRect.anchorMin = Vector3.zero;
|
||||||
|
mainPanelRect.anchorMax = new Vector2(0, 1);
|
||||||
|
mainPanelRect.sizeDelta = new Vector2(320f, mainPanelRect.sizeDelta.y);
|
||||||
|
mainPanelRect.anchoredPosition = new Vector2(200, 0);
|
||||||
|
mainPanelRect.offsetMin = new Vector2(mainPanelRect.offsetMin.x, 100); // bottom
|
||||||
|
mainPanelRect.offsetMax = new Vector2(mainPanelRect.offsetMax.x, -50); // top
|
||||||
|
mainPanelRect.pivot = new Vector2(0.5f, 0.5f);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void ConstructPanelContent()
|
||||||
|
{
|
||||||
|
// Tab bar
|
||||||
|
var tabGroup = UIFactory.CreateHorizontalGroup(content, "TabBar", true, true, true, true, 2, new Vector4(2, 2, 2, 2));
|
||||||
|
UIFactory.SetLayoutElement(tabGroup, minHeight: 25, flexibleHeight: 0);
|
||||||
|
|
||||||
|
// Scene Explorer
|
||||||
|
SceneExplorer = new SceneExplorer(this);
|
||||||
|
SceneExplorer.ConstructUI(content);
|
||||||
|
tabPages.Add(SceneExplorer);
|
||||||
|
|
||||||
|
// Object search
|
||||||
|
ObjectSearch = new ObjectSearch(this);
|
||||||
|
ObjectSearch.ConstructUI(content);
|
||||||
|
tabPages.Add(ObjectSearch);
|
||||||
|
|
||||||
|
// set up tabs
|
||||||
|
AddTabButton(tabGroup, "Scene Explorer");
|
||||||
|
AddTabButton(tabGroup, "Object Search");
|
||||||
|
|
||||||
|
// default active state: Active
|
||||||
|
UIManager.SetPanelActive(PanelType, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddTabButton(GameObject tabGroup, string label)
|
||||||
|
{
|
||||||
|
var button = UIFactory.CreateButton(tabGroup, $"Button_{label}", label);
|
||||||
|
|
||||||
|
int idx = tabButtons.Count;
|
||||||
|
button.onClick.AddListener(() => { SetTab(idx); });
|
||||||
|
|
||||||
|
tabButtons.Add(button);
|
||||||
|
|
||||||
|
DisableTab(tabButtons.Count - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -150,7 +150,7 @@ namespace UnityExplorer.UI
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static GameObject CreatePanel(string name, out GameObject contentHolder, Color? bgColor = null)
|
public static GameObject CreatePanel(string name, out GameObject contentHolder, Color? bgColor = null)
|
||||||
{
|
{
|
||||||
var panelObj = CreateUIObject(name, UIManager.CanvasRoot);
|
var panelObj = CreateUIObject(name, UIManager.PanelHolder);
|
||||||
var rect = panelObj.GetComponent<RectTransform>();
|
var rect = panelObj.GetComponent<RectTransform>();
|
||||||
rect.anchorMin = Vector2.zero;
|
rect.anchorMin = Vector2.zero;
|
||||||
rect.anchorMax = Vector2.one;
|
rect.anchorMax = Vector2.one;
|
||||||
@ -506,7 +506,7 @@ namespace UnityExplorer.UI
|
|||||||
|
|
||||||
Image mainImage = mainObj.AddComponent<Image>();
|
Image mainImage = mainObj.AddComponent<Image>();
|
||||||
mainImage.type = Image.Type.Sliced;
|
mainImage.type = Image.Type.Sliced;
|
||||||
mainImage.color = new Color(0.15f, 0.15f, 0.15f);
|
mainImage.color = new Color(0.12f, 0.12f, 0.12f);
|
||||||
|
|
||||||
inputField = mainObj.AddComponent<InputField>();
|
inputField = mainObj.AddComponent<InputField>();
|
||||||
Navigation nav = inputField.navigation;
|
Navigation nav = inputField.navigation;
|
||||||
@ -721,7 +721,7 @@ namespace UnityExplorer.UI
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static ScrollPool CreateScrollPool(GameObject parent, string name, out GameObject uiRoot,
|
public static ScrollPool CreateScrollPool(GameObject parent, string name, out GameObject uiRoot,
|
||||||
out GameObject content, Color? bgColor = null, bool autoResizeSliderHandle = true)
|
out GameObject content, Color? bgColor = null)
|
||||||
{
|
{
|
||||||
var mainObj = CreateUIObject(name, parent, new Vector2(1, 1));
|
var mainObj = CreateUIObject(name, parent, new Vector2(1, 1));
|
||||||
mainObj.AddComponent<Image>().color = bgColor ?? new Color(0.12f, 0.12f, 0.12f);
|
mainObj.AddComponent<Image>().color = bgColor ?? new Color(0.12f, 0.12f, 0.12f);
|
||||||
@ -774,17 +774,14 @@ namespace UnityExplorer.UI
|
|||||||
|
|
||||||
RuntimeProvider.Instance.SetColorBlock(slider, disabled: new Color(0.1f, 0.1f, 0.1f));
|
RuntimeProvider.Instance.SetColorBlock(slider, disabled: new Color(0.1f, 0.1f, 0.1f));
|
||||||
|
|
||||||
if (autoResizeSliderHandle)
|
slider.handleRect.offsetMin = new Vector2(slider.handleRect.offsetMin.x, 0);
|
||||||
{
|
slider.handleRect.offsetMax = new Vector2(slider.handleRect.offsetMax.x, 0);
|
||||||
slider.handleRect.offsetMin = new Vector2(slider.handleRect.offsetMin.x, 0);
|
slider.handleRect.pivot = new Vector2(0.5f, 0.5f);
|
||||||
slider.handleRect.offsetMax = new Vector2(slider.handleRect.offsetMax.x, 0);
|
|
||||||
slider.handleRect.pivot = new Vector2(0.5f, 0.5f);
|
|
||||||
|
|
||||||
var container = slider.m_HandleContainerRect;
|
var container = slider.m_HandleContainerRect;
|
||||||
container.anchorMin = Vector3.zero;
|
container.anchorMin = Vector3.zero;
|
||||||
container.anchorMax = Vector3.one;
|
container.anchorMax = Vector3.one;
|
||||||
container.pivot = new Vector3(0.5f, 0.5f);
|
container.pivot = new Vector3(0.5f, 0.5f);
|
||||||
}
|
|
||||||
|
|
||||||
// finalize and create ScrollPool
|
// finalize and create ScrollPool
|
||||||
|
|
||||||
|
@ -12,22 +12,37 @@ using UnityExplorer.UI.Models;
|
|||||||
using UnityExplorer.UI.Panels;
|
using UnityExplorer.UI.Panels;
|
||||||
using UnityExplorer.UI.Utility;
|
using UnityExplorer.UI.Utility;
|
||||||
using UnityExplorer.UI.Widgets;
|
using UnityExplorer.UI.Widgets;
|
||||||
|
using UnityExplorer.UI.Widgets.AutoComplete;
|
||||||
|
|
||||||
namespace UnityExplorer.UI
|
namespace UnityExplorer.UI
|
||||||
{
|
{
|
||||||
public static class UIManager
|
public static class UIManager
|
||||||
{
|
{
|
||||||
|
public enum Panels
|
||||||
|
{
|
||||||
|
ObjectExplorer,
|
||||||
|
Inspector,
|
||||||
|
CSConsole,
|
||||||
|
Options,
|
||||||
|
ConsoleLog,
|
||||||
|
}
|
||||||
|
|
||||||
public static GameObject CanvasRoot { get; private set; }
|
public static GameObject CanvasRoot { get; private set; }
|
||||||
|
public static Canvas Canvas { get; private set; }
|
||||||
public static EventSystem EventSys { get; private set; }
|
public static EventSystem EventSys { get; private set; }
|
||||||
|
|
||||||
// panels
|
// panels
|
||||||
public static SceneExplorer SceneExplorer { get; private set; }
|
internal static GameObject PanelHolder { get; private set; }
|
||||||
|
public static ObjectExplorer Explorer { get; private set; }
|
||||||
public static InspectorTest Inspector { get; private set; }
|
public static InspectorTest Inspector { get; private set; }
|
||||||
|
|
||||||
// bundle assets
|
// bundle assets
|
||||||
internal static Font ConsoleFont { get; private set; }
|
internal static Font ConsoleFont { get; private set; }
|
||||||
internal static Shader BackupShader { get; private set; }
|
internal static Shader BackupShader { get; private set; }
|
||||||
|
|
||||||
|
internal static readonly Color navButtonEnabledColor = new Color(0.2f, 0.4f, 0.28f);
|
||||||
|
internal static readonly Color navButtonDisabledColor = new Color(0.25f, 0.25f, 0.25f);
|
||||||
|
|
||||||
public static bool ShowMenu
|
public static bool ShowMenu
|
||||||
{
|
{
|
||||||
get => s_showMenu;
|
get => s_showMenu;
|
||||||
@ -50,20 +65,17 @@ namespace UnityExplorer.UI
|
|||||||
UIFactory.Init();
|
UIFactory.Init();
|
||||||
|
|
||||||
CreateRootCanvas();
|
CreateRootCanvas();
|
||||||
|
CreateTopNavBar();
|
||||||
|
|
||||||
SceneExplorer = new SceneExplorer();
|
AutoCompleter.ConstructUI();
|
||||||
SceneExplorer.ConstructUI(CanvasRoot);
|
//InspectUnderMouse.ConstructUI();
|
||||||
|
|
||||||
|
Explorer = new ObjectExplorer();
|
||||||
|
Explorer.ConstructUI(CanvasRoot);
|
||||||
|
|
||||||
Inspector = new InspectorTest();
|
Inspector = new InspectorTest();
|
||||||
Inspector.ConstructUI(CanvasRoot);
|
Inspector.ConstructUI(CanvasRoot);
|
||||||
|
|
||||||
//MainMenu.Create();
|
|
||||||
//InspectUnderMouse.ConstructUI();
|
|
||||||
//PanelDragger.CreateCursorUI();
|
|
||||||
|
|
||||||
// Force refresh of anchors etc
|
|
||||||
Canvas.ForceUpdateCanvases();
|
|
||||||
|
|
||||||
ShowMenu = !ConfigManager.Hide_On_Startup.Value;
|
ShowMenu = !ConfigManager.Hide_On_Startup.Value;
|
||||||
|
|
||||||
ExplorerCore.Log("UI initialized.");
|
ExplorerCore.Log("UI initialized.");
|
||||||
@ -89,17 +101,14 @@ namespace UnityExplorer.UI
|
|||||||
if (InputManager.GetKeyDown(ConfigManager.Force_Unlock_Keybind.Value))
|
if (InputManager.GetKeyDown(ConfigManager.Force_Unlock_Keybind.Value))
|
||||||
CursorUnlocker.Unlock = !CursorUnlocker.Unlock;
|
CursorUnlocker.Unlock = !CursorUnlocker.Unlock;
|
||||||
|
|
||||||
UIPanel.UpdateFocus();
|
|
||||||
|
|
||||||
UIBehaviourModel.UpdateInstances();
|
|
||||||
|
|
||||||
if (EventSystem.current != EventSys)
|
if (EventSystem.current != EventSys)
|
||||||
CursorUnlocker.SetEventSystem();
|
CursorUnlocker.SetEventSystem();
|
||||||
|
|
||||||
// TODO could make these UIBehaviourModels
|
UIPanel.UpdateFocus();
|
||||||
PanelDragger.UpdateInstances();
|
PanelDragger.UpdateInstances();
|
||||||
SliderScrollbar.UpdateInstances();
|
|
||||||
InputFieldScroller.UpdateInstances();
|
UIBehaviourModel.UpdateInstances();
|
||||||
|
AutoCompleter.Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void CreateRootCanvas()
|
private static void CreateRootCanvas()
|
||||||
@ -113,18 +122,114 @@ namespace UnityExplorer.UI
|
|||||||
EventSys = CanvasRoot.AddComponent<EventSystem>();
|
EventSys = CanvasRoot.AddComponent<EventSystem>();
|
||||||
InputManager.AddUIModule();
|
InputManager.AddUIModule();
|
||||||
|
|
||||||
Canvas canvas = CanvasRoot.AddComponent<Canvas>();
|
Canvas = CanvasRoot.AddComponent<Canvas>();
|
||||||
canvas.renderMode = RenderMode.ScreenSpaceCamera;
|
Canvas.renderMode = RenderMode.ScreenSpaceCamera;
|
||||||
canvas.referencePixelsPerUnit = 100;
|
Canvas.referencePixelsPerUnit = 100;
|
||||||
canvas.sortingOrder = 999;
|
Canvas.sortingOrder = 999;
|
||||||
|
|
||||||
CanvasScaler scaler = CanvasRoot.AddComponent<CanvasScaler>();
|
CanvasScaler scaler = CanvasRoot.AddComponent<CanvasScaler>();
|
||||||
scaler.referenceResolution = new Vector2(1920, 1080);
|
scaler.referenceResolution = new Vector2(1920, 1080);
|
||||||
scaler.screenMatchMode = CanvasScaler.ScreenMatchMode.Expand;
|
scaler.screenMatchMode = CanvasScaler.ScreenMatchMode.Expand;
|
||||||
|
|
||||||
CanvasRoot.AddComponent<GraphicRaycaster>();
|
CanvasRoot.AddComponent<GraphicRaycaster>();
|
||||||
|
|
||||||
|
PanelHolder = new GameObject("PanelHolder");
|
||||||
|
PanelHolder.transform.SetParent(CanvasRoot.transform, false);
|
||||||
|
PanelHolder.layer = 5;
|
||||||
|
var rect = PanelHolder.AddComponent<RectTransform>();
|
||||||
|
rect.sizeDelta = Vector2.zero;
|
||||||
|
rect.anchoredPosition = Vector2.zero;
|
||||||
|
rect.pivot = new Vector2(0.5f, 0.5f);
|
||||||
|
rect.anchorMin = Vector2.zero;
|
||||||
|
rect.anchorMax = Vector2.one;
|
||||||
|
PanelHolder.transform.SetAsFirstSibling();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static UIPanel GetPanel(Panels panel)
|
||||||
|
{
|
||||||
|
switch (panel)
|
||||||
|
{
|
||||||
|
case Panels.ObjectExplorer:
|
||||||
|
return Explorer;
|
||||||
|
case Panels.Inspector:
|
||||||
|
return Inspector;
|
||||||
|
default:
|
||||||
|
throw new NotImplementedException($"TODO GetPanel: {panel}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void TogglePanel(Panels panel)
|
||||||
|
{
|
||||||
|
var uiPanel = GetPanel(panel);
|
||||||
|
SetPanelActive(panel, !uiPanel.Enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SetPanelActive(Panels panel, bool active)
|
||||||
|
{
|
||||||
|
GetPanel(panel).SetActive(active);
|
||||||
|
var color = active ? navButtonEnabledColor : navButtonDisabledColor;
|
||||||
|
RuntimeProvider.Instance.SetColorBlock(navButtonDict[panel], color, color * 1.2f);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void CreateTopNavBar()
|
||||||
|
{
|
||||||
|
var panel = UIFactory.CreateUIObject("MainNavbar", CanvasRoot);
|
||||||
|
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(panel, false, true, true, true, 5, 3, 3, 10, 10, TextAnchor.MiddleCenter);
|
||||||
|
panel.AddComponent<Image>().color = new Color(0.1f, 0.1f, 0.1f);
|
||||||
|
var panelRect = panel.GetComponent<RectTransform>();
|
||||||
|
panelRect.pivot = new Vector2(0.5f, 1f);
|
||||||
|
panelRect.anchorMin = new Vector2(0.5f, 1f);
|
||||||
|
panelRect.anchorMax = new Vector2(0.5f, 1f);
|
||||||
|
panelRect.sizeDelta = new Vector2(900f, 35f);
|
||||||
|
|
||||||
|
string titleTxt = $"{ExplorerCore.NAME} <i><color=grey>{ExplorerCore.VERSION}</color></i>";
|
||||||
|
var title = UIFactory.CreateLabel(panel, "Title", titleTxt, TextAnchor.MiddleLeft, default, true, 18);
|
||||||
|
UIFactory.SetLayoutElement(title.gameObject, minWidth: 240, flexibleWidth: 0);
|
||||||
|
|
||||||
|
CreateNavButton(panel, Panels.ObjectExplorer, "Object Explorer");
|
||||||
|
CreateNavButton(panel, Panels.Inspector, "Inspector");
|
||||||
|
CreateNavButton(panel, Panels.CSConsole, "C# Console");
|
||||||
|
CreateNavButton(panel, Panels.Options, "Options");
|
||||||
|
CreateNavButton(panel, Panels.ConsoleLog, "Console Log");
|
||||||
|
|
||||||
|
// close button
|
||||||
|
|
||||||
|
var closeBtn = UIFactory.CreateButton(panel, "CloseButton", "X", () => { ShowMenu = false; });
|
||||||
|
UIFactory.SetLayoutElement(closeBtn.gameObject, minHeight: 25, minWidth: 25, flexibleWidth: 0);
|
||||||
|
RuntimeProvider.Instance.SetColorBlock(closeBtn, new Color(0.63f, 0.32f, 0.31f),
|
||||||
|
new Color(0.81f, 0.25f, 0.2f), new Color(0.6f, 0.18f, 0.16f));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static readonly Dictionary<Panels, Button> navButtonDict = new Dictionary<Panels, Button>();
|
||||||
|
|
||||||
|
private static void CreateNavButton(GameObject navbar, Panels panel, string label)
|
||||||
|
{
|
||||||
|
var button = UIFactory.CreateButton(navbar, $"Button_{panel}", label);
|
||||||
|
UIFactory.SetLayoutElement(button.gameObject, minWidth: 118, flexibleWidth: 0);
|
||||||
|
RuntimeProvider.Instance.SetColorBlock(button, navButtonDisabledColor, navButtonDisabledColor * 1.2f);
|
||||||
|
button.onClick.AddListener(() =>
|
||||||
|
{
|
||||||
|
TogglePanel(panel);
|
||||||
|
});
|
||||||
|
navButtonDict.Add(panel, button);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Could be cool, need to investigate properly.
|
||||||
|
// It works but the input/eventsystem doesnt respond properly or at all.
|
||||||
|
//public static void TrySetTargetDisplay(int displayIndex)
|
||||||
|
//{
|
||||||
|
// ExplorerCore.Log("displays connected: " + Display.displays.Length);
|
||||||
|
// // Display.displays[0] is the primary, default display and is always ON, so start at index 1.
|
||||||
|
|
||||||
|
// if (Display.displays.Length > displayIndex)
|
||||||
|
// {
|
||||||
|
// Display.displays[displayIndex].Activate();
|
||||||
|
// Canvas.targetDisplay = displayIndex;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
#region UI AssetBundle
|
||||||
|
|
||||||
private static void LoadBundle()
|
private static void LoadBundle()
|
||||||
{
|
{
|
||||||
AssetBundle bundle = null;
|
AssetBundle bundle = null;
|
||||||
@ -178,5 +283,7 @@ namespace UnityExplorer.UI
|
|||||||
return ms.ToArray();
|
return ms.ToArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ using System.Linq;
|
|||||||
|
|
||||||
namespace UnityExplorer.UI.Utility
|
namespace UnityExplorer.UI.Utility
|
||||||
{
|
{
|
||||||
public class PanelDragger
|
public class PanelDragger
|
||||||
{
|
{
|
||||||
static PanelDragger()
|
static PanelDragger()
|
||||||
{
|
{
|
||||||
@ -51,6 +51,9 @@ namespace UnityExplorer.UI.Utility
|
|||||||
handledInstanceThisFrame = false;
|
handledInstanceThisFrame = false;
|
||||||
foreach (var instance in Instances)
|
foreach (var instance in Instances)
|
||||||
{
|
{
|
||||||
|
if (!instance.Panel.gameObject.activeSelf)
|
||||||
|
continue;
|
||||||
|
|
||||||
instance.Update(state, mousePos);
|
instance.Update(state, mousePos);
|
||||||
if (handledInstanceThisFrame)
|
if (handledInstanceThisFrame)
|
||||||
break;
|
break;
|
||||||
|
@ -14,15 +14,23 @@ namespace UnityExplorer.UI.Utility
|
|||||||
internal static Dictionary<Type, MethodInfo> toStringMethods = new Dictionary<Type, MethodInfo>();
|
internal static Dictionary<Type, MethodInfo> toStringMethods = new Dictionary<Type, MethodInfo>();
|
||||||
internal static Dictionary<Type, MethodInfo> toStringFormattedMethods = new Dictionary<Type, MethodInfo>();
|
internal static Dictionary<Type, MethodInfo> toStringFormattedMethods = new Dictionary<Type, MethodInfo>();
|
||||||
|
|
||||||
public static string GetDefaultLabel(object value, Type fallbackType, bool includeNamespace = true, bool includeName = true)
|
public static string ToString(object value, Type fallbackType, bool includeNamespace = true, bool includeName = true, bool objectAsType = false)
|
||||||
{
|
{
|
||||||
if (value == null && fallbackType == null)
|
if (value == null && fallbackType == null)
|
||||||
return "<null>";
|
return "<null>";
|
||||||
|
|
||||||
var type = value?.GetActualType() ?? fallbackType;
|
Type type;
|
||||||
|
if (objectAsType)
|
||||||
|
type = value.TryCast<Type>();
|
||||||
|
else
|
||||||
|
type = value?.GetActualType() ?? fallbackType;
|
||||||
|
|
||||||
|
|
||||||
var richType = SignatureHighlighter.ParseFullSyntax(type, includeNamespace);
|
var richType = SignatureHighlighter.ParseFullSyntax(type, includeNamespace);
|
||||||
|
|
||||||
|
if (objectAsType)
|
||||||
|
return richType;
|
||||||
|
|
||||||
if (!includeName)
|
if (!includeName)
|
||||||
return richType;
|
return richType;
|
||||||
|
|
||||||
|
140
src/UI/Widgets/AutoComplete/AutoCompleter.cs
Normal file
140
src/UI/Widgets/AutoComplete/AutoCompleter.cs
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.EventSystems;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
using UnityExplorer.Core.Input;
|
||||||
|
using UnityExplorer.Core.Runtime;
|
||||||
|
using UnityExplorer.UI;
|
||||||
|
using UnityExplorer.UI.Models;
|
||||||
|
|
||||||
|
namespace UnityExplorer.UI.Widgets.AutoComplete
|
||||||
|
{
|
||||||
|
// todo add a 'close' button if the user wants to manually hide the suggestions box
|
||||||
|
|
||||||
|
public static class AutoCompleter
|
||||||
|
{
|
||||||
|
public static ISuggestionProvider CurrentHandler;
|
||||||
|
|
||||||
|
public static GameObject UIRoot => uiRoot;
|
||||||
|
public static GameObject uiRoot;
|
||||||
|
|
||||||
|
public static ButtonListSource<Suggestion> dataHandler;
|
||||||
|
public static ScrollPool scrollPool;
|
||||||
|
|
||||||
|
private static List<Suggestion> suggestions = new List<Suggestion>();
|
||||||
|
|
||||||
|
private static int lastCaretPos;
|
||||||
|
|
||||||
|
public static void Update()
|
||||||
|
{
|
||||||
|
if (!UIRoot || !UIRoot.activeSelf)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (suggestions.Any() && CurrentHandler != null)
|
||||||
|
{
|
||||||
|
if (!CurrentHandler.InputField.gameObject.activeInHierarchy)
|
||||||
|
ReleaseOwnership(CurrentHandler);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lastCaretPos = CurrentHandler.InputField.caretPosition;
|
||||||
|
UpdatePosition();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void TakeOwnership(ISuggestionProvider provider)
|
||||||
|
{
|
||||||
|
CurrentHandler = provider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ReleaseOwnership(ISuggestionProvider provider)
|
||||||
|
{
|
||||||
|
if (CurrentHandler == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (CurrentHandler == provider)
|
||||||
|
{
|
||||||
|
CurrentHandler = null;
|
||||||
|
UIRoot.SetActive(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<Suggestion> GetEntries() => suggestions;
|
||||||
|
|
||||||
|
private static bool ShouldDisplay(Suggestion data, string filter) => true;
|
||||||
|
|
||||||
|
public static void SetSuggestions(List<Suggestion> collection)
|
||||||
|
{
|
||||||
|
suggestions = collection;
|
||||||
|
|
||||||
|
if (!suggestions.Any())
|
||||||
|
UIRoot.SetActive(false);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UIRoot.SetActive(true);
|
||||||
|
dataHandler.RefreshData();
|
||||||
|
scrollPool.Rebuild();
|
||||||
|
//scrollPool.RefreshCells(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void OnCellClicked(int dataIndex)
|
||||||
|
{
|
||||||
|
var suggestion = suggestions[dataIndex];
|
||||||
|
CurrentHandler.OnSuggestionClicked(suggestion);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void SetCell(ButtonCell<Suggestion> cell, int index)
|
||||||
|
{
|
||||||
|
if (index < 0 || index >= suggestions.Count)
|
||||||
|
{
|
||||||
|
cell.Disable();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var suggestion = suggestions[index];
|
||||||
|
cell.buttonText.text = suggestion.DisplayText;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void UpdatePosition()
|
||||||
|
{
|
||||||
|
if (CurrentHandler == null || !CurrentHandler.InputField.isFocused)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var input = CurrentHandler.InputField;
|
||||||
|
var textGen = input.textComponent.cachedTextGenerator;
|
||||||
|
int caretPos = lastCaretPos;
|
||||||
|
caretPos--;
|
||||||
|
|
||||||
|
caretPos = Math.Max(0, caretPos);
|
||||||
|
caretPos = Math.Min(textGen.characters.Count - 1, caretPos);
|
||||||
|
|
||||||
|
var pos = textGen.characters[caretPos].cursorPos;
|
||||||
|
pos = input.transform.TransformPoint(pos);
|
||||||
|
|
||||||
|
uiRoot.transform.position = new Vector3(pos.x + 10, pos.y - 20, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ConstructUI()
|
||||||
|
{
|
||||||
|
var parent = UIManager.CanvasRoot;
|
||||||
|
|
||||||
|
dataHandler = new ButtonListSource<Suggestion>(scrollPool, GetEntries, SetCell, ShouldDisplay, OnCellClicked);
|
||||||
|
|
||||||
|
scrollPool = UIFactory.CreateScrollPool(parent, "AutoCompleter", out uiRoot, out GameObject scrollContent);
|
||||||
|
var mainRect = uiRoot.GetComponent<RectTransform>();
|
||||||
|
mainRect.pivot = new Vector2(0f, 1f);
|
||||||
|
mainRect.anchorMin = new Vector2(0.45f, 0.45f);
|
||||||
|
mainRect.anchorMax = new Vector2(0.65f, 0.6f);
|
||||||
|
mainRect.offsetMin = Vector2.zero;
|
||||||
|
mainRect.offsetMax = Vector2.zero;
|
||||||
|
UIFactory.SetLayoutGroup<VerticalLayoutGroup>(scrollContent, true, false, true, false);
|
||||||
|
|
||||||
|
scrollPool.Initialize(dataHandler, ButtonCell<Suggestion>.CreatePrototypeCell(parent));
|
||||||
|
|
||||||
|
UIRoot.SetActive(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
16
src/UI/Widgets/AutoComplete/ISuggestionProvider.cs
Normal file
16
src/UI/Widgets/AutoComplete/ISuggestionProvider.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
|
||||||
|
namespace UnityExplorer.UI.Widgets.AutoComplete
|
||||||
|
{
|
||||||
|
public interface ISuggestionProvider
|
||||||
|
{
|
||||||
|
InputField InputField { get; }
|
||||||
|
|
||||||
|
void OnSuggestionClicked(Suggestion suggestion);
|
||||||
|
}
|
||||||
|
}
|
27
src/UI/Widgets/AutoComplete/Suggestion.cs
Normal file
27
src/UI/Widgets/AutoComplete/Suggestion.cs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityExplorer.Core;
|
||||||
|
|
||||||
|
namespace UnityExplorer.UI.Widgets.AutoComplete
|
||||||
|
{
|
||||||
|
public struct Suggestion
|
||||||
|
{
|
||||||
|
public readonly string DisplayText;
|
||||||
|
public readonly string Prefix;
|
||||||
|
public readonly string Addition;
|
||||||
|
public readonly Color TextColor;
|
||||||
|
|
||||||
|
public string Full => Prefix + Addition;
|
||||||
|
|
||||||
|
public Suggestion(string displayText, string prefix, string addition, Color color)
|
||||||
|
{
|
||||||
|
DisplayText = displayText;
|
||||||
|
Addition = addition;
|
||||||
|
Prefix = prefix;
|
||||||
|
TextColor = color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
119
src/UI/Widgets/AutoComplete/TypeCompleter.cs
Normal file
119
src/UI/Widgets/AutoComplete/TypeCompleter.cs
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
using UnityExplorer.UI.Models;
|
||||||
|
|
||||||
|
namespace UnityExplorer.UI.Widgets.AutoComplete
|
||||||
|
{
|
||||||
|
public class TypeCompleter : ISuggestionProvider
|
||||||
|
{
|
||||||
|
private struct CachedType
|
||||||
|
{
|
||||||
|
public string FilteredName;
|
||||||
|
public string DisplayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Type BaseType { get; }
|
||||||
|
public InputField InputField { get; }
|
||||||
|
|
||||||
|
public event Action<Suggestion> SuggestionClicked;
|
||||||
|
public void OnSuggestionClicked(Suggestion suggestion)
|
||||||
|
{
|
||||||
|
SuggestionClicked?.Invoke(suggestion);
|
||||||
|
suggestions.Clear();
|
||||||
|
AutoCompleter.SetSuggestions(suggestions);
|
||||||
|
|
||||||
|
timeOfLastCheck = Time.time;
|
||||||
|
InputField.text = suggestion.DisplayText;
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly List<Suggestion> suggestions = new List<Suggestion>();
|
||||||
|
|
||||||
|
private readonly Dictionary<string, CachedType> typeCache = new Dictionary<string, CachedType>();
|
||||||
|
|
||||||
|
//// cached list of names for displaying (with proper case)
|
||||||
|
//private readonly List<string> cachedTypesNames = new List<string>();
|
||||||
|
//// cached list of lookup by index (lowercase)
|
||||||
|
//private readonly List<string> cachedTypesFilter = new List<string>();
|
||||||
|
//// cached hashset of names (lower case)
|
||||||
|
//private readonly HashSet<string> cachedTypesSet = new HashSet<string>();
|
||||||
|
|
||||||
|
public TypeCompleter(Type baseType, InputField inputField)
|
||||||
|
{
|
||||||
|
BaseType = baseType;
|
||||||
|
InputField = inputField;
|
||||||
|
|
||||||
|
inputField.onValueChanged.AddListener(OnInputFieldChanged);
|
||||||
|
|
||||||
|
var types = ReflectionUtility.GetImplementationsOf(typeof(UnityEngine.Object), true);
|
||||||
|
foreach (var type in types.OrderBy(it => it.FullName))
|
||||||
|
{
|
||||||
|
var name = type.FullName;
|
||||||
|
typeCache.Add(name.ToLower(), new CachedType
|
||||||
|
{
|
||||||
|
DisplayName = name,
|
||||||
|
FilteredName = name.ToLower()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private float timeOfLastCheck;
|
||||||
|
|
||||||
|
private void OnInputFieldChanged(string value)
|
||||||
|
{
|
||||||
|
if (timeOfLastCheck == Time.time)
|
||||||
|
return;
|
||||||
|
|
||||||
|
timeOfLastCheck = Time.time;
|
||||||
|
|
||||||
|
value = value?.ToLower() ?? "";
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(value))
|
||||||
|
{
|
||||||
|
AutoCompleter.ReleaseOwnership(this);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GetSuggestions(value);
|
||||||
|
|
||||||
|
AutoCompleter.TakeOwnership(this);
|
||||||
|
AutoCompleter.SetSuggestions(suggestions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GetSuggestions(string value)
|
||||||
|
{
|
||||||
|
suggestions.Clear();
|
||||||
|
|
||||||
|
var added = new HashSet<string>();
|
||||||
|
|
||||||
|
if (typeCache.TryGetValue(value, out CachedType cache))
|
||||||
|
{
|
||||||
|
added.Add(value);
|
||||||
|
suggestions.Add(new Suggestion(cache.DisplayName,
|
||||||
|
value,
|
||||||
|
cache.FilteredName.Substring(value.Length, cache.FilteredName.Length - value.Length),
|
||||||
|
Color.white));
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var entry in typeCache.Values)
|
||||||
|
{
|
||||||
|
if (added.Contains(entry.FilteredName))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (entry.FilteredName.Contains(value))
|
||||||
|
{
|
||||||
|
suggestions.Add(new Suggestion(entry.DisplayName,
|
||||||
|
value,
|
||||||
|
entry.FilteredName.Substring(value.Length, entry.FilteredName.Length - value.Length),
|
||||||
|
Color.white));
|
||||||
|
}
|
||||||
|
|
||||||
|
added.Add(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -12,7 +12,8 @@ namespace UnityExplorer.UI.Widgets
|
|||||||
public bool Enabled => m_enabled;
|
public bool Enabled => m_enabled;
|
||||||
private bool m_enabled;
|
private bool m_enabled;
|
||||||
|
|
||||||
public Action<ButtonCell<T>> OnClick;
|
public Action<int> OnClick;
|
||||||
|
public int CurrentDataIndex;
|
||||||
|
|
||||||
public ButtonListSource<T> list;
|
public ButtonListSource<T> list;
|
||||||
|
|
||||||
@ -30,7 +31,7 @@ namespace UnityExplorer.UI.Widgets
|
|||||||
this.buttonText = text;
|
this.buttonText = text;
|
||||||
this.button = button;
|
this.button = button;
|
||||||
|
|
||||||
button.onClick.AddListener(() => { OnClick?.Invoke(this); });
|
button.onClick.AddListener(() => { OnClick?.Invoke(CurrentDataIndex); });
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Disable()
|
public void Disable()
|
||||||
|
@ -21,7 +21,7 @@ namespace UnityExplorer.UI.Widgets
|
|||||||
public Func<List<T>> GetEntries;
|
public Func<List<T>> GetEntries;
|
||||||
public Action<ButtonCell<T>, int> SetICell;
|
public Action<ButtonCell<T>, int> SetICell;
|
||||||
public Func<T, string, bool> ShouldDisplay;
|
public Func<T, string, bool> ShouldDisplay;
|
||||||
public Action<ButtonCell<T>> OnCellClicked;
|
public Action<int> OnCellClicked;
|
||||||
|
|
||||||
public string CurrentFilter
|
public string CurrentFilter
|
||||||
{
|
{
|
||||||
@ -30,11 +30,11 @@ namespace UnityExplorer.UI.Widgets
|
|||||||
}
|
}
|
||||||
private string currentFilter;
|
private string currentFilter;
|
||||||
|
|
||||||
public ButtonListSource(ScrollPool infiniteScroller, Func<List<T>> getEntriesMethod,
|
public ButtonListSource(ScrollPool scrollPool, Func<List<T>> getEntriesMethod,
|
||||||
Action<ButtonCell<T>, int> setICellMethod, Func<T, string, bool> shouldDisplayMethod,
|
Action<ButtonCell<T>, int> setICellMethod, Func<T, string, bool> shouldDisplayMethod,
|
||||||
Action<ButtonCell<T>> onCellClickedMethod)
|
Action<int> onCellClickedMethod)
|
||||||
{
|
{
|
||||||
Scroller = infiniteScroller;
|
Scroller = scrollPool;
|
||||||
|
|
||||||
GetEntries = getEntriesMethod;
|
GetEntries = getEntriesMethod;
|
||||||
SetICell = setICellMethod;
|
SetICell = setICellMethod;
|
||||||
@ -44,13 +44,6 @@ namespace UnityExplorer.UI.Widgets
|
|||||||
|
|
||||||
public void Init()
|
public void Init()
|
||||||
{
|
{
|
||||||
RuntimeProvider.Instance.StartCoroutine(InitCoroutine());
|
|
||||||
}
|
|
||||||
|
|
||||||
private IEnumerator InitCoroutine()
|
|
||||||
{
|
|
||||||
yield return null;
|
|
||||||
|
|
||||||
var proto = ButtonCell<T>.CreatePrototypeCell(Scroller.UIRoot);
|
var proto = ButtonCell<T>.CreatePrototypeCell(Scroller.UIRoot);
|
||||||
|
|
||||||
RefreshData();
|
RefreshData();
|
||||||
@ -90,11 +83,15 @@ namespace UnityExplorer.UI.Widgets
|
|||||||
|
|
||||||
public void SetCell(ICell cell, int index)
|
public void SetCell(ICell cell, int index)
|
||||||
{
|
{
|
||||||
|
if (currentEntries == null)
|
||||||
|
RefreshData();
|
||||||
|
|
||||||
if (index < 0 || index >= currentEntries.Count)
|
if (index < 0 || index >= currentEntries.Count)
|
||||||
cell.Disable();
|
cell.Disable();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cell.Enable();
|
cell.Enable();
|
||||||
|
(cell as ButtonCell<T>).CurrentDataIndex = index;
|
||||||
SetICell.Invoke((ButtonCell<T>)cell, index);
|
SetICell.Invoke((ButtonCell<T>)cell, index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,30 +7,33 @@ using UnityEngine;
|
|||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
using UnityEngine.EventSystems;
|
using UnityEngine.EventSystems;
|
||||||
using UnityEngine.Events;
|
using UnityEngine.Events;
|
||||||
|
using UnityExplorer.UI.Models;
|
||||||
|
|
||||||
namespace UnityExplorer.UI.Utility
|
namespace UnityExplorer.UI.Utility
|
||||||
{
|
{
|
||||||
// To fix an issue with Input Fields and allow them to go inside a ScrollRect nicely.
|
// To fix an issue with Input Fields and allow them to go inside a ScrollRect nicely.
|
||||||
|
|
||||||
public class InputFieldScroller
|
public class InputFieldScroller : UIBehaviourModel
|
||||||
{
|
{
|
||||||
public static readonly List<InputFieldScroller> Instances = new List<InputFieldScroller>();
|
//public static readonly List<InputFieldScroller> Instances = new List<InputFieldScroller>();
|
||||||
|
|
||||||
public static void UpdateInstances()
|
//public static void UpdateInstances()
|
||||||
{
|
//{
|
||||||
if (!Instances.Any())
|
// if (!Instances.Any())
|
||||||
return;
|
// return;
|
||||||
|
|
||||||
for (int i = 0; i < Instances.Count; i++)
|
// for (int i = 0; i < Instances.Count; i++)
|
||||||
{
|
// {
|
||||||
var input = Instances[i];
|
// var input = Instances[i];
|
||||||
|
|
||||||
if (input.CheckDestroyed())
|
// if (input.CheckDestroyed())
|
||||||
i--;
|
// i--;
|
||||||
else
|
// else
|
||||||
input.Update();
|
// input.Update();
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|
||||||
|
public override GameObject UIRoot => inputField.gameObject;
|
||||||
|
|
||||||
internal SliderScrollbar sliderScroller;
|
internal SliderScrollbar sliderScroller;
|
||||||
internal InputField inputField;
|
internal InputField inputField;
|
||||||
@ -43,7 +46,7 @@ namespace UnityExplorer.UI.Utility
|
|||||||
|
|
||||||
public InputFieldScroller(SliderScrollbar sliderScroller, InputField inputField)
|
public InputFieldScroller(SliderScrollbar sliderScroller, InputField inputField)
|
||||||
{
|
{
|
||||||
Instances.Add(this);
|
//Instances.Add(this);
|
||||||
|
|
||||||
this.sliderScroller = sliderScroller;
|
this.sliderScroller = sliderScroller;
|
||||||
this.inputField = inputField;
|
this.inputField = inputField;
|
||||||
@ -69,7 +72,7 @@ namespace UnityExplorer.UI.Utility
|
|||||||
// only done once, to fix height on creation.
|
// only done once, to fix height on creation.
|
||||||
internal bool heightInitAfterLayout;
|
internal bool heightInitAfterLayout;
|
||||||
|
|
||||||
public void Update()
|
public override void Update()
|
||||||
{
|
{
|
||||||
if (!heightInitAfterLayout)
|
if (!heightInitAfterLayout)
|
||||||
{
|
{
|
||||||
@ -85,16 +88,16 @@ namespace UnityExplorer.UI.Utility
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal bool CheckDestroyed()
|
//internal bool CheckDestroyed()
|
||||||
{
|
//{
|
||||||
if (sliderScroller == null || sliderScroller.CheckDestroyed())
|
// if (sliderScroller == null || sliderScroller.CheckDestroyed())
|
||||||
{
|
// {
|
||||||
Instances.Remove(this);
|
// Instances.Remove(this);
|
||||||
return true;
|
// return true;
|
||||||
}
|
// }
|
||||||
|
|
||||||
return false;
|
// return false;
|
||||||
}
|
//}
|
||||||
|
|
||||||
internal void OnTextChanged(string text)
|
internal void OnTextChanged(string text)
|
||||||
{
|
{
|
||||||
@ -128,5 +131,10 @@ namespace UnityExplorer.UI.Utility
|
|||||||
sliderScroller.m_slider.value = 0f;
|
sliderScroller.m_slider.value = 0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void ConstructUI(GameObject parent)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
194
src/UI/Widgets/ObjectExplorer/ObjectSearch.cs
Normal file
194
src/UI/Widgets/ObjectExplorer/ObjectSearch.cs
Normal file
@ -0,0 +1,194 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
using UnityExplorer.Core.Search;
|
||||||
|
using UnityExplorer.UI.Models;
|
||||||
|
using UnityExplorer.UI.Panels;
|
||||||
|
using UnityExplorer.UI.Utility;
|
||||||
|
using UnityExplorer.UI.Widgets.AutoComplete;
|
||||||
|
|
||||||
|
namespace UnityExplorer.UI.Widgets
|
||||||
|
{
|
||||||
|
public class ObjectSearch : UIModel
|
||||||
|
{
|
||||||
|
public ObjectExplorer Parent { get; }
|
||||||
|
|
||||||
|
public ObjectSearch(ObjectExplorer parent)
|
||||||
|
{
|
||||||
|
Parent = parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
private SearchContext m_context = SearchContext.UnityObject;
|
||||||
|
private SceneFilter m_sceneFilter = SceneFilter.Any;
|
||||||
|
private ChildFilter m_childFilter = ChildFilter.Any;
|
||||||
|
|
||||||
|
public ButtonListSource<object> dataHandler;
|
||||||
|
|
||||||
|
private ScrollPool resultsScrollPool;
|
||||||
|
private List<object> currentResults = new List<object>();
|
||||||
|
|
||||||
|
public override GameObject UIRoot => uiRoot;
|
||||||
|
private GameObject uiRoot;
|
||||||
|
|
||||||
|
private GameObject sceneFilterRow;
|
||||||
|
private GameObject childFilterRow;
|
||||||
|
private GameObject unityObjectClassRow;
|
||||||
|
|
||||||
|
private InputField nameInputField;
|
||||||
|
private InputField classInputField;
|
||||||
|
|
||||||
|
private Text resultsLabel;
|
||||||
|
|
||||||
|
public List<object> GetEntries() => currentResults;
|
||||||
|
|
||||||
|
private void OnContextDropdownChanged(int value)
|
||||||
|
{
|
||||||
|
m_context = (SearchContext)value;
|
||||||
|
|
||||||
|
// show/hide other filters depending on what we just selected.
|
||||||
|
bool shouldShowGoFilters = m_context == SearchContext.GameObject
|
||||||
|
|| m_context == SearchContext.Component
|
||||||
|
|| m_context == SearchContext.Custom;
|
||||||
|
|
||||||
|
sceneFilterRow.SetActive(shouldShowGoFilters);
|
||||||
|
childFilterRow.SetActive(shouldShowGoFilters);
|
||||||
|
|
||||||
|
unityObjectClassRow.SetActive(m_context == SearchContext.Custom);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnSceneFilterDropChanged(int value) => m_sceneFilter = (SceneFilter)value;
|
||||||
|
|
||||||
|
private void OnChildFilterDropChanged(int value) => m_childFilter = (ChildFilter)value;
|
||||||
|
|
||||||
|
public void DoSearch()
|
||||||
|
{
|
||||||
|
if (m_context == SearchContext.Singleton)
|
||||||
|
currentResults = SearchProvider.SingletonSearch(nameInputField.text);
|
||||||
|
else if (m_context == SearchContext.StaticClass)
|
||||||
|
currentResults = SearchProvider.StaticClassSearch(nameInputField.text);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
string compType = "";
|
||||||
|
if (m_context == SearchContext.Custom)
|
||||||
|
compType = classInputField.text;
|
||||||
|
|
||||||
|
currentResults = SearchProvider.UnityObjectSearch(nameInputField.text, compType, m_context, m_childFilter, m_sceneFilter);
|
||||||
|
}
|
||||||
|
|
||||||
|
dataHandler.RefreshData();
|
||||||
|
resultsScrollPool.RefreshCells(true);
|
||||||
|
|
||||||
|
resultsLabel.text = $"{currentResults.Count} results";
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetCell(ButtonCell<object> cell, int index)
|
||||||
|
{
|
||||||
|
bool objectAsType = m_context == SearchContext.StaticClass;
|
||||||
|
cell.buttonText.text = ToStringUtility.ToString(currentResults[index], currentResults[index].GetActualType(), objectAsType: objectAsType);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnCellClicked(int dataIndex)
|
||||||
|
{
|
||||||
|
ExplorerCore.Log("TODO");
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool ShouldDisplayCell(object arg1, string arg2) => true;
|
||||||
|
|
||||||
|
public override void ConstructUI(GameObject parent)
|
||||||
|
{
|
||||||
|
uiRoot = UIFactory.CreateVerticalGroup(parent, "ObjectSearch", true, true, true, true, 2, new Vector4(2, 2, 2, 2));
|
||||||
|
UIFactory.SetLayoutElement(uiRoot, flexibleHeight: 9999);
|
||||||
|
|
||||||
|
// Search context row
|
||||||
|
|
||||||
|
var contextGroup = UIFactory.CreateHorizontalGroup(uiRoot, "SearchContextRow", false, true, true, true, 2, new Vector4(2, 2, 2, 2));
|
||||||
|
UIFactory.SetLayoutElement(contextGroup, minHeight: 25, flexibleHeight: 0);
|
||||||
|
|
||||||
|
var contextLbl = UIFactory.CreateLabel(contextGroup, "SearchContextLabel", "Searching for:", TextAnchor.MiddleLeft);
|
||||||
|
UIFactory.SetLayoutElement(contextLbl.gameObject, minWidth: 110, flexibleWidth: 0);
|
||||||
|
|
||||||
|
var contextDropObj = UIFactory.CreateDropdown(contextGroup, out Dropdown contextDrop, null, 14, OnContextDropdownChanged);
|
||||||
|
foreach (var name in Enum.GetNames(typeof(SearchContext)))
|
||||||
|
contextDrop.options.Add(new Dropdown.OptionData(name));
|
||||||
|
UIFactory.SetLayoutElement(contextDropObj, minHeight: 25, flexibleHeight: 0, flexibleWidth: 9999);
|
||||||
|
|
||||||
|
// Unity class input
|
||||||
|
|
||||||
|
unityObjectClassRow = UIFactory.CreateHorizontalGroup(uiRoot, "UnityClassRow", false, true, true, true, 2, new Vector4(2, 2, 2, 2));
|
||||||
|
UIFactory.SetLayoutElement(unityObjectClassRow, minHeight: 25, flexibleHeight: 0);
|
||||||
|
|
||||||
|
var unityClassLbl = UIFactory.CreateLabel(unityObjectClassRow, "UnityClassLabel", "Custom Type:", TextAnchor.MiddleLeft);
|
||||||
|
UIFactory.SetLayoutElement(unityClassLbl.gameObject, minWidth: 110, flexibleWidth: 0);
|
||||||
|
|
||||||
|
var classInputObj = UIFactory.CreateInputField(unityObjectClassRow, "ClassInput", "...", out this.classInputField);
|
||||||
|
UIFactory.SetLayoutElement(classInputObj, minHeight: 25, flexibleHeight: 0, flexibleWidth: 9999);
|
||||||
|
|
||||||
|
new TypeCompleter(typeof(UnityEngine.Object), classInputField);
|
||||||
|
|
||||||
|
unityObjectClassRow.SetActive(false);
|
||||||
|
|
||||||
|
// Child filter row
|
||||||
|
|
||||||
|
childFilterRow = UIFactory.CreateHorizontalGroup(uiRoot, "ChildFilterRow", false, true, true, true, 2, new Vector4(2, 2, 2, 2));
|
||||||
|
UIFactory.SetLayoutElement(childFilterRow, minHeight: 25, flexibleHeight: 0);
|
||||||
|
|
||||||
|
var childLbl = UIFactory.CreateLabel(childFilterRow, "ChildLabel", "Child filter:", TextAnchor.MiddleLeft);
|
||||||
|
UIFactory.SetLayoutElement(childLbl.gameObject, minWidth: 110, flexibleWidth: 0);
|
||||||
|
|
||||||
|
var childDropObj = UIFactory.CreateDropdown(childFilterRow, out Dropdown childDrop, null, 14, OnChildFilterDropChanged);
|
||||||
|
foreach (var name in Enum.GetNames(typeof(ChildFilter)))
|
||||||
|
childDrop.options.Add(new Dropdown.OptionData(name));
|
||||||
|
UIFactory.SetLayoutElement(childDropObj, minHeight: 25, flexibleHeight: 0, flexibleWidth: 9999);
|
||||||
|
|
||||||
|
childFilterRow.SetActive(false);
|
||||||
|
|
||||||
|
// Scene filter row
|
||||||
|
|
||||||
|
sceneFilterRow = UIFactory.CreateHorizontalGroup(uiRoot, "SceneFilterRow", false, true, true, true, 2, new Vector4(2, 2, 2, 2));
|
||||||
|
UIFactory.SetLayoutElement(sceneFilterRow, minHeight: 25, flexibleHeight: 0);
|
||||||
|
|
||||||
|
var sceneLbl = UIFactory.CreateLabel(sceneFilterRow, "SceneLabel", "Scene filter:", TextAnchor.MiddleLeft);
|
||||||
|
UIFactory.SetLayoutElement(sceneLbl.gameObject, minWidth: 110, flexibleWidth: 0);
|
||||||
|
|
||||||
|
var sceneDropObj = UIFactory.CreateDropdown(sceneFilterRow, out Dropdown sceneDrop, null, 14, OnSceneFilterDropChanged);
|
||||||
|
foreach (var name in Enum.GetNames(typeof(SceneFilter)))
|
||||||
|
sceneDrop.options.Add(new Dropdown.OptionData(name));
|
||||||
|
UIFactory.SetLayoutElement(sceneDropObj, minHeight: 25, flexibleHeight: 0, flexibleWidth: 9999);
|
||||||
|
|
||||||
|
sceneFilterRow.SetActive(false);
|
||||||
|
|
||||||
|
// Name filter input
|
||||||
|
|
||||||
|
var nameRow = UIFactory.CreateHorizontalGroup(uiRoot, "NameRow", true, true, true, true, 2, new Vector4(2, 2, 2, 2));
|
||||||
|
UIFactory.SetLayoutElement(nameRow, minHeight: 25, flexibleHeight: 0);
|
||||||
|
|
||||||
|
var nameLbl = UIFactory.CreateLabel(nameRow, "NameFilterLabel", "Name contains:", TextAnchor.MiddleLeft);
|
||||||
|
UIFactory.SetLayoutElement(nameLbl.gameObject, minWidth: 110, flexibleWidth: 0);
|
||||||
|
|
||||||
|
var nameInputObj = UIFactory.CreateInputField(nameRow, "NameFilterInput", "...", out this.nameInputField);
|
||||||
|
UIFactory.SetLayoutElement(nameInputObj, minHeight: 25, flexibleHeight: 0, flexibleWidth: 9999);
|
||||||
|
|
||||||
|
// Search button
|
||||||
|
|
||||||
|
var searchButton = UIFactory.CreateButton(uiRoot, "SearchButton", "Search", DoSearch);
|
||||||
|
UIFactory.SetLayoutElement(searchButton.gameObject, minHeight: 25, flexibleHeight: 0);
|
||||||
|
|
||||||
|
// Results count label
|
||||||
|
|
||||||
|
var resultsCountRow = UIFactory.CreateHorizontalGroup(uiRoot, "ResultsCountRow", true, true, true, true);
|
||||||
|
UIFactory.SetLayoutElement(resultsCountRow, minHeight: 25, flexibleHeight: 0);
|
||||||
|
|
||||||
|
resultsLabel = UIFactory.CreateLabel(resultsCountRow, "ResultsLabel", "0 results", TextAnchor.MiddleCenter);
|
||||||
|
|
||||||
|
// RESULTS SCROLL POOL
|
||||||
|
|
||||||
|
dataHandler = new ButtonListSource<object>(resultsScrollPool, GetEntries, SetCell, ShouldDisplayCell, OnCellClicked);
|
||||||
|
resultsScrollPool = UIFactory.CreateScrollPool(uiRoot, "ResultsList", out GameObject scrollObj, out GameObject scrollContent);
|
||||||
|
resultsScrollPool.Initialize(dataHandler, ButtonCell<object>.CreatePrototypeCell(uiRoot));
|
||||||
|
UIFactory.SetLayoutElement(scrollObj, flexibleHeight: 9999);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
@ -9,16 +8,25 @@ using UnityEngine;
|
|||||||
using UnityEngine.SceneManagement;
|
using UnityEngine.SceneManagement;
|
||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
using UnityExplorer.Core;
|
using UnityExplorer.Core;
|
||||||
using UnityExplorer.Core.Config;
|
|
||||||
using UnityExplorer.UI.Models;
|
using UnityExplorer.UI.Models;
|
||||||
using UnityExplorer.UI.Utility;
|
using UnityExplorer.UI.Panels;
|
||||||
using UnityExplorer.UI.Widgets;
|
|
||||||
|
|
||||||
namespace UnityExplorer.UI.Panels
|
namespace UnityExplorer.UI.Widgets
|
||||||
{
|
{
|
||||||
public class SceneExplorer : UIPanel
|
public class SceneExplorer : UIModel
|
||||||
{
|
{
|
||||||
public override string Name => "Scene Explorer";
|
public ObjectExplorer Parent { get; }
|
||||||
|
|
||||||
|
public SceneExplorer(ObjectExplorer parent)
|
||||||
|
{
|
||||||
|
Parent = parent;
|
||||||
|
|
||||||
|
SceneHandler.OnInspectedSceneChanged += SceneHandler_OnInspectedSceneChanged;
|
||||||
|
SceneHandler.OnLoadedScenesChanged += SceneHandler_OnLoadedScenesChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override GameObject UIRoot => m_uiRoot;
|
||||||
|
private GameObject m_uiRoot;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether to automatically update per auto-update interval or not.
|
/// Whether to automatically update per auto-update interval or not.
|
||||||
@ -32,12 +40,6 @@ namespace UnityExplorer.UI.Panels
|
|||||||
private Dropdown sceneDropdown;
|
private Dropdown sceneDropdown;
|
||||||
private readonly Dictionary<int, Dropdown.OptionData> sceneToDropdownOption = new Dictionary<int, Dropdown.OptionData>();
|
private readonly Dictionary<int, Dropdown.OptionData> sceneToDropdownOption = new Dictionary<int, Dropdown.OptionData>();
|
||||||
|
|
||||||
public SceneExplorer()
|
|
||||||
{
|
|
||||||
SceneHandler.OnInspectedSceneChanged += SceneHandler_OnInspectedSceneChanged;
|
|
||||||
SceneHandler.OnLoadedScenesChanged += SceneHandler_OnLoadedScenesChanged;
|
|
||||||
}
|
|
||||||
|
|
||||||
private IEnumerable<GameObject> GetRootEntries() => SceneHandler.CurrentRootObjects;
|
private IEnumerable<GameObject> GetRootEntries() => SceneHandler.CurrentRootObjects;
|
||||||
|
|
||||||
public void ForceUpdate()
|
public void ForceUpdate()
|
||||||
@ -45,7 +47,7 @@ namespace UnityExplorer.UI.Panels
|
|||||||
ExpensiveUpdate();
|
ExpensiveUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Update()
|
public void Update()
|
||||||
{
|
{
|
||||||
if ((AutoUpdate || !SceneHandler.InspectingAssetScene) && Time.realtimeSinceStartup - timeOfLastUpdate >= 1f)
|
if ((AutoUpdate || !SceneHandler.InspectingAssetScene) && Time.realtimeSinceStartup - timeOfLastUpdate >= 1f)
|
||||||
{
|
{
|
||||||
@ -56,10 +58,8 @@ namespace UnityExplorer.UI.Panels
|
|||||||
|
|
||||||
public void ExpensiveUpdate()
|
public void ExpensiveUpdate()
|
||||||
{
|
{
|
||||||
//Tree.Scroller.WritingLocked = true;
|
|
||||||
SceneHandler.Update();
|
SceneHandler.Update();
|
||||||
Tree.RefreshData(true);
|
Tree.RefreshData(true);
|
||||||
////Tree.Scroller.WritingLocked = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnDropdownChanged(int value)
|
private void OnDropdownChanged(int value)
|
||||||
@ -128,54 +128,33 @@ namespace UnityExplorer.UI.Panels
|
|||||||
Tree.RefreshData(true, true);
|
Tree.RefreshData(true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
//private float highestRectHeight;
|
private void TryLoadScene(LoadSceneMode mode, Dropdown allSceneDrop)
|
||||||
|
|
||||||
//public override void OnFinishResize(RectTransform panel)
|
|
||||||
//{
|
|
||||||
// base.OnFinishResize(panel);
|
|
||||||
// RuntimeProvider.Instance.StartCoroutine(DelayedRefresh(panel));
|
|
||||||
//}
|
|
||||||
|
|
||||||
//private IEnumerator DelayedRefresh(RectTransform obj)
|
|
||||||
//{
|
|
||||||
// yield return null;
|
|
||||||
|
|
||||||
// if (obj.rect.height > highestRectHeight)
|
|
||||||
// {
|
|
||||||
// // height increased, hard refresh required.
|
|
||||||
// highestRectHeight = obj.rect.height;
|
|
||||||
// //Tree.Scroller.ReloadData();
|
|
||||||
// }
|
|
||||||
// Tree.Scroller.RefreshCells(true);
|
|
||||||
//}
|
|
||||||
|
|
||||||
public override void SaveToConfigManager()
|
|
||||||
{
|
{
|
||||||
ConfigManager.SceneExplorerData.Value = this.ToSaveData();
|
var text = allSceneDrop.options[allSceneDrop.value].text;
|
||||||
|
|
||||||
|
if (text == DEFAULT_LOAD_TEXT)
|
||||||
|
return;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
SceneManager.LoadScene(text, mode);
|
||||||
|
allSceneDrop.value = 0;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
ExplorerCore.LogWarning($"Unable to load the Scene! {ex.ReflectionExToString()}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void LoadSaveData()
|
public override void ConstructUI(GameObject content)
|
||||||
{
|
{
|
||||||
ApplySaveData(ConfigManager.SceneExplorerData.Value);
|
m_uiRoot = UIFactory.CreateUIObject("SceneExplorer", content);
|
||||||
}
|
UIFactory.SetLayoutGroup<VerticalLayoutGroup>(m_uiRoot, true, true, true, true, 0, 2, 2, 2, 2);
|
||||||
|
UIFactory.SetLayoutElement(m_uiRoot, flexibleHeight: 9999);
|
||||||
|
|
||||||
public override void SetDefaultPosAndAnchors()
|
|
||||||
{
|
|
||||||
mainPanelRect.localPosition = Vector2.zero;
|
|
||||||
mainPanelRect.anchorMin = Vector3.zero;
|
|
||||||
mainPanelRect.anchorMax = new Vector2(0, 1);
|
|
||||||
mainPanelRect.sizeDelta = new Vector2(300f, mainPanelRect.sizeDelta.y);
|
|
||||||
mainPanelRect.anchoredPosition = new Vector2(200, 0);
|
|
||||||
mainPanelRect.offsetMin = new Vector2(mainPanelRect.offsetMin.x, 100); // bottom
|
|
||||||
mainPanelRect.offsetMax = new Vector2(mainPanelRect.offsetMax.x, -50); // top
|
|
||||||
mainPanelRect.pivot = new Vector2(0.5f, 0.5f);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void ConstructPanelContent()
|
|
||||||
{
|
|
||||||
// Tool bar (top area)
|
// Tool bar (top area)
|
||||||
|
|
||||||
var toolbar = UIFactory.CreateVerticalGroup(content, "Toolbar", true, true, true, true, 2, new Vector4(2, 2, 2, 2),
|
var toolbar = UIFactory.CreateVerticalGroup(m_uiRoot, "Toolbar", true, true, true, true, 2, new Vector4(2, 2, 2, 2),
|
||||||
new Color(0.15f, 0.15f, 0.15f));
|
new Color(0.15f, 0.15f, 0.15f));
|
||||||
|
|
||||||
// Scene selector dropdown
|
// Scene selector dropdown
|
||||||
@ -219,8 +198,8 @@ namespace UnityExplorer.UI.Panels
|
|||||||
refreshRow.SetActive(false);
|
refreshRow.SetActive(false);
|
||||||
|
|
||||||
// Transform Tree
|
// Transform Tree
|
||||||
|
|
||||||
var scrollPool = UIFactory.CreateScrollPool(content, "TransformTree", out GameObject scrollObj,
|
var scrollPool = UIFactory.CreateScrollPool(m_uiRoot, "TransformTree", out GameObject scrollObj,
|
||||||
out GameObject scrollContent, new Color(0.15f, 0.15f, 0.15f));
|
out GameObject scrollContent, new Color(0.15f, 0.15f, 0.15f));
|
||||||
UIFactory.SetLayoutElement(scrollObj, flexibleHeight: 9999);
|
UIFactory.SetLayoutElement(scrollObj, flexibleHeight: 9999);
|
||||||
UIFactory.SetLayoutElement(scrollContent, flexibleHeight: 9999);
|
UIFactory.SetLayoutElement(scrollContent, flexibleHeight: 9999);
|
||||||
@ -245,7 +224,7 @@ namespace UnityExplorer.UI.Panels
|
|||||||
{
|
{
|
||||||
if (SceneHandler.WasAbleToGetScenesInBuild)
|
if (SceneHandler.WasAbleToGetScenesInBuild)
|
||||||
{
|
{
|
||||||
var sceneLoaderObj = UIFactory.CreateVerticalGroup(content, "SceneLoader", true, true, true, true);
|
var sceneLoaderObj = UIFactory.CreateVerticalGroup(m_uiRoot, "SceneLoader", true, true, true, true);
|
||||||
UIFactory.SetLayoutElement(sceneLoaderObj, minHeight: 25);
|
UIFactory.SetLayoutElement(sceneLoaderObj, minHeight: 25);
|
||||||
//sceneLoaderObj.SetActive(false);
|
//sceneLoaderObj.SetActive(false);
|
||||||
|
|
||||||
@ -284,7 +263,7 @@ namespace UnityExplorer.UI.Panels
|
|||||||
loadButton.interactable = false;
|
loadButton.interactable = false;
|
||||||
loadAdditiveButton.interactable = false;
|
loadAdditiveButton.interactable = false;
|
||||||
|
|
||||||
allSceneDrop.onValueChanged.AddListener((int val) =>
|
allSceneDrop.onValueChanged.AddListener((int val) =>
|
||||||
{
|
{
|
||||||
var text = allSceneDrop.options[val].text;
|
var text = allSceneDrop.options[val].text;
|
||||||
if (text == DEFAULT_LOAD_TEXT)
|
if (text == DEFAULT_LOAD_TEXT)
|
||||||
@ -305,23 +284,5 @@ namespace UnityExplorer.UI.Panels
|
|||||||
ExplorerCore.LogWarning($"Could not create the Scene Loader helper! {ex.ReflectionExToString()}");
|
ExplorerCore.LogWarning($"Could not create the Scene Loader helper! {ex.ReflectionExToString()}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void TryLoadScene(LoadSceneMode mode, Dropdown allSceneDrop)
|
|
||||||
{
|
|
||||||
var text = allSceneDrop.options[allSceneDrop.value].text;
|
|
||||||
|
|
||||||
if (text == DEFAULT_LOAD_TEXT)
|
|
||||||
return;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
SceneManager.LoadScene(text, mode);
|
|
||||||
allSceneDrop.value = 0;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
ExplorerCore.LogWarning($"Unable to load the Scene! {ex.ReflectionExToString()}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -223,7 +223,7 @@ namespace UnityExplorer.UI.Widgets
|
|||||||
cache = null;
|
cache = null;
|
||||||
int rangeIndex = GetNormalizedHeight(desiredHeight);
|
int rangeIndex = GetNormalizedHeight(desiredHeight);
|
||||||
|
|
||||||
if (rangeToDataIndexCache.Count <= rangeIndex)
|
if (rangeToDataIndexCache.Count <= rangeIndex || rangeIndex < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
int dataIndex = rangeToDataIndexCache[rangeIndex];
|
int dataIndex = rangeToDataIndexCache[rangeIndex];
|
||||||
|
@ -106,7 +106,7 @@ namespace UnityExplorer.UI.Widgets
|
|||||||
|
|
||||||
public void Rebuild()
|
public void Rebuild()
|
||||||
{
|
{
|
||||||
RecreateCellPool(true, true, null);
|
RecreateCellPool(true, true, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void EnableTempCache()
|
public void EnableTempCache()
|
||||||
|
@ -8,32 +8,35 @@ using UnityEngine.UI;
|
|||||||
using UnityExplorer;
|
using UnityExplorer;
|
||||||
using UnityExplorer.Core;
|
using UnityExplorer.Core;
|
||||||
using UnityExplorer.UI;
|
using UnityExplorer.UI;
|
||||||
|
using UnityExplorer.UI.Models;
|
||||||
|
|
||||||
namespace UnityExplorer.UI.Utility
|
namespace UnityExplorer.UI.Utility
|
||||||
{
|
{
|
||||||
// Basically just to fix an issue with Scrollbars, instead we use a Slider as the scrollbar.
|
// Basically just to fix an issue with Scrollbars, instead we use a Slider as the scrollbar.
|
||||||
public class SliderScrollbar
|
public class SliderScrollbar : UIBehaviourModel
|
||||||
{
|
{
|
||||||
internal static readonly List<SliderScrollbar> Instances = new List<SliderScrollbar>();
|
//internal static readonly List<SliderScrollbar> Instances = new List<SliderScrollbar>();
|
||||||
|
|
||||||
public static void UpdateInstances()
|
//public static void UpdateInstances()
|
||||||
{
|
//{
|
||||||
if (!Instances.Any())
|
// if (!Instances.Any())
|
||||||
return;
|
// return;
|
||||||
|
|
||||||
for (int i = 0; i < Instances.Count; i++)
|
// for (int i = 0; i < Instances.Count; i++)
|
||||||
{
|
// {
|
||||||
var slider = Instances[i];
|
// var slider = Instances[i];
|
||||||
|
|
||||||
if (slider.CheckDestroyed())
|
// if (slider.CheckDestroyed())
|
||||||
i--;
|
// i--;
|
||||||
else
|
// else
|
||||||
slider.Update();
|
// slider.Update();
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|
||||||
public bool IsActive { get; private set; }
|
public bool IsActive { get; private set; }
|
||||||
|
|
||||||
|
public override GameObject UIRoot => m_slider.gameObject;
|
||||||
|
|
||||||
public event Action<float> OnValueChanged;
|
public event Action<float> OnValueChanged;
|
||||||
|
|
||||||
internal readonly Scrollbar m_scrollbar;
|
internal readonly Scrollbar m_scrollbar;
|
||||||
@ -44,7 +47,7 @@ namespace UnityExplorer.UI.Utility
|
|||||||
|
|
||||||
public SliderScrollbar(Scrollbar scrollbar, Slider slider)
|
public SliderScrollbar(Scrollbar scrollbar, Slider slider)
|
||||||
{
|
{
|
||||||
Instances.Add(this);
|
//Instances.Add(this);
|
||||||
|
|
||||||
this.m_scrollbar = scrollbar;
|
this.m_scrollbar = scrollbar;
|
||||||
this.m_slider = slider;
|
this.m_slider = slider;
|
||||||
@ -57,18 +60,18 @@ namespace UnityExplorer.UI.Utility
|
|||||||
this.m_slider.Set(1f, false);
|
this.m_slider.Set(1f, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal bool CheckDestroyed()
|
//internal bool CheckDestroyed()
|
||||||
{
|
//{
|
||||||
if (!m_slider || !m_scrollbar)
|
// if (!m_slider || !m_scrollbar)
|
||||||
{
|
// {
|
||||||
Instances.Remove(this);
|
// Instances.Remove(this);
|
||||||
return true;
|
// return true;
|
||||||
}
|
// }
|
||||||
|
|
||||||
return false;
|
// return false;
|
||||||
}
|
//}
|
||||||
|
|
||||||
internal void Update()
|
public override void Update()
|
||||||
{
|
{
|
||||||
this.RefreshVisibility();
|
this.RefreshVisibility();
|
||||||
}
|
}
|
||||||
@ -167,6 +170,11 @@ namespace UnityExplorer.UI.Utility
|
|||||||
return sliderObj;
|
return sliderObj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void ConstructUI(GameObject parent)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -219,7 +219,8 @@
|
|||||||
<Compile Include="Core\Config\InternalConfigHandler.cs" />
|
<Compile Include="Core\Config\InternalConfigHandler.cs" />
|
||||||
<Compile Include="Core\CSharp\ScriptEvaluator.cs" />
|
<Compile Include="Core\CSharp\ScriptEvaluator.cs" />
|
||||||
<Compile Include="Core\CSharp\ScriptInteraction.cs" />
|
<Compile Include="Core\CSharp\ScriptInteraction.cs" />
|
||||||
<Compile Include="Core\CSharp\Suggestion.cs" />
|
<Compile Include="UI\Widgets\AutoComplete\ISuggestionProvider.cs" />
|
||||||
|
<Compile Include="UI\Widgets\AutoComplete\Suggestion.cs" />
|
||||||
<Compile Include="Core\Config\ConfigElement.cs" />
|
<Compile Include="Core\Config\ConfigElement.cs" />
|
||||||
<Compile Include="Core\Config\ConfigHandler.cs" />
|
<Compile Include="Core\Config\ConfigHandler.cs" />
|
||||||
<Compile Include="Core\Config\ConfigManager.cs" />
|
<Compile Include="Core\Config\ConfigManager.cs" />
|
||||||
@ -266,12 +267,16 @@
|
|||||||
<Compile Include="UI\Models\UIModel.cs" />
|
<Compile Include="UI\Models\UIModel.cs" />
|
||||||
<Compile Include="UI\Models\UIPanel.cs" />
|
<Compile Include="UI\Models\UIPanel.cs" />
|
||||||
<Compile Include="UI\Panels\InspectorTest.cs" />
|
<Compile Include="UI\Panels\InspectorTest.cs" />
|
||||||
<Compile Include="UI\Panels\SceneExplorer.cs" />
|
<Compile Include="UI\Panels\ObjectExplorer.cs" />
|
||||||
<Compile Include="UI\UIFactory.cs" />
|
<Compile Include="UI\UIFactory.cs" />
|
||||||
<Compile Include="UI\UIManager.cs" />
|
<Compile Include="UI\UIManager.cs" />
|
||||||
<Compile Include="UI\Utility\PanelDragger.cs" />
|
<Compile Include="UI\Utility\PanelDragger.cs" />
|
||||||
<Compile Include="UI\Utility\SignatureHighlighter.cs" />
|
<Compile Include="UI\Utility\SignatureHighlighter.cs" />
|
||||||
<Compile Include="UI\Utility\ToStringUtility.cs" />
|
<Compile Include="UI\Utility\ToStringUtility.cs" />
|
||||||
|
<Compile Include="UI\Widgets\AutoComplete\AutoCompleter.cs" />
|
||||||
|
<Compile Include="UI\Widgets\AutoComplete\TypeCompleter.cs" />
|
||||||
|
<Compile Include="UI\Widgets\ObjectExplorer\ObjectSearch.cs" />
|
||||||
|
<Compile Include="UI\Widgets\ObjectExplorer\SceneExplorer.cs" />
|
||||||
<Compile Include="UI\Widgets\ScrollPool\DataHeightCache.cs" />
|
<Compile Include="UI\Widgets\ScrollPool\DataHeightCache.cs" />
|
||||||
<Compile Include="UI\Widgets\ScrollPool\CellViewHolder.cs" />
|
<Compile Include="UI\Widgets\ScrollPool\CellViewHolder.cs" />
|
||||||
<Compile Include="UI\Widgets\ScrollPool\ICell.cs" />
|
<Compile Include="UI\Widgets\ScrollPool\ICell.cs" />
|
||||||
|
Loading…
x
Reference in New Issue
Block a user