Enum parse support, start work on CSConsole, cleanup

This commit is contained in:
Sinai 2021-05-09 20:18:33 +10:00
parent 7b700cbe55
commit e6b253fed9
30 changed files with 1616 additions and 213 deletions

View File

@ -4,17 +4,20 @@ using System.Linq;
using System.Text; using System.Text;
using UnityEngine; using UnityEngine;
using UnityEngine.UI; using UnityEngine.UI;
using UnityExplorer.UI;
using UnityExplorer.UI.CacheObject; using UnityExplorer.UI.CacheObject;
using UnityExplorer.UI.Inspectors;
using UnityExplorer.UI.ObjectPool; using UnityExplorer.UI.ObjectPool;
using UnityExplorer.UI.Panels; using UnityExplorer.UI.Panels;
namespace UnityExplorer.UI.Inspectors namespace UnityExplorer
{ {
public static class InspectorManager public static class InspectorManager
{ {
public static readonly List<InspectorBase> Inspectors = new List<InspectorBase>(); public static readonly List<InspectorBase> Inspectors = new List<InspectorBase>();
public static InspectorBase ActiveInspector { get; private set; } public static InspectorBase ActiveInspector { get; private set; }
private static InspectorBase lastActiveInspector;
public static float PanelWidth; public static float PanelWidth;
@ -28,10 +31,6 @@ namespace UnityExplorer.UI.Inspectors
if (TryFocusActiveInspector(obj)) if (TryFocusActiveInspector(obj))
return; return;
// var type = obj.GetActualType();
//if (type.IsEnumerable())
// CreateInspector<ListInspector>(obj, false, sourceCache);
//// todo dict
if (obj is GameObject) if (obj is GameObject)
CreateInspector<GameObjectInspector>(obj); CreateInspector<GameObjectInspector>(obj);
else else
@ -68,9 +67,12 @@ namespace UnityExplorer.UI.Inspectors
public static void UnsetActiveInspector() public static void UnsetActiveInspector()
{ {
if (ActiveInspector != null) if (ActiveInspector != null)
{
lastActiveInspector = ActiveInspector;
ActiveInspector.OnSetInactive(); ActiveInspector.OnSetInactive();
ActiveInspector = null;
}
} }
private static void CreateInspector<T>(object target, bool staticReflection = false, CacheObjectBase sourceCache = null) where T : InspectorBase private static void CreateInspector<T>(object target, bool staticReflection = false, CacheObjectBase sourceCache = null) where T : InspectorBase
{ {
var inspector = Pool<T>.Borrow(); var inspector = Pool<T>.Borrow();
@ -96,10 +98,35 @@ namespace UnityExplorer.UI.Inspectors
internal static void ReleaseInspector<T>(T inspector) where T : InspectorBase internal static void ReleaseInspector<T>(T inspector) where T : InspectorBase
{ {
if (lastActiveInspector == inspector)
lastActiveInspector = null;
bool wasActive = ActiveInspector == inspector;
int wasIdx = Inspectors.IndexOf(inspector);
Inspectors.Remove(inspector);
inspector.OnReturnToPool(); inspector.OnReturnToPool();
Pool<T>.Return(inspector); Pool<T>.Return(inspector);
Inspectors.Remove(inspector); if (wasActive)
{
ActiveInspector = null;
// Try focus another inspector, or close the window.
if (lastActiveInspector != null)
{
SetInspectorActive(lastActiveInspector);
lastActiveInspector = null;
}
else if (Inspectors.Any())
{
int newIdx = Math.Min(Inspectors.Count - 1, Math.Max(0, wasIdx - 1));
SetInspectorActive(Inspectors[newIdx]);
}
else
{
UIManager.SetPanelActive(UIManager.Panels.Inspector, false);
}
}
} }
internal static void Update() internal static void Update()

View File

@ -1,14 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace UnityExplorer.Core.Search
{
public enum ChildFilter
{
Any,
RootObject,
HasParent
}
}

View File

@ -1,15 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace UnityExplorer.Core.Search
{
public enum SceneFilter
{
Any,
ActivelyLoaded,
DontDestroyOnLoad,
HideAndDontSave,
}
}

View File

@ -1,17 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace UnityExplorer.Core.Search
{
public enum SearchContext
{
UnityObject,
GameObject,
//Component,
//Custom,
Singleton,
StaticClass
}
}

View File

@ -4,6 +4,8 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using UnityEngine; using UnityEngine;
using UnityExplorer.UI.IValues;
using System.Reflection;
#if CPP #if CPP
using UnhollowerRuntimeLib; using UnhollowerRuntimeLib;
using UnhollowerBaseLib; using UnhollowerBaseLib;
@ -11,8 +13,69 @@ using UnhollowerBaseLib;
namespace UnityExplorer.Tests namespace UnityExplorer.Tests
{ {
public struct TestValueStruct
{
public const object TestIgnoreThis = null;
public const string TestIgnoreButValid = "";
public string aString;
public int anInt;
public float aFloat;
public bool aBool;
public Vector3 AVector3;
public Vector4 aVector4;
public DateTime aDateTime;
public Color32 aColor32;
public CameraClearFlags clearFlags;
}
public enum TestEnum : long
{
Neg50 = -50,
Neg1 = -1,
Zero = 0,
One = 1,
Pos49 = 49,
Implicit50,
Also50 = 50,
AlsoAlso50 = 50,
};
public enum TestEnum2 : ulong
{
Min = ulong.MinValue,
Max = ulong.MaxValue
}
[Flags]
public enum TestFlags : int
{
All = -1,
Zero = 0,
Ok = 1,
Two = 2,
Three = 4,
Four = 8,
Five = 16,
Six = 32,
Seven = 64,
Thirteen = Six | Seven,
Fifteen = Four | Five | Six,
}
public static class TestClass public static class TestClass
{ {
public static void ATestMethod(string s, float f, Vector3 vector, DateTime date, Quaternion quater, bool b, CameraClearFlags enumvalue)
{
ExplorerCore.Log($"{s}, {f}, {vector.ToString()}, {date}, {quater.eulerAngles.ToString()}, {b}, {enumvalue}");
}
public static TestValueStruct AATestStruct;
public static TestEnum AATestEnumOne = TestEnum.Neg50;
public static TestEnum2 AATestEnumTwo = TestEnum2.Max;
public static TestFlags AATestFlags = TestFlags.Thirteen;
public static BindingFlags AATestbinding;
public static HideFlags AAHideFlags;
public static List<int> AWritableList = new List<int> { 1, 2, 3, 4, 5 }; public static List<int> AWritableList = new List<int> { 1, 2, 3, 4, 5 };
public static Dictionary<string, int> AWritableDict = new Dictionary<string, int> { { "one", 1 }, { "two", 2 } }; public static Dictionary<string, int> AWritableDict = new Dictionary<string, int> { { "one", 1 }, { "two", 2 } };
@ -67,6 +130,9 @@ namespace UnityExplorer.Tests
public const int ConstantInt = 5; public const int ConstantInt = 5;
public static Color AColor = Color.magenta;
public static Color32 AColor32 = Color.red;
public static byte[] ByteArray = new byte[16]; public static byte[] ByteArray = new byte[16];
public static string LongString = new string('#', 10000); public static string LongString = new string('#', 10000);
public static List<string> BigList = new List<string>(10000); public static List<string> BigList = new List<string>(10000);
@ -123,7 +189,6 @@ namespace UnityExplorer.Tests
} }
#if CPP #if CPP
public static List<Il2CppSystem.Object> TestWritableBoxedList;
public static string testStringOne = "Test"; public static string testStringOne = "Test";
public static Il2CppSystem.Object testStringTwo = "string boxed as cpp object"; public static Il2CppSystem.Object testStringTwo = "string boxed as cpp object";
@ -141,6 +206,21 @@ namespace UnityExplorer.Tests
public static Il2CppSystem.Object cppDecimalBoxed; public static Il2CppSystem.Object cppDecimalBoxed;
public static Il2CppSystem.Object cppVector3Boxed; public static Il2CppSystem.Object cppVector3Boxed;
public static Il2CppSystem.Object RandomBoxedColor
{
get
{
int ran = UnityEngine.Random.Range(0, 3);
switch (ran)
{
case 1: return new Color32().BoxIl2CppObject();
case 2: return Color.magenta.BoxIl2CppObject();
default:
return null;
}
}
}
public static Il2CppSystem.Collections.Hashtable cppHashset; public static Il2CppSystem.Collections.Hashtable cppHashset;
public static Dictionary<Il2CppSystem.String, Il2CppSystem.Object> CppBoxedDict; public static Dictionary<Il2CppSystem.String, Il2CppSystem.Object> CppBoxedDict;
@ -167,6 +247,7 @@ namespace UnityExplorer.Tests
CppBoxedList = new List<Il2CppSystem.Object>(); CppBoxedList = new List<Il2CppSystem.Object>();
CppBoxedList.Add((Il2CppSystem.String)"boxedString"); CppBoxedList.Add((Il2CppSystem.String)"boxedString");
CppBoxedList.Add(new Il2CppSystem.Int32 { m_value = 5 }.BoxIl2CppObject()); CppBoxedList.Add(new Il2CppSystem.Int32 { m_value = 5 }.BoxIl2CppObject());
CppBoxedList.Add(Color.red.BoxIl2CppObject());
try try
{ {
@ -205,12 +286,6 @@ namespace UnityExplorer.Tests
cppBoxedInt = new Il2CppSystem.Int32() { m_value = 5 }.BoxIl2CppObject(); cppBoxedInt = new Il2CppSystem.Int32() { m_value = 5 }.BoxIl2CppObject();
cppInt = new Il2CppSystem.Int32 { m_value = 420 }; cppInt = new Il2CppSystem.Int32 { m_value = 420 };
TestWritableBoxedList = new List<Il2CppSystem.Object>();
TestWritableBoxedList.Add(new Il2CppSystem.Int32 { m_value = 1 }.BoxIl2CppObject());
TestWritableBoxedList.Add(new Il2CppSystem.Int32 { m_value = 2 }.BoxIl2CppObject());
TestWritableBoxedList.Add(new Il2CppSystem.Int32 { m_value = 3 }.BoxIl2CppObject());
TestWritableBoxedList.Add(new Il2CppSystem.Int32 { m_value = 4 }.BoxIl2CppObject());
cppHashset = new Il2CppSystem.Collections.Hashtable(); cppHashset = new Il2CppSystem.Collections.Hashtable();
cppHashset.Add("key1", "itemOne"); cppHashset.Add("key1", "itemOne");
cppHashset.Add("key2", "itemTwo"); cppHashset.Add("key2", "itemTwo");

View File

@ -23,7 +23,7 @@ namespace UnityExplorer
{ {
if (string.IsNullOrEmpty(type.FullName)) if (string.IsNullOrEmpty(type.FullName))
return false; return false;
return type.IsPrimitive || nonPrimitiveTypes.Contains(type) || customTypes.ContainsKey(type.FullName); return type.IsPrimitive || type.IsEnum || nonPrimitiveTypes.Contains(type) || customTypes.ContainsKey(type.FullName);
} }
public static bool TryParse(string input, Type type, out object obj, out Exception parseException) public static bool TryParse(string input, Type type, out object obj, out Exception parseException)
@ -40,6 +40,20 @@ namespace UnityExplorer
return true; return true;
} }
if (type.IsEnum)
{
try
{
obj = Enum.Parse(type, input);
return true;
}
catch (Exception ex)
{
parseException = ex.GetInnerMostException();
return false;
}
}
try try
{ {
if (customTypes.ContainsKey(type.FullName)) if (customTypes.ContainsKey(type.FullName))
@ -63,6 +77,12 @@ namespace UnityExplorer
return false; return false;
} }
private static readonly HashSet<Type> nonFormattedTypes = new HashSet<Type>
{
typeof(IntPtr),
typeof(UIntPtr),
};
public static string ToStringForInput(object obj, Type type) public static string ToStringForInput(object obj, Type type)
{ {
if (type == null || obj == null) if (type == null || obj == null)
@ -71,6 +91,13 @@ namespace UnityExplorer
if (type == typeof(string)) if (type == typeof(string))
return obj as string; return obj as string;
if (type.IsEnum)
{
return Enum.IsDefined(type, obj)
? Enum.GetName(type, obj)
: obj.ToString();
}
try try
{ {
if (customTypes.ContainsKey(type.FullName)) if (customTypes.ContainsKey(type.FullName))
@ -79,10 +106,8 @@ namespace UnityExplorer
} }
else else
{ {
if (obj is IntPtr ptr) if (nonFormattedTypes.Contains(type))
return ptr.ToString(); return obj.ToString();
else if (obj is UIntPtr uPtr)
return uPtr.ToString();
else else
return ReflectionUtility.GetMethodInfo(type, "ToString", new Type[] { typeof(IFormatProvider) }) return ReflectionUtility.GetMethodInfo(type, "ToString", new Type[] { typeof(IFormatProvider) })
.Invoke(obj, new object[] { en_US }) .Invoke(obj, new object[] { en_US })
@ -104,8 +129,15 @@ namespace UnityExplorer
{ {
try try
{ {
var instance = Activator.CreateInstance(type); if (type.IsEnum)
typeInputExamples.Add(type.AssemblyQualifiedName, ToStringForInput(instance, type)); {
typeInputExamples.Add(type.AssemblyQualifiedName, Enum.GetNames(type).First());
}
else
{
var instance = Activator.CreateInstance(type);
typeInputExamples.Add(type.AssemblyQualifiedName, ToStringForInput(instance, type));
}
} }
catch (Exception ex) catch (Exception ex)
{ {

View File

@ -231,6 +231,18 @@ namespace UnityExplorer
return sb.ToString(); return sb.ToString();
} }
public static string GetMemberInfoColor(MemberTypes type)
{
switch (type)
{
case MemberTypes.Method: return METHOD_INSTANCE;
case MemberTypes.Property: return PROP_INSTANCE;
case MemberTypes.Field: return FIELD_INSTANCE;
default: return null;
}
}
public static string GetMemberInfoColor(MemberInfo memberInfo, out bool isStatic) public static string GetMemberInfoColor(MemberInfo memberInfo, out bool isStatic)
{ {
isStatic = false; isStatic = false;

View File

@ -0,0 +1,237 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.Core.CSharp;
using UnityExplorer.Core.Input;
using UnityExplorer.UI.Panels;
namespace UnityExplorer.UI.CSharpConsole
{
public static class CSConsole
{
#region Strings / defaults
internal const string STARTUP_TEXT = @"Welcome to the UnityExplorer C# Console.
The following helper methods are available:
* <color=#add490>Log(""message"")</color> logs a message to the debug console
* <color=#add490>StartCoroutine(IEnumerator routine)</color> start the IEnumerator as a UnityEngine.Coroutine
* <color=#add490>CurrentTarget()</color> returns the currently inspected target on the Home page
* <color=#add490>AllTargets()</color> returns an object[] array containing all inspected instances
* <color=#add490>Inspect(someObject)</color> to inspect an instance, eg. Inspect(Camera.main);
* <color=#add490>Inspect(typeof(SomeClass))</color> to inspect a Class with static reflection
* <color=#add490>AddUsing(""SomeNamespace"")</color> adds a using directive to the C# console
* <color=#add490>GetUsing()</color> logs the current using directives to the debug console
* <color=#add490>Reset()</color> resets all using directives and variables
";
internal static readonly string[] DefaultUsing = new string[]
{
"System",
"System.Linq",
"System.Collections",
"System.Collections.Generic",
"System.Reflection",
"UnityEngine",
#if CPP
"UnhollowerBaseLib",
"UnhollowerRuntimeLib",
#endif
};
#endregion
public static ScriptEvaluator Evaluator;
public static CSLexer Lexer;
private static StringBuilder evaluatorOutput;
private static HashSet<string> usingDirectives;
private static CSConsolePanel Panel => UIManager.CSharpConsole;
private static InputField InputField => Panel.InputField.InputField;
// Todo save as config?
public static bool EnableCtrlRShortcut { get; private set; } = true;
public static bool EnableAutoIndent { get; private set; } = true;
public static bool EnableSuggestions { get; private set; } = true;
public static void Init()
{
try
{
Lexer = new CSLexer();
ResetConsole(false);
Evaluator.Compile("0 == 0");
Panel.OnInputChanged += OnConsoleInputChanged;
// TODO other panel listeners
}
catch (Exception ex)
{
ExplorerCore.LogWarning(ex);
}
}
#region Evaluating console input
public static void ResetConsole(bool logSuccess = true)
{
if (Evaluator != null)
Evaluator.Dispose();
evaluatorOutput = new StringBuilder();
Evaluator = new ScriptEvaluator(new StringWriter(evaluatorOutput))
{
InteractiveBaseClass = typeof(ScriptInteraction)
};
usingDirectives = new HashSet<string>();
foreach (var use in DefaultUsing)
AddUsing(use);
if (logSuccess)
ExplorerCore.Log($"C# Console reset. Using directives:\r\n{Evaluator.GetUsing()}");
}
public static void AddUsing(string assemblyName)
{
if (!usingDirectives.Contains(assemblyName))
{
Evaluate($"using {assemblyName};", true);
usingDirectives.Add(assemblyName);
}
}
public static void Evaluate(string input, bool supressLog = false)
{
try
{
Evaluator.Run(input);
string output = ScriptEvaluator._textWriter.ToString();
var outputSplit = output.Split('\n');
if (outputSplit.Length >= 2)
output = outputSplit[outputSplit.Length - 2];
evaluatorOutput.Clear();
if (ScriptEvaluator._reportPrinter.ErrorsCount > 0)
throw new FormatException($"Unable to compile the code. Evaluator's last output was:\r\n{output}");
if (!supressLog)
ExplorerCore.Log("Code executed successfully.");
}
catch (FormatException fex)
{
if (!supressLog)
ExplorerCore.LogWarning(fex.Message);
}
catch (Exception ex)
{
if (!supressLog)
ExplorerCore.LogWarning(ex);
}
}
#endregion
// Updating and event listeners
private static readonly KeyCode[] onFocusKeys =
{
KeyCode.Return, KeyCode.Backspace, KeyCode.UpArrow,
KeyCode.DownArrow, KeyCode.LeftArrow, KeyCode.RightArrow
};
public static void Update()
{
if (EnableCtrlRShortcut)
{
if ((InputManager.GetKey(KeyCode.LeftControl) || InputManager.GetKey(KeyCode.RightControl))
&& InputManager.GetKeyDown(KeyCode.R))
{
var text = Panel.InputField.Text.Trim();
if (!string.IsNullOrEmpty(text))
{
Evaluate(text);
return;
}
}
}
if (EnableAutoIndent && InputManager.GetKeyDown(KeyCode.Return))
DoAutoIndent();
//if (EnableAutocompletes && InputField.isFocused)
//{
// if (InputManager.GetMouseButton(0) || onFocusKeys.Any(it => InputManager.GetKeyDown(it)))
// UpdateAutocompletes();
//}
}
private static void OnConsoleInputChanged(string input)
{
// todo update auto completes
// todo update syntax highlight
}
// Autocompletes
private static string SyntaxHighlight(string input)
{
var sb = new StringBuilder();
int curIdx = 0;
foreach (var match in Lexer.GetMatches(input))
{
// append non-highlighted text between last match and this
for (int i = curIdx; i < match.startIndex; i++)
sb.Append(input[i]);
// append the highlighted match
sb.Append(match.htmlColorTag);
for (int i = match.startIndex; i < match.endIndex; i++)
sb.Append(input[i]);
sb.Append(SignatureHighlighter.CLOSE_COLOR);
// update the index
curIdx = match.endIndex;
}
return sb.ToString();
}
// Indent
private static void DoAutoIndent()
{
int caret = Panel.LastCaretPosition;
Panel.InputField.Text = Lexer.AutoIndentOnEnter(InputField.text, ref caret);
InputField.caretPosition = caret;
Panel.InputText.Rebuild(CanvasUpdate.Prelayout);
InputField.ForceLabelUpdate();
InputField.Rebuild(CanvasUpdate.Prelayout);
OnConsoleInputChanged(InputField.text);
}
}
}

View File

@ -1,34 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace UnityExplorer.UI.CSConsole
{
public static class CSConsoleManager
{
internal const string STARTUP_TEXT = @"Welcome to the UnityExplorer C# Console.
The following helper methods are available:
* <color=#add490>Log(""message"")</color> logs a message to the debug console
* <color=#add490>StartCoroutine(IEnumerator routine)</color> start the IEnumerator as a UnityEngine.Coroutine
* <color=#add490>CurrentTarget()</color> returns the currently inspected target on the Home page
* <color=#add490>AllTargets()</color> returns an object[] array containing all inspected instances
* <color=#add490>Inspect(someObject)</color> to inspect an instance, eg. Inspect(Camera.main);
* <color=#add490>Inspect(typeof(SomeClass))</color> to inspect a Class with static reflection
* <color=#add490>AddUsing(""SomeNamespace"")</color> adds a using directive to the C# console
* <color=#add490>GetUsing()</color> logs the current using directives to the debug console
* <color=#add490>Reset()</color> resets all using directives and variables
";
}
}

354
src/UI/CSConsole/CSLexer.cs Normal file
View File

@ -0,0 +1,354 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine.UI;
using UnityExplorer.UI.CSharpConsole.Lexer;
namespace UnityExplorer.UI.CSharpConsole
{
public struct LexerMatchInfo
{
public int startIndex;
public int endIndex;
public string htmlColorTag;
}
public enum DelimiterType
{
Start,
End,
};
public class CSLexer
{
private string inputString;
private readonly Matcher[] matchers;
private readonly HashSet<char> startDelimiters;
private readonly HashSet<char> endDelimiters;
private int currentIndex;
private int currentLookaheadIndex;
public char Current { get; private set; }
public char Previous { get; private set; }
public bool EndOfStream => currentLookaheadIndex >= inputString.Length;
public static char indentOpen = '{';
public static char indentClose = '}';
//private static StringBuilder indentBuilder = new StringBuilder();
public static char[] delimiters = new[]
{
'[', ']', '(', ')', '{', '}', ';', ':', ',', '.'
};
private static readonly CommentMatch commentMatcher = new CommentMatch();
private static readonly SymbolMatch symbolMatcher = new SymbolMatch();
private static readonly NumberMatch numberMatcher = new NumberMatch();
private static readonly StringMatch stringMatcher = new StringMatch();
private static readonly KeywordMatch keywordMatcher = new KeywordMatch();
public CSLexer()
{
startDelimiters = new HashSet<char>(delimiters);
endDelimiters = new HashSet<char>(delimiters);
this.matchers = new Matcher[]
{
commentMatcher,
symbolMatcher,
numberMatcher,
stringMatcher,
keywordMatcher,
};
foreach (Matcher lexer in matchers)
{
foreach (char c in lexer.StartChars)
{
if (!startDelimiters.Contains(c))
startDelimiters.Add(c);
}
foreach (char c in lexer.EndChars)
{
if (!endDelimiters.Contains(c))
endDelimiters.Add(c);
}
}
}
public IEnumerable<LexerMatchInfo> GetMatches(string input)
{
if (input == null || matchers == null || matchers.Length == 0)
yield break;
inputString = input;
Current = ' ';
Previous = ' ';
currentIndex = 0;
currentLookaheadIndex = 0;
while (!EndOfStream)
{
bool didMatchLexer = false;
ReadWhiteSpace();
foreach (Matcher matcher in matchers)
{
int startIndex = currentIndex;
bool isMatched = matcher.IsMatch(this);
if (isMatched)
{
int endIndex = currentIndex;
didMatchLexer = true;
yield return new LexerMatchInfo
{
startIndex = startIndex,
endIndex = endIndex,
htmlColorTag = matcher.HexColorTag,
};
break;
}
}
if (!didMatchLexer)
{
ReadNext();
Commit();
}
}
}
// Lexer reading
public char ReadNext()
{
if (EndOfStream)
return '\0';
Previous = Current;
Current = inputString[currentLookaheadIndex];
currentLookaheadIndex++;
return Current;
}
public void Rollback(int amount = -1)
{
if (amount == -1)
currentLookaheadIndex = currentIndex;
else
{
if (currentLookaheadIndex > currentIndex)
currentLookaheadIndex -= amount;
}
int previousIndex = currentLookaheadIndex - 1;
if (previousIndex >= inputString.Length)
Previous = inputString[inputString.Length - 1];
else if (previousIndex >= 0)
Previous = inputString[previousIndex];
else
Previous = ' ';
}
public void Commit()
{
currentIndex = currentLookaheadIndex;
}
public bool IsSpecialSymbol(char character, DelimiterType position = DelimiterType.Start)
{
if (position == DelimiterType.Start)
return startDelimiters.Contains(character);
return endDelimiters.Contains(character);
}
private void ReadWhiteSpace()
{
while (char.IsWhiteSpace(ReadNext()) == true)
Commit();
Rollback();
}
// Auto-indenting
public int GetIndentLevel(string input, int toIndex)
{
bool stringState = false;
int indent = 0;
for (int i = 0; i < toIndex && i < input.Length; i++)
{
char character = input[i];
if (character == '"')
stringState = !stringState;
else if (!stringState && character == indentOpen)
indent++;
else if (!stringState && character == indentClose)
indent--;
}
if (indent < 0)
indent = 0;
return indent;
}
// TODO not quite correct, but almost there.
public string AutoIndentOnEnter(string input, ref int caretPos)
{
var sb = new StringBuilder(input);
bool inString = false;
bool inChar = false;
int currentIndent = 0;
int curLineIndent = 0;
bool prevWasNewLine = true;
// process before caret position
for (int i = 0; i < caretPos; i++)
{
char c = sb[i];
ExplorerCore.Log(i + ": " + c);
// update string/char state
if (!inChar && c == '\"')
inString = !inString;
else if (!inString && c == '\'')
inChar = !inChar;
// continue if inside string or char
if (inString || inChar)
continue;
// check for new line
if (c == '\n')
{
ExplorerCore.Log("new line, resetting line counts");
curLineIndent = 0;
prevWasNewLine = true;
}
// check for indent
else if (c == '\t' && prevWasNewLine)
{
ExplorerCore.Log("its a tab");
if (curLineIndent > currentIndent)
{
ExplorerCore.Log("too many tabs, removing");
// already reached the indent we should have
sb.Remove(i, 1);
i--;
caretPos--;
curLineIndent--;
}
else
curLineIndent++;
}
// remove spaces on new lines
else if (c == ' ' && prevWasNewLine)
{
ExplorerCore.Log("removing newline-space");
sb.Remove(i, 1);
i--;
caretPos--;
}
else
{
if (prevWasNewLine && curLineIndent < currentIndent)
{
ExplorerCore.Log("line is not indented enough");
// line is not indented enough
int diff = currentIndent - curLineIndent;
sb.Insert(i, new string('\t', diff));
caretPos += diff;
i += diff;
}
// check for brackets
if (c == indentClose || c == indentOpen)
{
ExplorerCore.Log("char is a bracket");
if (c == indentOpen)
currentIndent++;
else if (c == indentClose)
currentIndent--;
if (!prevWasNewLine)
{
ExplorerCore.Log("it wasnt on a new line, doing so...");
// need to put it on a new line
sb.Insert(i, $"\n{new string('\t', currentIndent - 1)}");
caretPos += 1 + currentIndent;
i += 1 + currentIndent;
}
}
prevWasNewLine = false;
}
}
// process after caret position, make sure there are equal opened/closed brackets
ExplorerCore.Log("-- after caret --");
for (int i = caretPos; i < sb.Length; i++)
{
char c = sb[i];
ExplorerCore.Log(i + ": " + c);
// update string/char state
if (!inChar && c == '\"')
inString = !inString;
else if (!inString && c == '\'')
inChar = !inChar;
if (inString || inChar)
continue;
if (c == indentOpen)
currentIndent++;
else if (c == indentClose)
currentIndent--;
}
if (currentIndent > 0)
{
ExplorerCore.Log("there are not enough closing brackets, curIndent is " + currentIndent);
// There are not enough close brackets
while (currentIndent > 0)
{
ExplorerCore.Log("Inserting closing bracket with " + currentIndent + " indent");
// append the indented '}' on a new line
sb.Insert(caretPos, $"\n{new string('\t', currentIndent - 1)}}}");
currentIndent--;
}
}
//else if (currentIndent < 0)
//{
// // There are too many close brackets
//
// // todo?
//}
return sb.ToString();
}
}
}

View File

@ -0,0 +1,48 @@
using System.Collections.Generic;
using UnityEngine;
namespace UnityExplorer.UI.CSharpConsole.Lexer
{
public class CommentMatch : Matcher
{
public string lineCommentStart = @"//";
public string blockCommentStart = @"/*";
public string blockCommentEnd = @"*/";
public override Color HighlightColor => new Color(0.34f, 0.65f, 0.29f, 1.0f);
public override IEnumerable<char> StartChars => new char[] { lineCommentStart[0], blockCommentStart[0] };
public override IEnumerable<char> EndChars => new char[] { blockCommentEnd[0] };
public override bool IsImplicitMatch(CSLexer lexer) => IsMatch(lexer, lineCommentStart) || IsMatch(lexer, blockCommentStart);
private bool IsMatch(CSLexer lexer, string commentType)
{
if (!string.IsNullOrEmpty(commentType))
{
lexer.Rollback();
bool match = true;
for (int i = 0; i < commentType.Length; i++)
{
if (commentType[i] != lexer.ReadNext())
{
match = false;
break;
}
}
if (match)
{
// Read until end of line or file
while (!IsEndLineOrEndFile(lexer, lexer.ReadNext())) { }
return true;
}
}
return false;
}
private bool IsEndLineOrEndFile(CSLexer lexer, char character) => lexer.EndOfStream || character == '\n' || character == '\r';
}
}

View File

@ -0,0 +1,91 @@
using System.Collections.Generic;
using UnityEngine;
namespace UnityExplorer.UI.CSharpConsole.Lexer
{
public class KeywordMatch : Matcher
{
public string[] Keywords = new[] { "add", "as", "ascending", "await", "bool", "break", "by", "byte",
"case", "catch", "char", "checked", "const", "continue", "decimal", "default", "descending", "do", "dynamic",
"else", "equals", "false", "finally", "float", "for", "foreach", "from", "global", "goto", "group",
"if", "in", "int", "into", "is", "join", "let", "lock", "long", "new", "null", "object", "on", "orderby", "out",
"ref", "remove", "return", "sbyte", "select", "short", "sizeof", "stackalloc", "string",
"switch", "throw", "true", "try", "typeof", "uint", "ulong", "ushort", "var", "where", "while", "yield",
"abstract", "async", "base", "class", "delegate", "enum", "explicit", "extern", "fixed", "get",
"implicit", "interface", "internal", "namespace", "operator", "override", "params", "private", "protected", "public",
"using", "partial", "readonly", "sealed", "set", "static", "struct", "this", "unchecked", "unsafe", "value", "virtual", "volatile", "void" };
public override Color HighlightColor => highlightColor;
public Color highlightColor = new Color(0.33f, 0.61f, 0.83f, 1.0f);
private readonly HashSet<string> shortlist = new HashSet<string>();
private readonly Stack<string> removeList = new Stack<string>();
public override bool IsImplicitMatch(CSLexer lexer)
{
if (!char.IsWhiteSpace(lexer.Previous) &&
!lexer.IsSpecialSymbol(lexer.Previous, DelimiterType.End))
{
return false;
}
shortlist.Clear();
int currentIndex = 0;
char currentChar = lexer.ReadNext();
for (int i = 0; i < Keywords.Length; i++)
{
if (Keywords[i][0] == currentChar)
shortlist.Add(Keywords[i]);
}
if (shortlist.Count == 0)
return false;
do
{
if (lexer.EndOfStream)
{
RemoveLongStrings(currentIndex + 1);
break;
}
currentChar = lexer.ReadNext();
currentIndex++;
if (char.IsWhiteSpace(currentChar) ||
lexer.IsSpecialSymbol(currentChar, DelimiterType.Start))
{
RemoveLongStrings(currentIndex);
lexer.Rollback(1);
break;
}
foreach (string keyword in shortlist)
{
if (currentIndex >= keyword.Length || keyword[currentIndex] != currentChar)
removeList.Push(keyword);
}
while (removeList.Count > 0)
shortlist.Remove(removeList.Pop());
}
while (shortlist.Count > 0);
return shortlist.Count > 0;
}
private void RemoveLongStrings(int length)
{
foreach (string keyword in shortlist)
{
if (keyword.Length > length)
removeList.Push(keyword);
}
while (removeList.Count > 0)
shortlist.Remove(removeList.Pop());
}
}
}

View File

@ -0,0 +1,31 @@
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
namespace UnityExplorer.UI.CSharpConsole.Lexer
{
public abstract class Matcher
{
public abstract Color HighlightColor { get; }
public string HexColorTag => htmlColor ?? (htmlColor = "<color=#" + HighlightColor.ToHex() + ">");
private string htmlColor;
public virtual IEnumerable<char> StartChars => Enumerable.Empty<char>();
public virtual IEnumerable<char> EndChars => Enumerable.Empty<char>();
public abstract bool IsImplicitMatch(CSLexer lexer);
public bool IsMatch(CSLexer lexer)
{
if (IsImplicitMatch(lexer))
{
lexer.Commit();
return true;
}
lexer.Rollback();
return false;
}
}
}

View File

@ -0,0 +1,39 @@
using UnityEngine;
namespace UnityExplorer.UI.CSharpConsole.Lexer
{
public class NumberMatch : Matcher
{
public override Color HighlightColor => new Color(0.58f, 0.33f, 0.33f, 1.0f);
public override bool IsImplicitMatch(CSLexer lexer)
{
if (!char.IsWhiteSpace(lexer.Previous) &&
!lexer.IsSpecialSymbol(lexer.Previous, DelimiterType.End))
{
return false;
}
bool matchedNumber = false;
while (!lexer.EndOfStream)
{
if (IsNumberOrDecimalPoint(lexer.ReadNext()))
{
matchedNumber = true;
lexer.Commit();
}
else
{
lexer.Rollback();
break;
}
}
return matchedNumber;
}
private bool IsNumberOrDecimalPoint(char character) => char.IsNumber(character) || character == '.';
}
}

View File

@ -0,0 +1,26 @@
using System.Collections.Generic;
using UnityEngine;
namespace UnityExplorer.UI.CSharpConsole.Lexer
{
public class StringMatch : Matcher
{
public override Color HighlightColor => new Color(0.79f, 0.52f, 0.32f, 1.0f);
public override IEnumerable<char> StartChars => new[] { '"' };
public override IEnumerable<char> EndChars => new[] { '"' };
public override bool IsImplicitMatch(CSLexer lexer)
{
if (lexer.ReadNext() == '"')
{
while (!IsClosingQuoteOrEndFile(lexer, lexer.ReadNext())) { }
return true;
}
return false;
}
private bool IsClosingQuoteOrEndFile(CSLexer lexer, char character) => lexer.EndOfStream || character == '"';
}
}

View File

@ -0,0 +1,98 @@
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace UnityExplorer.UI.CSharpConsole.Lexer
{
public class SymbolMatch : Matcher
{
public override Color HighlightColor => new Color(0.58f, 0.47f, 0.37f, 1.0f);
private readonly string[] symbols = new[]
{
"[", "]", "(", ")", ".", "?", ":", "+", "-", "*", "/", "%", "&", "|", "^", "~", "=", "<", ">",
"++", "--", "&&", "||", "<<", ">>", "==", "!=", "<=", ">=", "+=", "-=", "*=", "/=", "%=", "&=",
"|=", "^=", "<<=", ">>=", "->", "??", "=>",
};
private static readonly List<string> shortlist = new List<string>();
private static readonly Stack<string> removeList = new Stack<string>();
public override IEnumerable<char> StartChars => symbols.Select(s => s[0]);
public override IEnumerable<char> EndChars => symbols.Select(s => s[0]);
public override bool IsImplicitMatch(CSLexer lexer)
{
if (lexer == null)
return false;
if (!char.IsWhiteSpace(lexer.Previous) &&
!char.IsLetter(lexer.Previous) &&
!char.IsDigit(lexer.Previous) &&
!lexer.IsSpecialSymbol(lexer.Previous, DelimiterType.End))
{
return false;
}
shortlist.Clear();
int currentIndex = 0;
char currentChar = lexer.ReadNext();
for (int i = symbols.Length - 1; i >= 0; i--)
{
if (symbols[i][0] == currentChar)
shortlist.Add(symbols[i]);
}
if (shortlist.Count == 0)
return false;
do
{
if (lexer.EndOfStream)
{
RemoveLongStrings(currentIndex + 1);
break;
}
currentChar = lexer.ReadNext();
currentIndex++;
if (char.IsWhiteSpace(currentChar) ||
char.IsLetter(currentChar) ||
char.IsDigit(currentChar) ||
lexer.IsSpecialSymbol(currentChar, DelimiterType.Start))
{
RemoveLongStrings(currentIndex);
lexer.Rollback(1);
break;
}
foreach (string symbol in shortlist)
{
if (currentIndex >= symbol.Length || symbol[currentIndex] != currentChar)
removeList.Push(symbol);
}
while (removeList.Count > 0)
shortlist.Remove(removeList.Pop());
}
while (shortlist.Count > 0);
return shortlist.Count > 0;
}
private void RemoveLongStrings(int length)
{
foreach (string keyword in shortlist)
{
if (keyword.Length > length)
removeList.Push(keyword);
}
while (removeList.Count > 0)
shortlist.Remove(removeList.Pop());
}
}
}

View File

@ -65,9 +65,7 @@ namespace UnityExplorer.Core.CSharp
{ {
string name = assembly.GetName().Name; string name = assembly.GetName().Name;
if (StdLib.Contains(name)) if (StdLib.Contains(name))
{
continue; continue;
}
import(assembly); import(assembly);
} }

View File

@ -21,22 +21,27 @@ namespace UnityExplorer.UI.Inspectors
public class ReflectionInspector : InspectorBase, IPoolDataSource<CacheMemberCell>, ICacheObjectController public class ReflectionInspector : InspectorBase, IPoolDataSource<CacheMemberCell>, ICacheObjectController
{ {
public CacheObjectBase ParentCacheObject { get; set; } public CacheObjectBase ParentCacheObject { get; set; }
public Type TargetType { get; private set; } public Type TargetType { get; private set; }
public bool CanWrite => true;
// Instance state
public bool StaticOnly { get; internal set; } public bool StaticOnly { get; internal set; }
public bool CanWrite => true;
public BindingFlags FlagsFilter { get; private set; }
public string NameFilter { get; private set; }
public bool AutoUpdateWanted { get; set; }
private List<CacheMember> members = new List<CacheMember>(); private List<CacheMember> members = new List<CacheMember>();
private readonly List<CacheMember> filteredMembers = new List<CacheMember>(); private readonly List<CacheMember> filteredMembers = new List<CacheMember>();
public bool AutoUpdateWanted { get; set; }
private BindingFlags FlagsFilter;
private string NameFilter;
private MemberFlags MemberFilter = MemberFlags.All;
private enum MemberFlags
{
None = 0,
Property = 1,
Field = 2,
Method = 4,
All = 7
}
// UI // UI
@ -44,27 +49,15 @@ namespace UnityExplorer.UI.Inspectors
public Text NameText; public Text NameText;
public Text AssemblyText; public Text AssemblyText;
private Toggle autoUpdateToggle;
// Unity object helpers
private UnityEngine.Object ObjectRef;
private Component ComponentRef;
private Texture2D TextureRef;
private bool TextureViewerWanted;
private GameObject unityObjectRow;
private ButtonRef gameObjectButton;
private InputFieldRef nameInput;
private InputFieldRef instanceIdInput;
private ButtonRef textureButton;
private GameObject textureViewer;
private readonly Color disabledButtonColor = new Color(0.24f, 0.24f, 0.24f); private readonly Color disabledButtonColor = new Color(0.24f, 0.24f, 0.24f);
private readonly Color enabledButtonColor = new Color(0.2f, 0.27f, 0.2f); private readonly Color enabledButtonColor = new Color(0.2f, 0.27f, 0.2f);
private readonly Dictionary<BindingFlags, ButtonRef> scopeFilterButtons = new Dictionary<BindingFlags, ButtonRef>(); private readonly Dictionary<BindingFlags, ButtonRef> scopeFilterButtons = new Dictionary<BindingFlags, ButtonRef>();
private readonly List<Toggle> memberTypeToggles = new List<Toggle>();
private InputFieldRef filterInputField; private InputFieldRef filterInputField;
//private LayoutElement memberTitleLayout; // Setup / return
private Toggle autoUpdateToggle;
public override void OnBorrowedFromPool(object target) public override void OnBorrowedFromPool(object target)
{ {
@ -144,7 +137,14 @@ namespace UnityExplorer.UI.Inspectors
// Get cache members, and set filter to default // Get cache members, and set filter to default
this.members = CacheMember.GetCacheMembers(Target, TargetType, this); this.members = CacheMember.GetCacheMembers(Target, TargetType, this);
this.filterInputField.Text = ""; this.filterInputField.Text = "";
SetFilter("", StaticOnly ? BindingFlags.Static : BindingFlags.Instance); SetFilter("", StaticOnly ? BindingFlags.Static : BindingFlags.Instance);
scopeFilterButtons[BindingFlags.Default].Button.gameObject.SetActive(!StaticOnly);
scopeFilterButtons[BindingFlags.Instance].Button.gameObject.SetActive(!StaticOnly);
foreach (var toggle in memberTypeToggles)
toggle.isOn = true;
refreshWanted = true; refreshWanted = true;
} }
@ -153,6 +153,7 @@ namespace UnityExplorer.UI.Inspectors
private bool refreshWanted; private bool refreshWanted;
private string lastNameFilter; private string lastNameFilter;
private BindingFlags lastFlagsFilter; private BindingFlags lastFlagsFilter;
private MemberFlags lastMemberFilter = MemberFlags.All;
private float timeOfLastAutoUpdate; private float timeOfLastAutoUpdate;
public override void Update() public override void Update()
@ -166,10 +167,11 @@ namespace UnityExplorer.UI.Inspectors
return; return;
} }
if (refreshWanted || NameFilter != lastNameFilter || FlagsFilter != lastFlagsFilter) if (refreshWanted || NameFilter != lastNameFilter || FlagsFilter != lastFlagsFilter || lastMemberFilter != MemberFilter)
{ {
lastNameFilter = NameFilter; lastNameFilter = NameFilter;
lastFlagsFilter = FlagsFilter; lastFlagsFilter = FlagsFilter;
lastMemberFilter = MemberFilter;
FilterMembers(); FilterMembers();
MemberScrollPool.Refresh(true, true); MemberScrollPool.Refresh(true, true);
@ -206,6 +208,14 @@ namespace UnityExplorer.UI.Inspectors
} }
} }
private void OnMemberTypeToggled(MemberFlags flag, bool val)
{
if (!val)
MemberFilter &= ~flag;
else
MemberFilter |= flag;
}
private void FilterMembers() private void FilterMembers()
{ {
filteredMembers.Clear(); filteredMembers.Clear();
@ -214,9 +224,6 @@ namespace UnityExplorer.UI.Inspectors
{ {
var member = members[i]; var member = members[i];
if (!string.IsNullOrEmpty(NameFilter) && !member.NameForFiltering.ContainsIgnoreCase(NameFilter))
continue;
if (FlagsFilter != BindingFlags.Default) if (FlagsFilter != BindingFlags.Default)
{ {
if (FlagsFilter == BindingFlags.Instance && member.IsStatic if (FlagsFilter == BindingFlags.Instance && member.IsStatic
@ -224,6 +231,14 @@ namespace UnityExplorer.UI.Inspectors
continue; continue;
} }
if ((member is CacheMethod && !MemberFilter.HasFlag(MemberFlags.Method))
|| (member is CacheField && !MemberFilter.HasFlag(MemberFlags.Field))
|| (member is CacheProperty && !MemberFilter.HasFlag(MemberFlags.Property)))
continue;
if (!string.IsNullOrEmpty(NameFilter) && !member.NameForFiltering.ContainsIgnoreCase(NameFilter))
continue;
filteredMembers.Add(member); filteredMembers.Add(member);
} }
} }
@ -313,9 +328,9 @@ namespace UnityExplorer.UI.Inspectors
new Color(0.12f, 0.12f, 0.12f)); new Color(0.12f, 0.12f, 0.12f));
UIFactory.SetLayoutElement(mainContentHolder, flexibleWidth: 9999, flexibleHeight: 9999); UIFactory.SetLayoutElement(mainContentHolder, flexibleWidth: 9999, flexibleHeight: 9999);
ConstructFilterRow(mainContentHolder); ConstructFirstRow(mainContentHolder);
ConstructUpdateRow(mainContentHolder); ConstructSecondRow(mainContentHolder);
// Member scroll pool // Member scroll pool
@ -335,67 +350,115 @@ namespace UnityExplorer.UI.Inspectors
return UIRoot; return UIRoot;
} }
// Filter row // First row
private void ConstructFilterRow(GameObject parent) private void ConstructFirstRow(GameObject parent)
{ {
var filterRow = UIFactory.CreateUIObject("FilterRow", parent); var rowObj = UIFactory.CreateUIObject("FirstRow", parent);
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(filterRow, true, true, true, true, 5, 2, 2, 2, 2); UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(rowObj, true, true, true, true, 5, 2, 2, 2, 2);
UIFactory.SetLayoutElement(filterRow, minHeight: 25, flexibleHeight: 0, flexibleWidth: 9999); UIFactory.SetLayoutElement(rowObj, minHeight: 25, flexibleHeight: 0, flexibleWidth: 9999);
var nameLabel = UIFactory.CreateLabel(filterRow, "NameFilterLabel", "Filter names:", TextAnchor.MiddleLeft, Color.grey); var nameLabel = UIFactory.CreateLabel(rowObj, "NameFilterLabel", "Filter names:", TextAnchor.MiddleLeft, Color.grey);
UIFactory.SetLayoutElement(nameLabel.gameObject, minHeight: 25, minWidth: 90, flexibleWidth: 0); UIFactory.SetLayoutElement(nameLabel.gameObject, minHeight: 25, minWidth: 90, flexibleWidth: 0);
filterInputField = UIFactory.CreateInputField(filterRow, "NameFilterInput", "..."); filterInputField = UIFactory.CreateInputField(rowObj, "NameFilterInput", "...");
UIFactory.SetLayoutElement(filterInputField.UIRoot, minHeight: 25, flexibleWidth: 300); UIFactory.SetLayoutElement(filterInputField.UIRoot, minHeight: 25, flexibleWidth: 300);
filterInputField.OnValueChanged += (string val) => { SetFilter(val); }; filterInputField.OnValueChanged += (string val) => { SetFilter(val); };
var spacer = UIFactory.CreateUIObject("Spacer", filterRow); var spacer = UIFactory.CreateUIObject("Spacer", rowObj);
UIFactory.SetLayoutElement(spacer, minWidth: 25); UIFactory.SetLayoutElement(spacer, minWidth: 25);
var scopeLabel = UIFactory.CreateLabel(filterRow, "ScopeLabel", "Scope:", TextAnchor.MiddleLeft, Color.grey); // Update button and toggle
UIFactory.SetLayoutElement(scopeLabel.gameObject, minHeight: 25, minWidth: 60, flexibleWidth: 0);
AddFilterButton(filterRow, BindingFlags.Default, true); var updateButton = UIFactory.CreateButton(rowObj, "UpdateButton", "Update displayed values", new Color(0.22f, 0.28f, 0.22f));
AddFilterButton(filterRow, BindingFlags.Instance); UIFactory.SetLayoutElement(updateButton.Button.gameObject, minHeight: 25, minWidth: 175, flexibleWidth: 0);
AddFilterButton(filterRow, BindingFlags.Static); updateButton.OnClick += UpdateDisplayedMembers;
var toggleObj = UIFactory.CreateToggle(rowObj, "AutoUpdateToggle", out autoUpdateToggle, out Text toggleText);
//GameObject.DestroyImmediate(toggleText);
UIFactory.SetLayoutElement(toggleObj, minWidth: 125, minHeight: 25);
autoUpdateToggle.isOn = false;
autoUpdateToggle.onValueChanged.AddListener((bool val) => { AutoUpdateWanted = val; });
toggleText.text = "Auto-update";
} }
private void AddFilterButton(GameObject parent, BindingFlags flags, bool setAsActive = false) // Second row
private void ConstructSecondRow(GameObject parent)
{
var rowObj = UIFactory.CreateUIObject("SecondRow", parent);
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(rowObj, false, false, true, true, 5, 2, 2, 2, 2);
UIFactory.SetLayoutElement(rowObj, minHeight: 25, flexibleHeight: 0, flexibleWidth: 9999);
// Scope buttons
var scopeLabel = UIFactory.CreateLabel(rowObj, "ScopeLabel", "Scope:", TextAnchor.MiddleLeft, Color.grey);
UIFactory.SetLayoutElement(scopeLabel.gameObject, minHeight: 25, minWidth: 60, flexibleWidth: 0);
AddScopeFilterButton(rowObj, BindingFlags.Default, true);
AddScopeFilterButton(rowObj, BindingFlags.Instance);
AddScopeFilterButton(rowObj, BindingFlags.Static);
var spacer = UIFactory.CreateUIObject("Spacer", rowObj);
UIFactory.SetLayoutElement(spacer, minWidth: 15);
// Member type toggles
//var typeLabel = UIFactory.CreateLabel(rowObj, "MemberTypeLabel", "Show:", TextAnchor.MiddleLeft, Color.grey);
//UIFactory.SetLayoutElement(typeLabel.gameObject, minHeight: 25, minWidth: 40);
AddMemberTypeToggle(rowObj, MemberTypes.Property, 90);
AddMemberTypeToggle(rowObj, MemberTypes.Field, 70);
AddMemberTypeToggle(rowObj, MemberTypes.Method, 90);
}
private void AddScopeFilterButton(GameObject parent, BindingFlags flags, bool setAsActive = false)
{ {
string lbl = flags == BindingFlags.Default ? "All" : flags.ToString(); string lbl = flags == BindingFlags.Default ? "All" : flags.ToString();
var color = setAsActive ? enabledButtonColor : disabledButtonColor; var color = setAsActive ? enabledButtonColor : disabledButtonColor;
var button = UIFactory.CreateButton(parent, "Filter_" + flags, lbl, color); var button = UIFactory.CreateButton(parent, "Filter_" + flags, lbl, color);
UIFactory.SetLayoutElement(button.Button.gameObject, minHeight: 25, flexibleHeight: 0, minWidth: 100, flexibleWidth: 0); UIFactory.SetLayoutElement(button.Button.gameObject, minHeight: 25, flexibleHeight: 0, minWidth: 70, flexibleWidth: 0);
scopeFilterButtons.Add(flags, button); scopeFilterButtons.Add(flags, button);
button.OnClick += () => { SetFilter(flags); }; button.OnClick += () => { SetFilter(flags); };
} }
// Update row private void AddMemberTypeToggle(GameObject parent, MemberTypes type, int width)
private void ConstructUpdateRow(GameObject parent)
{ {
var updateRow = UIFactory.CreateUIObject("UpdateRow", parent); var toggleObj = UIFactory.CreateToggle(parent, "Toggle_" + type, out Toggle toggle, out Text toggleText);
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(updateRow, false, false, true, true, 4); UIFactory.SetLayoutElement(toggleObj, minHeight: 25, minWidth: width);
UIFactory.SetLayoutElement(updateRow, minHeight: 25, flexibleHeight: 0, flexibleWidth: 9999); toggleText.text = $"<color={SignatureHighlighter.GetMemberInfoColor(type)}>{type}</color>";
var updateButton = UIFactory.CreateButton(updateRow, "UpdateButton", "Update displayed values", new Color(0.22f, 0.28f, 0.22f)); toggle.graphic.TryCast<Image>().color = new Color(0.25f, 0.25f, 0.25f);
UIFactory.SetLayoutElement(updateButton.Button.gameObject, minHeight: 25, minWidth: 175, flexibleWidth: 0);
updateButton.OnClick += UpdateDisplayedMembers;
var toggleObj = UIFactory.CreateToggle(updateRow, "AutoUpdateToggle", out autoUpdateToggle, out Text toggleText); MemberFlags flag;
//GameObject.DestroyImmediate(toggleText); switch (type)
UIFactory.SetLayoutElement(toggleObj, minWidth: 185, minHeight: 25); {
autoUpdateToggle.isOn = false; case MemberTypes.Method: flag = MemberFlags.Method; break;
autoUpdateToggle.onValueChanged.AddListener((bool val) => { AutoUpdateWanted = val; }); case MemberTypes.Property: flag = MemberFlags.Property; break;
toggleText.text = "Auto-update displayed"; case MemberTypes.Field: flag = MemberFlags.Field; break;
default: return;
}
toggle.onValueChanged.AddListener((bool val) => { OnMemberTypeToggled(flag, val); });
memberTypeToggles.Add(toggle);
} }
#region UNITY OBJECT SPECIFIC #region UNITY OBJECT SPECIFIC
// Unity object helpers // Unity object helpers
private UnityEngine.Object ObjectRef;
private Component ComponentRef;
private Texture2D TextureRef;
private bool TextureViewerWanted;
private GameObject unityObjectRow;
private ButtonRef gameObjectButton;
private InputFieldRef nameInput;
private InputFieldRef instanceIdInput;
private ButtonRef textureButton;
private GameObject textureViewer;
private void SetUnityTargets() private void SetUnityTargets()
{ {
if (!typeof(UnityEngine.Object).IsAssignableFrom(TargetType)) if (!typeof(UnityEngine.Object).IsAssignableFrom(TargetType))

View File

@ -0,0 +1,327 @@
//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;
//using UnityEngine;
//using UnityEngine.EventSystems;
//using UnityEngine.UI;
//using UnityExplorer.Core;
//using UnityExplorer.Core.Input;
//using UnityExplorer.Core.Runtime;
//using UnityExplorer.UI;
//using UnityExplorer.UI.Main;
//using UnityExplorer.Inspectors;
//namespace UnityExplorer.UI.Main.Home
//{
// public class InspectUnderMouse
// {
// public enum MouseInspectMode
// {
// World,
// UI
// }
// public static bool Inspecting { get; set; }
// public static MouseInspectMode Mode { get; set; }
// private static GameObject s_lastHit;
// private static Vector3 s_lastMousePos;
// private static readonly List<Graphic> _wasDisabledGraphics = new List<Graphic>();
// private static readonly List<CanvasGroup> _wasDisabledCanvasGroups = new List<CanvasGroup>();
// private static readonly List<GameObject> _objectsAddedCastersTo = new List<GameObject>();
// internal static Camera MainCamera;
// internal static GraphicRaycaster[] graphicRaycasters;
// public static void Init()
// {
// ConstructUI();
// }
// public static void StartInspect(MouseInspectMode mode)
// {
// MainCamera = Camera.main;
// if (!MainCamera)
// return;
// Mode = mode;
// Inspecting = true;
// MainMenu.Instance.MainPanel.SetActive(false);
// s_UIContent.SetActive(true);
// if (mode == MouseInspectMode.UI)
// SetupUIRaycast();
// }
// internal static void ClearHitData()
// {
// s_lastHit = null;
// s_objNameLabel.text = "No hits...";
// s_objPathLabel.text = "";
// }
// public static void StopInspect()
// {
// Inspecting = false;
// MainMenu.Instance.MainPanel.SetActive(true);
// s_UIContent.SetActive(false);
// if (Mode == MouseInspectMode.UI)
// StopUIInspect();
// ClearHitData();
// }
// public static void UpdateInspect()
// {
// if (InputManager.GetKeyDown(KeyCode.Escape))
// {
// StopInspect();
// return;
// }
// var mousePos = InputManager.MousePosition;
// if (mousePos != s_lastMousePos)
// UpdatePosition(mousePos);
// // actual inspect raycast
// switch (Mode)
// {
// case MouseInspectMode.UI:
// RaycastUI(mousePos); break;
// case MouseInspectMode.World:
// RaycastWorld(mousePos); break;
// }
// }
// internal static void UpdatePosition(Vector2 mousePos)
// {
// s_lastMousePos = mousePos;
// var inversePos = UIManager.CanvasRoot.transform.InverseTransformPoint(mousePos);
// s_mousePosLabel.text = $"<color=grey>Mouse Position:</color> {mousePos.ToString()}";
// float yFix = mousePos.y < 120 ? 80 : -80;
// s_UIContent.transform.localPosition = new Vector3(inversePos.x, inversePos.y + yFix, 0);
// }
// internal static void OnHitGameObject(GameObject obj)
// {
// if (obj != s_lastHit)
// {
// s_lastHit = obj;
// s_objNameLabel.text = $"<b>Click to Inspect:</b> <color=cyan>{obj.name}</color>";
// s_objPathLabel.text = $"Path: {obj.transform.GetTransformPath(true)}";
// }
// if (InputManager.GetMouseButtonDown(0))
// {
// StopInspect();
// InspectorManager.Instance.Inspect(obj);
// }
// }
// // Collider raycasting
// internal static void RaycastWorld(Vector2 mousePos)
// {
// var ray = MainCamera.ScreenPointToRay(mousePos);
// Physics.Raycast(ray, out RaycastHit hit, 1000f);
// if (hit.transform)
// {
// var obj = hit.transform.gameObject;
// OnHitGameObject(obj);
// }
// else
// {
// if (s_lastHit)
// ClearHitData();
// }
// }
// // UI Graphic raycasting
// private static void SetupUIRaycast()
// {
// foreach (var obj in RuntimeProvider.Instance.FindObjectsOfTypeAll(typeof(Canvas)))
// {
// var canvas = obj.Cast(typeof(Canvas)) as Canvas;
// if (!canvas || !canvas.enabled || !canvas.gameObject.activeInHierarchy)
// continue;
// if (!canvas.GetComponent<GraphicRaycaster>())
// {
// canvas.gameObject.AddComponent<GraphicRaycaster>();
// //ExplorerCore.Log("Added raycaster to " + canvas.name);
// _objectsAddedCastersTo.Add(canvas.gameObject);
// }
// }
// // recache Graphic Raycasters each time we start
// var casters = RuntimeProvider.Instance.FindObjectsOfTypeAll(typeof(GraphicRaycaster));
// graphicRaycasters = new GraphicRaycaster[casters.Length];
// for (int i = 0; i < casters.Length; i++)
// {
// graphicRaycasters[i] = casters[i].Cast(typeof(GraphicRaycaster)) as GraphicRaycaster;
// }
// // enable raycastTarget on Graphics
// foreach (var obj in RuntimeProvider.Instance.FindObjectsOfTypeAll(typeof(Graphic)))
// {
// var graphic = obj.Cast(typeof(Graphic)) as Graphic;
// if (!graphic || !graphic.enabled || graphic.raycastTarget || !graphic.gameObject.activeInHierarchy)
// continue;
// graphic.raycastTarget = true;
// //ExplorerCore.Log("Enabled raycastTarget on " + graphic.name);
// _wasDisabledGraphics.Add(graphic);
// }
// // enable blocksRaycasts on CanvasGroups
// foreach (var obj in RuntimeProvider.Instance.FindObjectsOfTypeAll(typeof(CanvasGroup)))
// {
// var canvas = obj.Cast(typeof(CanvasGroup)) as CanvasGroup;
// if (!canvas || !canvas.gameObject.activeInHierarchy || canvas.blocksRaycasts)
// continue;
// canvas.blocksRaycasts = true;
// //ExplorerCore.Log("Enabled raycasts on " + canvas.name);
// _wasDisabledCanvasGroups.Add(canvas);
// }
// }
// internal static void RaycastUI(Vector2 mousePos)
// {
// var ped = new PointerEventData(null)
// {
// position = mousePos
// };
// //ExplorerCore.Log("~~~~~~~~~ begin raycast ~~~~~~~~");
// GameObject hitObject = null;
// int highestLayer = int.MinValue;
// int highestOrder = int.MinValue;
// int highestDepth = int.MinValue;
// foreach (var gr in graphicRaycasters)
// {
// var list = new List<RaycastResult>();
// RuntimeProvider.Instance.GraphicRaycast(gr, ped, list);
// //gr.Raycast(ped, list);
// if (list.Count > 0)
// {
// foreach (var hit in list)
// {
// // Manual trying to determine which object is "on top".
// // Not perfect, but not terrible.
// if (!hit.gameObject)
// continue;
// if (hit.gameObject.GetComponent<CanvasGroup>() is CanvasGroup group && group.alpha == 0)
// continue;
// if (hit.gameObject.GetComponent<Graphic>() is Graphic graphic && graphic.color.a == 0f)
// continue;
// if (hit.sortingLayer < highestLayer)
// continue;
// if (hit.sortingLayer > highestLayer)
// {
// highestLayer = hit.sortingLayer;
// highestDepth = int.MinValue;
// }
// if (hit.depth < highestDepth)
// continue;
// if (hit.depth > highestDepth)
// {
// highestDepth = hit.depth;
// highestOrder = int.MinValue;
// }
// if (hit.sortingOrder <= highestOrder)
// continue;
// highestOrder = hit.sortingOrder;
// hitObject = hit.gameObject;
// }
// }
// else
// {
// if (s_lastHit)
// ClearHitData();
// }
// }
// if (hitObject)
// OnHitGameObject(hitObject);
// //ExplorerCore.Log("~~~~~~~~~ end raycast ~~~~~~~~");
// }
// private static void StopUIInspect()
// {
// foreach (var obj in _objectsAddedCastersTo)
// {
// if (obj.GetComponent<GraphicRaycaster>() is GraphicRaycaster raycaster)
// GameObject.Destroy(raycaster);
// }
// foreach (var graphic in _wasDisabledGraphics)
// graphic.raycastTarget = false;
// foreach (var canvas in _wasDisabledCanvasGroups)
// canvas.blocksRaycasts = false;
// _objectsAddedCastersTo.Clear();
// _wasDisabledCanvasGroups.Clear();
// _wasDisabledGraphics.Clear();
// }
// internal static Text s_objNameLabel;
// internal static Text s_objPathLabel;
// internal static Text s_mousePosLabel;
// internal static GameObject s_UIContent;
// internal static void ConstructUI()
// {
// s_UIContent = UIFactory.CreatePanel("InspectUnderMouse_UI", out GameObject content);
// var baseRect = s_UIContent.GetComponent<RectTransform>();
// var half = new Vector2(0.5f, 0.5f);
// baseRect.anchorMin = half;
// baseRect.anchorMax = half;
// baseRect.pivot = half;
// baseRect.sizeDelta = new Vector2(700, 150);
// var group = content.GetComponent<VerticalLayoutGroup>();
// group.childForceExpandHeight = true;
// // Title text
// UIFactory.CreateLabel(content, "InspectLabel", "<b>Mouse Inspector</b> (press <b>ESC</b> to cancel)", TextAnchor.MiddleCenter);
// s_mousePosLabel = UIFactory.CreateLabel(content, "MousePosLabel", "Mouse Position:", TextAnchor.MiddleCenter);
// s_objNameLabel = UIFactory.CreateLabel(content, "HitLabelObj", "No hits...", TextAnchor.MiddleLeft);
// s_objNameLabel.horizontalOverflow = HorizontalWrapMode.Overflow;
// s_objPathLabel = UIFactory.CreateLabel(content, "PathLabel", "", TextAnchor.MiddleLeft);
// s_objPathLabel.fontStyle = FontStyle.Italic;
// s_objPathLabel.horizontalOverflow = HorizontalWrapMode.Wrap;
// UIFactory.SetLayoutElement(s_objPathLabel.gameObject, minHeight: 75);
// s_UIContent.SetActive(false);
// }
// }
//}

View File

@ -40,11 +40,6 @@ namespace UnityExplorer.UI.Models
Instances.Add(this); Instances.Add(this);
} }
public virtual void Init()
{
}
/// <summary> /// <summary>
/// Default empty method, override and implement if NeedsUpdateTick is true. /// Default empty method, override and implement if NeedsUpdateTick is true.
/// </summary> /// </summary>

View File

@ -4,21 +4,21 @@ using System.Linq;
using System.Text; using System.Text;
using UnityEngine; using UnityEngine;
using UnityEngine.UI; using UnityEngine.UI;
using UnityExplorer.Core.Search;
using UnityExplorer.UI.Inspectors; using UnityExplorer.UI.Inspectors;
using UnityExplorer.UI.Models; using UnityExplorer.UI.Models;
using UnityExplorer.UI.ObjectPool; using UnityExplorer.UI.ObjectPool;
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; using UnityExplorer.UI.Widgets.AutoComplete;
namespace UnityExplorer.UI.Panels namespace UnityExplorer.UI.ObjectExplorer
{ {
public class ObjectSearch : UIModel public class ObjectSearch : UIModel
{ {
public ObjectExplorer Parent { get; } public ObjectExplorerPanel Parent { get; }
public ObjectSearch(ObjectExplorer parent) public ObjectSearch(ObjectExplorerPanel parent)
{ {
Parent = parent; Parent = parent;
} }

View File

@ -9,15 +9,16 @@ using UnityEngine.SceneManagement;
using UnityEngine.UI; using UnityEngine.UI;
using UnityExplorer.Core; using UnityExplorer.Core;
using UnityExplorer.UI.Models; using UnityExplorer.UI.Models;
using UnityExplorer.UI.Panels;
using UnityExplorer.UI.Widgets; using UnityExplorer.UI.Widgets;
namespace UnityExplorer.UI.Panels namespace UnityExplorer.UI.ObjectExplorer
{ {
public class SceneExplorer : UIModel public class SceneExplorer : UIModel
{ {
public ObjectExplorer Parent { get; } public ObjectExplorerPanel Parent { get; }
public SceneExplorer(ObjectExplorer parent) public SceneExplorer(ObjectExplorerPanel parent)
{ {
Parent = parent; Parent = parent;

View File

@ -5,10 +5,34 @@ using System.Reflection;
using System.Text; using System.Text;
using UnityEngine; using UnityEngine;
using UnityEngine.SceneManagement; using UnityEngine.SceneManagement;
using UnityExplorer.Core;
using UnityExplorer.Core.Runtime; using UnityExplorer.Core.Runtime;
namespace UnityExplorer.Core.Search namespace UnityExplorer.UI.ObjectExplorer
{ {
public enum SearchContext
{
UnityObject,
GameObject,
Singleton,
StaticClass
}
public enum ChildFilter
{
Any,
RootObject,
HasParent
}
public enum SceneFilter
{
Any,
ActivelyLoaded,
DontDestroyOnLoad,
HideAndDontSave,
}
public static class SearchProvider public static class SearchProvider
{ {

View File

@ -6,7 +6,7 @@ using UnityEngine;
using UnityEngine.EventSystems; using UnityEngine.EventSystems;
using UnityEngine.UI; using UnityEngine.UI;
using UnityExplorer.Core.Config; using UnityExplorer.Core.Config;
using UnityExplorer.UI.CSConsole; using UnityExplorer.UI.CSharpConsole;
using UnityExplorer.UI.Utility; using UnityExplorer.UI.Utility;
namespace UnityExplorer.UI.Panels namespace UnityExplorer.UI.Panels
@ -18,14 +18,11 @@ namespace UnityExplorer.UI.Panels
public override int MinWidth => 400; public override int MinWidth => 400;
public override int MinHeight => 300; public override int MinHeight => 300;
public static CSConsolePanel Instance { get; private set; }
public InputFieldRef InputField { get; private set; } public InputFieldRef InputField { get; private set; }
public Text InputText { get; private set; } public Text InputText { get; private set; }
public Text HighlightText { get; private set; } public Text HighlightText { get; private set; }
public Action<string> OnInputChanged; public Action<string> OnInputChanged;
//private float m_timeOfLastInputInvoke;
public Action OnResetClicked; public Action OnResetClicked;
public Action OnCompileClicked; public Action OnCompileClicked;
@ -33,7 +30,7 @@ namespace UnityExplorer.UI.Panels
public Action<bool> OnSuggestionsToggled; public Action<bool> OnSuggestionsToggled;
public Action<bool> OnAutoIndentToggled; public Action<bool> OnAutoIndentToggled;
private int m_lastCaretPosition; public int LastCaretPosition { get; private set; }
private int m_desiredCaretFix; private int m_desiredCaretFix;
private bool m_fixWaiting; private bool m_fixWaiting;
private float m_defaultInputFieldAlpha; private float m_defaultInputFieldAlpha;
@ -41,10 +38,10 @@ namespace UnityExplorer.UI.Panels
public void UseSuggestion(string suggestion) public void UseSuggestion(string suggestion)
{ {
string input = InputField.Text; string input = InputField.Text;
input = input.Insert(m_lastCaretPosition, suggestion); input = input.Insert(LastCaretPosition, suggestion);
InputField.Text = input; InputField.Text = input;
m_desiredCaretFix = m_lastCaretPosition += suggestion.Length; m_desiredCaretFix = LastCaretPosition += suggestion.Length;
var color = InputField.InputField.selectionColor; var color = InputField.InputField.selectionColor;
color.a = 0f; color.a = 0f;
@ -56,10 +53,6 @@ namespace UnityExplorer.UI.Panels
if (value.Length == UIManager.MAX_INPUTFIELD_CHARS) if (value.Length == UIManager.MAX_INPUTFIELD_CHARS)
ExplorerCore.LogWarning($"Reached maximum InputField character length! ({UIManager.MAX_INPUTFIELD_CHARS})"); ExplorerCore.LogWarning($"Reached maximum InputField character length! ({UIManager.MAX_INPUTFIELD_CHARS})");
//if (m_timeOfLastInputInvoke.OccuredEarlierThanDefault())
// return;
//
//m_timeOfLastInputInvoke = Time.realtimeSinceStartup;
OnInputChanged?.Invoke(value); OnInputChanged?.Invoke(value);
} }
@ -67,6 +60,8 @@ namespace UnityExplorer.UI.Panels
{ {
base.Update(); base.Update();
CSConsole.Update();
if (m_desiredCaretFix >= 0) if (m_desiredCaretFix >= 0)
{ {
if (!m_fixWaiting) if (!m_fixWaiting)
@ -87,7 +82,7 @@ namespace UnityExplorer.UI.Panels
} }
} }
else if (InputField.InputField.caretPosition > 0) else if (InputField.InputField.caretPosition > 0)
m_lastCaretPosition = InputField.InputField.caretPosition; LastCaretPosition = InputField.InputField.caretPosition;
} }
// Saving // Saving
@ -111,9 +106,6 @@ namespace UnityExplorer.UI.Panels
public override void ConstructPanelContent() public override void ConstructPanelContent()
{ {
//Content = UIFactory.CreateVerticalGroup(MainMenu.Instance.PageViewport, "CSharpConsole", true, true, true, true);
//UIFactory.SetLayoutElement(Content, preferredHeight: 500, flexibleHeight: 9000);
#region TOP BAR #region TOP BAR
// Main group object // Main group object
@ -157,10 +149,7 @@ namespace UnityExplorer.UI.Panels
int fontSize = 16; int fontSize = 16;
//var inputObj = UIFactory.CreateSrollInputField(this.content, "ConsoleInput", CSConsoleManager.STARTUP_TEXT, var inputObj = UIFactory.CreateSrollInputField(this.content, "ConsoleInput", CSConsole.STARTUP_TEXT, out var inputScroller, fontSize);
// out InputFieldScroller consoleScroll, fontSize);
var inputObj = UIFactory.CreateSrollInputField(this.content, "ConsoleInput", CSConsoleManager.STARTUP_TEXT, out var inputScroller, fontSize);
InputField = inputScroller.InputField; InputField = inputScroller.InputField;
m_defaultInputFieldAlpha = InputField.InputField.selectionColor.a; m_defaultInputFieldAlpha = InputField.InputField.selectionColor.a;
InputField.OnValueChanged += InvokeOnValueChanged; InputField.OnValueChanged += InvokeOnValueChanged;

View File

@ -19,7 +19,7 @@ namespace UnityExplorer.UI.Panels
public override string Name => "Inspector"; public override string Name => "Inspector";
public override UIManager.Panels PanelType => UIManager.Panels.Inspector; public override UIManager.Panels PanelType => UIManager.Panels.Inspector;
public override bool ShouldSaveActiveState => false; public override bool ShouldSaveActiveState => false;
public override int MinWidth => 550; public override int MinWidth => 625;
public override int MinHeight => 350; public override int MinHeight => 350;
public GameObject NavbarHolder; public GameObject NavbarHolder;

View File

@ -11,12 +11,13 @@ using UnityEngine.UI;
using UnityExplorer.Core; using UnityExplorer.Core;
using UnityExplorer.Core.Config; using UnityExplorer.Core.Config;
using UnityExplorer.UI.Models; using UnityExplorer.UI.Models;
using UnityExplorer.UI.ObjectExplorer;
using UnityExplorer.UI.Utility; using UnityExplorer.UI.Utility;
using UnityExplorer.UI.Widgets; using UnityExplorer.UI.Widgets;
namespace UnityExplorer.UI.Panels namespace UnityExplorer.UI.Panels
{ {
public class ObjectExplorer : UIPanel public class ObjectExplorerPanel : UIPanel
{ {
public override string Name => "Object Explorer"; public override string Name => "Object Explorer";
public override UIManager.Panels PanelType => UIManager.Panels.ObjectExplorer; public override UIManager.Panels PanelType => UIManager.Panels.ObjectExplorer;

View File

@ -893,6 +893,15 @@ namespace UnityExplorer.UI
var inputField = CreateInputField(viewportObj, "InputField", placeHolderText); var inputField = CreateInputField(viewportObj, "InputField", placeHolderText);
var content = inputField.UIRoot; var content = inputField.UIRoot;
var textComp = inputField.InputField.textComponent;
textComp.alignment = TextAnchor.UpperLeft;
textComp.fontSize = fontSize;
textComp.horizontalOverflow = HorizontalWrapMode.Wrap;
inputField.InputField.lineType = InputField.LineType.MultiLineNewline;
inputField.InputField.targetGraphic.color = color;
inputField.PlaceholderText.alignment = TextAnchor.UpperLeft;
inputField.PlaceholderText.fontSize = fontSize;
inputField.PlaceholderText.horizontalOverflow = HorizontalWrapMode.Wrap;
//var content = CreateInputField(viewportObj, name, placeHolderText ?? "...", out InputField inputField, fontSize, 0); //var content = CreateInputField(viewportObj, name, placeHolderText ?? "...", out InputField inputField, fontSize, 0);
SetLayoutElement(content, flexibleHeight: 9999, flexibleWidth: 9999); SetLayoutElement(content, flexibleHeight: 9999, flexibleWidth: 9999);

View File

@ -8,6 +8,7 @@ using UnityEngine.EventSystems;
using UnityEngine.UI; using UnityEngine.UI;
using UnityExplorer.Core.Config; using UnityExplorer.Core.Config;
using UnityExplorer.Core.Input; using UnityExplorer.Core.Input;
using UnityExplorer.UI.CSharpConsole;
using UnityExplorer.UI.Models; using UnityExplorer.UI.Models;
using UnityExplorer.UI.Panels; using UnityExplorer.UI.Panels;
using UnityExplorer.UI.Utility; using UnityExplorer.UI.Utility;
@ -39,9 +40,9 @@ namespace UnityExplorer.UI
// panels // panels
internal static GameObject PanelHolder { get; private set; } internal static GameObject PanelHolder { get; private set; }
public static ObjectExplorer Explorer { get; private set; } public static ObjectExplorerPanel Explorer { get; private set; }
public static InspectorPanel Inspector { get; private set; } public static InspectorPanel Inspector { get; private set; }
public static CSConsolePanel CSConsole { get; private set; } public static CSConsolePanel CSharpConsole { get; private set; }
public static AutoCompleter AutoCompleter { get; private set; } public static AutoCompleter AutoCompleter { get; private set; }
@ -69,7 +70,7 @@ namespace UnityExplorer.UI
case Panels.AutoCompleter: case Panels.AutoCompleter:
return AutoCompleter; return AutoCompleter;
case Panels.CSConsole: case Panels.CSConsole:
return CSConsole; return CSharpConsole;
default: default:
throw new NotImplementedException($"TODO GetPanel: {panel}"); throw new NotImplementedException($"TODO GetPanel: {panel}");
} }
@ -170,14 +171,15 @@ namespace UnityExplorer.UI
AutoCompleter = new AutoCompleter(); AutoCompleter = new AutoCompleter();
AutoCompleter.ConstructUI(); AutoCompleter.ConstructUI();
Explorer = new ObjectExplorer(); Explorer = new ObjectExplorerPanel();
Explorer.ConstructUI(); Explorer.ConstructUI();
Inspector = new InspectorPanel(); Inspector = new InspectorPanel();
Inspector.ConstructUI(); Inspector.ConstructUI();
CSConsole = new CSConsolePanel(); CSharpConsole = new CSConsolePanel();
CSConsole.ConstructUI(); CSharpConsole.ConstructUI();
CSConsole.Init();
ShowMenu = !ConfigManager.Hide_On_Startup.Value; ShowMenu = !ConfigManager.Hide_On_Startup.Value;

View File

@ -219,8 +219,15 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Core\Config\InternalConfigHandler.cs" /> <Compile Include="Core\Config\InternalConfigHandler.cs" />
<Compile Include="Core\CSharp\ScriptEvaluator.cs" /> <Compile Include="UI\CSConsole\CSLexer.cs" />
<Compile Include="Core\CSharp\ScriptInteraction.cs" /> <Compile Include="UI\CSConsole\Lexer\CommentMatch.cs" />
<Compile Include="UI\CSConsole\Lexer\KeywordMatch.cs" />
<Compile Include="UI\CSConsole\Lexer\Matcher.cs" />
<Compile Include="UI\CSConsole\Lexer\NumberMatch.cs" />
<Compile Include="UI\CSConsole\Lexer\StringMatch.cs" />
<Compile Include="UI\CSConsole\Lexer\SymbolMatch.cs" />
<Compile Include="UI\CSConsole\ScriptEvaluator.cs" />
<Compile Include="UI\CSConsole\ScriptInteraction.cs" />
<Compile Include="Core\ExplorerBehaviour.cs" /> <Compile Include="Core\ExplorerBehaviour.cs" />
<Compile Include="Core\Reflection\Extensions.cs" /> <Compile Include="Core\Reflection\Extensions.cs" />
<Compile Include="Core\Reflection\Il2CppReflection.cs" /> <Compile Include="Core\Reflection\Il2CppReflection.cs" />
@ -228,7 +235,7 @@
<Compile Include="Core\Utility\MiscUtility.cs" /> <Compile Include="Core\Utility\MiscUtility.cs" />
<Compile Include="Core\Utility\ParseUtility.cs" /> <Compile Include="Core\Utility\ParseUtility.cs" />
<Compile Include="UI\Inspectors\TODO_InspectUnderMouse.cs" /> <Compile Include="UI\Inspectors\TODO_InspectUnderMouse.cs" />
<Compile Include="UI\CSConsole\CSConsoleManager.cs" /> <Compile Include="UI\CSConsole\CSConsole.cs" />
<Compile Include="UI\CacheObject\CacheField.cs" /> <Compile Include="UI\CacheObject\CacheField.cs" />
<Compile Include="UI\CacheObject\CacheKeyValuePair.cs" /> <Compile Include="UI\CacheObject\CacheKeyValuePair.cs" />
<Compile Include="UI\CacheObject\CacheListEntry.cs" /> <Compile Include="UI\CacheObject\CacheListEntry.cs" />
@ -243,7 +250,7 @@
<Compile Include="UI\CacheObject\Views\EvaluateWidget.cs" /> <Compile Include="UI\CacheObject\Views\EvaluateWidget.cs" />
<Compile Include="UI\Inspectors\GameObjectInspector.cs" /> <Compile Include="UI\Inspectors\GameObjectInspector.cs" />
<Compile Include="UI\CacheObject\ICacheObjectController.cs" /> <Compile Include="UI\CacheObject\ICacheObjectController.cs" />
<Compile Include="UI\Inspectors\InspectorManager.cs" /> <Compile Include="Core\InspectorManager.cs" />
<Compile Include="UI\Inspectors\InspectorTab.cs" /> <Compile Include="UI\Inspectors\InspectorTab.cs" />
<Compile Include="UI\Inspectors\InspectorBase.cs" /> <Compile Include="UI\Inspectors\InspectorBase.cs" />
<Compile Include="UI\IValues\InteractiveColor.cs" /> <Compile Include="UI\IValues\InteractiveColor.cs" />
@ -283,10 +290,7 @@
<Compile Include="Core\Runtime\RuntimeProvider.cs" /> <Compile Include="Core\Runtime\RuntimeProvider.cs" />
<Compile Include="Core\Runtime\TextureUtilProvider.cs" /> <Compile Include="Core\Runtime\TextureUtilProvider.cs" />
<Compile Include="Core\SceneHandler.cs" /> <Compile Include="Core\SceneHandler.cs" />
<Compile Include="Core\Search\ChildFilter.cs" /> <Compile Include="UI\ObjectExplorer\SearchProvider.cs" />
<Compile Include="Core\Search\SceneFilter.cs" />
<Compile Include="Core\Search\SearchContext.cs" />
<Compile Include="Core\Search\SearchProvider.cs" />
<Compile Include="Core\Tests\TestClass.cs" /> <Compile Include="Core\Tests\TestClass.cs" />
<Compile Include="Core\Utility\UnityHelpers.cs" /> <Compile Include="Core\Utility\UnityHelpers.cs" />
<Compile Include="ExplorerCore.cs" /> <Compile Include="ExplorerCore.cs" />
@ -302,7 +306,7 @@
<Compile Include="UI\Models\UIModel.cs" /> <Compile Include="UI\Models\UIModel.cs" />
<Compile Include="UI\Panels\UIPanel.cs" /> <Compile Include="UI\Panels\UIPanel.cs" />
<Compile Include="UI\Panels\InspectorPanel.cs" /> <Compile Include="UI\Panels\InspectorPanel.cs" />
<Compile Include="UI\Panels\ObjectExplorer.cs" /> <Compile Include="UI\Panels\ObjectExplorerPanel.cs" />
<Compile Include="UI\UIFactory.cs" /> <Compile Include="UI\UIFactory.cs" />
<Compile Include="UI\UIManager.cs" /> <Compile Include="UI\UIManager.cs" />
<Compile Include="UI\Panels\PanelDragger.cs" /> <Compile Include="UI\Panels\PanelDragger.cs" />