Compare commits

..

20 Commits
4.7.1 ... 4.7.4

Author SHA1 Message Date
1f87e89b97 Add some more functionality to Freecam
- Option to use Game's camera
- Button to reset position back to original cam pos
- Free cam position will be stored between stopping/starting free cam
2022-04-19 19:37:05 +10:00
495bc41a8d Bump Editor package 2022-04-19 18:06:16 +10:00
9cf62c3250 Bump UniverseLib, fix EventSystem issue 2022-04-19 18:05:55 +10:00
4c9b3115cd Update UnityEditorPackage 2022-04-19 01:23:11 +10:00
ebdce70418 Move instructions 2022-04-19 01:22:25 +10:00
7c0b37440b Update UnityEditorPackage 2022-04-19 01:19:04 +10:00
0d8ab8bf14 Allow FreeCam to run when menu closed 2022-04-19 01:12:33 +10:00
5a3cad9be2 Fix weird Behaviour inheritance issue 2022-04-19 00:57:13 +10:00
70d67f1dad Bump version 2022-04-18 21:39:50 +10:00
469484d129 Add FreeCam panel 2022-04-18 21:39:17 +10:00
c5e262d1c3 Fix UEPanel save data issue 2022-04-18 21:39:11 +10:00
53c8dfcb6d Bump UniverseLib 2022-04-18 21:38:49 +10:00
ae3ac21992 Add test for Il2CppSystem.Array 2022-04-18 19:12:42 +10:00
7765b64748 Make MouseInspector panel just a PanelBase 2022-04-18 19:12:21 +10:00
a5023d03f4 Update to UniverseLib 1.3.4 2022-04-18 19:11:39 +10:00
a5e6b65dee Add UniverseLib to C# Console default usings 2022-04-18 19:10:24 +10:00
c45cd8c1e1 Update editor package 2022-04-14 02:41:18 +10:00
e46e24e1af Fix typo 2022-04-14 02:32:01 +10:00
3d66493f9c Use UniverseLib PanelBase/PanelDragger 2022-04-14 01:25:59 +10:00
7e0f98ef91 Automatic code cleanup (no real changes)
- Use explicit type of var
- Use 'new()'
- Remove unnecessary usings
- Sort usings
- Apply formatting
2022-04-12 05:20:35 +10:00
103 changed files with 1651 additions and 2836 deletions

View File

@ -1,6 +1,6 @@
{
"name": "com.sinai-dev.unityexplorer",
"version": "4.7.0",
"version": "4.7.3",
"displayName": "UnityExplorer",
"description": "An in-game UI for exploring, debugging and modifying Unity games.",
"unity": "2017.1",

View File

@ -2,12 +2,10 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityExplorer.CSConsole.Lexers;
using UnityExplorer.UI;
using UnityExplorer.UI.Panels;
using UnityExplorer.UI.Widgets.AutoComplete;
using UniverseLib;
using UniverseLib.UI;
using UniverseLib.UI.Models;
using UniverseLib.Utility;
@ -29,10 +27,23 @@ namespace UnityExplorer.CSConsole
private readonly HashSet<char> delimiters = new()
{
'{', '}', ',', ';', '<', '>', '(', ')', '[', ']', '=', '|', '&', '?'
'{',
'}',
',',
';',
'<',
'>',
'(',
')',
'[',
']',
'=',
'|',
'&',
'?'
};
private readonly List<Suggestion> suggestions = new List<Suggestion>();
private readonly List<Suggestion> suggestions = new();
public void CheckAutocompletes()
{
@ -83,7 +94,7 @@ namespace UnityExplorer.CSConsole
// Get manual namespace completions
foreach (var ns in ReflectionUtility.AllNamespaces)
foreach (string ns in ReflectionUtility.AllNamespaces)
{
if (ns.StartsWith(input))
{
@ -97,7 +108,7 @@ namespace UnityExplorer.CSConsole
// Get manual keyword completions
foreach (var kw in KeywordLexer.keywords)
foreach (string kw in KeywordLexer.keywords)
{
if (kw.StartsWith(input))// && kw.Length > input.Length)
{
@ -121,11 +132,11 @@ namespace UnityExplorer.CSConsole
}
private readonly Dictionary<string, string> namespaceHighlights = new Dictionary<string, string>();
private readonly Dictionary<string, string> namespaceHighlights = new();
private readonly Dictionary<string, string> keywordHighlights = new Dictionary<string, string>();
private readonly Dictionary<string, string> keywordHighlights = new();
private readonly StringBuilder highlightBuilder = new StringBuilder();
private readonly StringBuilder highlightBuilder = new();
private const string OPEN_HIGHLIGHT = "<color=cyan>";
private string GetHighlightString(string prefix, string completion)

View File

@ -1,4 +1,6 @@
using System;
using HarmonyLib;
using Mono.CSharp;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
@ -8,18 +10,14 @@ using System.Text;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using UniverseLib.Input;
using UnityExplorer.CSConsole;
using UnityExplorer.UI;
using UnityExplorer.UI.Panels;
using UnityExplorer.UI.Widgets.AutoComplete;
using UniverseLib.UI;
using UniverseLib;
using UniverseLib.Input;
using UniverseLib.Runtime;
using UniverseLib.UI.Models;
using UniverseLib.Utility;
using HarmonyLib;
using UniverseLib.Runtime;
using Mono.CSharp;
namespace UnityExplorer.CSConsole
{
@ -54,6 +52,7 @@ namespace UnityExplorer.CSConsole
"System.Collections",
"System.Collections.Generic",
"UnityEngine",
"UniverseLib",
#if CPP
"UnhollowerBaseLib",
"UnhollowerRuntimeLib",
@ -62,8 +61,6 @@ namespace UnityExplorer.CSConsole
public static void Init()
{
InitEventSystemPropertyHandlers();
// Make sure console is supported on this platform
try
{
@ -99,11 +96,11 @@ namespace UnityExplorer.CSConsole
if (!Directory.Exists(ScriptsFolder))
Directory.CreateDirectory(ScriptsFolder);
var startupPath = Path.Combine(ScriptsFolder, "startup.cs");
string startupPath = Path.Combine(ScriptsFolder, "startup.cs");
if (File.Exists(startupPath))
{
ExplorerCore.Log($"Executing startup script from '{startupPath}'...");
var text = File.ReadAllText(startupPath);
string text = File.ReadAllText(startupPath);
Input.Text = text;
Evaluate();
}
@ -153,7 +150,7 @@ namespace UnityExplorer.CSConsole
if (Evaluator != null)
Evaluator.Dispose();
GenerateTextWriter();
Evaluator = new ScriptEvaluator(evaluatorStringWriter)
{
@ -161,7 +158,7 @@ namespace UnityExplorer.CSConsole
};
usingDirectives = new HashSet<string>();
foreach (var use in DefaultUsing)
foreach (string use in DefaultUsing)
AddUsing(use);
if (logSuccess)
@ -200,7 +197,7 @@ namespace UnityExplorer.CSConsole
{
// Compile the code. If it returned a CompiledMethod, it is REPL.
CompiledMethod repl = Evaluator.Compile(input);
if (repl != null)
{
// Valid REPL, we have a delegate to the evaluation.
@ -208,7 +205,7 @@ namespace UnityExplorer.CSConsole
{
object ret = null;
repl.Invoke(ref ret);
var result = ret?.ToString();
string result = ret?.ToString();
if (!string.IsNullOrEmpty(result))
ExplorerCore.Log($"Invoked REPL, result: {ret}");
else
@ -222,13 +219,13 @@ namespace UnityExplorer.CSConsole
else
{
// The compiled code was not REPL, so it was a using directive or it defined classes.
string output = Evaluator._textWriter.ToString();
var outputSplit = output.Split('\n');
string[] 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}");
else if (!supressLog)
@ -286,7 +283,7 @@ namespace UnityExplorer.CSConsole
DoAutoIndent();
}
var inStringOrComment = HighlightVisibleInput();
bool inStringOrComment = HighlightVisibleInput();
if (!settingCaretCoroutine)
{
@ -359,12 +356,12 @@ namespace UnityExplorer.CSConsole
// If caret moved, ensure caret is visible in the viewport
if (caretMoved)
{
var charInfo = Input.TextGenerator.characters[LastCaretPosition];
var charTop = charInfo.cursorPos.y;
var charBot = charTop - CSCONSOLE_LINEHEIGHT;
UICharInfo charInfo = Input.TextGenerator.characters[LastCaretPosition];
float charTop = charInfo.cursorPos.y;
float charBot = charTop - CSCONSOLE_LINEHEIGHT;
var viewportMin = Input.Transform.rect.height - Input.Transform.anchoredPosition.y - (Input.Transform.rect.height * 0.5f);
var viewportMax = viewportMin - Panel.InputScroller.ViewportRect.rect.height;
float viewportMin = Input.Transform.rect.height - Input.Transform.anchoredPosition.y - (Input.Transform.rect.height * 0.5f);
float viewportMax = viewportMin - Panel.InputScroller.ViewportRect.rect.height;
float diff = 0f;
if (charTop > viewportMin)
@ -374,7 +371,7 @@ namespace UnityExplorer.CSConsole
if (Math.Abs(diff) > 1)
{
var rect = Input.Transform;
RectTransform rect = Input.Transform;
rect.anchoredPosition = new Vector2(rect.anchoredPosition.x, rect.anchoredPosition.y - diff);
}
}
@ -387,77 +384,17 @@ namespace UnityExplorer.CSConsole
RuntimeHelper.StartCoroutine(SetCaretCoroutine(caretPosition));
}
static void InitEventSystemPropertyHandlers()
{
try
{
foreach (var member in typeof(EventSystem).GetMembers(AccessTools.all))
{
if (member.Name == "m_CurrentSelected")
{
Type backingType;
if (member.MemberType == MemberTypes.Property)
backingType = (member as PropertyInfo).PropertyType;
else
backingType = (member as FieldInfo).FieldType;
usingEventSystemDictionaryMembers = ReflectionUtility.IsDictionary(backingType);
break;
}
}
}
catch (Exception ex)
{
ExplorerCore.LogWarning($"Exception checking EventSystem property backing type: {ex}");
}
}
static bool usingEventSystemDictionaryMembers;
static readonly AmbiguousMemberHandler<EventSystem, GameObject> m_CurrentSelected_Handler_Normal
= new(true, true, "m_CurrentSelected", "m_currentSelected");
static readonly AmbiguousMemberHandler<EventSystem, Dictionary<int, GameObject>> m_CurrentSelected_Handler_Dictionary
= new(true, true, "m_CurrentSelected", "m_currentSelected");
static readonly AmbiguousMemberHandler<EventSystem, bool> m_SelectionGuard_Handler_Normal
= new(true, true, "m_SelectionGuard", "m_selectionGuard");
static readonly AmbiguousMemberHandler<EventSystem, Dictionary<int, bool>> m_SelectionGuard_Handler_Dictionary
= new(true, true, "m_SelectionGuard", "m_selectionGuard");
static void SetCurrentSelectedGameObject(EventSystem instance, GameObject value)
{
instance.SetSelectedGameObject(value);
if (usingEventSystemDictionaryMembers)
m_CurrentSelected_Handler_Dictionary.GetValue(instance)[0] = value;
else
m_CurrentSelected_Handler_Normal.SetValue(instance, value);
}
static void SetSelectionGuard(EventSystem instance, bool value)
{
if (usingEventSystemDictionaryMembers)
m_SelectionGuard_Handler_Dictionary.GetValue(instance)[0] = value;
else
m_SelectionGuard_Handler_Normal.SetValue(instance, value);
}
private static IEnumerator SetCaretCoroutine(int caretPosition)
{
var color = Input.Component.selectionColor;
Color color = Input.Component.selectionColor;
color.a = 0f;
Input.Component.selectionColor = color;
try { SetCurrentSelectedGameObject(CursorUnlocker.CurrentEventSystem, null); }
catch (Exception ex) { ExplorerCore.Log($"Failed removing selected object: {ex}"); }
EventSystemHelper.SetSelectedGameObject(null);
yield return null; // ~~~~~~~ YIELD FRAME ~~~~~~~~~
try { SetSelectionGuard(CursorUnlocker.CurrentEventSystem, false); }
catch (Exception ex) { ExplorerCore.Log($"Failed setting selection guard: {ex}"); }
try { SetCurrentSelectedGameObject(CursorUnlocker.CurrentEventSystem, Input.GameObject); }
catch (Exception ex) { ExplorerCore.Log($"Failed setting selected gameobject: {ex}"); }
EventSystemHelper.SetSelectedGameObject(null);
yield return null; // ~~~~~~~ YIELD FRAME ~~~~~~~~~
@ -495,12 +432,12 @@ namespace UnityExplorer.CSConsole
// the top and bottom position of the viewport in relation to the text height
// they need the half-height adjustment to normalize against the 'line.topY' value.
var viewportMin = Input.Transform.rect.height - Input.Transform.anchoredPosition.y - (Input.Transform.rect.height * 0.5f);
var viewportMax = viewportMin - Panel.InputScroller.ViewportRect.rect.height;
float viewportMin = Input.Transform.rect.height - Input.Transform.anchoredPosition.y - (Input.Transform.rect.height * 0.5f);
float viewportMax = viewportMin - Panel.InputScroller.ViewportRect.rect.height;
for (int i = 0; i < Input.TextGenerator.lineCount; i++)
{
var line = Input.TextGenerator.lines[i];
UILineInfo line = Input.TextGenerator.lines[i];
// if not set the top line yet, and top of line is below the viewport top
if (topLine == -1 && line.topY <= viewportMin)
topLine = i;
@ -534,7 +471,7 @@ namespace UnityExplorer.CSConsole
realStartLine++;
char lastPrev = '\n';
var sb = new StringBuilder();
StringBuilder sb = new();
// append leading new lines for spacing (no point rendering line numbers we cant see)
for (int i = 0; i < topLine; i++)
@ -676,7 +613,7 @@ Doorstop example:
public static void SetupHelpInteraction()
{
var drop = Panel.HelpDropdown;
Dropdown drop = Panel.HelpDropdown;
helpDict.Add("Help", "");
helpDict.Add("Usings", HELP_USINGS);
@ -684,7 +621,7 @@ Doorstop example:
helpDict.Add("Classes", HELP_CLASSES);
helpDict.Add("Coroutines", HELP_COROUTINES);
foreach (var opt in helpDict)
foreach (KeyValuePair<string, string> opt in helpDict)
drop.options.Add(new Dropdown.OptionData(opt.Key));
}
@ -693,7 +630,7 @@ Doorstop example:
if (index == 0)
return;
var helpText = helpDict.ElementAt(index);
KeyValuePair<string, string> helpText = helpDict.ElementAt(index);
Input.Text = helpText.Value;
@ -706,7 +643,7 @@ Doorstop example:
// It is recommended to use the Log panel (or a console log window) while using this tool.
// Use the Help dropdown to see detailed examples of how to use the console.
// To execute a script automatically on startup, put the script at 'UnityExplorer\Scripts\startup.cs'</color>";
// To execute a script automatically on startup, put the script at 'sinai-dev-UnityExplorer\Scripts\startup.cs'</color>";
internal const string HELP_USINGS = @"// You can add a using directive to any namespace, but you must compile for it to take effect.
// It will remain in effect until you Reset the console.

View File

@ -1,12 +1,7 @@
using Mono.CSharp;
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.CSConsole.Lexers;
using UniverseLib;
using UniverseLib.Utility;
namespace UnityExplorer.CSConsole
@ -25,14 +20,14 @@ namespace UnityExplorer.CSConsole
#region Core and initialization
public const char WHITESPACE = ' ';
public readonly HashSet<char> IndentOpenChars = new HashSet<char> { '{', '(' };
public readonly HashSet<char> IndentCloseChars = new HashSet<char> { '}', ')' };
public readonly HashSet<char> IndentOpenChars = new() { '{', '(' };
public readonly HashSet<char> IndentCloseChars = new() { '}', ')' };
private readonly Lexer[] lexers;
private readonly HashSet<char> delimiters = new HashSet<char>();
private readonly HashSet<char> delimiters = new();
private readonly StringLexer stringLexer = new StringLexer();
private readonly CommentLexer commentLexer = new CommentLexer();
private readonly StringLexer stringLexer = new();
private readonly CommentLexer commentLexer = new();
public LexerBuilder()
{
@ -45,7 +40,7 @@ namespace UnityExplorer.CSConsole
new KeywordLexer(),
};
foreach (var matcher in lexers)
foreach (Lexer matcher in lexers)
{
foreach (char c in matcher.Delimiters)
{
@ -97,13 +92,13 @@ namespace UnityExplorer.CSConsole
currentStartIdx = startIdx;
currentEndIdx = endIdx;
var sb = new StringBuilder();
StringBuilder sb = new();
for (int i = 0; i < leadingLines; i++)
sb.Append('\n');
int lastUnhighlighted = startIdx;
foreach (var match in GetMatches())
foreach (MatchInfo match in GetMatches())
{
// append non-highlighted text between last match and this
for (int i = lastUnhighlighted; i < match.startIndex; i++)
@ -130,7 +125,7 @@ namespace UnityExplorer.CSConsole
}
// check caretIdx to determine inStringOrComment state
if (caretIdx >= match.startIndex && (caretIdx <= (matchEndIdx+1) || (caretIdx >= input.Length && matchEndIdx >= input.Length - 1)))
if (caretIdx >= match.startIndex && (caretIdx <= (matchEndIdx + 1) || (caretIdx >= input.Length && matchEndIdx >= input.Length - 1)))
caretInStringOrComment = match.isStringOrComment;
}
@ -158,7 +153,7 @@ namespace UnityExplorer.CSConsole
bool anyMatch = false;
int startIndex = CommittedIndex + 1;
foreach (var lexer in lexers)
foreach (Lexer lexer in lexers)
{
if (lexer.TryMatchCurrent(this))
{

View File

@ -1,6 +1,4 @@
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine;
namespace UnityExplorer.CSConsole.Lexers
{
@ -13,7 +11,7 @@ namespace UnityExplorer.CSConsole.Lexers
}
// forest green
protected override Color HighlightColor => new Color(0.34f, 0.65f, 0.29f, 1.0f);
protected override Color HighlightColor => new(0.34f, 0.65f, 0.29f, 1.0f);
public override bool TryMatchCurrent(LexerBuilder lexer)
{

View File

@ -7,9 +7,9 @@ namespace UnityExplorer.CSConsole.Lexers
public class KeywordLexer : Lexer
{
// system blue
protected override Color HighlightColor => new Color(0.33f, 0.61f, 0.83f, 1.0f);
protected override Color HighlightColor => new(0.33f, 0.61f, 0.83f, 1.0f);
public static readonly HashSet<string> keywords = new HashSet<string>
public static readonly HashSet<string> keywords = new()
{
// reserved keywords
"abstract", "as", "base", "bool", "break", "byte", "case", "catch", "char", "checked", "class", "const", "continue",
@ -28,15 +28,15 @@ namespace UnityExplorer.CSConsole.Lexers
public override bool TryMatchCurrent(LexerBuilder lexer)
{
var prev = lexer.Previous;
var first = lexer.Current;
char prev = lexer.Previous;
char first = lexer.Current;
// check for keywords
if (lexer.IsDelimiter(prev, true) && char.IsLetter(first))
{
// can be a keyword...
var sb = new StringBuilder();
StringBuilder sb = new();
sb.Append(lexer.Current);
while (!lexer.EndOfInput && char.IsLetter(lexer.PeekNext()))
sb.Append(lexer.Current);

View File

@ -1,7 +1,6 @@
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UniverseLib;
using UniverseLib.Utility;
namespace UnityExplorer.CSConsole.Lexers

View File

@ -5,7 +5,7 @@ namespace UnityExplorer.CSConsole.Lexers
public class NumberLexer : Lexer
{
// Maroon
protected override Color HighlightColor => new Color(0.58f, 0.33f, 0.33f, 1.0f);
protected override Color HighlightColor => new(0.58f, 0.33f, 0.33f, 1.0f);
private bool IsNumeric(char c) => char.IsNumber(c) || c == '.';

View File

@ -8,7 +8,7 @@ namespace UnityExplorer.CSConsole.Lexers
public override IEnumerable<char> Delimiters => new[] { '"', '\'', };
// orange
protected override Color HighlightColor => new Color(0.79f, 0.52f, 0.32f, 1.0f);
protected override Color HighlightColor => new(0.79f, 0.52f, 0.32f, 1.0f);
public override bool TryMatchCurrent(LexerBuilder lexer)
{

View File

@ -1,6 +1,5 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
namespace UnityExplorer.CSConsole.Lexers
@ -8,14 +7,14 @@ namespace UnityExplorer.CSConsole.Lexers
public class SymbolLexer : Lexer
{
// silver
protected override Color HighlightColor => new Color(0.6f, 0.6f, 0.6f);
protected override Color HighlightColor => new(0.6f, 0.6f, 0.6f);
// all symbols are delimiters
public override IEnumerable<char> Delimiters => symbols.Where(it => it != '.'); // '.' is not a delimiter, only a separator.
public static bool IsSymbol(char c) => symbols.Contains(c);
public static readonly HashSet<char> symbols = new HashSet<char>
public static readonly HashSet<char> symbols = new()
{
'[', '{', '(', // open
']', '}', ')', // close

View File

@ -3,7 +3,6 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
// Thanks to ManlyMarco for this
@ -13,7 +12,10 @@ namespace UnityExplorer.CSConsole
{
private static readonly HashSet<string> StdLib = new(StringComparer.InvariantCultureIgnoreCase)
{
"mscorlib", "System.Core", "System", "System.Xml"
"mscorlib",
"System.Core",
"System",
"System.Xml"
};
internal TextWriter _textWriter;
@ -45,7 +47,7 @@ namespace UnityExplorer.CSConsole
private void Reference(Assembly asm)
{
var name = asm.GetName().Name;
string name = asm.GetName().Name;
if (name == "completions")
return;
ReferenceAssembly(asm);
@ -55,7 +57,7 @@ namespace UnityExplorer.CSConsole
{
_reportPrinter = new StreamReportPrinter(tw);
var settings = new CompilerSettings
CompilerSettings settings = new()
{
Version = LanguageVersion.Experimental,
GenerateDebugInfo = false,

View File

@ -2,11 +2,9 @@
using Mono.CSharp;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityExplorer.Runtime;
using UnityExplorer.UI.Panels;
using UniverseLib;
@ -29,16 +27,16 @@ namespace UnityExplorer.CSConsole
public static void Inspect(Type type)
=> InspectorManager.Inspect(type);
public static Coroutine Start(IEnumerator ienumerator)
public static Coroutine Start(IEnumerator ienumerator)
=> RuntimeHelper.StartCoroutine(ienumerator);
public static void Stop(Coroutine coro)
=> RuntimeHelper.StopCoroutine(coro);
public static void Copy(object obj)
public static void Copy(object obj)
=> ClipboardPanel.Copy(obj);
public static object Paste()
public static object Paste()
=> ClipboardPanel.Current;
public static void GetUsing()
@ -46,7 +44,7 @@ namespace UnityExplorer.CSConsole
public static void GetVars()
{
var vars = Evaluator.GetVars()?.Trim();
string vars = Evaluator.GetVars()?.Trim();
if (string.IsNullOrEmpty(vars))
ExplorerCore.LogWarning("No variables seem to be defined!");
else
@ -59,12 +57,12 @@ namespace UnityExplorer.CSConsole
.GetValue(Evaluator) is CompilationSourceFile sourceFile
&& sourceFile.Containers.Any())
{
var sb = new StringBuilder();
StringBuilder sb = new();
sb.Append($"There are {sourceFile.Containers.Count} defined classes:");
foreach (TypeDefinition type in sourceFile.Containers.Where(it => it is TypeDefinition))
{
sb.Append($"\n\n{type.MemberName.Name}:");
foreach (var member in type.Members)
foreach (MemberCore member in type.Members)
sb.Append($"\n\t- {member.AttributeTargets}: \"{member.MemberName.Name}\" ({member.ModFlags})");
}
Log(sb.ToString());

View File

@ -1,9 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityExplorer.CacheObject.Views;
using UnityExplorer.Config;
using UnityExplorer.CacheObject.Views;
namespace UnityExplorer.CacheObject
{

View File

@ -1,8 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using UnityExplorer.Inspectors;
using UniverseLib.Utility;
@ -52,7 +49,7 @@ namespace UnityExplorer.CacheObject
Arguments = CtorInfo.GetParameters();
ctorReturnType = CtorInfo.DeclaringType;
}
if (ctorReturnType.IsGenericTypeDefinition)
GenericArguments = ctorReturnType.GetGenericArguments();
}

View File

@ -1,8 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using UnityExplorer.Inspectors;
namespace UnityExplorer.CacheObject
@ -31,7 +28,7 @@ namespace UnityExplorer.CacheObject
{
try
{
var ret = FieldInfo.GetValue(DeclaringInstance);
object ret = FieldInfo.GetValue(DeclaringInstance);
LastException = null;
return ret;
}

View File

@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityExplorer.CacheObject.IValues;
using UnityExplorer.CacheObject.Views;
using UniverseLib;
@ -41,7 +38,7 @@ namespace UnityExplorer.CacheObject
this.DictKey = key;
this.DisplayedKey = key.TryCast();
var type = DisplayedKey.GetType();
Type type = DisplayedKey.GetType();
if (ParseUtility.CanParse(type))
{
KeyInputWanted = true;
@ -60,7 +57,7 @@ namespace UnityExplorer.CacheObject
{
base.SetDataToCell(cell);
var kvpCell = cell as CacheKeyValuePairCell;
CacheKeyValuePairCell kvpCell = cell as CacheKeyValuePairCell;
kvpCell.NameLabel.text = $"{DictIndex}:";
kvpCell.HiddenNameLabel.Text = "";

View File

@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityExplorer.CacheObject.IValues;
using UnityExplorer.CacheObject.IValues;
using UnityExplorer.CacheObject.Views;
namespace UnityExplorer.CacheObject
@ -25,7 +21,7 @@ namespace UnityExplorer.CacheObject
{
base.SetDataToCell(cell);
var listCell = cell as CacheListEntryCell;
CacheListEntryCell listCell = cell as CacheListEntryCell;
listCell.NameLabel.text = $"{ListIndex}:";
listCell.HiddenNameLabel.Text = "";

View File

@ -1,21 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using UnityEngine;
using UnityExplorer.Runtime;
using UnityExplorer.CacheObject.Views;
using UnityExplorer.Inspectors;
using UniverseLib.UI.Models;
using UnityExplorer.UI;
using UniverseLib;
using UniverseLib.UI;
using UnityExplorer.UI.Widgets;
using UniverseLib.Utility;
using UniverseLib;
using UniverseLib.UI.ObjectPool;
using System.Collections;
using HarmonyLib;
using UniverseLib.Utility;
namespace UnityExplorer.CacheObject
{
@ -105,7 +96,7 @@ namespace UnityExplorer.CacheObject
protected override bool TryAutoEvaluateIfUnitialized(CacheObjectCell objectcell)
{
var cell = objectcell as CacheMemberCell;
CacheMemberCell cell = objectcell as CacheMemberCell;
cell.EvaluateHolder.SetActive(!ShouldAutoEvaluate);
if (!ShouldAutoEvaluate)

View File

@ -1,14 +1,11 @@
using System;
using System.Collections;
using HarmonyLib;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using UnityExplorer.Inspectors;
using UnityExplorer.Runtime;
using UniverseLib;
using HarmonyLib;
using HarmonyLib.Tools;
namespace UnityExplorer.CacheObject
{
@ -75,8 +72,8 @@ namespace UnityExplorer.CacheObject
return sorted;
}
static void TryCacheMember<T>(MemberInfo member, List<T> list, HashSet<string> cachedSigs,
Type declaringType, ReflectionInspector inspector, bool ignorePropertyMethodInfos = true)
static void TryCacheMember<T>(MemberInfo member, List<T> list, HashSet<string> cachedSigs,
Type declaringType, ReflectionInspector inspector, bool ignorePropertyMethodInfos = true)
where T : CacheMember
{
try

View File

@ -1,10 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using UnityExplorer.Inspectors;
using UniverseLib;
using UniverseLib.Utility;
namespace UnityExplorer.CacheObject
@ -18,7 +14,7 @@ namespace UnityExplorer.CacheObject
public override bool ShouldAutoEvaluate => false;
public CacheMethod (MethodInfo mi)
public CacheMethod(MethodInfo mi)
{
this.MethodInfo = mi;
}
@ -36,14 +32,14 @@ namespace UnityExplorer.CacheObject
{
try
{
var methodInfo = MethodInfo;
MethodInfo methodInfo = MethodInfo;
if (methodInfo.IsGenericMethod)
methodInfo = MethodInfo.MakeGenericMethod(Evaluator.TryParseGenericArguments());
object ret;
if (HasArguments)
ret = methodInfo.Invoke(DeclaringInstance, Evaluator.TryParseArguments());
else
else
ret = methodInfo.Invoke(DeclaringInstance, ArgumentUtility.EmptyArgs);
LastException = null;
return ret;

View File

@ -1,20 +1,12 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.Runtime;
using UnityExplorer.CacheObject.IValues;
using UnityExplorer.CacheObject.Views;
using UniverseLib.UI.Models;
using UnityExplorer.UI;
using UniverseLib;
using UniverseLib.UI;
using UniverseLib.Utility;
using UniverseLib.UI.ObjectPool;
using UniverseLib.Utility;
namespace UnityExplorer.CacheObject
{
@ -134,7 +126,7 @@ namespace UnityExplorer.CacheObject
protected virtual void ProcessOnEvaluate()
{
var prevState = State;
ValueState prevState = State;
if (LastException != null)
{
@ -276,9 +268,9 @@ namespace UnityExplorer.CacheObject
if (cell.CopyButton != null)
{
bool hasEvaluated = State != ValueState.NotEvaluated && State != ValueState.Exception;
cell.CopyButton.Component.gameObject.SetActive(hasEvaluated);
cell.PasteButton.Component.gameObject.SetActive(hasEvaluated && this.CanWrite);
bool canCopy = State != ValueState.NotEvaluated && State != ValueState.Exception;
cell.CopyButton.Component.gameObject.SetActive(canCopy);
cell.PasteButton.Component.gameObject.SetActive(canCopy && this.CanWrite);
}
if (!evaluated)
@ -319,7 +311,7 @@ namespace UnityExplorer.CacheObject
SetValueState(cell, new(true, inspectActive: !LastValueWasNull, subContentButtonActive: !LastValueWasNull));
break;
case ValueState.Unsupported:
SetValueState(cell, new (true, inspectActive: !LastValueWasNull));
SetValueState(cell, new(true, inspectActive: !LastValueWasNull));
break;
}
@ -369,7 +361,7 @@ namespace UnityExplorer.CacheObject
// set subcontent button if needed, and for null strings and exceptions
cell.SubContentButton.Component.gameObject.SetActive(
args.subContentButtonActive
args.subContentButtonActive
&& (!LastValueWasNull || State == ValueState.String || State == ValueState.Exception));
}
@ -474,12 +466,12 @@ namespace UnityExplorer.CacheObject
public Color valueColor;
public bool valueActive, valueRichText, typeLabelActive, toggleActive, inputActive, applyActive, inspectActive, subContentButtonActive;
public ValueStateArgs(bool valueActive = true,
bool valueRichText = true,
public ValueStateArgs(bool valueActive = true,
bool valueRichText = true,
Color? valueColor = null,
bool typeLabelActive = false,
bool toggleActive = false,
bool inputActive = false,
bool typeLabelActive = false,
bool toggleActive = false,
bool inputActive = false,
bool applyActive = false,
bool inspectActive = false,
bool subContentButtonActive = false)

View File

@ -1,11 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using UnityEngine;
using UnityExplorer.Inspectors;
using UnityExplorer.Runtime;
namespace UnityExplorer.CacheObject
{

View File

@ -1,9 +1,5 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityExplorer.CacheObject;
using UnityExplorer.CacheObject.Views;
namespace UnityExplorer.CacheObject
@ -33,7 +29,7 @@ namespace UnityExplorer.CacheObject
return;
}
var entry = (CacheObjectBase)cachedEntries[index];
CacheObjectBase entry = (CacheObjectBase)cachedEntries[index];
if (entry.CellView != null && entry.CellView != cell)
entry.UnlinkFromView();

View File

@ -1,11 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.CacheObject;
using UnityExplorer.UI;
using UniverseLib.UI;
using UniverseLib.UI.Models;
using UniverseLib;
@ -32,9 +27,9 @@ namespace UnityExplorer.CacheObject.IValues
applyButton.Component.gameObject.SetActive(owner.CanWrite);
foreach (var slider in sliders)
foreach (Slider slider in sliders)
slider.interactable = owner.CanWrite;
foreach (var input in inputs)
foreach (InputFieldRef input in inputs)
input.Component.readOnly = !owner.CanWrite;
}
@ -54,7 +49,7 @@ namespace UnityExplorer.CacheObject.IValues
inputs[1].Text = c32.g.ToString();
inputs[2].Text = c32.b.ToString();
inputs[3].Text = c32.a.ToString();
foreach (var slider in sliders)
foreach (Slider slider in sliders)
slider.maxValue = 255;
}
else
@ -65,7 +60,7 @@ namespace UnityExplorer.CacheObject.IValues
inputs[1].Text = EditedColor.g.ToString();
inputs[2].Text = EditedColor.b.ToString();
inputs[3].Text = EditedColor.a.ToString();
foreach (var slider in sliders)
foreach (Slider slider in sliders)
slider.maxValue = 1;
}
@ -156,12 +151,12 @@ namespace UnityExplorer.CacheObject.IValues
// hori group
var horiGroup = UIFactory.CreateHorizontalGroup(UIRoot, "ColorEditor", false, false, true, true, 5,
GameObject horiGroup = UIFactory.CreateHorizontalGroup(UIRoot, "ColorEditor", false, false, true, true, 5,
default, new Color(1, 1, 1, 0), TextAnchor.MiddleLeft);
// sliders / inputs
var grid = UIFactory.CreateGridGroup(horiGroup, "Grid", new Vector2(140, 25), new Vector2(2, 2), new Color(1, 1, 1, 0));
GameObject grid = UIFactory.CreateGridGroup(horiGroup, "Grid", new Vector2(140, 25), new Vector2(2, 2), new Color(1, 1, 1, 0));
UIFactory.SetLayoutElement(grid, minWidth: 580, minHeight: 25, flexibleWidth: 0);
for (int i = 0; i < 4; i++)
@ -175,7 +170,7 @@ namespace UnityExplorer.CacheObject.IValues
// image of color
var imgObj = UIFactory.CreateUIObject("ColorImageHelper", horiGroup);
GameObject imgObj = UIFactory.CreateUIObject("ColorImageHelper", horiGroup);
UIFactory.SetLayoutElement(imgObj, minHeight: 25, minWidth: 50, flexibleWidth: 50);
colorImage = imgObj.AddComponent<Image>();
@ -184,18 +179,18 @@ namespace UnityExplorer.CacheObject.IValues
internal void AddEditorRow(int index, GameObject groupObj)
{
var row = UIFactory.CreateHorizontalGroup(groupObj, "EditorRow_" + fieldNames[index],
GameObject row = UIFactory.CreateHorizontalGroup(groupObj, "EditorRow_" + fieldNames[index],
false, true, true, true, 5, default, new Color(1, 1, 1, 0));
var label = UIFactory.CreateLabel(row, "RowLabel", $"{fieldNames[index]}:", TextAnchor.MiddleRight, Color.cyan);
Text label = UIFactory.CreateLabel(row, "RowLabel", $"{fieldNames[index]}:", TextAnchor.MiddleRight, Color.cyan);
UIFactory.SetLayoutElement(label.gameObject, minWidth: 17, flexibleWidth: 0, minHeight: 25);
var input = UIFactory.CreateInputField(row, "Input", "...");
InputFieldRef input = UIFactory.CreateInputField(row, "Input", "...");
UIFactory.SetLayoutElement(input.UIRoot, minWidth: 40, minHeight: 25, flexibleHeight: 0);
inputs[index] = input;
input.OnValueChanged += (string val) => { OnInputChanged(val, index); };
var sliderObj = UIFactory.CreateSlider(row, "Slider", out Slider slider);
GameObject sliderObj = UIFactory.CreateSlider(row, "Slider", out Slider slider);
sliders[index] = slider;
UIFactory.SetLayoutElement(sliderObj, minHeight: 25, minWidth: 70, flexibleWidth: 999, flexibleHeight: 0);
slider.minValue = 0;

View File

@ -1,19 +1,12 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.CacheObject;
using UnityExplorer.CacheObject.Views;
using UnityExplorer.Inspectors;
using UnityExplorer.UI;
using UnityExplorer.UI.Panels;
using UnityExplorer.UI.Widgets;
using UniverseLib;
using UniverseLib.UI;
using UniverseLib.UI.Widgets;
using UniverseLib.UI.Widgets.ScrollView;
using UniverseLib.Utility;
@ -32,7 +25,7 @@ namespace UnityExplorer.CacheObject.IValues
public IDictionary RefIDictionary;
public int ItemCount => cachedEntries.Count;
private readonly List<CacheKeyValuePair> cachedEntries = new List<CacheKeyValuePair>();
private readonly List<CacheKeyValuePair> cachedEntries = new();
public ScrollPool<CacheKeyValuePairCell> DictScrollPool { get; private set; }
@ -61,7 +54,7 @@ namespace UnityExplorer.CacheObject.IValues
{
RefIDictionary = null;
foreach (var entry in cachedEntries)
foreach (CacheKeyValuePair entry in cachedEntries)
{
entry.UnlinkFromView();
entry.ReleasePooledObjects();
@ -80,7 +73,7 @@ namespace UnityExplorer.CacheObject.IValues
}
else
{
var type = value.GetActualType();
Type type = value.GetActualType();
ReflectionUtility.TryGetEntryTypes(type, out KeysType, out ValuesType);
CacheEntries(value);
@ -124,7 +117,7 @@ namespace UnityExplorer.CacheObject.IValues
{
for (int i = cachedEntries.Count - 1; i >= idx; i--)
{
var cache = cachedEntries[i];
CacheKeyValuePair cache = cachedEntries[i];
if (cache.CellView != null)
cache.UnlinkFromView();
@ -153,7 +146,7 @@ namespace UnityExplorer.CacheObject.IValues
RefIDictionary[key] = value;
var entry = cachedEntries[keyIndex];
CacheKeyValuePair entry = cachedEntries[keyIndex];
entry.SetValueFromSource(value);
if (entry.CellView != null)
entry.SetDataToCell(entry.CellView);
@ -177,12 +170,12 @@ namespace UnityExplorer.CacheObject.IValues
public override void SetLayout()
{
var minHeight = 5f;
float minHeight = 5f;
KeyTitleLayout.minWidth = AdjustedWidth * 0.44f;
ValueTitleLayout.minWidth = AdjustedWidth * 0.55f;
foreach (var cell in DictScrollPool.CellPool)
foreach (CacheKeyValuePairCell cell in DictScrollPool.CellPool)
{
SetCellLayout(cell);
if (cell.Enabled)
@ -194,7 +187,7 @@ namespace UnityExplorer.CacheObject.IValues
private void SetCellLayout(CacheObjectCell objcell)
{
var cell = objcell as CacheKeyValuePairCell;
CacheKeyValuePairCell cell = objcell as CacheKeyValuePairCell;
cell.KeyGroupLayout.minWidth = cell.AdjustedWidth * 0.44f;
cell.RightGroupLayout.minWidth = cell.AdjustedWidth * 0.55f;
@ -221,15 +214,15 @@ namespace UnityExplorer.CacheObject.IValues
// key / value titles
var titleGroup = UIFactory.CreateUIObject("TitleGroup", UIRoot);
GameObject titleGroup = UIFactory.CreateUIObject("TitleGroup", UIRoot);
UIFactory.SetLayoutElement(titleGroup, minHeight: 25, flexibleWidth: 9999, flexibleHeight: 0);
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(titleGroup, false, true, true, true, padLeft: 65, padRight: 0, childAlignment: TextAnchor.LowerLeft);
var keyTitle = UIFactory.CreateLabel(titleGroup, "KeyTitle", "Keys", TextAnchor.MiddleLeft);
Text keyTitle = UIFactory.CreateLabel(titleGroup, "KeyTitle", "Keys", TextAnchor.MiddleLeft);
UIFactory.SetLayoutElement(keyTitle.gameObject, minWidth: 100, flexibleWidth: 0);
KeyTitleLayout = keyTitle.GetComponent<LayoutElement>();
var valueTitle = UIFactory.CreateLabel(titleGroup, "ValueTitle", "Values", TextAnchor.MiddleLeft);
Text valueTitle = UIFactory.CreateLabel(titleGroup, "ValueTitle", "Values", TextAnchor.MiddleLeft);
UIFactory.SetLayoutElement(valueTitle.gameObject, minWidth: 100, flexibleWidth: 0);
ValueTitleLayout = valueTitle.GetComponent<LayoutElement>();

View File

@ -2,13 +2,10 @@
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.CacheObject;
using UnityExplorer.UI;
using UnityExplorer.UI.Panels;
using UnityExplorer.UI.Widgets.AutoComplete;
using UniverseLib;
using UniverseLib.UI;
using UniverseLib.UI.Models;
using UniverseLib.Utility;
@ -110,7 +107,7 @@ namespace UnityExplorer.CacheObject.IValues
{
try
{
List<string> values = new List<string>();
List<string> values = new();
for (int i = 0; i < CurrentValues.Count; i++)
{
if (flagToggles[i].isOn)
@ -138,11 +135,11 @@ namespace UnityExplorer.CacheObject.IValues
new Color(0.06f, 0.06f, 0.06f));
UIFactory.SetLayoutElement(UIRoot, minHeight: 25, flexibleHeight: 9999, flexibleWidth: 9999);
var hori = UIFactory.CreateUIObject("Hori", UIRoot);
GameObject hori = UIFactory.CreateUIObject("Hori", UIRoot);
UIFactory.SetLayoutElement(hori, minHeight: 25, flexibleWidth: 9999);
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(hori, false, false, true, true, 2);
var applyButton = UIFactory.CreateButton(hori, "ApplyButton", "Apply", new Color(0.2f, 0.27f, 0.2f));
ButtonRef applyButton = UIFactory.CreateButton(hori, "ApplyButton", "Apply", new Color(0.2f, 0.27f, 0.2f));
UIFactory.SetLayoutElement(applyButton.Component.gameObject, minHeight: 25, minWidth: 100);
applyButton.OnClick += OnApplyClicked;
@ -192,11 +189,11 @@ namespace UnityExplorer.CacheObject.IValues
private void AddToggleRow()
{
var row = UIFactory.CreateUIObject("ToggleRow", toggleHolder);
GameObject row = UIFactory.CreateUIObject("ToggleRow", toggleHolder);
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(row, false, false, true, true, 2);
UIFactory.SetLayoutElement(row, minHeight: 25, flexibleWidth: 9999);
var toggleObj = UIFactory.CreateToggle(row, "ToggleObj", out Toggle toggle, out Text toggleText);
GameObject toggleObj = UIFactory.CreateToggle(row, "ToggleObj", out Toggle toggle, out Text toggleText);
UIFactory.SetLayoutElement(toggleObj, minHeight: 25, flexibleWidth: 9999);
flagToggles.Add(toggle);
@ -205,7 +202,7 @@ namespace UnityExplorer.CacheObject.IValues
#region Enum cache
internal static readonly Dictionary<string, OrderedDictionary> enumCache = new Dictionary<string, OrderedDictionary>();
internal static readonly Dictionary<string, OrderedDictionary> enumCache = new();
internal static OrderedDictionary GetEnumValues(Type enumType)
{
@ -213,13 +210,13 @@ namespace UnityExplorer.CacheObject.IValues
if (!enumCache.ContainsKey(enumType.AssemblyQualifiedName))
{
var dict = new OrderedDictionary();
var addedNames = new HashSet<string>();
OrderedDictionary dict = new();
HashSet<string> addedNames = new();
int i = 0;
foreach (var value in Enum.GetValues(enumType))
foreach (object value in Enum.GetValues(enumType))
{
var name = value.ToString();
string name = value.ToString();
if (addedNames.Contains(name))
continue;
addedNames.Add(name);

View File

@ -5,15 +5,10 @@ using System.Linq;
using System.Reflection;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.CacheObject;
using UnityExplorer.CacheObject.Views;
using UnityExplorer.Inspectors;
using UnityExplorer.UI;
using UnityExplorer.UI.Panels;
using UnityExplorer.UI.Widgets;
using UniverseLib;
using UniverseLib.UI;
using UniverseLib.UI.Widgets;
using UniverseLib.UI.Widgets.ScrollView;
using UniverseLib.Utility;
@ -60,7 +55,7 @@ namespace UnityExplorer.CacheObject.IValues
{
RefIList = null;
foreach (var entry in cachedEntries)
foreach (CacheListEntry entry in cachedEntries)
{
entry.UnlinkFromView();
entry.ReleasePooledObjects();
@ -73,9 +68,9 @@ namespace UnityExplorer.CacheObject.IValues
public override void SetLayout()
{
var minHeight = 5f;
float minHeight = 5f;
foreach (var cell in ListScrollPool.CellPool)
foreach (CacheListEntryCell cell in ListScrollPool.CellPool)
{
if (cell.Enabled)
minHeight += cell.Rect.rect.height;
@ -102,7 +97,7 @@ namespace UnityExplorer.CacheObject.IValues
}
else
{
var type = value.GetActualType();
Type type = value.GetActualType();
ReflectionUtility.TryGetEntryType(type, out EntryType);
CacheEntries(value);
@ -132,7 +127,7 @@ namespace UnityExplorer.CacheObject.IValues
while (enumerator.MoveNext())
{
var entry = enumerator.Current;
object entry = enumerator.Current;
// If list count increased, create new cache entries
CacheListEntry cache;
@ -155,7 +150,7 @@ namespace UnityExplorer.CacheObject.IValues
{
for (int i = cachedEntries.Count - 1; i >= idx; i--)
{
var cache = cachedEntries[i];
CacheListEntry cache = cachedEntries[i];
if (cache.CellView != null)
cache.UnlinkFromView();
@ -174,7 +169,7 @@ namespace UnityExplorer.CacheObject.IValues
{
try
{
var type = value.GetType();
Type type = value.GetType();
if (type.GetInterfaces().Any(it => it.IsGenericType && it.GetGenericTypeDefinition() == typeof(IList<>)))
IsWritableGenericIList = !(bool)type.GetProperty("IsReadOnly").GetValue(value, null);
else
@ -184,7 +179,7 @@ namespace UnityExplorer.CacheObject.IValues
{
// Find the "this[int index]" property.
// It might be a private implementation.
foreach (var prop in type.GetProperties(ReflectionUtility.FLAGS))
foreach (PropertyInfo prop in type.GetProperties(ReflectionUtility.FLAGS))
{
if ((prop.Name == "Item"
|| (prop.Name.StartsWith("System.Collections.Generic.IList<") && prop.Name.EndsWith(">.Item")))
@ -226,7 +221,7 @@ namespace UnityExplorer.CacheObject.IValues
genericIndexer.SetValue(CurrentOwner.Value, value, new object[] { index });
}
var entry = cachedEntries[index];
CacheListEntry entry = cachedEntries[index];
entry.SetValueFromSource(value);
if (entry.CellView != null)

View File

@ -1,16 +1,8 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.IO;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.Config;
using UnityExplorer.CacheObject;
using UnityExplorer.UI.Widgets;
using UnityExplorer.UI;
using UniverseLib.UI;
using UniverseLib;
using UniverseLib.UI.Models;
using UniverseLib.Utility;
@ -88,7 +80,7 @@ namespace UnityExplorer.CacheObject.IValues
return;
}
var path = IOUtility.EnsureValidFilePath(SaveFilePath.Text);
string path = IOUtility.EnsureValidFilePath(SaveFilePath.Text);
if (File.Exists(path))
File.Delete(path);
@ -110,10 +102,10 @@ namespace UnityExplorer.CacheObject.IValues
UIFactory.CreateLabel(SaveFileRow, "Info", "<color=red>String is too long! Save to file if you want to see the full string.</color>",
TextAnchor.MiddleLeft);
var horizRow = UIFactory.CreateUIObject("Horiz", SaveFileRow);
GameObject horizRow = UIFactory.CreateUIObject("Horiz", SaveFileRow);
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(horizRow, false, false, true, true, 4);
var saveButton = UIFactory.CreateButton(horizRow, "SaveButton", "Save file");
ButtonRef saveButton = UIFactory.CreateButton(horizRow, "SaveButton", "Save file");
UIFactory.SetLayoutElement(saveButton.Component.gameObject, minHeight: 25, minWidth: 100, flexibleWidth: 0);
saveButton.OnClick += OnSaveFileClicked;

View File

@ -1,13 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.CacheObject;
using UnityExplorer.UI;
using UniverseLib.UI;
using UniverseLib.UI.Models;
using UniverseLib.UI.ObjectPool;
namespace UnityExplorer.CacheObject.IValues

View File

@ -2,11 +2,8 @@
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.CacheObject;
using UnityExplorer.UI;
using UniverseLib;
using UniverseLib.UI;
using UniverseLib.UI.Models;
@ -31,7 +28,7 @@ namespace UnityExplorer.CacheObject.IValues
public void SetValue(object instance, string input, int fieldIndex)
{
var field = Fields[fieldIndex];
FieldInfo field = Fields[fieldIndex];
object val;
if (field.FieldType == typeof(string))
@ -51,8 +48,8 @@ namespace UnityExplorer.CacheObject.IValues
public string GetValue(object instance, int fieldIndex)
{
var field = Fields[fieldIndex];
var value = field.GetValue(instance);
FieldInfo field = Fields[fieldIndex];
object value = field.GetValue(instance);
return ParseUtility.ToStringForInput(value, field.FieldType);
}
}
@ -67,12 +64,12 @@ namespace UnityExplorer.CacheObject.IValues
if (!type.IsValueType || string.IsNullOrEmpty(type.AssemblyQualifiedName) || type.FullName == SYSTEM_VOID)
return false;
if (typeSupportCache.TryGetValue(type.AssemblyQualifiedName, out var info))
if (typeSupportCache.TryGetValue(type.AssemblyQualifiedName, out StructInfo info))
return info.IsSupported;
var supported = false;
bool supported = false;
var fields = type.GetFields(INSTANCE_FLAGS);
FieldInfo[] fields = type.GetFields(INSTANCE_FLAGS);
if (fields.Length > 0)
{
if (fields.Any(it => !ParseUtility.CanParse(it.FieldType)))
@ -100,9 +97,9 @@ namespace UnityExplorer.CacheObject.IValues
private Type lastStructType;
private ButtonRef applyButton;
private readonly List<GameObject> fieldRows = new List<GameObject>();
private readonly List<InputFieldRef> inputFields = new List<InputFieldRef>();
private readonly List<Text> labels = new List<Text>();
private readonly List<GameObject> fieldRows = new();
private readonly List<InputFieldRef> inputFields = new();
private readonly List<Text> labels = new();
public override void OnBorrowed(CacheObjectBase owner)
{
@ -117,7 +114,7 @@ namespace UnityExplorer.CacheObject.IValues
{
RefInstance = value;
var type = RefInstance.GetType();
Type type = RefInstance.GetType();
if (type != lastStructType)
{
@ -177,21 +174,21 @@ namespace UnityExplorer.CacheObject.IValues
private void AddEditorRow()
{
var row = UIFactory.CreateUIObject("HoriGroup", UIRoot);
GameObject row = UIFactory.CreateUIObject("HoriGroup", UIRoot);
//row.AddComponent<ContentSizeFitter>().horizontalFit = ContentSizeFitter.FitMode.PreferredSize;
UIFactory.SetLayoutElement(row, minHeight: 25, flexibleWidth: 9999);
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(row, false, false, true, true, 8, childAlignment: TextAnchor.MiddleLeft);
fieldRows.Add(row);
var label = UIFactory.CreateLabel(row, "Label", "notset", TextAnchor.MiddleLeft);
Text label = UIFactory.CreateLabel(row, "Label", "notset", TextAnchor.MiddleLeft);
UIFactory.SetLayoutElement(label.gameObject, minHeight: 25, minWidth: 50, flexibleWidth: 0);
label.horizontalOverflow = HorizontalWrapMode.Wrap;
labels.Add(label);
var input = UIFactory.CreateInputField(row, "InputField", "...");
InputFieldRef input = UIFactory.CreateInputField(row, "InputField", "...");
UIFactory.SetLayoutElement(input.UIRoot, minHeight: 25, minWidth: 200);
var fitter = input.UIRoot.AddComponent<ContentSizeFitter>();
ContentSizeFitter fitter = input.UIRoot.AddComponent<ContentSizeFitter>();
fitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
fitter.horizontalFit = ContentSizeFitter.FitMode.PreferredSize;
input.Component.lineType = InputField.LineType.MultiLineNewline;

View File

@ -1,13 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.UI;
using UniverseLib;
using UniverseLib.UI;
using UniverseLib.Utility;
using UniverseLib;
namespace UnityExplorer.CacheObject.Views
{
@ -32,7 +27,7 @@ namespace UnityExplorer.CacheObject.Views
// horizontal group
var horiGroup = UIFactory.CreateUIObject("RightHoriGroup", UIRoot);
GameObject horiGroup = UIFactory.CreateUIObject("RightHoriGroup", UIRoot);
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(horiGroup, false, false, true, true, 4, childAlignment: TextAnchor.UpperLeft);
UIFactory.SetLayoutElement(horiGroup, minHeight: 25, minWidth: 200, flexibleWidth: 9999, flexibleHeight: 800);
@ -48,7 +43,7 @@ namespace UnityExplorer.CacheObject.Views
// Bool and number value interaction
var toggleObj = UIFactory.CreateToggle(horiGroup, "Toggle", out Toggle, out ToggleText);
GameObject toggleObj = UIFactory.CreateToggle(horiGroup, "Toggle", out Toggle, out ToggleText);
UIFactory.SetLayoutElement(toggleObj, minWidth: 70, minHeight: 25, flexibleWidth: 0, flexibleHeight: 0);
ToggleText.color = SignatureHighlighter.KeywordBlue;
Toggle.onValueChanged.AddListener(ToggleClicked);
@ -77,7 +72,7 @@ namespace UnityExplorer.CacheObject.Views
SubContentHolder.SetActive(false);
// Bottom separator
var separator = UIFactory.CreateUIObject("BottomSeperator", UIRoot);
GameObject separator = UIFactory.CreateUIObject("BottomSeperator", UIRoot);
UIFactory.SetLayoutElement(separator, minHeight: 1, flexibleHeight: 0, flexibleWidth: 9999);
separator.AddComponent<Image>().color = Color.black;

View File

@ -1,13 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.CacheObject.IValues;
using UnityExplorer.Inspectors;
using UnityExplorer.UI;
using UnityExplorer.UI.Widgets;
using UniverseLib.UI;
using UniverseLib.UI.Models;
@ -24,8 +17,8 @@ namespace UnityExplorer.CacheObject.Views
public InputFieldRef KeyInputField;
public Text KeyInputTypeLabel;
public static Color EvenColor = new Color(0.07f, 0.07f, 0.07f);
public static Color OddColor = new Color(0.063f, 0.063f, 0.063f);
public static Color EvenColor = new(0.07f, 0.07f, 0.07f);
public static Color OddColor = new(0.063f, 0.063f, 0.063f);
public int AdjustedWidth => (int)Rect.rect.width - 70;
@ -40,7 +33,7 @@ namespace UnityExplorer.CacheObject.Views
public override GameObject CreateContent(GameObject parent)
{
var root = base.CreateContent(parent);
GameObject root = base.CreateContent(parent);
Image = root.AddComponent<Image>();
@ -53,7 +46,7 @@ namespace UnityExplorer.CacheObject.Views
this.RightGroupLayout.minWidth = AdjustedWidth * 0.55f;
// Key area
var keyGroup = UIFactory.CreateUIObject("KeyHolder", root.transform.Find("HoriGroup").gameObject);
GameObject keyGroup = UIFactory.CreateUIObject("KeyHolder", root.transform.Find("HoriGroup").gameObject);
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(keyGroup, false, false, true, true, 2, 0, 0, 4, 4, childAlignment: TextAnchor.MiddleLeft);
KeyGroupLayout = UIFactory.SetLayoutElement(keyGroup, minHeight: 30, minWidth: (int)(AdjustedWidth * 0.44f), flexibleWidth: 0);

View File

@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.CacheObject.IValues;
@ -13,12 +9,12 @@ namespace UnityExplorer.CacheObject.Views
public Image Image { get; private set; }
public InteractiveList ListOwner => Occupant.Owner as InteractiveList;
public static Color EvenColor = new Color(0.12f, 0.12f, 0.12f);
public static Color OddColor = new Color(0.1f, 0.1f, 0.1f);
public static Color EvenColor = new(0.12f, 0.12f, 0.12f);
public static Color OddColor = new(0.1f, 0.1f, 0.1f);
public override GameObject CreateContent(GameObject parent)
{
var root = base.CreateContent(parent);
GameObject root = base.CreateContent(parent);
Image = root.AddComponent<Image>();

View File

@ -1,11 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.UI;
using UnityExplorer.UI.Widgets;
using UniverseLib.UI;
using UniverseLib.UI.Models;

View File

@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.UI.Panels;
using UniverseLib;
@ -116,7 +112,7 @@ namespace UnityExplorer.CacheObject.Views
UIFactory.SetLayoutElement(UIRoot, minWidth: 100, flexibleWidth: 9999, minHeight: 30, flexibleHeight: 600);
UIRoot.AddComponent<ContentSizeFitter>().verticalFit = ContentSizeFitter.FitMode.PreferredSize;
var horiRow = UIFactory.CreateUIObject("HoriGroup", UIRoot);
GameObject horiRow = UIFactory.CreateUIObject("HoriGroup", UIRoot);
UIFactory.SetLayoutElement(horiRow, minHeight: 29, flexibleHeight: 150, flexibleWidth: 9999);
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(horiRow, false, false, true, true, 5, 2, childAlignment: TextAnchor.UpperLeft);
horiRow.AddComponent<ContentSizeFitter>().verticalFit = ContentSizeFitter.FitMode.PreferredSize;
@ -129,7 +125,7 @@ namespace UnityExplorer.CacheObject.Views
UIFactory.SetLayoutGroup<VerticalLayoutGroup>(NameLabel.gameObject, true, true, true, true);
HiddenNameLabel = UIFactory.CreateInputField(NameLabel.gameObject, "HiddenNameLabel", "");
var hiddenRect = HiddenNameLabel.Component.GetComponent<RectTransform>();
RectTransform hiddenRect = HiddenNameLabel.Component.GetComponent<RectTransform>();
hiddenRect.anchorMin = Vector2.zero;
hiddenRect.anchorMax = Vector2.one;
HiddenNameLabel.Component.readOnly = true;
@ -150,7 +146,7 @@ namespace UnityExplorer.CacheObject.Views
// Right horizontal group
var rightHoriGroup = UIFactory.CreateUIObject("RightHoriGroup", RightGroupContent);
GameObject rightHoriGroup = UIFactory.CreateUIObject("RightHoriGroup", RightGroupContent);
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(rightHoriGroup, false, false, true, true, 4, childAlignment: TextAnchor.UpperLeft);
UIFactory.SetLayoutElement(rightHoriGroup, minHeight: 25, minWidth: 200, flexibleWidth: 9999, flexibleHeight: 800);
@ -166,7 +162,7 @@ namespace UnityExplorer.CacheObject.Views
// Bool and number value interaction
var toggleObj = UIFactory.CreateToggle(rightHoriGroup, "Toggle", out Toggle, out ToggleText);
GameObject toggleObj = UIFactory.CreateToggle(rightHoriGroup, "Toggle", out Toggle, out ToggleText);
UIFactory.SetLayoutElement(toggleObj, minWidth: 70, minHeight: 25, flexibleWidth: 0, flexibleHeight: 0);
ToggleText.color = SignatureHighlighter.KeywordBlue;
Toggle.onValueChanged.AddListener(ToggleClicked);
@ -194,8 +190,8 @@ namespace UnityExplorer.CacheObject.Views
// Copy and Paste buttons
var buttonHolder = UIFactory.CreateHorizontalGroup(rightHoriGroup, "CopyPasteButtons", false, false, true, true, 4,
bgColor: new(1,1,1,0), childAlignment: TextAnchor.MiddleLeft);
GameObject buttonHolder = UIFactory.CreateHorizontalGroup(rightHoriGroup, "CopyPasteButtons", false, false, true, true, 4,
bgColor: new(1, 1, 1, 0), childAlignment: TextAnchor.MiddleLeft);
UIFactory.SetLayoutElement(buttonHolder, minWidth: 60, flexibleWidth: 0);
CopyButton = UIFactory.CreateButton(buttonHolder, "CopyButton", "Copy", new Color(0.13f, 0.13f, 0.13f, 1f));
@ -219,7 +215,7 @@ namespace UnityExplorer.CacheObject.Views
SubContentHolder.SetActive(false);
// Bottom separator
var separator = UIFactory.CreateUIObject("BottomSeperator", UIRoot);
GameObject separator = UIFactory.CreateUIObject("BottomSeperator", UIRoot);
UIFactory.SetLayoutElement(separator, minHeight: 1, flexibleHeight: 0, flexibleWidth: 9999);
separator.AddComponent<Image>().color = Color.black;

View File

@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace UnityExplorer.Config
{

View File

@ -1,9 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace UnityExplorer.Config
namespace UnityExplorer.Config
{
public abstract class ConfigHandler
{

View File

@ -1,9 +1,5 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityExplorer.UI;
@ -81,6 +77,10 @@ namespace UnityExplorer.Config
"The key to enable or disable UnityExplorer's menu and features.",
KeyCode.F7);
Hide_On_Startup = new ConfigElement<bool>("Hide On Startup",
"Should UnityExplorer be hidden on startup?",
false);
Target_Display = new ConfigElement<int>("Target Display",
"The monitor index for UnityExplorer to use, if you have multiple. 0 is the default display, 1 is secondary, etc. " +
"Restart recommended when changing this setting. Make sure your extra monitors are the same resolution as your primary monitor.",
@ -90,16 +90,12 @@ namespace UnityExplorer.Config
"The vertical anchor of the main UnityExplorer Navbar, in case you want to move it.",
UIManager.VerticalAnchor.Top);
Hide_On_Startup = new ConfigElement<bool>("Hide On Startup",
"Should UnityExplorer be hidden on startup?",
false);
World_MouseInspect_Keybind = new("World Mouse-Inspect Keybind",
"Optional keybind to being a World-mode Mouse Inspect.",
KeyCode.None);
UI_MouseInspect_Keybind = new("UI Mouse-Inspect Keybind",
"Optional keybind to begin a UI_mode Mouse Inspect.",
UI_MouseInspect_Keybind = new("UI Mouse-Inspect Keybind",
"Optional keybind to begin a UI-mode Mouse Inspect.",
KeyCode.None);
Force_Unlock_Mouse = new ConfigElement<bool>("Force Unlock Mouse",

View File

@ -1,12 +1,9 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityExplorer.UI;
using Tomlet;
using Tomlet.Models;
using UnityExplorer.UI;
namespace UnityExplorer.Config
{
@ -49,9 +46,12 @@ namespace UnityExplorer.Config
return false;
TomlDocument document = TomlParser.ParseFile(CONFIG_PATH);
foreach (var key in document.Keys)
foreach (string key in document.Keys)
{
var panelKey = (UIManager.Panels)Enum.Parse(typeof(UIManager.Panels), key);
if (!Enum.IsDefined(typeof(UIManager.Panels), key))
continue;
UIManager.Panels panelKey = (UIManager.Panels)Enum.Parse(typeof(UIManager.Panels), key);
ConfigManager.GetPanelSaveData(panelKey).Value = document.GetString(key);
}
@ -69,8 +69,8 @@ namespace UnityExplorer.Config
if (UIManager.Initializing)
return;
var tomlDocument = TomlDocument.CreateEmpty();
foreach (var entry in ConfigManager.InternalConfigs)
TomlDocument tomlDocument = TomlDocument.CreateEmpty();
foreach (KeyValuePair<string, IConfigElement> entry in ConfigManager.InternalConfigs)
tomlDocument.Put(entry.Key, entry.Value.BoxedValue as string, false);
File.WriteAllText(CONFIG_PATH, tomlDocument.SerializedValue);

View File

@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine;
#if CPP
using UnhollowerRuntimeLib;
#endif
@ -14,7 +10,7 @@ namespace UnityExplorer
internal static ExplorerBehaviour Instance { get; private set; }
#if CPP
public ExplorerBehaviour(IntPtr ptr) : base(ptr) { }
public ExplorerBehaviour(System.IntPtr ptr) : base(ptr) { }
#endif
internal static void Setup()

View File

@ -1,7 +1,6 @@
using System;
using System.IO;
using UnityEngine;
using UnityExplorer.CacheObject;
using UnityExplorer.Config;
using UnityExplorer.ObjectExplorer;
using UnityExplorer.Runtime;
@ -15,7 +14,7 @@ namespace UnityExplorer
public static class ExplorerCore
{
public const string NAME = "UnityExplorer";
public const string VERSION = "4.7.1";
public const string VERSION = "4.7.4";
public const string AUTHOR = "Sinai";
public const string GUID = "com.sinai.unityexplorer";
@ -58,8 +57,6 @@ namespace UnityExplorer
// Default delay is 1 second which is usually enough.
static void LateInit()
{
Log($"Setting up late core features...");
SceneHandler.Init();
Log($"Creating UI...");
@ -67,6 +64,8 @@ namespace UnityExplorer
UIManager.InitUI();
Log($"{NAME} {VERSION} ({Universe.Context}) initialized.");
// InspectorManager.Inspect(typeof(Tests.TestClass));
}
internal static void Update()
@ -76,60 +75,6 @@ namespace UnityExplorer
UIManager.ShowMenu = !UIManager.ShowMenu;
}
// Can be removed eventually. For migration from <4.7.0
static void CheckLegacyExplorerFolder()
{
string legacyPath = Path.Combine(Loader.ExplorerFolderDestination, "UnityExplorer");
if (Directory.Exists(legacyPath))
{
LogWarning($"Attempting to migrate old 'UnityExplorer/' folder to 'sinai-dev-UnityExplorer/'...");
// If new folder doesn't exist yet, let's just use Move().
if (!Directory.Exists(ExplorerFolder))
{
try
{
Directory.Move(legacyPath, ExplorerFolder);
Log("Migrated successfully.");
}
catch (Exception ex)
{
LogWarning($"Exception migrating folder: {ex}");
}
}
else // We have to merge
{
try
{
CopyAll(new(legacyPath), new(ExplorerFolder));
Directory.Delete(legacyPath, true);
Log("Migrated successfully.");
}
catch (Exception ex)
{
LogWarning($"Exception migrating folder: {ex}");
}
}
}
}
public static void CopyAll(DirectoryInfo source, DirectoryInfo target)
{
// Check if the target directory exists, if not, create it.
if (!Directory.Exists(target.FullName))
Directory.CreateDirectory(target.FullName);
// Copy each file into it's new directory.
foreach (FileInfo fi in source.GetFiles())
fi.MoveTo(Path.Combine(target.ToString(), fi.Name));
// Copy each subdirectory using recursion.
foreach (DirectoryInfo diSourceSubDir in source.GetDirectories())
{
DirectoryInfo nextTargetSubDir = target.CreateSubdirectory(diSourceSubDir.Name);
CopyAll(diSourceSubDir, nextTargetSubDir);
}
}
#region LOGGING
@ -175,5 +120,63 @@ namespace UnityExplorer
}
#endregion
#region LEGACY FOLDER MIGRATION
// Can be removed eventually. For migration from <4.7.0
static void CheckLegacyExplorerFolder()
{
string legacyPath = Path.Combine(Loader.ExplorerFolderDestination, "UnityExplorer");
if (Directory.Exists(legacyPath))
{
LogWarning($"Attempting to migrate old 'UnityExplorer/' folder to 'sinai-dev-UnityExplorer/'...");
// If new folder doesn't exist yet, let's just use Move().
if (!Directory.Exists(ExplorerFolder))
{
try
{
Directory.Move(legacyPath, ExplorerFolder);
Log("Migrated successfully.");
}
catch (Exception ex)
{
LogWarning($"Exception migrating folder: {ex}");
}
}
else // We have to merge
{
try
{
CopyAll(new(legacyPath), new(ExplorerFolder));
Directory.Delete(legacyPath, true);
Log("Migrated successfully.");
}
catch (Exception ex)
{
LogWarning($"Exception migrating folder: {ex}");
}
}
}
}
public static void CopyAll(DirectoryInfo source, DirectoryInfo target)
{
Directory.CreateDirectory(target.FullName);
// Copy each file into it's new directory.
foreach (FileInfo fi in source.GetFiles())
fi.MoveTo(Path.Combine(target.ToString(), fi.Name));
// Copy each subdirectory using recursion.
foreach (DirectoryInfo diSourceSubDir in source.GetDirectories())
{
DirectoryInfo nextTargetSubDir = target.CreateSubdirectory(diSourceSubDir.Name);
CopyAll(diSourceSubDir, nextTargetSubDir);
}
}
#endregion
}
}

View File

@ -1,14 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.UI;
using UnityExplorer.UI.Widgets;
using UniverseLib.UI;
using UniverseLib.UI.Models;
using UniverseLib.UI.Widgets;
using UniverseLib.UI.Widgets.ScrollView;
namespace UnityExplorer.Hooks

View File

@ -1,12 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine;
using UnityEngine.UI;
using UniverseLib.UI;
using UniverseLib.UI.Models;
using UniverseLib.UI.Widgets;
using UniverseLib.UI.Widgets.ScrollView;
namespace UnityExplorer.Hooks

View File

@ -1,11 +1,10 @@
using System;
using System.CodeDom.Compiler;
using HarmonyLib;
using Mono.CSharp;
using System;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using HarmonyLib;
using Mono.CSharp;
using UnityExplorer.CSConsole;
using UniverseLib;
@ -66,7 +65,7 @@ namespace UnityExplorer.Hooks
// Dynamically compile the patch method
var codeBuilder = new StringBuilder();
StringBuilder codeBuilder = new();
codeBuilder.AppendLine($"public class DynamicPatch_{DateTime.Now.Ticks}");
codeBuilder.AppendLine("{");
@ -80,11 +79,11 @@ namespace UnityExplorer.Hooks
// TODO: Publicize MCS to avoid this reflection
// Get the most recent Patch type in the source file
var typeContainer = ((CompilationSourceFile)fi_sourceFile.GetValue(scriptEvaluator))
TypeContainer typeContainer = ((CompilationSourceFile)fi_sourceFile.GetValue(scriptEvaluator))
.Containers
.Last(it => it.MemberName.Name.StartsWith("DynamicPatch_"));
// Get the TypeSpec from the TypeDefinition, then get its "MetaInfo" (System.Type)
var patchClass = ((TypeSpec)pi_Definition.GetValue((Class)typeContainer, null)).GetMetaInfo();
Type patchClass = ((TypeSpec)pi_Definition.GetValue((Class)typeContainer, null)).GetMetaInfo();
// Create the harmony patches as defined
@ -115,7 +114,7 @@ namespace UnityExplorer.Hooks
private string GenerateDefaultPatchSourceCode(MethodInfo targetMethod)
{
var codeBuilder = new StringBuilder();
StringBuilder codeBuilder = new();
// Arguments
codeBuilder.Append("public static void Postfix(System.Reflection.MethodBase __originalMethod");
@ -126,10 +125,10 @@ namespace UnityExplorer.Hooks
if (targetMethod.ReturnType != typeof(void))
codeBuilder.Append($", {targetMethod.ReturnType.FullName} __result");
var parameters = targetMethod.GetParameters();
ParameterInfo[] parameters = targetMethod.GetParameters();
int paramIdx = 0;
foreach (var param in parameters)
foreach (ParameterInfo param in parameters)
{
codeBuilder.Append($", {param.ParameterType.FullDescription().Replace("&", "")} __{paramIdx}");
paramIdx++;
@ -145,14 +144,14 @@ namespace UnityExplorer.Hooks
// Log message
var logMessage = new StringBuilder();
StringBuilder logMessage = new();
logMessage.Append($"Patch called: {shortSignature}\\n");
if (!targetMethod.IsStatic)
logMessage.Append("__instance: {__instance.ToString()}\\n");
paramIdx = 0;
foreach (var param in parameters)
foreach (ParameterInfo param in parameters)
{
logMessage.Append($"Parameter {paramIdx} {param.Name}: ");
Type pType = param.ParameterType;

View File

@ -1,18 +1,14 @@
using System;
using HarmonyLib;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Reflection;
using System.Text;
using HarmonyLib;
using UnityEngine;
using UnityExplorer.Runtime;
using UnityExplorer.CSConsole;
using UnityExplorer.Runtime;
using UnityExplorer.UI;
using UnityExplorer.UI.Panels;
using UnityExplorer.UI.Widgets;
using UniverseLib;
using UniverseLib.UI.Widgets;
using UniverseLib.UI.Widgets.ScrollView;
using UniverseLib.Utility;
@ -32,22 +28,22 @@ namespace UnityExplorer.Hooks
public int ItemCount => isAddingMethods ? filteredEligableMethods.Count : currentHooks.Count;
// current hooks
private readonly HashSet<string> hookedSignatures = new HashSet<string>();
private readonly OrderedDictionary currentHooks = new OrderedDictionary();
private readonly HashSet<string> hookedSignatures = new();
private readonly OrderedDictionary currentHooks = new();
// adding hooks
private readonly List<MethodInfo> currentAddEligableMethods = new List<MethodInfo>();
private readonly List<MethodInfo> filteredEligableMethods = new List<MethodInfo>();
private readonly List<MethodInfo> currentAddEligableMethods = new();
private readonly List<MethodInfo> filteredEligableMethods = new();
// hook editor
private readonly LexerBuilder Lexer = new LexerBuilder();
private readonly LexerBuilder Lexer = new();
private HookInstance currentEditedHook;
// ~~~~~~~~~~~ Main Current Hooks window ~~~~~~~~~~~
public void EnableOrDisableHookClicked(int index)
{
var hook = (HookInstance)currentHooks[index];
HookInstance hook = (HookInstance)currentHooks[index];
hook.TogglePatch();
Panel.HooksScrollPool.Refresh(true, false);
@ -55,7 +51,7 @@ namespace UnityExplorer.Hooks
public void DeleteHookClicked(int index)
{
var hook = (HookInstance)currentHooks[index];
HookInstance hook = (HookInstance)currentHooks[index];
hook.Unpatch();
currentHooks.RemoveAt(index);
hookedSignatures.Remove(hook.TargetMethod.FullDescription());
@ -66,7 +62,7 @@ namespace UnityExplorer.Hooks
public void EditPatchClicked(int index)
{
Panel.SetPage(HookManagerPanel.Pages.HookSourceEditor);
var hook = (HookInstance)currentHooks[index];
HookInstance hook = (HookInstance)currentHooks[index];
currentEditedHook = hook;
Panel.EditorInput.Text = hook.PatchSourceCode;
}
@ -84,7 +80,7 @@ namespace UnityExplorer.Hooks
}
cell.CurrentDisplayedIndex = index;
var hook = (HookInstance)this.currentHooks[index];
HookInstance hook = (HookInstance)this.currentHooks[index];
cell.MethodNameLabel.text = SignatureHighlighter.HighlightMethod(hook.TargetMethod);
@ -97,7 +93,7 @@ namespace UnityExplorer.Hooks
public void OnClassSelectedForHooks(string typeFullName)
{
var type = ReflectionUtility.GetTypeByName(typeFullName);
Type type = ReflectionUtility.GetTypeByName(typeFullName);
if (type == null)
{
ExplorerCore.LogWarning($"Could not find any type by name {typeFullName}!");
@ -109,7 +105,7 @@ namespace UnityExplorer.Hooks
Panel.ResetMethodFilter();
filteredEligableMethods.Clear();
currentAddEligableMethods.Clear();
foreach (var method in type.GetMethods(ReflectionUtility.FLAGS))
foreach (MethodInfo method in type.GetMethods(ReflectionUtility.FLAGS))
{
if (method.IsGenericMethod || UERuntimeHelper.IsBlacklisted(method))
continue;
@ -140,11 +136,11 @@ namespace UnityExplorer.Hooks
public void AddHook(MethodInfo method)
{
var sig = method.FullDescription();
string sig = method.FullDescription();
if (hookedSignatures.Contains(sig))
return;
var hook = new HookInstance(method);
HookInstance hook = new(method);
if (hook.Enabled)
{
hookedSignatures.Add(sig);
@ -160,7 +156,7 @@ namespace UnityExplorer.Hooks
filteredEligableMethods.AddRange(currentAddEligableMethods);
else
{
foreach (var method in currentAddEligableMethods)
foreach (MethodInfo method in currentAddEligableMethods)
{
if (method.Name.ContainsIgnoreCase(input))
filteredEligableMethods.Add(method);
@ -183,11 +179,11 @@ namespace UnityExplorer.Hooks
}
cell.CurrentDisplayedIndex = index;
var method = this.filteredEligableMethods[index];
MethodInfo method = this.filteredEligableMethods[index];
cell.MethodNameLabel.text = SignatureHighlighter.HighlightMethod(method);
var sig = method.FullDescription();
string sig = method.FullDescription();
if (hookedSignatures.Contains(sig))
{
cell.HookButton.Component.gameObject.SetActive(false);
@ -216,7 +212,7 @@ namespace UnityExplorer.Hooks
public void EditorInputSave()
{
var input = Panel.EditorInput.Text;
string input = Panel.EditorInput.Text;
bool wasEnabled = currentEditedHook.Enabled;
if (currentEditedHook.CompileAndGenerateProcessor(input))
{

View File

@ -2,18 +2,15 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
using UniverseLib.Input;
using UnityExplorer.UI;
using UniverseLib.UI.Models;
using UnityExplorer.UI.Panels;
using UnityExplorer.UI.Widgets;
using UnityExplorer.UI.Widgets.AutoComplete;
using UniverseLib.UI.Widgets;
using UniverseLib.UI;
using UniverseLib;
using UniverseLib.UI;
using UniverseLib.UI.Models;
using UniverseLib.UI.Widgets;
using UniverseLib.UI.Widgets.ScrollView;
using UniverseLib.Utility;
@ -29,7 +26,7 @@ namespace UnityExplorer.Inspectors
public TransformTree TransformTree;
private ScrollPool<TransformCell> transformScroll;
private readonly List<GameObject> cachedChildren = new List<GameObject>();
private readonly List<GameObject> cachedChildren = new();
public ComponentList ComponentList;
private ScrollPool<ComponentCell> componentScroll;
@ -77,7 +74,7 @@ namespace UnityExplorer.Inspectors
InspectorManager.ReleaseInspector(this);
}
public void ChangeTarget(GameObject newTarget)
public void OnTransformCellClicked(GameObject newTarget)
{
this.Target = newTarget;
GOControls.UpdateGameObjectInfo(true, true);
@ -127,10 +124,10 @@ namespace UnityExplorer.Inspectors
return cachedChildren;
}
private readonly List<Component> componentEntries = new List<Component>();
private readonly HashSet<int> compInstanceIDs = new HashSet<int>();
private readonly List<Behaviour> behaviourEntries = new List<Behaviour>();
private readonly List<bool> behaviourEnabledStates = new List<bool>();
private readonly List<Component> componentEntries = new();
private readonly HashSet<int> compInstanceIDs = new();
private readonly List<Behaviour> behaviourEntries = new();
private readonly List<bool> behaviourEnabledStates = new();
// ComponentList.GetRootEntriesMethod
private List<Component> GetComponentEntries() => GOTarget ? componentEntries : Enumerable.Empty<Component>().ToList();
@ -149,13 +146,13 @@ namespace UnityExplorer.Inspectors
}
// Check if we actually need to refresh the component cells or not.
var comps = GOTarget.GetComponents<Component>();
var behaviours = GOTarget.GetComponents<Behaviour>();
IEnumerable<Component> comps = GOTarget.GetComponents<Component>();
IEnumerable<Behaviour> behaviours = GOTarget.GetComponents<Behaviour>();
bool needRefresh = false;
int count = 0;
foreach (var comp in comps)
foreach (Component comp in comps)
{
if (!comp)
continue;
@ -173,7 +170,7 @@ namespace UnityExplorer.Inspectors
else
{
count = 0;
foreach (var behaviour in behaviours)
foreach (Behaviour behaviour in behaviours)
{
if (!behaviour)
continue;
@ -194,19 +191,35 @@ namespace UnityExplorer.Inspectors
componentEntries.Clear();
compInstanceIDs.Clear();
foreach (var comp in comps)
foreach (Component comp in comps)
{
if (!comp) continue;
if (!comp)
continue;
componentEntries.Add(comp);
compInstanceIDs.Add(comp.GetInstanceID());
}
behaviourEntries.Clear();
behaviourEnabledStates.Clear();
foreach (var behaviour in behaviours)
foreach (Behaviour behaviour in behaviours)
{
if (!behaviour) continue;
behaviourEntries.Add(behaviour);
if (!behaviour)
continue;
// Don't ask me how, but in some games this can be true for certain components.
// They get picked up from GetComponents<Behaviour>, but they are not actually Behaviour...?
if (!typeof(Behaviour).IsAssignableFrom(behaviour.GetType()))
continue;
try
{
behaviourEntries.Add(behaviour);
}
catch (Exception ex)
{
ExplorerCore.LogWarning(ex);
}
behaviourEnabledStates.Add(behaviour.enabled);
}
@ -217,7 +230,7 @@ namespace UnityExplorer.Inspectors
private void OnAddChildClicked(string input)
{
var newObject = new GameObject(input);
GameObject newObject = new(input);
newObject.transform.parent = GOTarget.transform;
TransformTree.RefreshData(true, false, true, false);
@ -250,7 +263,7 @@ namespace UnityExplorer.Inspectors
UIRoot = UIFactory.CreateVerticalGroup(parent, "GameObjectInspector", true, false, true, true, 5,
new Vector4(4, 4, 4, 4), new Color(0.065f, 0.065f, 0.065f));
var scrollObj = UIFactory.CreateScrollView(UIRoot, "GameObjectInspector", out Content, out var scrollbar,
GameObject scrollObj = UIFactory.CreateScrollView(UIRoot, "GameObjectInspector", out Content, out AutoSliderScrollbar scrollbar,
new Color(0.065f, 0.065f, 0.065f));
UIFactory.SetLayoutElement(scrollObj, minHeight: 250, preferredHeight: 300, flexibleHeight: 0, flexibleWidth: 9999);
@ -268,27 +281,27 @@ namespace UnityExplorer.Inspectors
private void ConstructLists()
{
var listHolder = UIFactory.CreateUIObject("ListHolders", UIRoot);
GameObject listHolder = UIFactory.CreateUIObject("ListHolders", UIRoot);
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(listHolder, false, true, true, true, 8, 2, 2, 2, 2);
UIFactory.SetLayoutElement(listHolder, minHeight: 150, flexibleWidth: 9999, flexibleHeight: 9999);
// Left group (Children)
var leftGroup = UIFactory.CreateUIObject("ChildrenGroup", listHolder);
GameObject leftGroup = UIFactory.CreateUIObject("ChildrenGroup", listHolder);
UIFactory.SetLayoutElement(leftGroup, flexibleWidth: 9999, flexibleHeight: 9999);
UIFactory.SetLayoutGroup<VerticalLayoutGroup>(leftGroup, false, false, true, true, 2);
var childrenLabel = UIFactory.CreateLabel(leftGroup, "ChildListTitle", "Children", TextAnchor.MiddleCenter, default, false, 16);
Text childrenLabel = UIFactory.CreateLabel(leftGroup, "ChildListTitle", "Children", TextAnchor.MiddleCenter, default, false, 16);
UIFactory.SetLayoutElement(childrenLabel.gameObject, flexibleWidth: 9999);
// Add Child
var addChildRow = UIFactory.CreateUIObject("AddChildRow", leftGroup);
GameObject addChildRow = UIFactory.CreateUIObject("AddChildRow", leftGroup);
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(addChildRow, false, false, true, true, 2);
addChildInput = UIFactory.CreateInputField(addChildRow, "AddChildInput", "Enter a name...");
UIFactory.SetLayoutElement(addChildInput.Component.gameObject, minHeight: 25, preferredWidth: 9999);
var addChildButton = UIFactory.CreateButton(addChildRow, "AddChildButton", "Add Child");
ButtonRef addChildButton = UIFactory.CreateButton(addChildRow, "AddChildButton", "Add Child");
UIFactory.SetLayoutElement(addChildButton.Component.gameObject, minHeight: 25, minWidth: 80);
addChildButton.OnClick += () => { OnAddChildClicked(addChildInput.Text); };
@ -296,30 +309,26 @@ namespace UnityExplorer.Inspectors
transformScroll = UIFactory.CreateScrollPool<TransformCell>(leftGroup, "TransformTree", out GameObject transformObj,
out GameObject transformContent, new Color(0.11f, 0.11f, 0.11f));
UIFactory.SetLayoutElement(transformObj, flexibleHeight: 9999);
UIFactory.SetLayoutElement(transformContent, flexibleHeight: 9999);
TransformTree = new TransformTree(transformScroll, GetTransformEntries);
TransformTree.Init();
TransformTree.OnClickOverrideHandler = ChangeTarget;
TransformTree = new TransformTree(transformScroll, GetTransformEntries, OnTransformCellClicked);
// Right group (Components)
var rightGroup = UIFactory.CreateUIObject("ComponentGroup", listHolder);
GameObject rightGroup = UIFactory.CreateUIObject("ComponentGroup", listHolder);
UIFactory.SetLayoutElement(rightGroup, flexibleWidth: 9999, flexibleHeight: 9999);
UIFactory.SetLayoutGroup<VerticalLayoutGroup>(rightGroup, false, false, true, true, 2);
var compLabel = UIFactory.CreateLabel(rightGroup, "CompListTitle", "Components", TextAnchor.MiddleCenter, default, false, 16);
Text compLabel = UIFactory.CreateLabel(rightGroup, "CompListTitle", "Components", TextAnchor.MiddleCenter, default, false, 16);
UIFactory.SetLayoutElement(compLabel.gameObject, flexibleWidth: 9999);
// Add Comp
var addCompRow = UIFactory.CreateUIObject("AddCompRow", rightGroup);
GameObject addCompRow = UIFactory.CreateUIObject("AddCompRow", rightGroup);
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(addCompRow, false, false, true, true, 2);
addCompInput = UIFactory.CreateInputField(addCompRow, "AddCompInput", "Enter a Component type...");
UIFactory.SetLayoutElement(addCompInput.Component.gameObject, minHeight: 25, preferredWidth: 9999);
var addCompButton = UIFactory.CreateButton(addCompRow, "AddCompButton", "Add Comp");
ButtonRef addCompButton = UIFactory.CreateButton(addCompRow, "AddCompButton", "Add Comp");
UIFactory.SetLayoutElement(addCompButton.Component.gameObject, minHeight: 25, minWidth: 80);
addCompButton.OnClick += () => { OnAddComponentClicked(addCompInput.Text); };
@ -333,8 +342,10 @@ namespace UnityExplorer.Inspectors
UIFactory.SetLayoutElement(compObj, flexibleHeight: 9999);
UIFactory.SetLayoutElement(compContent, flexibleHeight: 9999);
ComponentList = new ComponentList(componentScroll, GetComponentEntries);
ComponentList.Parent = this;
ComponentList = new ComponentList(componentScroll, GetComponentEntries)
{
Parent = this
};
componentScroll.Initialize(ComponentList);
}

View File

@ -1,13 +1,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
using UniverseLib;
using UniverseLib.UI;
using UniverseLib.UI.Models;
using UniverseLib.UI.Widgets.ButtonList;
using UniverseLib;
namespace UnityExplorer.Inspectors
{
@ -31,7 +28,7 @@ namespace UnityExplorer.Inspectors
public override GameObject CreateContent(GameObject parent)
{
var root = base.CreateContent(parent);
GameObject root = base.CreateContent(parent);
// Add mask to button so text doesnt overlap on Close button
//this.Button.Component.gameObject.AddComponent<Mask>().showMaskGraphic = true;
@ -39,7 +36,7 @@ namespace UnityExplorer.Inspectors
// Behaviour toggle
var toggleObj = UIFactory.CreateToggle(UIRoot, "BehaviourToggle", out BehaviourToggle, out var behavText);
GameObject toggleObj = UIFactory.CreateToggle(UIRoot, "BehaviourToggle", out BehaviourToggle, out Text behavText);
UIFactory.SetLayoutElement(toggleObj, minHeight: 25, minWidth: 25);
BehaviourToggle.onValueChanged.AddListener(BehaviourToggled);
// put at first object

View File

@ -1,7 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UniverseLib;
using UniverseLib.UI.Widgets.ButtonList;
@ -45,12 +43,12 @@ namespace UnityExplorer.Inspectors
private void OnComponentClicked(int index)
{
var entries = GetEntries();
List<Component> entries = GetEntries();
if (index < 0 || index >= entries.Count)
return;
var comp = entries[index];
Component comp = entries[index];
if (comp)
InspectorManager.Inspect(comp);
}
@ -59,8 +57,8 @@ namespace UnityExplorer.Inspectors
{
try
{
var entries = GetEntries();
var comp = entries[index];
List<Component> entries = GetEntries();
Component comp = entries[index];
if (comp.TryCast<Behaviour>() is Behaviour behaviour)
behaviour.enabled = value;
@ -75,8 +73,8 @@ namespace UnityExplorer.Inspectors
{
try
{
var entries = GetEntries();
var comp = entries[index];
List<Component> entries = GetEntries();
Component comp = entries[index];
GameObject.DestroyImmediate(comp);
@ -88,16 +86,16 @@ namespace UnityExplorer.Inspectors
}
}
private static readonly Dictionary<string, string> compToStringCache = new Dictionary<string, string>();
private static readonly Dictionary<string, string> compToStringCache = new();
// Called from ButtonListHandler.SetCell, will be valid
private void SetComponentCell(ComponentCell cell, int index)
{
var entries = GetEntries();
List<Component> entries = GetEntries();
cell.Enable();
var comp = entries[index];
var type = comp.GetActualType();
Component comp = entries[index];
Type type = comp.GetActualType();
if (!compToStringCache.ContainsKey(type.AssemblyQualifiedName))
compToStringCache.Add(type.AssemblyQualifiedName, SignatureHighlighter.Parse(type, true));

View File

@ -1,14 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
using UniverseLib.Input;
using UnityExplorer.UI;
using UniverseLib.UI;
using UniverseLib;
using UnityExplorer.UI.Panels;
using UniverseLib;
using UniverseLib.Input;
using UniverseLib.UI;
using UniverseLib.UI.Models;
using UniverseLib.Utility;
@ -149,7 +148,7 @@ namespace UnityExplorer.Inspectors
{
if (this.GOTarget && this.GOTarget.transform.parent)
{
Parent.ChangeTarget(this.GOTarget.transform.parent.gameObject);
Parent.OnTransformCellClicked(this.GOTarget.transform.parent.gameObject);
}
}
@ -176,14 +175,14 @@ namespace UnityExplorer.Inspectors
else
{
// look for inactive objects
var name = input.Split('/').Last();
var allObjects = RuntimeHelper.FindObjectsOfTypeAll(typeof(GameObject));
var shortList = new List<GameObject>();
foreach (var obj in allObjects)
string name = input.Split('/').Last();
UnityEngine.Object[] allObjects = RuntimeHelper.FindObjectsOfTypeAll(typeof(GameObject));
List<GameObject> shortList = new();
foreach (UnityEngine.Object obj in allObjects)
if (obj.name == name) shortList.Add(obj.TryCast<GameObject>());
foreach (var go in shortList)
foreach (GameObject go in shortList)
{
var path = go.transform.GetTransformPath(true);
string path = go.transform.GetTransformPath(true);
if (path.EndsWith("/"))
path = path.Remove(path.Length - 1);
if (path == input)
@ -245,7 +244,7 @@ namespace UnityExplorer.Inspectors
private void OnExploreButtonClicked()
{
var panel = UIManager.GetPanel<UI.Panels.ObjectExplorerPanel>(UIManager.Panels.ObjectExplorer);
ObjectExplorerPanel panel = UIManager.GetPanel<UI.Panels.ObjectExplorerPanel>(UIManager.Panels.ObjectExplorer);
panel.SceneExplorer.JumpToTransform(this.Parent.GOTarget.transform);
}
@ -259,7 +258,7 @@ namespace UnityExplorer.Inspectors
{
try
{
var enumVal = hideFlagsValues[FlagsDropdown.options[value].text];
HideFlags enumVal = hideFlagsValues[FlagsDropdown.options[value].text];
GOTarget.hideFlags = enumVal;
UpdateGameObjectInfo(false, true);
@ -278,7 +277,7 @@ namespace UnityExplorer.Inspectors
private void OnInstantiateClicked()
{
var clone = GameObject.Instantiate(this.GOTarget);
GameObject clone = GameObject.Instantiate(this.GOTarget);
InspectorManager.Inspect(clone);
}
@ -322,7 +321,7 @@ namespace UnityExplorer.Inspectors
public void UpdateTransformControlValues(bool force)
{
var transform = GOTarget.transform;
Transform transform = GOTarget.transform;
if (force || (!PositionControl.Input.Component.isFocused && lastPosValue != transform.position))
{
PositionControl.Input.Text = ParseUtility.ToStringForInput(transform.position, typeof(Vector3));
@ -404,7 +403,7 @@ namespace UnityExplorer.Inspectors
return;
}
var transform = GOTarget.transform;
Transform transform = GOTarget.transform;
Vector3 vector = Vector2.zero;
switch (currentSlidingVectorControl.parentControl.Type)
@ -453,14 +452,14 @@ namespace UnityExplorer.Inspectors
private void ConstructTopInfo()
{
var topInfoHolder = UIFactory.CreateVerticalGroup(Parent.Content, "TopInfoHolder", false, false, true, true, 3,
GameObject topInfoHolder = UIFactory.CreateVerticalGroup(Parent.Content, "TopInfoHolder", false, false, true, true, 3,
new Vector4(3, 3, 3, 3), new Color(0.1f, 0.1f, 0.1f), TextAnchor.MiddleLeft);
UIFactory.SetLayoutElement(topInfoHolder, minHeight: 100, flexibleWidth: 9999);
topInfoHolder.AddComponent<ContentSizeFitter>().verticalFit = ContentSizeFitter.FitMode.PreferredSize;
// first row (parent, path)
var firstRow = UIFactory.CreateUIObject("ParentRow", topInfoHolder);
GameObject firstRow = UIFactory.CreateUIObject("ParentRow", topInfoHolder);
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(firstRow, false, false, true, true, 5, 0, 0, 0, 0, default);
UIFactory.SetLayoutElement(firstRow, minHeight: 25, flexibleWidth: 9999);
@ -475,7 +474,7 @@ namespace UnityExplorer.Inspectors
UIFactory.SetLayoutElement(PathInput.UIRoot, minHeight: 25, minWidth: 100, flexibleWidth: 9999);
PathInput.Component.lineType = InputField.LineType.MultiLineSubmit;
var copyButton = UIFactory.CreateButton(firstRow, "CopyButton", "Copy to Clipboard", new Color(0.2f, 0.2f, 0.2f, 1));
ButtonRef copyButton = UIFactory.CreateButton(firstRow, "CopyButton", "Copy to Clipboard", new Color(0.2f, 0.2f, 0.2f, 1));
copyButton.ButtonText.color = Color.yellow;
UIFactory.SetLayoutElement(copyButton.Component.gameObject, minHeight: 25, minWidth: 120);
copyButton.OnClick += OnCopyClicked;
@ -488,10 +487,10 @@ namespace UnityExplorer.Inspectors
// Title and update row
var titleRow = UIFactory.CreateUIObject("TitleRow", topInfoHolder);
GameObject titleRow = UIFactory.CreateUIObject("TitleRow", topInfoHolder);
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(titleRow, false, false, true, true, 5);
var titleLabel = UIFactory.CreateLabel(titleRow, "Title", SignatureHighlighter.Parse(typeof(GameObject), false),
Text titleLabel = UIFactory.CreateLabel(titleRow, "Title", SignatureHighlighter.Parse(typeof(GameObject), false),
TextAnchor.MiddleLeft, fontSize: 17);
UIFactory.SetLayoutElement(titleLabel.gameObject, minHeight: 30, minWidth: 100);
@ -504,25 +503,25 @@ namespace UnityExplorer.Inspectors
// second row (toggles, instanceID, tag, buttons)
var secondRow = UIFactory.CreateUIObject("ParentRow", topInfoHolder);
GameObject secondRow = UIFactory.CreateUIObject("ParentRow", topInfoHolder);
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(secondRow, false, false, true, true, 5, 0, 0, 0, 0, default);
UIFactory.SetLayoutElement(secondRow, minHeight: 25, flexibleWidth: 9999);
// activeSelf
var activeToggleObj = UIFactory.CreateToggle(secondRow, "ActiveSelf", out ActiveSelfToggle, out ActiveSelfText);
GameObject activeToggleObj = UIFactory.CreateToggle(secondRow, "ActiveSelf", out ActiveSelfToggle, out ActiveSelfText);
UIFactory.SetLayoutElement(activeToggleObj, minHeight: 25, minWidth: 100);
ActiveSelfText.text = "ActiveSelf";
ActiveSelfToggle.onValueChanged.AddListener(OnActiveSelfToggled);
// isStatic
var isStaticObj = UIFactory.CreateToggle(secondRow, "IsStatic", out IsStaticToggle, out Text staticText);
GameObject isStaticObj = UIFactory.CreateToggle(secondRow, "IsStatic", out IsStaticToggle, out Text staticText);
UIFactory.SetLayoutElement(isStaticObj, minHeight: 25, minWidth: 80);
staticText.text = "IsStatic";
staticText.color = Color.grey;
IsStaticToggle.interactable = false;
// InstanceID
var instanceIdLabel = UIFactory.CreateLabel(secondRow, "InstanceIDLabel", "Instance ID:", TextAnchor.MiddleRight, Color.grey);
Text instanceIdLabel = UIFactory.CreateLabel(secondRow, "InstanceIDLabel", "Instance ID:", TextAnchor.MiddleRight, Color.grey);
UIFactory.SetLayoutElement(instanceIdLabel.gameObject, minHeight: 25, minWidth: 90);
InstanceIDInput = UIFactory.CreateInputField(secondRow, "InstanceIDInput", "error");
@ -531,7 +530,7 @@ namespace UnityExplorer.Inspectors
InstanceIDInput.Component.readOnly = true;
//Tag
var tagLabel = UIFactory.CreateLabel(secondRow, "TagLabel", "Tag:", TextAnchor.MiddleRight, Color.grey);
Text tagLabel = UIFactory.CreateLabel(secondRow, "TagLabel", "Tag:", TextAnchor.MiddleRight, Color.grey);
UIFactory.SetLayoutElement(tagLabel.gameObject, minHeight: 25, minWidth: 40);
TagInput = UIFactory.CreateInputField(secondRow, "TagInput", "none");
@ -540,29 +539,29 @@ namespace UnityExplorer.Inspectors
TagInput.Component.GetOnEndEdit().AddListener((string val) => { OnTagEndEdit(val); });
// Instantiate
var instantiateBtn = UIFactory.CreateButton(secondRow, "InstantiateBtn", "Instantiate", new Color(0.2f, 0.2f, 0.2f));
ButtonRef instantiateBtn = UIFactory.CreateButton(secondRow, "InstantiateBtn", "Instantiate", new Color(0.2f, 0.2f, 0.2f));
UIFactory.SetLayoutElement(instantiateBtn.Component.gameObject, minHeight: 25, minWidth: 120);
instantiateBtn.OnClick += OnInstantiateClicked;
// Destroy
var destroyBtn = UIFactory.CreateButton(secondRow, "DestroyBtn", "Destroy", new Color(0.3f, 0.2f, 0.2f));
ButtonRef destroyBtn = UIFactory.CreateButton(secondRow, "DestroyBtn", "Destroy", new Color(0.3f, 0.2f, 0.2f));
UIFactory.SetLayoutElement(destroyBtn.Component.gameObject, minHeight: 25, minWidth: 80);
destroyBtn.OnClick += OnDestroyClicked;
// third row (scene, layer, flags)
var thirdrow = UIFactory.CreateUIObject("ParentRow", topInfoHolder);
GameObject thirdrow = UIFactory.CreateUIObject("ParentRow", topInfoHolder);
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(thirdrow, false, false, true, true, 5, 0, 0, 0, 0, default);
UIFactory.SetLayoutElement(thirdrow, minHeight: 25, flexibleWidth: 9999);
// Inspect in Explorer button
var explorerBtn = UIFactory.CreateButton(thirdrow, "ExploreBtn", "Show in Explorer", new Color(0.15f, 0.15f, 0.15f));
ButtonRef explorerBtn = UIFactory.CreateButton(thirdrow, "ExploreBtn", "Show in Explorer", new Color(0.15f, 0.15f, 0.15f));
UIFactory.SetLayoutElement(explorerBtn.Component.gameObject, minHeight: 25, minWidth: 100);
explorerBtn.ButtonText.fontSize = 12;
explorerBtn.OnClick += OnExploreButtonClicked;
// Scene
var sceneLabel = UIFactory.CreateLabel(thirdrow, "SceneLabel", "Scene:", TextAnchor.MiddleLeft, Color.grey);
Text sceneLabel = UIFactory.CreateLabel(thirdrow, "SceneLabel", "Scene:", TextAnchor.MiddleLeft, Color.grey);
UIFactory.SetLayoutElement(sceneLabel.gameObject, minHeight: 25, minWidth: 50);
SceneInput = UIFactory.CreateInputField(thirdrow, "SceneInput", "untitled");
@ -571,29 +570,29 @@ namespace UnityExplorer.Inspectors
SceneInput.Component.textComponent.color = new Color(0.7f, 0.7f, 0.7f);
// Layer
var layerLabel = UIFactory.CreateLabel(thirdrow, "LayerLabel", "Layer:", TextAnchor.MiddleLeft, Color.grey);
Text layerLabel = UIFactory.CreateLabel(thirdrow, "LayerLabel", "Layer:", TextAnchor.MiddleLeft, Color.grey);
UIFactory.SetLayoutElement(layerLabel.gameObject, minHeight: 25, minWidth: 50);
var layerDrop = UIFactory.CreateDropdown(thirdrow, "LayerDropdown", out LayerDropdown, "0", 14, OnLayerDropdownChanged);
GameObject layerDrop = UIFactory.CreateDropdown(thirdrow, "LayerDropdown", out LayerDropdown, "0", 14, OnLayerDropdownChanged);
UIFactory.SetLayoutElement(layerDrop, minHeight: 25, minWidth: 110, flexibleWidth: 999);
LayerDropdown.captionText.color = SignatureHighlighter.EnumGreen;
if (layerToNames == null)
GetLayerNames();
foreach (var name in layerToNames)
foreach (string name in layerToNames)
LayerDropdown.options.Add(new Dropdown.OptionData(name));
LayerDropdown.value = 0;
LayerDropdown.RefreshShownValue();
// Flags
var flagsLabel = UIFactory.CreateLabel(thirdrow, "FlagsLabel", "Flags:", TextAnchor.MiddleRight, Color.grey);
Text flagsLabel = UIFactory.CreateLabel(thirdrow, "FlagsLabel", "Flags:", TextAnchor.MiddleRight, Color.grey);
UIFactory.SetLayoutElement(flagsLabel.gameObject, minHeight: 25, minWidth: 50);
var flagsDrop = UIFactory.CreateDropdown(thirdrow, "FlagsDropdown", out FlagsDropdown, "None", 14, OnFlagsDropdownChanged);
GameObject flagsDrop = UIFactory.CreateDropdown(thirdrow, "FlagsDropdown", out FlagsDropdown, "None", 14, OnFlagsDropdownChanged);
FlagsDropdown.captionText.color = SignatureHighlighter.EnumGreen;
UIFactory.SetLayoutElement(flagsDrop, minHeight: 25, minWidth: 135, flexibleWidth: 999);
if (hideFlagsValues == null)
GetHideFlagNames();
foreach (var name in hideFlagsValues.Keys)
foreach (string name in hideFlagsValues.Keys)
FlagsDropdown.options.Add(new Dropdown.OptionData(name));
FlagsDropdown.value = 0;
FlagsDropdown.RefreshShownValue();
@ -606,7 +605,7 @@ namespace UnityExplorer.Inspectors
layerToNames = new List<string>();
for (int i = 0; i < 32; i++)
{
var name = RuntimeHelper.LayerToName(i);
string name = RuntimeHelper.LayerToName(i);
if (string.IsNullOrEmpty(name))
name = i.ToString();
layerToNames.Add(name);
@ -619,7 +618,7 @@ namespace UnityExplorer.Inspectors
{
hideFlagsValues = new Dictionary<string, HideFlags>();
var names = Enum.GetValues(typeof(HideFlags));
Array names = Enum.GetValues(typeof(HideFlags));
foreach (HideFlags value in names)
{
hideFlagsValues.Add(value.ToString(), value);
@ -633,7 +632,7 @@ namespace UnityExplorer.Inspectors
private void ConstructTransformControls()
{
var transformGroup = UIFactory.CreateVerticalGroup(Parent.Content, "TransformControls", false, false, true, true, 2,
GameObject transformGroup = UIFactory.CreateVerticalGroup(Parent.Content, "TransformControls", false, false, true, true, 2,
new Vector4(2, 2, 0, 0), new Color(0.1f, 0.1f, 0.1f));
UIFactory.SetLayoutElement(transformGroup, minHeight: 100, flexibleWidth: 9999);
//transformGroup.SetActive(false);
@ -650,19 +649,19 @@ namespace UnityExplorer.Inspectors
private TransformControl AddTransformRow(GameObject transformGroup, string title, TransformType type)
{
var rowObj = UIFactory.CreateUIObject("Row_" + title, transformGroup);
GameObject rowObj = UIFactory.CreateUIObject("Row_" + title, transformGroup);
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(rowObj, false, false, true, true, 5, 0, 0, 0, 0, default);
UIFactory.SetLayoutElement(rowObj, minHeight: 25, flexibleWidth: 9999);
var titleLabel = UIFactory.CreateLabel(rowObj, "PositionLabel", title, TextAnchor.MiddleRight, Color.grey);
Text titleLabel = UIFactory.CreateLabel(rowObj, "PositionLabel", title, TextAnchor.MiddleRight, Color.grey);
UIFactory.SetLayoutElement(titleLabel.gameObject, minHeight: 25, minWidth: 110);
var inputField = UIFactory.CreateInputField(rowObj, "InputField", "...");
InputFieldRef inputField = UIFactory.CreateInputField(rowObj, "InputField", "...");
UIFactory.SetLayoutElement(inputField.Component.gameObject, minHeight: 25, minWidth: 100, flexibleWidth: 999);
inputField.Component.GetOnEndEdit().AddListener((string value) => { OnTransformInputEndEdit(type, value); });
var control = new TransformControl(type, inputField);
TransformControl control = new(type, inputField);
AddVectorAxisSlider(rowObj, "X", 0, control);
AddVectorAxisSlider(rowObj, "Y", 1, control);
@ -673,16 +672,16 @@ namespace UnityExplorer.Inspectors
private VectorSlider AddVectorAxisSlider(GameObject parent, string title, int axis, TransformControl control)
{
var label = UIFactory.CreateLabel(parent, "Label_" + title, title + ":", TextAnchor.MiddleRight, Color.grey);
Text label = UIFactory.CreateLabel(parent, "Label_" + title, title + ":", TextAnchor.MiddleRight, Color.grey);
UIFactory.SetLayoutElement(label.gameObject, minHeight: 25, minWidth: 30);
var sliderObj = UIFactory.CreateSlider(parent, "Slider_" + title, out var slider);
GameObject sliderObj = UIFactory.CreateSlider(parent, "Slider_" + title, out Slider slider);
UIFactory.SetLayoutElement(sliderObj, minHeight: 25, minWidth: 120, flexibleWidth: 0);
slider.m_FillImage.color = Color.clear;
slider.minValue = -1;
slider.maxValue = 1;
var sliderControl = new VectorSlider(axis, slider, control);
VectorSlider sliderControl = new(axis, slider, control);
slider.onValueChanged.AddListener((float val) =>
{

View File

@ -1,13 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.UI;
using UniverseLib.UI.Models;
using UnityExplorer.UI.Panels;
using UniverseLib.UI;
using UniverseLib.UI.ObjectPool;
namespace UnityExplorer.Inspectors

View File

@ -1,16 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.UI;
using UnityExplorer.CacheObject;
using UnityExplorer.Inspectors;
using UniverseLib.UI.Models;
using UnityExplorer.UI;
using UnityExplorer.UI.Panels;
using UniverseLib;
using UniverseLib.UI;
using UniverseLib.UI.ObjectPool;
using UniverseLib.Utility;
@ -50,7 +46,7 @@ namespace UnityExplorer
private static bool TryFocusActiveInspector(object target)
{
foreach (var inspector in Inspectors)
foreach (InspectorBase inspector in Inspectors)
{
if (inspector.Target.ReferenceEqual(target))
{
@ -96,7 +92,7 @@ namespace UnityExplorer
private static void CreateInspector<T>(object target, bool staticReflection = false,
CacheObjectBase parentObject = null) where T : InspectorBase
{
var inspector = Pool<T>.Borrow();
T inspector = Pool<T>.Borrow();
Inspectors.Add(inspector);
inspector.Target = target;
@ -164,7 +160,7 @@ namespace UnityExplorer
{
PanelWidth = width;
foreach (var obj in Inspectors)
foreach (InspectorBase obj in Inspectors)
{
if (obj is ReflectionInspector inspector)
{

View File

@ -1,15 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.UI;
using UniverseLib.UI.Models;
using UnityExplorer.UI.Widgets;
using UniverseLib.UI;
using UniverseLib;
using UnityExplorer.UI.Panels;
using UniverseLib.UI;
using UniverseLib.UI.Models;
using UniverseLib.UI.ObjectPool;
namespace UnityExplorer.Inspectors

View File

@ -1,19 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine;
using UnityEngine.UI;
using UniverseLib.Input;
using UnityExplorer.Runtime;
using UnityExplorer.Config;
using UnityExplorer.Inspectors.MouseInspectors;
using UnityExplorer.UI;
using UnityExplorer.UI.Panels;
using UniverseLib;
using UniverseLib.Input;
using UniverseLib.UI;
using UniverseLib.UI.Panels;
using UniverseLib.Utility;
using UnityExplorer.Config;
namespace UnityExplorer.Inspectors
{
@ -23,7 +17,7 @@ namespace UnityExplorer.Inspectors
UI
}
public class MouseInspector : UIPanel
public class MouseInspector : PanelBase
{
public static MouseInspector Instance { get; private set; }
@ -44,22 +38,21 @@ namespace UnityExplorer.Inspectors
// UIPanel
internal static readonly string UIBaseGUID = $"{ExplorerCore.GUID}.MouseInspector";
private UIBase inspectorUIBase;
internal static UIBase inspectorUIBase;
public override string Name => "Inspect Under Mouse";
public override UIManager.Panels PanelType => UIManager.Panels.MouseInspector;
public override int MinWidth => -1;
public override int MinHeight => -1;
public override Vector2 DefaultAnchorMin => Vector2.zero;
public override Vector2 DefaultAnchorMax => Vector2.zero;
public override bool CanDragAndResize => false;
public override bool NavButtonWanted => false;
public override bool ShouldSaveActiveState => false;
public override bool ShowByDefault => false;
internal Text objNameLabel;
internal Text objPathLabel;
internal Text mousePosLabel;
public MouseInspector()
public MouseInspector(UIBase owner) : base(owner)
{
Instance = this;
worldInspector = new WorldInspector();
@ -84,11 +77,12 @@ namespace UnityExplorer.Inspectors
CurrentInspector.OnBeginMouseInspect();
PanelDragger.ForceEnd();
PanelManager.ForceEndResize();
UIManager.NavBarRect.gameObject.SetActive(false);
UIManager.PanelHolder.SetActive(false);
UIManager.UiBase.Panels.PanelHolder.SetActive(false);
UIManager.UiBase.SetOnTop();
UIRoot.SetActive(true);
SetActive(true);
}
internal void ClearHitData()
@ -106,9 +100,9 @@ namespace UnityExplorer.Inspectors
Inspecting = false;
UIManager.NavBarRect.gameObject.SetActive(true);
UIManager.PanelHolder.SetActive(true);
UIManager.UiBase.Panels.PanelHolder.SetActive(true);
var drop = InspectorPanel.Instance.MouseInspectDropdown;
Dropdown drop = InspectorPanel.Instance.MouseInspectDropdown;
if (drop.transform.Find("Dropdown List") is Transform list)
drop.DestroyDropdownList(list.gameObject);
@ -130,7 +124,7 @@ namespace UnityExplorer.Inspectors
if (InputManager.GetKeyDown(ConfigManager.World_MouseInspect_Keybind.Value))
Instance.StartInspect(MouseInspectMode.World);
}
if (Inspecting)
UpdateInspect();
@ -152,7 +146,7 @@ namespace UnityExplorer.Inspectors
return;
}
var mousePos = InputManager.MousePosition;
Vector3 mousePos = InputManager.MousePosition;
if (mousePos != lastMousePos)
UpdatePosition(mousePos);
@ -181,34 +175,36 @@ namespace UnityExplorer.Inspectors
mousePos.y -= 10;
// calculate and set our UI position
var inversePos = inspectorUIBase.RootObject.transform.InverseTransformPoint(mousePos);
Vector3 inversePos = inspectorUIBase.RootObject.transform.InverseTransformPoint(mousePos);
UIRoot.transform.localPosition = new Vector3(inversePos.x, inversePos.y, 0);
}
// UI Construction
protected internal override void DoSetDefaultPosAndAnchors()
public override void SetDefaultSizeAndPosition()
{
base.SetDefaultSizeAndPosition();
Rect.anchorMin = Vector2.zero;
Rect.anchorMax = Vector2.zero;
Rect.pivot = new Vector2(0.5f, 1);
Rect.sizeDelta = new Vector2(700, 150);
}
public override void ConstructPanelContent()
protected override void ConstructPanelContent()
{
// hide title bar
this.TitleBar.SetActive(false);
this.UIRoot.transform.SetParent(UIManager.UIRoot.transform, false);
var inspectContent = UIFactory.CreateVerticalGroup(this.uiContent, "InspectContent", true, true, true, true, 3, new Vector4(2, 2, 2, 2));
GameObject inspectContent = UIFactory.CreateVerticalGroup(this.ContentRoot, "InspectContent", true, true, true, true, 3, new Vector4(2, 2, 2, 2));
UIFactory.SetLayoutElement(inspectContent, flexibleWidth: 9999, flexibleHeight: 9999);
// Title text
var title = UIFactory.CreateLabel(inspectContent,
Text title = UIFactory.CreateLabel(inspectContent,
"InspectLabel",
"<b>Mouse Inspector</b> (press <b>ESC</b> to cancel)",
"<b>Mouse Inspector</b> (press <b>ESC</b> to cancel)",
TextAnchor.MiddleCenter);
UIFactory.SetLayoutElement(title.gameObject, flexibleWidth: 9999);
@ -225,11 +221,10 @@ namespace UnityExplorer.Inspectors
UIRoot.SetActive(false);
// Create a new canvas for this panel to live on.
// It needs to always be shown on the main display, other panels can move displays.
inspectorUIBase = UniversalUI.RegisterUI(UIBaseGUID, null);
UIRoot.transform.SetParent(inspectorUIBase.RootObject.transform);
//// Create a new canvas for this panel to live on.
//// It needs to always be shown on the main display, other panels can move displays.
//
//UIRoot.transform.SetParent(inspectorUIBase.RootObject.transform);
}
}
}

View File

@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine;
namespace UnityExplorer.Inspectors.MouseInspectors
{

View File

@ -1,29 +1,26 @@
using System;
using System.Collections;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using UnityExplorer.UI;
using UnityExplorer.UI.Panels;
using UniverseLib;
using UniverseLib.Input;
namespace UnityExplorer.Inspectors.MouseInspectors
{
public class UiInspector : MouseInspectorBase
{
public static readonly List<GameObject> LastHitObjects = new List<GameObject>();
public static readonly List<GameObject> LastHitObjects = new();
private static GraphicRaycaster[] graphicRaycasters;
private static readonly List<GameObject> currentHitObjects = new List<GameObject>();
private static readonly List<GameObject> currentHitObjects = new();
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>();
private static readonly List<Graphic> wasDisabledGraphics = new();
private static readonly List<CanvasGroup> wasDisabledCanvasGroups = new();
private static readonly List<GameObject> objectsAddedCastersTo = new();
public override void OnBeginMouseInspect()
{
@ -46,7 +43,7 @@ namespace UnityExplorer.Inspectors.MouseInspectors
IEnumerator SetPanelActiveCoro()
{
yield return null;
var panel = UIManager.GetPanel<MouseInspectorResultsPanel>(UIManager.Panels.UIInspectorResults);
MouseInspectorResultsPanel panel = UIManager.GetPanel<MouseInspectorResultsPanel>(UIManager.Panels.UIInspectorResults);
panel.SetActive(true);
panel.ShowResults();
}
@ -55,28 +52,28 @@ namespace UnityExplorer.Inspectors.MouseInspectors
{
currentHitObjects.Clear();
var ped = new PointerEventData(null)
PointerEventData ped = new(null)
{
position = mousePos
};
foreach (var gr in graphicRaycasters)
foreach (GraphicRaycaster gr in graphicRaycasters)
{
if (!gr || !gr.canvas)
continue;
var list = new List<RaycastResult>();
List<RaycastResult> list = new();
RuntimeHelper.GraphicRaycast(gr, ped, list);
if (list.Count > 0)
{
foreach (var hit in list)
foreach (RaycastResult hit in list)
{
if (hit.gameObject)
currentHitObjects.Add(hit.gameObject);
}
}
}
if (currentHitObjects.Any())
MouseInspector.Instance.objNameLabel.text = $"Click to view UI Objects under mouse: {currentHitObjects.Count}";
else
@ -85,9 +82,9 @@ namespace UnityExplorer.Inspectors.MouseInspectors
private static void SetupUIRaycast()
{
foreach (var obj in RuntimeHelper.FindObjectsOfTypeAll(typeof(Canvas)))
foreach (UnityEngine.Object obj in RuntimeHelper.FindObjectsOfTypeAll(typeof(Canvas)))
{
var canvas = obj.TryCast<Canvas>();
Canvas canvas = obj.TryCast<Canvas>();
if (!canvas || !canvas.enabled || !canvas.gameObject.activeInHierarchy)
continue;
if (!canvas.GetComponent<GraphicRaycaster>())
@ -99,7 +96,7 @@ namespace UnityExplorer.Inspectors.MouseInspectors
}
// recache Graphic Raycasters each time we start
var casters = RuntimeHelper.FindObjectsOfTypeAll(typeof(GraphicRaycaster));
UnityEngine.Object[] casters = RuntimeHelper.FindObjectsOfTypeAll(typeof(GraphicRaycaster));
graphicRaycasters = new GraphicRaycaster[casters.Length];
for (int i = 0; i < casters.Length; i++)
{
@ -107,9 +104,9 @@ namespace UnityExplorer.Inspectors.MouseInspectors
}
// enable raycastTarget on Graphics
foreach (var obj in RuntimeHelper.FindObjectsOfTypeAll(typeof(Graphic)))
foreach (UnityEngine.Object obj in RuntimeHelper.FindObjectsOfTypeAll(typeof(Graphic)))
{
var graphic = obj.TryCast<Graphic>();
Graphic graphic = obj.TryCast<Graphic>();
if (!graphic || !graphic.enabled || graphic.raycastTarget || !graphic.gameObject.activeInHierarchy)
continue;
graphic.raycastTarget = true;
@ -118,9 +115,9 @@ namespace UnityExplorer.Inspectors.MouseInspectors
}
// enable blocksRaycasts on CanvasGroups
foreach (var obj in RuntimeHelper.FindObjectsOfTypeAll(typeof(CanvasGroup)))
foreach (UnityEngine.Object obj in RuntimeHelper.FindObjectsOfTypeAll(typeof(CanvasGroup)))
{
var canvas = obj.TryCast<CanvasGroup>();
CanvasGroup canvas = obj.TryCast<CanvasGroup>();
if (!canvas || !canvas.gameObject.activeInHierarchy || canvas.blocksRaycasts)
continue;
canvas.blocksRaycasts = true;
@ -131,16 +128,16 @@ namespace UnityExplorer.Inspectors.MouseInspectors
public override void OnEndInspect()
{
foreach (var obj in objectsAddedCastersTo)
foreach (GameObject obj in objectsAddedCastersTo)
{
if (obj.GetComponent<GraphicRaycaster>() is GraphicRaycaster raycaster)
GameObject.Destroy(raycaster);
}
foreach (var graphic in wasDisabledGraphics)
foreach (Graphic graphic in wasDisabledGraphics)
graphic.raycastTarget = false;
foreach (var canvas in wasDisabledCanvasGroups)
foreach (CanvasGroup canvas in wasDisabledCanvasGroups)
canvas.blocksRaycasts = false;
objectsAddedCastersTo.Clear();

View File

@ -1,9 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UniverseLib;
using UnityEngine;
using UniverseLib.Utility;
namespace UnityExplorer.Inspectors.MouseInspectors
@ -45,7 +40,7 @@ namespace UnityExplorer.Inspectors.MouseInspectors
return;
}
var ray = MainCamera.ScreenPointToRay(mousePos);
Ray ray = MainCamera.ScreenPointToRay(mousePos);
Physics.Raycast(ray, out RaycastHit hit, 1000f);
if (hit.transform)

View File

@ -107,7 +107,7 @@ namespace UnityExplorer.Inspectors
public override void OnReturnToPool()
{
foreach (var member in members)
foreach (CacheMember member in members)
{
member.UnlinkFromView();
member.ReleasePooledObjects();
@ -175,7 +175,7 @@ namespace UnityExplorer.Inspectors
scopeFilterButtons[BindingFlags.Default].Component.gameObject.SetActive(!StaticOnly);
scopeFilterButtons[BindingFlags.Instance].Component.gameObject.SetActive(!StaticOnly);
foreach (var toggle in memberTypeToggles)
foreach (Toggle toggle in memberTypeToggles)
toggle.isOn = true;
refreshWanted = true;
@ -236,7 +236,7 @@ namespace UnityExplorer.Inspectors
if (flags != scopeFlagsFilter)
{
var btn = scopeFilterButtons[scopeFlagsFilter].Component;
Button btn = scopeFilterButtons[scopeFlagsFilter].Component;
RuntimeHelper.SetColorBlock(btn, disabledButtonColor, disabledButtonColor * 1.3f);
this.scopeFlagsFilter = flags;
@ -259,7 +259,7 @@ namespace UnityExplorer.Inspectors
for (int i = 0; i < members.Count; i++)
{
var member = members[i];
CacheMember member = members[i];
if (scopeFlagsFilter != BindingFlags.Default)
{
@ -284,11 +284,11 @@ namespace UnityExplorer.Inspectors
private void UpdateDisplayedMembers()
{
bool shouldRefresh = false;
foreach (var cell in MemberScrollPool.CellPool)
foreach (CacheMemberCell cell in MemberScrollPool.CellPool)
{
if (!cell.Enabled || cell.Occupant == null)
continue;
var member = cell.MemberOccupant;
CacheMember member = cell.MemberOccupant;
if (member.ShouldAutoEvaluate)
{
shouldRefresh = true;
@ -316,7 +316,7 @@ namespace UnityExplorer.Inspectors
{
CalculateLayouts();
foreach (var cell in MemberScrollPool.CellPool)
foreach (CacheMemberCell cell in MemberScrollPool.CellPool)
SetCellLayout(cell);
}
@ -349,21 +349,21 @@ namespace UnityExplorer.Inspectors
// Class name, assembly
var topRow = UIFactory.CreateHorizontalGroup(UIRoot, "TopRow", false, false, true, true, 4, default, new(1, 1, 1, 0), TextAnchor.MiddleLeft);
GameObject topRow = UIFactory.CreateHorizontalGroup(UIRoot, "TopRow", false, false, true, true, 4, default, new(1, 1, 1, 0), TextAnchor.MiddleLeft);
UIFactory.SetLayoutElement(topRow, minHeight: 25, flexibleWidth: 9999);
var titleHolder = UIFactory.CreateUIObject("TitleHolder", topRow);
GameObject titleHolder = UIFactory.CreateUIObject("TitleHolder", topRow);
UIFactory.SetLayoutElement(titleHolder, minHeight: 35, flexibleHeight: 0, flexibleWidth: 9999);
NameText = UIFactory.CreateLabel(titleHolder, "VisibleTitle", "NotSet", TextAnchor.MiddleLeft);
var namerect = NameText.GetComponent<RectTransform>();
RectTransform namerect = NameText.GetComponent<RectTransform>();
namerect.anchorMin = new Vector2(0, 0);
namerect.anchorMax = new Vector2(1, 1);
NameText.fontSize = 17;
UIFactory.SetLayoutElement(NameText.gameObject, minHeight: 35, flexibleHeight: 0, minWidth: 300, flexibleWidth: 9999);
HiddenNameText = UIFactory.CreateInputField(titleHolder, "Title", "not set");
var hiddenrect = HiddenNameText.Component.gameObject.GetComponent<RectTransform>();
RectTransform hiddenrect = HiddenNameText.Component.gameObject.GetComponent<RectTransform>();
hiddenrect.anchorMin = new Vector2(0, 0);
hiddenrect.anchorMax = new Vector2(1, 1);
HiddenNameText.Component.readOnly = true;
@ -374,7 +374,7 @@ namespace UnityExplorer.Inspectors
HiddenNameText.Component.textComponent.color = Color.clear;
UIFactory.SetLayoutElement(HiddenNameText.Component.gameObject, minHeight: 35, flexibleHeight: 0, flexibleWidth: 9999);
var copyButton = UIFactory.CreateButton(topRow, "CopyButton", "Copy to Clipboard", new Color(0.2f, 0.2f, 0.2f, 1));
ButtonRef copyButton = UIFactory.CreateButton(topRow, "CopyButton", "Copy to Clipboard", new Color(0.2f, 0.2f, 0.2f, 1));
copyButton.ButtonText.color = Color.yellow;
UIFactory.SetLayoutElement(copyButton.Component.gameObject, minHeight: 25, minWidth: 120, flexibleWidth: 0);
copyButton.OnClick += OnCopyClicked;
@ -392,7 +392,7 @@ namespace UnityExplorer.Inspectors
// Member scroll pool
var memberBorder = UIFactory.CreateVerticalGroup(mainContentHolder, "ScrollPoolHolder", false, false, true, true, padding: new Vector4(2, 2, 2, 2),
GameObject memberBorder = UIFactory.CreateVerticalGroup(mainContentHolder, "ScrollPoolHolder", false, false, true, true, padding: new Vector4(2, 2, 2, 2),
bgColor: new Color(0.05f, 0.05f, 0.05f));
UIFactory.SetLayoutElement(memberBorder, flexibleWidth: 9999, flexibleHeight: 9999);
@ -413,27 +413,27 @@ namespace UnityExplorer.Inspectors
private void ConstructFirstRow(GameObject parent)
{
var rowObj = UIFactory.CreateUIObject("FirstRow", parent);
GameObject rowObj = UIFactory.CreateUIObject("FirstRow", parent);
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(rowObj, true, true, true, true, 5, 2, 2, 2, 2);
UIFactory.SetLayoutElement(rowObj, minHeight: 25, flexibleHeight: 0, flexibleWidth: 9999);
var nameLabel = UIFactory.CreateLabel(rowObj, "NameFilterLabel", "Filter names:", TextAnchor.MiddleLeft, Color.grey);
Text nameLabel = UIFactory.CreateLabel(rowObj, "NameFilterLabel", "Filter names:", TextAnchor.MiddleLeft, Color.grey);
UIFactory.SetLayoutElement(nameLabel.gameObject, minHeight: 25, minWidth: 90, flexibleWidth: 0);
filterInputField = UIFactory.CreateInputField(rowObj, "NameFilterInput", "...");
UIFactory.SetLayoutElement(filterInputField.UIRoot, minHeight: 25, flexibleWidth: 300);
filterInputField.OnValueChanged += (string val) => { SetFilter(val); };
var spacer = UIFactory.CreateUIObject("Spacer", rowObj);
GameObject spacer = UIFactory.CreateUIObject("Spacer", rowObj);
UIFactory.SetLayoutElement(spacer, minWidth: 25);
// Update button and toggle
var updateButton = UIFactory.CreateButton(rowObj, "UpdateButton", "Update displayed values", new Color(0.22f, 0.28f, 0.22f));
ButtonRef updateButton = UIFactory.CreateButton(rowObj, "UpdateButton", "Update displayed values", new Color(0.22f, 0.28f, 0.22f));
UIFactory.SetLayoutElement(updateButton.Component.gameObject, minHeight: 25, minWidth: 175, flexibleWidth: 0);
updateButton.OnClick += UpdateClicked;
var toggleObj = UIFactory.CreateToggle(rowObj, "AutoUpdateToggle", out autoUpdateToggle, out Text toggleText);
GameObject toggleObj = UIFactory.CreateToggle(rowObj, "AutoUpdateToggle", out autoUpdateToggle, out Text toggleText);
UIFactory.SetLayoutElement(toggleObj, minWidth: 125, minHeight: 25);
autoUpdateToggle.isOn = false;
toggleText.text = "Auto-update";
@ -443,19 +443,19 @@ namespace UnityExplorer.Inspectors
private void ConstructSecondRow(GameObject parent)
{
var rowObj = UIFactory.CreateUIObject("SecondRow", parent);
GameObject 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);
Text 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);
GameObject spacer = UIFactory.CreateUIObject("Spacer", rowObj);
UIFactory.SetLayoutElement(spacer, minWidth: 15);
// Member type toggles
@ -469,9 +469,9 @@ namespace UnityExplorer.Inspectors
private void AddScopeFilterButton(GameObject parent, BindingFlags flags, bool setAsActive = false)
{
string lbl = flags == BindingFlags.Default ? "All" : flags.ToString();
var color = setAsActive ? enabledButtonColor : disabledButtonColor;
Color color = setAsActive ? enabledButtonColor : disabledButtonColor;
var button = UIFactory.CreateButton(parent, "Filter_" + flags, lbl, color);
ButtonRef button = UIFactory.CreateButton(parent, "Filter_" + flags, lbl, color);
UIFactory.SetLayoutElement(button.Component.gameObject, minHeight: 25, flexibleHeight: 0, minWidth: 70, flexibleWidth: 0);
scopeFilterButtons.Add(flags, button);
@ -480,7 +480,7 @@ namespace UnityExplorer.Inspectors
private void AddMemberTypeToggle(GameObject parent, MemberTypes type, int width)
{
var toggleObj = UIFactory.CreateToggle(parent, "Toggle_" + type, out Toggle toggle, out Text toggleText);
GameObject toggleObj = UIFactory.CreateToggle(parent, "Toggle_" + type, out Toggle toggle, out Text toggleText);
UIFactory.SetLayoutElement(toggleObj, minHeight: 25, minWidth: width);
string color = type switch
{

View File

@ -2,8 +2,6 @@
using BepInEx.Configuration;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityExplorer.Config;
namespace UnityExplorer.Loader.BIE
@ -21,7 +19,7 @@ namespace UnityExplorer.Loader.BIE
public override void RegisterConfigElement<T>(ConfigElement<T> config)
{
var entry = Config.Bind(CTG_NAME, config.Name, config.Value, config.Description);
ConfigEntry<T> entry = Config.Bind(CTG_NAME, config.Name, config.Value, config.Description);
entry.SettingChanged += (object o, EventArgs e) =>
{
@ -47,13 +45,13 @@ namespace UnityExplorer.Loader.BIE
public override void LoadConfig()
{
foreach (var entry in ConfigManager.ConfigElements)
foreach (KeyValuePair<string, IConfigElement> entry in ConfigManager.ConfigElements)
{
var key = entry.Key;
var def = new ConfigDefinition(CTG_NAME, key);
string key = entry.Key;
ConfigDefinition def = new(CTG_NAME, key);
if (Config.ContainsKey(def) && Config[def] is ConfigEntryBase configEntry)
{
var config = entry.Value;
IConfigElement config = entry.Value;
config.BoxedValue = configEntry.BoxedValue;
}
}

View File

@ -3,14 +3,8 @@ using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityExplorer.Config;
using UniverseLib.Input;
using UnityExplorer.Loader.BIE;
#if CPP
using BepInEx.IL2CPP;
@ -45,7 +39,7 @@ namespace UnityExplorer
public Harmony HarmonyInstance => s_harmony;
private static readonly Harmony s_harmony = new(ExplorerCore.GUID);
public string ExplorerFolderName => ExplorerCore.DEFAULT_EXPLORER_FOLDER_NAME;
public string ExplorerFolderDestination => Paths.PluginPath;

View File

@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityExplorer.Config;
namespace UnityExplorer

View File

@ -1,14 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
using UniverseLib.UI.Models;
using UnityExplorer.UI.Panels;
using UnityExplorer.UI.Widgets.AutoComplete;
using UniverseLib.UI;
using UniverseLib;
using UniverseLib.UI;
using UniverseLib.UI.Models;
using UniverseLib.UI.Widgets.ButtonList;
using UniverseLib.UI.Widgets.ScrollView;
using UniverseLib.Utility;
@ -73,7 +72,7 @@ namespace UnityExplorer.ObjectExplorer
//var type = ReflectionUtility.GetTypeByName(desiredTypeInput);
if (ReflectionUtility.GetTypeByName(desiredTypeInput) is Type cachedType)
{
var type = cachedType;
Type type = cachedType;
lastTypeCanHaveGameObject = typeof(Component).IsAssignableFrom(type) || type == typeof(GameObject);
sceneFilterRow.SetActive(lastTypeCanHaveGameObject);
childFilterRow.SetActive(lastTypeCanHaveGameObject);
@ -135,7 +134,7 @@ namespace UnityExplorer.ObjectExplorer
string text;
if (context == SearchContext.Class)
{
var type = currentResults[index] as Type;
Type type = currentResults[index] as Type;
text = $"{SignatureHighlighter.Parse(type, true)} <color=grey><i>({type.Assembly.GetName().Name})</i></color>";
}
else
@ -164,14 +163,14 @@ namespace UnityExplorer.ObjectExplorer
// Search context row
var contextGroup = UIFactory.CreateHorizontalGroup(uiRoot, "SearchContextRow", false, true, true, true, 2, new Vector4(2, 2, 2, 2));
GameObject 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);
Text contextLbl = UIFactory.CreateLabel(contextGroup, "SearchContextLabel", "Searching for:", TextAnchor.MiddleLeft);
UIFactory.SetLayoutElement(contextLbl.gameObject, minWidth: 110, flexibleWidth: 0);
var contextDropObj = UIFactory.CreateDropdown(contextGroup, "ContextDropdown", out Dropdown contextDrop, null, 14, OnContextDropdownChanged);
foreach (var name in Enum.GetNames(typeof(SearchContext)))
GameObject contextDropObj = UIFactory.CreateDropdown(contextGroup, "ContextDropdown", out Dropdown contextDrop, null, 14, OnContextDropdownChanged);
foreach (string name in Enum.GetNames(typeof(SearchContext)))
contextDrop.options.Add(new Dropdown.OptionData(name));
UIFactory.SetLayoutElement(contextDropObj, minHeight: 25, flexibleHeight: 0, flexibleWidth: 9999);
@ -180,10 +179,10 @@ namespace UnityExplorer.ObjectExplorer
classInputRow = UIFactory.CreateHorizontalGroup(uiRoot, "ClassRow", false, true, true, true, 2, new Vector4(2, 2, 2, 2));
UIFactory.SetLayoutElement(classInputRow, minHeight: 25, flexibleHeight: 0);
var unityClassLbl = UIFactory.CreateLabel(classInputRow, "ClassLabel", "Class filter:", TextAnchor.MiddleLeft);
Text unityClassLbl = UIFactory.CreateLabel(classInputRow, "ClassLabel", "Class filter:", TextAnchor.MiddleLeft);
UIFactory.SetLayoutElement(unityClassLbl.gameObject, minWidth: 110, flexibleWidth: 0);
var classInputField = UIFactory.CreateInputField(classInputRow, "ClassInput", "...");
InputFieldRef classInputField = UIFactory.CreateInputField(classInputRow, "ClassInput", "...");
UIFactory.SetLayoutElement(classInputField.UIRoot, minHeight: 25, flexibleHeight: 0, flexibleWidth: 9999);
typeAutocompleter = new TypeCompleter(typeof(UnityEngine.Object), classInputField);
@ -196,11 +195,11 @@ namespace UnityExplorer.ObjectExplorer
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);
Text childLbl = UIFactory.CreateLabel(childFilterRow, "ChildLabel", "Child filter:", TextAnchor.MiddleLeft);
UIFactory.SetLayoutElement(childLbl.gameObject, minWidth: 110, flexibleWidth: 0);
var childDropObj = UIFactory.CreateDropdown(childFilterRow, "ChildFilterDropdown", out Dropdown childDrop, null, 14, OnChildFilterDropChanged);
foreach (var name in Enum.GetNames(typeof(ChildFilter)))
GameObject childDropObj = UIFactory.CreateDropdown(childFilterRow, "ChildFilterDropdown", out Dropdown childDrop, null, 14, OnChildFilterDropChanged);
foreach (string name in Enum.GetNames(typeof(ChildFilter)))
childDrop.options.Add(new Dropdown.OptionData(name));
UIFactory.SetLayoutElement(childDropObj, minHeight: 25, flexibleHeight: 0, flexibleWidth: 9999);
@ -211,11 +210,11 @@ namespace UnityExplorer.ObjectExplorer
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);
Text sceneLbl = UIFactory.CreateLabel(sceneFilterRow, "SceneLabel", "Scene filter:", TextAnchor.MiddleLeft);
UIFactory.SetLayoutElement(sceneLbl.gameObject, minWidth: 110, flexibleWidth: 0);
var sceneDropObj = UIFactory.CreateDropdown(sceneFilterRow, "SceneFilterDropdown", out Dropdown sceneDrop, null, 14, OnSceneFilterDropChanged);
foreach (var name in Enum.GetNames(typeof(SceneFilter)))
GameObject sceneDropObj = UIFactory.CreateDropdown(sceneFilterRow, "SceneFilterDropdown", out Dropdown sceneDrop, null, 14, OnSceneFilterDropChanged);
foreach (string name in Enum.GetNames(typeof(SceneFilter)))
{
if (!SceneHandler.DontDestroyExists && name == "DontDestroyOnLoad")
continue;
@ -230,7 +229,7 @@ namespace UnityExplorer.ObjectExplorer
nameInputRow = UIFactory.CreateHorizontalGroup(uiRoot, "NameRow", true, true, true, true, 2, new Vector4(2, 2, 2, 2));
UIFactory.SetLayoutElement(nameInputRow, minHeight: 25, flexibleHeight: 0);
var nameLbl = UIFactory.CreateLabel(nameInputRow, "NameFilterLabel", "Name contains:", TextAnchor.MiddleLeft);
Text nameLbl = UIFactory.CreateLabel(nameInputRow, "NameFilterLabel", "Name contains:", TextAnchor.MiddleLeft);
UIFactory.SetLayoutElement(nameLbl.gameObject, minWidth: 110, flexibleWidth: 0);
nameInputField = UIFactory.CreateInputField(nameInputRow, "NameFilterInput", "...");
@ -238,13 +237,13 @@ namespace UnityExplorer.ObjectExplorer
// Search button
var searchButton = UIFactory.CreateButton(uiRoot, "SearchButton", "Search");
ButtonRef searchButton = UIFactory.CreateButton(uiRoot, "SearchButton", "Search");
UIFactory.SetLayoutElement(searchButton.Component.gameObject, minHeight: 25, flexibleHeight: 0);
searchButton.OnClick += DoSearch;
// Results count label
var resultsCountRow = UIFactory.CreateHorizontalGroup(uiRoot, "ResultsCountRow", true, true, true, true);
GameObject 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);

View File

@ -1,20 +1,19 @@
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.UI;
using UniverseLib.UI.Models;
using UnityExplorer.UI.Panels;
using UnityExplorer.UI.Widgets;
using UniverseLib.UI;
using UniverseLib;
using System.Collections;
using UniverseLib.UI;
using UniverseLib.UI.Models;
using UniverseLib.Utility;
using UniverseLib.UI.Widgets;
namespace UnityExplorer.ObjectExplorer
{
@ -76,7 +75,7 @@ namespace UnityExplorer.ObjectExplorer
this.Parent.SetTab(0);
// select the transform's scene
var go = transform.gameObject;
GameObject go = transform.gameObject;
if (SceneHandler.SelectedScene != go.scene)
{
int idx;
@ -109,7 +108,7 @@ namespace UnityExplorer.ObjectExplorer
if (sceneToDropdownOption.ContainsKey(scene))
{
var opt = sceneToDropdownOption[scene];
Dropdown.OptionData opt = sceneToDropdownOption[scene];
int idx = sceneDropdown.options.IndexOf(opt);
if (sceneDropdown.value != idx)
sceneDropdown.value = idx;
@ -136,7 +135,7 @@ namespace UnityExplorer.ObjectExplorer
sceneToDropdownOption.Clear();
sceneDropdown.options.Clear();
foreach (var scene in loadedScenes)
foreach (Scene scene in loadedScenes)
{
if (sceneToDropdownOption.ContainsKey(scene))
continue;
@ -148,7 +147,7 @@ namespace UnityExplorer.ObjectExplorer
else if (string.IsNullOrEmpty(name))
name = "<untitled>";
var option = new Dropdown.OptionData(name);
Dropdown.OptionData option = new(name);
sceneDropdown.options.Add(option);
sceneToDropdownOption.Add(scene, option);
}
@ -158,7 +157,7 @@ namespace UnityExplorer.ObjectExplorer
{
if ((!string.IsNullOrEmpty(input) && !Tree.Filtering) || (string.IsNullOrEmpty(input) && Tree.Filtering))
{
Tree.cachedTransforms.Clear();
Tree.Clear();
}
Tree.CurrentFilter = input;
@ -167,7 +166,7 @@ namespace UnityExplorer.ObjectExplorer
private void TryLoadScene(LoadSceneMode mode, Dropdown allSceneDrop)
{
var text = allSceneDrop.captionText.text;
string text = allSceneDrop.captionText.text;
if (text == DEFAULT_LOAD_TEXT)
return;
@ -191,18 +190,18 @@ namespace UnityExplorer.ObjectExplorer
// Tool bar (top area)
var toolbar = UIFactory.CreateVerticalGroup(uiRoot, "Toolbar", true, true, true, true, 2, new Vector4(2, 2, 2, 2),
GameObject toolbar = UIFactory.CreateVerticalGroup(uiRoot, "Toolbar", true, true, true, true, 2, new Vector4(2, 2, 2, 2),
new Color(0.15f, 0.15f, 0.15f));
// Scene selector dropdown
var dropRow = UIFactory.CreateHorizontalGroup(toolbar, "DropdownRow", true, true, true, true, 5, default, new Color(1, 1, 1, 0));
GameObject dropRow = UIFactory.CreateHorizontalGroup(toolbar, "DropdownRow", true, true, true, true, 5, default, new Color(1, 1, 1, 0));
UIFactory.SetLayoutElement(dropRow, minHeight: 25, flexibleWidth: 9999);
var dropLabel = UIFactory.CreateLabel(dropRow, "SelectorLabel", "Scene:", TextAnchor.MiddleLeft, Color.cyan, false, 15);
Text dropLabel = UIFactory.CreateLabel(dropRow, "SelectorLabel", "Scene:", TextAnchor.MiddleLeft, Color.cyan, false, 15);
UIFactory.SetLayoutElement(dropLabel.gameObject, minHeight: 25, minWidth: 60, flexibleWidth: 0);
var dropdownObj = UIFactory.CreateDropdown(dropRow, "SceneDropdown", out sceneDropdown, "<notset>", 13, OnSceneSelectionDropdownChanged);
GameObject dropdownObj = UIFactory.CreateDropdown(dropRow, "SceneDropdown", out sceneDropdown, "<notset>", 13, OnSceneSelectionDropdownChanged);
UIFactory.SetLayoutElement(dropdownObj, minHeight: 25, flexibleHeight: 0, flexibleWidth: 9999);
SceneHandler.Update();
@ -211,11 +210,11 @@ namespace UnityExplorer.ObjectExplorer
// Filter row
var filterRow = UIFactory.CreateHorizontalGroup(toolbar, "FilterGroup", true, true, true, true, 2, new Vector4(2, 2, 2, 2));
GameObject filterRow = UIFactory.CreateHorizontalGroup(toolbar, "FilterGroup", true, true, true, true, 2, new Vector4(2, 2, 2, 2));
UIFactory.SetLayoutElement(filterRow, minHeight: 25, flexibleHeight: 0);
//Filter input field
var inputField = UIFactory.CreateInputField(filterRow, "FilterInput", "Search and press enter...");
InputFieldRef inputField = UIFactory.CreateInputField(filterRow, "FilterInput", "Search and press enter...");
inputField.Component.targetGraphic.color = new Color(0.2f, 0.2f, 0.2f);
RuntimeHelper.SetColorBlock(inputField.Component, new Color(0.4f, 0.4f, 0.4f), new Color(0.2f, 0.2f, 0.2f),
new Color(0.08f, 0.08f, 0.08f));
@ -228,11 +227,11 @@ namespace UnityExplorer.ObjectExplorer
refreshRow = UIFactory.CreateHorizontalGroup(toolbar, "RefreshGroup", true, true, true, true, 2, new Vector4(2, 2, 2, 2));
UIFactory.SetLayoutElement(refreshRow, minHeight: 30, flexibleHeight: 0);
var refreshButton = UIFactory.CreateButton(refreshRow, "RefreshButton", "Update");
ButtonRef refreshButton = UIFactory.CreateButton(refreshRow, "RefreshButton", "Update");
UIFactory.SetLayoutElement(refreshButton.Component.gameObject, minWidth: 65, flexibleWidth: 0);
refreshButton.OnClick += UpdateTree;
var refreshToggle = UIFactory.CreateToggle(refreshRow, "RefreshToggle", out Toggle toggle, out Text text);
GameObject refreshToggle = UIFactory.CreateToggle(refreshRow, "RefreshToggle", out Toggle toggle, out Text text);
UIFactory.SetLayoutElement(refreshToggle, flexibleWidth: 9999);
text.text = "Auto-update (1 second)";
text.alignment = TextAnchor.MiddleLeft;
@ -245,24 +244,23 @@ namespace UnityExplorer.ObjectExplorer
// tree labels row
var labelsRow = UIFactory.CreateHorizontalGroup(toolbar, "LabelsRow", true, true, true, true, 2, new Vector4(2, 2, 2, 2));
GameObject labelsRow = UIFactory.CreateHorizontalGroup(toolbar, "LabelsRow", true, true, true, true, 2, new Vector4(2, 2, 2, 2));
UIFactory.SetLayoutElement(labelsRow, minHeight: 30, flexibleHeight: 0);
var nameLabel = UIFactory.CreateLabel(labelsRow, "NameLabel", "Name", TextAnchor.MiddleLeft, color: Color.grey);
Text nameLabel = UIFactory.CreateLabel(labelsRow, "NameLabel", "Name", TextAnchor.MiddleLeft, color: Color.grey);
UIFactory.SetLayoutElement(nameLabel.gameObject, flexibleWidth: 9999, minHeight: 25);
var indexLabel = UIFactory.CreateLabel(labelsRow, "IndexLabel", "Sibling Index", TextAnchor.MiddleLeft, fontSize: 12, color: Color.grey);
Text indexLabel = UIFactory.CreateLabel(labelsRow, "IndexLabel", "Sibling Index", TextAnchor.MiddleLeft, fontSize: 12, color: Color.grey);
UIFactory.SetLayoutElement(indexLabel.gameObject, minWidth: 100, flexibleWidth: 0, minHeight: 25);
// Transform Tree
var scrollPool = UIFactory.CreateScrollPool<TransformCell>(uiRoot, "TransformTree", out GameObject scrollObj,
UniverseLib.UI.Widgets.ScrollView.ScrollPool<TransformCell> scrollPool = UIFactory.CreateScrollPool<TransformCell>(uiRoot, "TransformTree", out GameObject scrollObj,
out GameObject scrollContent, new Color(0.11f, 0.11f, 0.11f));
UIFactory.SetLayoutElement(scrollObj, flexibleHeight: 9999);
UIFactory.SetLayoutElement(scrollContent, flexibleHeight: 9999);
Tree = new TransformTree(scrollPool, GetRootEntries);
Tree.Init();
Tree = new TransformTree(scrollPool, GetRootEntries, OnCellClicked);
Tree.RefreshData(true, true, true, false);
//scrollPool.Viewport.GetComponent<Mask>().enabled = false;
//UIRoot.GetComponent<Mask>().enabled = false;
@ -274,6 +272,8 @@ namespace UnityExplorer.ObjectExplorer
RuntimeHelper.StartCoroutine(TempFixCoro());
}
void OnCellClicked(GameObject obj) => InspectorManager.Inspect(obj);
// To "fix" a strange FPS drop issue with MelonLoader.
private IEnumerator TempFixCoro()
{
@ -294,7 +294,7 @@ namespace UnityExplorer.ObjectExplorer
allSceneDropdown.options.Clear();
allSceneDropdown.options.Add(new Dropdown.OptionData(DEFAULT_LOAD_TEXT));
foreach (var scene in SceneHandler.AllSceneNames)
foreach (string scene in SceneHandler.AllSceneNames)
{
if (string.IsNullOrEmpty(filter) || scene.ContainsIgnoreCase(filter))
allSceneDropdown.options.Add(new Dropdown.OptionData(Path.GetFileNameWithoutExtension(scene)));
@ -308,7 +308,7 @@ namespace UnityExplorer.ObjectExplorer
private void RefreshSceneLoaderButtons()
{
var text = allSceneDropdown.captionText.text;
string text = allSceneDropdown.captionText.text;
if (text == DEFAULT_LOAD_TEXT)
{
loadButton.Component.interactable = false;
@ -328,30 +328,30 @@ namespace UnityExplorer.ObjectExplorer
{
if (SceneHandler.WasAbleToGetScenesInBuild)
{
var sceneLoaderObj = UIFactory.CreateVerticalGroup(uiRoot, "SceneLoader", true, true, true, true);
GameObject sceneLoaderObj = UIFactory.CreateVerticalGroup(uiRoot, "SceneLoader", true, true, true, true);
UIFactory.SetLayoutElement(sceneLoaderObj, minHeight: 25);
// Title
var loaderTitle = UIFactory.CreateLabel(sceneLoaderObj, "SceneLoaderLabel", "Scene Loader", TextAnchor.MiddleLeft, Color.white, true, 14);
Text loaderTitle = UIFactory.CreateLabel(sceneLoaderObj, "SceneLoaderLabel", "Scene Loader", TextAnchor.MiddleLeft, Color.white, true, 14);
UIFactory.SetLayoutElement(loaderTitle.gameObject, minHeight: 25, flexibleHeight: 0);
// Search filter
var searchFilterObj = UIFactory.CreateInputField(sceneLoaderObj, "SearchFilterInput", "Filter scene names...");
InputFieldRef searchFilterObj = UIFactory.CreateInputField(sceneLoaderObj, "SearchFilterInput", "Filter scene names...");
UIFactory.SetLayoutElement(searchFilterObj.UIRoot, minHeight: 25, flexibleHeight: 0);
searchFilterObj.OnValueChanged += RefreshSceneLoaderOptions;
// Dropdown
var allSceneDropObj = UIFactory.CreateDropdown(sceneLoaderObj, "SceneLoaderDropdown", out allSceneDropdown, "", 14, null);
GameObject allSceneDropObj = UIFactory.CreateDropdown(sceneLoaderObj, "SceneLoaderDropdown", out allSceneDropdown, "", 14, null);
UIFactory.SetLayoutElement(allSceneDropObj, minHeight: 25, minWidth: 150, flexibleWidth: 0, flexibleHeight: 0);
RefreshSceneLoaderOptions(string.Empty);
// Button row
var buttonRow = UIFactory.CreateHorizontalGroup(sceneLoaderObj, "LoadButtons", true, true, true, true, 4);
GameObject buttonRow = UIFactory.CreateHorizontalGroup(sceneLoaderObj, "LoadButtons", true, true, true, true, 4);
loadButton = UIFactory.CreateButton(buttonRow, "LoadSceneButton", "Load (Single)", new Color(0.1f, 0.3f, 0.3f));
UIFactory.SetLayoutElement(loadButton.Component.gameObject, minHeight: 25, minWidth: 150);
@ -367,7 +367,7 @@ namespace UnityExplorer.ObjectExplorer
TryLoadScene(LoadSceneMode.Additive, allSceneDropdown);
};
var disabledColor = new Color(0.24f, 0.24f, 0.24f);
Color disabledColor = new(0.24f, 0.24f, 0.24f);
RuntimeHelper.SetColorBlock(loadButton.Component, disabled: disabledColor);
RuntimeHelper.SetColorBlock(loadAdditiveButton.Component, disabled: disabledColor);

View File

@ -1,8 +1,6 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.SceneManagement;
using UniverseLib;
@ -65,11 +63,11 @@ namespace UnityExplorer.ObjectExplorer
if (sceneUtil == null)
throw new Exception("This version of Unity does not ship with the 'SceneUtility' class, or it was not unstripped.");
var method = sceneUtil.GetMethod("GetScenePathByBuildIndex", ReflectionUtility.FLAGS);
System.Reflection.MethodInfo method = sceneUtil.GetMethod("GetScenePathByBuildIndex", ReflectionUtility.FLAGS);
int sceneCount = SceneManager.sceneCountInBuildSettings;
for (int i = 0; i < sceneCount; i++)
{
var scenePath = (string)method.Invoke(null, new object[] { i });
string scenePath = (string)method.Invoke(null, new object[] { i });
AllSceneNames.Add(scenePath);
}
@ -85,9 +83,9 @@ namespace UnityExplorer.ObjectExplorer
internal static void Update()
{
// Inspected scene will exist if it's DontDestroyOnLoad or HideAndDontSave
bool inspectedExists =
SelectedScene.HasValue
&& ((DontDestroyExists && SelectedScene.Value.handle == -12)
bool inspectedExists =
SelectedScene.HasValue
&& ((DontDestroyExists && SelectedScene.Value.handle == -12)
|| SelectedScene.Value.handle == -1);
LoadedScenes.Clear();
@ -121,11 +119,11 @@ namespace UnityExplorer.ObjectExplorer
CurrentRootObjects = RuntimeHelper.GetRootGameObjects((Scene)SelectedScene);
else
{
var allObjects = RuntimeHelper.FindObjectsOfTypeAll(typeof(GameObject));
var objects = new List<GameObject>();
foreach (var obj in allObjects)
UnityEngine.Object[] allObjects = RuntimeHelper.FindObjectsOfTypeAll(typeof(GameObject));
List<GameObject> objects = new();
foreach (UnityEngine.Object obj in allObjects)
{
var go = obj.TryCast<GameObject>();
GameObject go = obj.TryCast<GameObject>();
if (go.transform.parent == null && !go.scene.IsValid())
objects.Add(go);
}

View File

@ -2,12 +2,9 @@
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityExplorer.Runtime;
using UniverseLib;
using UniverseLib.Input;
using UniverseLib.Utility;
namespace UnityExplorer.ObjectExplorer
@ -50,7 +47,7 @@ namespace UnityExplorer.ObjectExplorer
internal static List<object> UnityObjectSearch(string input, string customTypeInput, ChildFilter childFilter, SceneFilter sceneFilter)
{
var results = new List<object>();
List<object> results = new();
Type searchType = null;
if (!string.IsNullOrEmpty(customTypeInput))
@ -69,7 +66,7 @@ namespace UnityExplorer.ObjectExplorer
if (searchType == null)
searchType = typeof(UnityEngine.Object);
var allObjects = RuntimeHelper.FindObjectsOfTypeAll(searchType);
UnityEngine.Object[] allObjects = RuntimeHelper.FindObjectsOfTypeAll(searchType);
// perform filter comparers
@ -79,14 +76,14 @@ namespace UnityExplorer.ObjectExplorer
bool shouldFilterGOs = searchType == typeof(GameObject) || typeof(Component).IsAssignableFrom(searchType);
foreach (var obj in allObjects)
foreach (UnityEngine.Object obj in allObjects)
{
// name check
if (!string.IsNullOrEmpty(nameFilter) && !obj.name.ContainsIgnoreCase(nameFilter))
continue;
GameObject go = null;
var type = obj.GetActualType();
Type type = obj.GetActualType();
if (type == typeof(GameObject))
go = obj.TryCast<GameObject>();
@ -130,15 +127,15 @@ namespace UnityExplorer.ObjectExplorer
internal static List<object> ClassSearch(string input)
{
var list = new List<object>();
List<object> list = new();
var nameFilter = "";
string nameFilter = "";
if (!string.IsNullOrEmpty(input))
nameFilter = input;
foreach (var asm in AppDomain.CurrentDomain.GetAssemblies())
foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies())
{
foreach (var type in asm.TryGetTypes())
foreach (Type type in asm.TryGetTypes())
{
if (!string.IsNullOrEmpty(nameFilter) && !type.FullName.ContainsIgnoreCase(nameFilter))
continue;
@ -165,30 +162,30 @@ namespace UnityExplorer.ObjectExplorer
internal static List<object> InstanceSearch(string input)
{
var instances = new List<object>();
List<object> instances = new();
var nameFilter = "";
string nameFilter = "";
if (!string.IsNullOrEmpty(input))
nameFilter = input;
var flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static;
foreach (var asm in AppDomain.CurrentDomain.GetAssemblies())
BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static;
foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies())
{
// Search all non-static, non-enum classes.
foreach (var type in asm.TryGetTypes().Where(it => !(it.IsSealed && it.IsAbstract) && !it.IsEnum))
foreach (Type type in asm.TryGetTypes().Where(it => !(it.IsSealed && it.IsAbstract) && !it.IsEnum))
{
try
{
if (!string.IsNullOrEmpty(nameFilter) && !type.FullName.ContainsIgnoreCase(nameFilter))
continue;
ReflectionUtility.FindSingleton(instanceNames, type, flags, instances);
}
catch { }
}
}
return instances;
}

View File

@ -1,13 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using UnityExplorer.Config;
using UniverseLib;
@ -20,7 +14,7 @@ namespace UnityExplorer.Runtime
public static UERuntimeHelper Instance;
public static void Init()
{
{
#if CPP
Instance = new Il2CppHelper();
#else
@ -50,10 +44,10 @@ namespace UnityExplorer.Runtime
try
{
var sigs = blacklist.Split(';');
foreach (var sig in sigs)
string[] sigs = blacklist.Split(';');
foreach (string sig in sigs)
{
var s = sig.Trim();
string s = sig.Trim();
if (string.IsNullOrEmpty(s))
continue;
if (!currentBlacklist.Contains(s))
@ -65,7 +59,7 @@ namespace UnityExplorer.Runtime
ExplorerCore.LogWarning($"Exception parsing blacklist string: {ex.ReflectionExToString()}");
}
foreach (var sig in Instance.DefaultReflectionBlacklist)
foreach (string sig in Instance.DefaultReflectionBlacklist)
{
if (!currentBlacklist.Contains(sig))
currentBlacklist.Add(sig);
@ -84,7 +78,7 @@ namespace UnityExplorer.Runtime
if (string.IsNullOrEmpty(member.DeclaringType?.Namespace))
return false;
var sig = $"{member.DeclaringType.FullName}.{member.Name}";
string sig = $"{member.DeclaringType.FullName}.{member.Name}";
return currentBlacklist.Contains(sig);
}

View File

@ -2,15 +2,13 @@
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using UnityEngine;
using UnityExplorer.CacheObject;
namespace UnityExplorer.Runtime
{
internal static class UnityCrashPrevention
{
static readonly HarmonyLib.Harmony harmony = new ($"{ExplorerCore.GUID}.crashprevention");
static readonly HarmonyLib.Harmony harmony = new($"{ExplorerCore.GUID}.crashprevention");
internal static void Init()
{
@ -27,7 +25,7 @@ namespace UnityExplorer.Runtime
try
{
harmony.Patch(
HarmonyLib.AccessTools.Method(typeof(T), orig, argTypes),
HarmonyLib.AccessTools.Method(typeof(T), orig, argTypes),
new HarmonyLib.HarmonyMethod(HarmonyLib.AccessTools.Method(typeof(UnityCrashPrevention), prefix)));
}
catch //(Exception ex)

View File

@ -1,12 +1,8 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using UnityEngine;
using UnityExplorer.UI;
using UnityExplorer.CacheObject.IValues;
#if CPP
using UnhollowerRuntimeLib;
using UnhollowerBaseLib;
@ -74,7 +70,7 @@ namespace UnityExplorer.Tests
{
get
{
var list = new List<object>();
List<object> list = new();
int count = UnityEngine.Random.Range(0, 100);
for (int i = 0; i < count; i++)
list.Add(GetRandomObject());
@ -178,6 +174,7 @@ namespace UnityExplorer.Tests
public static Il2CppSystem.Collections.IDictionary IL2CPP_IDict;
public static Il2CppSystem.Collections.IList IL2CPP_IList;
public static Dictionary<Il2CppSystem.Object, Il2CppSystem.Object> IL2CPP_BoxedDict;
public static Il2CppSystem.Array IL2CPP_NonGenericArray;
public static Il2CppSystem.Object IL2CPP_BoxedInt;
public static Il2CppSystem.Int32 IL2CPP_Int;
@ -191,6 +188,9 @@ namespace UnityExplorer.Tests
private static void Init_IL2CPP()
{
ExplorerCore.Log("IL2CPP 0: Non-generic array");
IL2CPP_NonGenericArray = new Il2CppStructArray<int>(5).TryCast<Il2CppSystem.Array>();
ExplorerCore.Log($"IL2CPP 1: Il2Cpp Dictionary<string, string>");
IL2CPP_Dict = new Il2CppSystem.Collections.Generic.Dictionary<string, string>();
IL2CPP_Dict.Add("key1", "value1");
@ -209,12 +209,12 @@ namespace UnityExplorer.Tests
IL2CPP_HashTable.Add("key3", "value3");
ExplorerCore.Log($"IL2CPP 3: Il2Cpp IDictionary");
var dict2 = new Il2CppSystem.Collections.Generic.Dictionary<string, string>();
Il2CppSystem.Collections.Generic.Dictionary<string, string> dict2 = new Il2CppSystem.Collections.Generic.Dictionary<string, string>();
dict2.Add("key1", "value1");
IL2CPP_IDict = dict2.TryCast<Il2CppSystem.Collections.IDictionary>();
ExplorerCore.Log($"IL2CPP 4: Il2Cpp List of Il2Cpp Object");
var list = new Il2CppSystem.Collections.Generic.List<Il2CppSystem.Object>(5);
Il2CppSystem.Collections.Generic.List<Il2CppSystem.Object> list = new Il2CppSystem.Collections.Generic.List<Il2CppSystem.Object>(5);
list.Add("one");
list.Add("two");
IL2CPP_IList = list.TryCast<Il2CppSystem.Collections.IList>();
@ -240,14 +240,14 @@ namespace UnityExplorer.Tests
// boxed enum test
try
{
var cppType = Il2CppType.Of<CameraClearFlags>();
if (cppType != null)
Il2CppSystem.Type cppType = Il2CppType.Of<CameraClearFlags>();
if (cppType is not null)
{
var boxedEnum = Il2CppSystem.Enum.Parse(cppType, "Color");
Il2CppSystem.Object boxedEnum = Il2CppSystem.Enum.Parse(cppType, "Color");
IL2CPP_listOfBoxedObjects.Add(boxedEnum);
}
var structBox = Vector3.one.BoxIl2CppObject();
Il2CppSystem.Object structBox = Vector3.one.BoxIl2CppObject();
IL2CPP_listOfBoxedObjects.Add(structBox);
}

View File

@ -1,8 +1,4 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using UnityEngine;
using UnityExplorer.Config;
using UniverseLib;
@ -45,7 +41,7 @@ namespace UnityExplorer.UI
ConfigManager.Target_Display.Value = 0;
return;
}
}
ActiveDisplayIndex = display;
ActiveDisplay.Activate();
@ -72,7 +68,7 @@ namespace UnityExplorer.UI
yield return null;
yield return null;
foreach (var panel in UIManager.UIPanels.Values)
foreach (Panels.UEPanel panel in UIManager.UIPanels.Values)
{
panel.EnsureValidSize();
panel.EnsureValidPosition();

19
src/UI/ExplorerUIBase.cs Normal file
View File

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UniverseLib.UI;
using UniverseLib.UI.Panels;
namespace UnityExplorer.UI
{
internal class ExplorerUIBase : UIBase
{
public ExplorerUIBase(string id, Action updateMethod) : base(id, updateMethod) { }
protected override PanelManager CreatePanelManager()
{
return new UEPanelManager(this);
}
}
}

View File

@ -1,10 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine;
using UnityEngine.UI;
using UniverseLib.Input;
using UniverseLib.UI;
namespace UnityExplorer.UI
@ -48,7 +43,7 @@ namespace UnityExplorer.UI
popupLabel = UIFactory.CreateLabel(UIManager.UIRoot, "ClipboardNotification", "", TextAnchor.MiddleCenter);
popupLabel.rectTransform.sizeDelta = new(500, 100);
popupLabel.gameObject.AddComponent<Outline>();
var popupGroup = popupLabel.gameObject.AddComponent<CanvasGroup>();
CanvasGroup popupGroup = popupLabel.gameObject.AddComponent<CanvasGroup>();
popupGroup.blocksRaycasts = false;
}
}

View File

@ -2,34 +2,36 @@
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using UniverseLib.Input;
using UnityExplorer.Runtime;
using UnityExplorer.UI;
using UnityExplorer.UI.Panels;
using UniverseLib.UI.Widgets;
using UnityExplorer.UI.Widgets.AutoComplete;
using UniverseLib;
using UniverseLib.Input;
using UniverseLib.UI;
using UniverseLib.UI.Models;
using UniverseLib.UI.Widgets.ButtonList;
using UniverseLib.UI.Widgets.ScrollView;
using UniverseLib.Utility;
using UniverseLib.UI.Models;
namespace UnityExplorer.UI.Widgets.AutoComplete
namespace UnityExplorer.UI.Panels
{
// Shared modal panel for "AutoComplete" suggestions.
// A data source implements ISuggestionProvider and uses TakeOwnership and ReleaseOwnership
// for control, and SetSuggestions to set the actual suggestion data.
public class AutoCompleteModal : UIPanel
public class AutoCompleteModal : UEPanel
{
public static AutoCompleteModal Instance => UIManager.GetPanel<AutoCompleteModal>(UIManager.Panels.AutoCompleter);
public override string Name => "AutoCompleter";
public override UIManager.Panels PanelType => UIManager.Panels.AutoCompleter;
public override int MinWidth => -1;
public override int MinHeight => -1;
public override int MinWidth => 100;
public override int MinHeight => 25;
public override Vector2 DefaultAnchorMin => new(MIN_X, 0.4f);
public override Vector2 DefaultAnchorMax => new(0.68f, MAX_Y);
const float MIN_X = 0.42f;
const float MAX_Y = 0.6f;
public override bool CanDragAndResize => true;
public override bool ShouldSaveActiveState => false;
@ -48,10 +50,10 @@ namespace UnityExplorer.UI.Widgets.AutoComplete
public static bool Suggesting(ISuggestionProvider handler) => CurrentHandler == handler && Instance.UIRoot.activeSelf;
public AutoCompleteModal()
public AutoCompleteModal(UIBase owner) : base(owner)
{
OnPanelsReordered += UIPanel_OnPanelsReordered;
OnClickedOutsidePanels += AutoCompleter_OnClickedOutsidePanels;
UIManager.UiBase.Panels.OnPanelsReordered += UIPanel_OnPanelsReordered;
UIManager.UiBase.Panels.OnClickedOutsidePanels += AutoCompleter_OnClickedOutsidePanels;
}
public static void TakeOwnership(ISuggestionProvider provider)
@ -184,7 +186,7 @@ namespace UnityExplorer.UI.Widgets.AutoComplete
private void OnCellClicked(int dataIndex)
{
var suggestion = Suggestions[dataIndex];
Suggestion suggestion = Suggestions[dataIndex];
CurrentHandler.OnSuggestionClicked(suggestion);
}
@ -198,7 +200,7 @@ namespace UnityExplorer.UI.Widgets.AutoComplete
return;
}
var suggestion = Suggestions[index];
Suggestion suggestion = Suggestions[index];
cell.Button.ButtonText.text = suggestion.DisplayText;
if (CurrentHandler.AllowNavigation && index == SelectedIndex && setFirstCell)
@ -230,7 +232,7 @@ namespace UnityExplorer.UI.Widgets.AutoComplete
if (CurrentHandler.AnchorToCaretPosition)
{
var textGen = input.Component.cachedInputTextGenerator;
TextGenerator textGen = input.Component.cachedInputTextGenerator;
int caretIdx = Math.Max(0, Math.Min(textGen.characterCount - 1, input.Component.caretPosition));
// normalize the caret horizontal position
@ -267,7 +269,7 @@ namespace UnityExplorer.UI.Widgets.AutoComplete
if (!this.UIRoot || !this.UIRoot.activeInHierarchy)
return;
if (this.UIRoot.transform.GetSiblingIndex() != UIManager.PanelHolder.transform.childCount - 1)
if (this.UIRoot.transform.GetSiblingIndex() != UIManager.UiBase.Panels.PanelHolder.transform.childCount - 1)
{
if (CurrentHandler != null)
ReleaseOwnership(CurrentHandler);
@ -276,46 +278,36 @@ namespace UnityExplorer.UI.Widgets.AutoComplete
}
}
// UI Construction
const float MIN_X = 0.42f;
const float MAX_Y = 0.6f;
protected internal override void DoSetDefaultPosAndAnchors()
public override void OnFinishResize()
{
Rect.pivot = new Vector2(0f, 1f);
Rect.anchorMin = new Vector2(MIN_X, 0.4f);
Rect.anchorMax = new Vector2(0.68f, MAX_Y);
}
public override void OnFinishResize(RectTransform panel)
{
float xDiff = panel.anchorMin.x - MIN_X;
float yDiff = panel.anchorMax.y - MAX_Y;
float xDiff = Rect.anchorMin.x - MIN_X;
float yDiff = Rect.anchorMax.y - MAX_Y;
if (xDiff != 0 || yDiff != 0)
{
panel.anchorMin = new(MIN_X, panel.anchorMin.y - yDiff);
panel.anchorMax = new(panel.anchorMax.x - xDiff, MAX_Y);
Rect.anchorMin = new(MIN_X, Rect.anchorMin.y - yDiff);
Rect.anchorMax = new(Rect.anchorMax.x - xDiff, MAX_Y);
}
base.OnFinishResize(panel);
base.OnFinishResize();
}
public override void ConstructPanelContent()
// UI Construction
protected override void ConstructPanelContent()
{
// hide the titlebar
this.TitleBar.gameObject.SetActive(false);
buttonListDataHandler = new ButtonListHandler<Suggestion, ButtonCell>(scrollPool, GetEntries, SetCell, ShouldDisplay, OnCellClicked);
scrollPool = UIFactory.CreateScrollPool<ButtonCell>(this.uiContent, "AutoCompleter", out GameObject scrollObj,
scrollPool = UIFactory.CreateScrollPool<ButtonCell>(this.ContentRoot, "AutoCompleter", out GameObject scrollObj,
out GameObject scrollContent);
scrollPool.Initialize(buttonListDataHandler);
UIFactory.SetLayoutElement(scrollObj, flexibleHeight: 9999);
UIFactory.SetLayoutGroup<VerticalLayoutGroup>(scrollContent, true, false, true, false);
navigationTipRow = UIFactory.CreateHorizontalGroup(this.uiContent, "BottomRow", true, true, true, true, 0, new Vector4(2, 2, 2, 2));
navigationTipRow = UIFactory.CreateHorizontalGroup(this.ContentRoot, "BottomRow", true, true, true, true, 0, new Vector4(2, 2, 2, 2));
UIFactory.SetLayoutElement(navigationTipRow, minHeight: 20, flexibleWidth: 9999);
UIFactory.CreateLabel(navigationTipRow, "HelpText", "Up/Down to select, Enter to use, Esc to close",
TextAnchor.MiddleLeft, Color.grey, false, 13);

View File

@ -1,14 +1,8 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using UnityExplorer.Config;
using UnityExplorer.CSConsole;
using UnityExplorer.UI.Widgets;
using UniverseLib;
using UniverseLib.UI;
using UniverseLib.UI.Models;
@ -16,12 +10,15 @@ using UniverseLib.UI.Widgets;
namespace UnityExplorer.UI.Panels
{
public class CSConsolePanel : UIPanel
public class CSConsolePanel : UEPanel
{
public override string Name => "C# Console";
public override UIManager.Panels PanelType => UIManager.Panels.CSConsole;
public override int MinWidth => 750;
public override int MinHeight => 300;
public override Vector2 DefaultAnchorMin => new(0.4f, 0.175f);
public override Vector2 DefaultAnchorMax => new(0.85f, 0.925f);
public InputFieldScroller InputScroller { get; private set; }
public InputFieldRef Input => InputScroller.InputField;
@ -41,6 +38,10 @@ namespace UnityExplorer.UI.Panels
public Action<bool> OnAutoIndentToggled;
public Action OnPanelResized;
public CSConsolePanel(UIBase owner) : base(owner)
{
}
private void InvokeOnValueChanged(string value)
{
if (value.Length == UniversalUI.MAX_INPUTFIELD_CHARS)
@ -58,49 +59,41 @@ namespace UnityExplorer.UI.Panels
// UI Construction
public override void OnFinishResize(RectTransform panel)
public override void OnFinishResize()
{
OnPanelResized?.Invoke();
}
protected internal override void DoSetDefaultPosAndAnchors()
{
Rect.localPosition = Vector2.zero;
Rect.pivot = new Vector2(0f, 1f);
Rect.anchorMin = new Vector2(0.4f, 0.175f);
Rect.anchorMax = new Vector2(0.85f, 0.925f);
}
public override void ConstructPanelContent()
protected override void ConstructPanelContent()
{
// Tools Row
var toolsRow = UIFactory.CreateHorizontalGroup(this.uiContent, "ToggleRow", false, false, true, true, 5, new Vector4(8, 8, 10, 5),
GameObject toolsRow = UIFactory.CreateHorizontalGroup(this.ContentRoot, "ToggleRow", false, false, true, true, 5, new Vector4(8, 8, 10, 5),
default, TextAnchor.MiddleLeft);
UIFactory.SetLayoutElement(toolsRow, minHeight: 25, flexibleHeight: 0, flexibleWidth: 9999);
// Buttons
var compileButton = UIFactory.CreateButton(toolsRow, "CompileButton", "Compile", new Color(0.33f, 0.5f, 0.33f));
ButtonRef compileButton = UIFactory.CreateButton(toolsRow, "CompileButton", "Compile", new Color(0.33f, 0.5f, 0.33f));
UIFactory.SetLayoutElement(compileButton.Component.gameObject, minHeight: 28, minWidth: 130, flexibleHeight: 0);
compileButton.ButtonText.fontSize = 15;
compileButton.OnClick += () => { OnCompileClicked?.Invoke(); };
var resetButton = UIFactory.CreateButton(toolsRow, "ResetButton", "Reset", new Color(0.33f, 0.33f, 0.33f));
ButtonRef resetButton = UIFactory.CreateButton(toolsRow, "ResetButton", "Reset", new Color(0.33f, 0.33f, 0.33f));
UIFactory.SetLayoutElement(resetButton.Component.gameObject, minHeight: 28, minWidth: 80, flexibleHeight: 0);
resetButton.ButtonText.fontSize = 15;
resetButton.OnClick += () => { OnResetClicked?.Invoke(); };
// Help dropdown
var helpDrop = UIFactory.CreateDropdown(toolsRow, "HelpDropdown", out var dropdown, "Help", 14, null);
GameObject helpDrop = UIFactory.CreateDropdown(toolsRow, "HelpDropdown", out Dropdown dropdown, "Help", 14, null);
UIFactory.SetLayoutElement(helpDrop, minHeight: 25, minWidth: 100);
HelpDropdown = dropdown;
HelpDropdown.onValueChanged.AddListener((int val) => { this.OnHelpDropdownChanged?.Invoke(val); });
// Enable Ctrl+R toggle
var ctrlRToggleObj = UIFactory.CreateToggle(toolsRow, "CtrlRToggle", out var CtrlRToggle, out Text ctrlRToggleText);
GameObject ctrlRToggleObj = UIFactory.CreateToggle(toolsRow, "CtrlRToggle", out Toggle CtrlRToggle, out Text ctrlRToggleText);
UIFactory.SetLayoutElement(ctrlRToggleObj, minWidth: 150, flexibleWidth: 0, minHeight: 25);
ctrlRToggleText.alignment = TextAnchor.UpperLeft;
ctrlRToggleText.text = "Compile on Ctrl+R";
@ -108,7 +101,7 @@ namespace UnityExplorer.UI.Panels
// Enable Suggestions toggle
var suggestToggleObj = UIFactory.CreateToggle(toolsRow, "SuggestionToggle", out var SuggestionsToggle, out Text suggestToggleText);
GameObject suggestToggleObj = UIFactory.CreateToggle(toolsRow, "SuggestionToggle", out Toggle SuggestionsToggle, out Text suggestToggleText);
UIFactory.SetLayoutElement(suggestToggleObj, minWidth: 120, flexibleWidth: 0, minHeight: 25);
suggestToggleText.alignment = TextAnchor.UpperLeft;
suggestToggleText.text = "Suggestions";
@ -116,7 +109,7 @@ namespace UnityExplorer.UI.Panels
// Enable Auto-indent toggle
var autoIndentToggleObj = UIFactory.CreateToggle(toolsRow, "IndentToggle", out var AutoIndentToggle, out Text autoIndentToggleText);
GameObject autoIndentToggleObj = UIFactory.CreateToggle(toolsRow, "IndentToggle", out Toggle AutoIndentToggle, out Text autoIndentToggleText);
UIFactory.SetLayoutElement(autoIndentToggleObj, minWidth: 120, flexibleWidth: 0, minHeight: 25);
autoIndentToggleText.alignment = TextAnchor.UpperLeft;
autoIndentToggleText.text = "Auto-indent";
@ -124,7 +117,7 @@ namespace UnityExplorer.UI.Panels
// Console Input
var inputArea = UIFactory.CreateUIObject("InputGroup", uiContent);
GameObject inputArea = UIFactory.CreateUIObject("InputGroup", ContentRoot);
UIFactory.SetLayoutElement(inputArea, flexibleWidth: 9999, flexibleHeight: 9999);
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(inputArea, false, true, true, true);
inputArea.AddComponent<Image>().color = Color.white;
@ -132,8 +125,8 @@ namespace UnityExplorer.UI.Panels
// line numbers
var linesHolder = UIFactory.CreateUIObject("LinesHolder", inputArea);
var linesRect = linesHolder.GetComponent<RectTransform>();
GameObject linesHolder = UIFactory.CreateUIObject("LinesHolder", inputArea);
RectTransform linesRect = linesHolder.GetComponent<RectTransform>();
linesRect.pivot = new Vector2(0, 1);
linesRect.anchorMin = new Vector2(0, 0);
linesRect.anchorMax = new Vector2(0, 1);
@ -149,8 +142,8 @@ namespace UnityExplorer.UI.Panels
int fontSize = 16;
var inputObj = UIFactory.CreateScrollInputField(inputArea, "ConsoleInput", ConsoleController.STARTUP_TEXT,
out var inputScroller, fontSize);
GameObject inputObj = UIFactory.CreateScrollInputField(inputArea, "ConsoleInput", ConsoleController.STARTUP_TEXT,
out InputFieldScroller inputScroller, fontSize);
InputScroller = inputScroller;
ConsoleController.defaultInputFieldAlpha = Input.Component.selectionColor.a;
Input.OnValueChanged += InvokeOnValueChanged;
@ -173,8 +166,8 @@ namespace UnityExplorer.UI.Panels
Input.PlaceholderText.fontSize = fontSize;
// Lexer highlight text overlay
var highlightTextObj = UIFactory.CreateUIObject("HighlightText", InputText.gameObject);
var highlightTextRect = highlightTextObj.GetComponent<RectTransform>();
GameObject highlightTextObj = UIFactory.CreateUIObject("HighlightText", InputText.gameObject);
RectTransform highlightTextRect = highlightTextObj.GetComponent<RectTransform>();
highlightTextRect.pivot = new Vector2(0, 1);
highlightTextRect.anchorMin = Vector2.zero;
highlightTextRect.anchorMax = Vector2.one;

View File

@ -1,29 +1,24 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.CacheObject;
using UnityExplorer.CacheObject.Views;
using UnityExplorer.Config;
using UniverseLib;
using UniverseLib.Input;
using UniverseLib.UI;
using UniverseLib.UI.Widgets;
using UniverseLib.Utility;
namespace UnityExplorer.UI.Panels
{
public class ClipboardPanel : UIPanel
public class ClipboardPanel : UEPanel
{
public static object Current { get; private set; }
public override UIManager.Panels PanelType => UIManager.Panels.Clipboard;
public override string Name => "Clipboard";
public override UIManager.Panels PanelType => UIManager.Panels.Clipboard;
public override int MinWidth => 500;
public override int MinHeight => 95;
public override Vector2 DefaultAnchorMin => new(0.1f, 0.05f);
public override Vector2 DefaultAnchorMax => new(0.4f, 0.15f);
public override bool CanDragAndResize => true;
public override bool NavButtonWanted => true;
public override bool ShouldSaveActiveState => true;
@ -31,6 +26,10 @@ namespace UnityExplorer.UI.Panels
private static Text CurrentPasteLabel;
public ClipboardPanel(UIBase owner) : base(owner)
{
}
public static void Copy(object obj)
{
Current = obj;
@ -41,14 +40,14 @@ namespace UnityExplorer.UI.Panels
public static bool TryPaste(Type targetType, out object paste)
{
paste = Current;
var pasteType = Current?.GetActualType();
Type pasteType = Current?.GetActualType();
if (Current != null && !targetType.IsAssignableFrom(pasteType))
{
Notification.ShowMessage($"Cannot assign '{pasteType.Name}' to '{targetType.Name}'!");
return false;
}
Notification.ShowMessage("Pasted!");
return true;
}
@ -74,35 +73,35 @@ namespace UnityExplorer.UI.Panels
InspectorManager.Inspect(Current);
}
protected internal override void DoSetDefaultPosAndAnchors()
public override void SetDefaultSizeAndPosition()
{
base.SetDefaultSizeAndPosition();
this.Rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, MinWidth);
this.Rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, MinHeight);
this.Rect.anchorMin = new Vector2(0.1f, 0.05f);
this.Rect.anchorMax = new Vector2(0.4f, 0.15f);
}
public override void ConstructPanelContent()
protected override void ConstructPanelContent()
{
this.UIRoot.GetComponent<Image>().color = new(0.1f, 0.1f, 0.1f);
// Actual panel content
var firstRow = UIFactory.CreateHorizontalGroup(uiContent, "FirstRow", false, false, true, true, 5, new(2,2,2,2), new(1,1,1,0));
GameObject firstRow = UIFactory.CreateHorizontalGroup(ContentRoot, "FirstRow", false, false, true, true, 5, new(2, 2, 2, 2), new(1, 1, 1, 0));
UIFactory.SetLayoutElement(firstRow, minHeight: 25, flexibleWidth: 999);
// Title for "Current Paste:"
var currentPasteTitle = UIFactory.CreateLabel(firstRow, "CurrentPasteTitle", "Current paste:", TextAnchor.MiddleLeft, color: Color.grey);
Text currentPasteTitle = UIFactory.CreateLabel(firstRow, "CurrentPasteTitle", "Current paste:", TextAnchor.MiddleLeft, color: Color.grey);
UIFactory.SetLayoutElement(currentPasteTitle.gameObject, minHeight: 25, minWidth: 100, flexibleWidth: 999);
// Clear clipboard button
var clearButton = UIFactory.CreateButton(firstRow, "ClearPasteButton", "Clear Clipboard");
UniverseLib.UI.Models.ButtonRef clearButton = UIFactory.CreateButton(firstRow, "ClearPasteButton", "Clear Clipboard");
UIFactory.SetLayoutElement(clearButton.Component.gameObject, minWidth: 120, minHeight: 25, flexibleWidth: 0);
clearButton.OnClick += () => Copy(null);
// Current Paste info row
var currentPasteHolder = UIFactory.CreateHorizontalGroup(uiContent, "SecondRow", false, false, true, true, 0,
GameObject currentPasteHolder = UIFactory.CreateHorizontalGroup(ContentRoot, "SecondRow", false, false, true, true, 0,
new(2, 2, 2, 2), childAlignment: TextAnchor.UpperCenter);
// Actual current paste info label
@ -111,7 +110,7 @@ namespace UnityExplorer.UI.Panels
UpdateCurrentPasteInfo();
// Inspect button
var inspectButton = UIFactory.CreateButton(currentPasteHolder, "InspectButton", "Inspect");
UniverseLib.UI.Models.ButtonRef inspectButton = UIFactory.CreateButton(currentPasteHolder, "InspectButton", "Inspect");
UIFactory.SetLayoutElement(inspectButton.Component.gameObject, minHeight: 25, flexibleHeight: 0, minWidth: 80, flexibleWidth: 0);
inspectButton.OnClick += InspectClipboard;
}

View File

@ -0,0 +1,392 @@
using HarmonyLib;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using UniverseLib;
using UniverseLib.Input;
using UniverseLib.UI;
using UniverseLib.UI.Models;
using UniverseLib.Utility;
namespace UnityExplorer.UI.Panels
{
internal class FreeCamPanel : UEPanel
{
public FreeCamPanel(UIBase owner) : base(owner)
{
}
public override string Name => "Freecam";
public override UIManager.Panels PanelType => UIManager.Panels.Freecam;
public override int MinWidth => 400;
public override int MinHeight => 320;
public override Vector2 DefaultAnchorMin => new(0.4f, 0.4f);
public override Vector2 DefaultAnchorMax => new(0.6f, 0.6f);
public override bool NavButtonWanted => true;
public override bool ShouldSaveActiveState => true;
internal static bool inFreeCamMode;
internal static bool usingGameCamera;
internal static Camera ourCamera;
internal static Camera lastMainCamera;
internal static FreeCamBehaviour freeCamScript;
internal static float desiredMoveSpeed = 10f;
internal static Vector3 originalCameraPosition;
internal static Quaternion originalCameraRotation;
internal static Vector3? currentUserCameraPosition;
internal static Quaternion? currentUserCameraRotation;
internal static Vector3 previousMousePosition;
internal static Vector3 lastSetCameraPosition;
static ButtonRef startStopButton;
static Toggle useGameCameraToggle;
static InputFieldRef positionInput;
static InputFieldRef moveSpeedInput;
static ButtonRef inspectButton;
internal static void BeginFreecam()
{
inFreeCamMode = true;
previousMousePosition = InputManager.MousePosition;
CacheMainCamera();
SetupFreeCamera();
inspectButton.GameObject.SetActive(true);
}
static void CacheMainCamera()
{
Camera currentMain = Camera.main;
if (currentMain)
{
lastMainCamera = currentMain;
originalCameraPosition = currentMain.transform.position;
originalCameraRotation = currentMain.transform.rotation;
if (currentUserCameraPosition == null)
{
currentUserCameraPosition = currentMain.transform.position;
currentUserCameraRotation = currentMain.transform.rotation;
}
}
else
originalCameraRotation = Quaternion.identity;
}
static void SetupFreeCamera()
{
if (useGameCameraToggle.isOn)
{
if (!lastMainCamera)
{
ExplorerCore.LogWarning($"There is no previous Camera found, reverting to default Free Cam.");
useGameCameraToggle.isOn = false;
}
else
{
usingGameCamera = true;
ourCamera = lastMainCamera;
}
}
if (!useGameCameraToggle.isOn)
{
usingGameCamera = false;
if (lastMainCamera)
lastMainCamera.enabled = false;
}
if (!ourCamera)
{
ourCamera = new GameObject("UE_Freecam").AddComponent<Camera>();
ourCamera.gameObject.tag = "MainCamera";
GameObject.DontDestroyOnLoad(ourCamera.gameObject);
ourCamera.gameObject.hideFlags = HideFlags.HideAndDontSave;
}
if (!freeCamScript)
freeCamScript = ourCamera.gameObject.AddComponent<FreeCamBehaviour>();
ourCamera.transform.position = (Vector3)currentUserCameraPosition;
ourCamera.transform.rotation = (Quaternion)currentUserCameraRotation;
ourCamera.gameObject.SetActive(true);
ourCamera.enabled = true;
}
internal static void EndFreecam()
{
inFreeCamMode = false;
if (usingGameCamera)
{
ourCamera = null;
if (lastMainCamera)
{
lastMainCamera.transform.position = originalCameraPosition;
lastMainCamera.transform.rotation = originalCameraRotation;
}
}
if (ourCamera)
ourCamera.gameObject.SetActive(false);
else
inspectButton.GameObject.SetActive(false);
if (freeCamScript)
{
GameObject.Destroy(freeCamScript);
freeCamScript = null;
}
if (lastMainCamera)
lastMainCamera.enabled = true;
}
static void SetCameraPosition(Vector3 pos)
{
if (!ourCamera || lastSetCameraPosition == pos)
return;
ourCamera.transform.position = pos;
lastSetCameraPosition = pos;
}
internal static void UpdatePositionInput()
{
if (!ourCamera)
return;
lastSetCameraPosition = ourCamera.transform.position;
positionInput.Text = ParseUtility.ToStringForInput<Vector3>(lastSetCameraPosition);
}
// ~~~~~~~~ UI construction / callbacks ~~~~~~~~
protected override void ConstructPanelContent()
{
startStopButton = UIFactory.CreateButton(ContentRoot, "ToggleButton", "Freecam");
UIFactory.SetLayoutElement(startStopButton.GameObject, minWidth: 150, minHeight: 25, flexibleWidth: 9999);
startStopButton.OnClick += StartStopButton_OnClick;
SetToggleButtonState();
AddSpacer(5);
GameObject toggleObj = UIFactory.CreateToggle(ContentRoot, "UseGameCameraToggle", out useGameCameraToggle, out Text toggleText);
UIFactory.SetLayoutElement(toggleObj, minHeight: 25, flexibleWidth: 9999);
useGameCameraToggle.onValueChanged.AddListener(OnUseGameCameraToggled);
useGameCameraToggle.isOn = false;
toggleText.text = "Use Game Camera?";
AddSpacer(5);
GameObject posRow = AddInputField("Position", "Freecam Pos:", "eg. 0 0 0", out positionInput, PositionInput_OnEndEdit);
ButtonRef resetPosButton = UIFactory.CreateButton(posRow, "ResetButton", "Reset");
UIFactory.SetLayoutElement(resetPosButton.GameObject, minWidth: 70, minHeight: 25);
resetPosButton.OnClick += OnResetPosButtonClicked;
AddSpacer(5);
AddInputField("MoveSpeed", "Move Speed:", "Default: 1", out moveSpeedInput, MoveSpeedInput_OnEndEdit);
moveSpeedInput.Text = desiredMoveSpeed.ToString();
AddSpacer(5);
string instructions = @"Controls:
- WASD / Arrows: Movement
- Space / PgUp: Move up
- LeftCtrl / PgDown: Move down
- Right Mouse Button: Free look
- Shift: Super speed";
Text instructionsText = UIFactory.CreateLabel(ContentRoot, "Instructions", instructions, TextAnchor.UpperLeft);
UIFactory.SetLayoutElement(instructionsText.gameObject, flexibleWidth: 9999, flexibleHeight: 9999);
AddSpacer(5);
inspectButton = UIFactory.CreateButton(ContentRoot, "InspectButton", "Inspect Free Camera");
UIFactory.SetLayoutElement(inspectButton.GameObject, flexibleWidth: 9999, minHeight: 25);
inspectButton.OnClick += () => { InspectorManager.Inspect(ourCamera); };
inspectButton.GameObject.SetActive(false);
AddSpacer(5);
}
void AddSpacer(int height)
{
GameObject obj = UIFactory.CreateUIObject("Spacer", ContentRoot);
UIFactory.SetLayoutElement(obj, minHeight: height, flexibleHeight: 0);
}
GameObject AddInputField(string name, string labelText, string placeHolder, out InputFieldRef inputField, Action<string> onInputEndEdit)
{
GameObject row = UIFactory.CreateHorizontalGroup(ContentRoot, $"{name}_Group", false, false, true, true, 3, default, new(1, 1, 1, 0));
Text posLabel = UIFactory.CreateLabel(row, $"{name}_Label", labelText);
UIFactory.SetLayoutElement(posLabel.gameObject, minWidth: 100, minHeight: 25);
inputField = UIFactory.CreateInputField(row, $"{name}_Input", placeHolder);
UIFactory.SetLayoutElement(inputField.GameObject, minWidth: 125, minHeight: 25, flexibleWidth: 9999);
inputField.Component.GetOnEndEdit().AddListener(onInputEndEdit);
return row;
}
void StartStopButton_OnClick()
{
EventSystemHelper.SetSelectedGameObject(null);
if (inFreeCamMode)
EndFreecam();
else
BeginFreecam();
SetToggleButtonState();
}
void SetToggleButtonState()
{
if (inFreeCamMode)
{
RuntimeHelper.SetColorBlockAuto(startStopButton.Component, new(0.4f, 0.2f, 0.2f));
startStopButton.ButtonText.text = "End Freecam";
}
else
{
RuntimeHelper.SetColorBlockAuto(startStopButton.Component, new(0.2f, 0.4f, 0.2f));
startStopButton.ButtonText.text = "Begin Freecam";
}
}
void OnUseGameCameraToggled(bool value)
{
EventSystemHelper.SetSelectedGameObject(null);
if (!inFreeCamMode)
return;
EndFreecam();
BeginFreecam();
}
void OnResetPosButtonClicked()
{
currentUserCameraPosition = originalCameraPosition;
currentUserCameraRotation = originalCameraRotation;
if (inFreeCamMode && ourCamera)
{
ourCamera.transform.position = (Vector3)currentUserCameraPosition;
ourCamera.transform.rotation = (Quaternion)currentUserCameraRotation;
}
}
void PositionInput_OnEndEdit(string input)
{
EventSystemHelper.SetSelectedGameObject(null);
if (!ParseUtility.TryParse(input, out Vector3 parsed, out Exception parseEx))
{
ExplorerCore.LogWarning($"Could not parse position to Vector3: {parseEx.ReflectionExToString()}");
UpdatePositionInput();
return;
}
SetCameraPosition(parsed);
}
void MoveSpeedInput_OnEndEdit(string input)
{
EventSystemHelper.SetSelectedGameObject(null);
if (!ParseUtility.TryParse(input, out float parsed, out Exception parseEx))
{
ExplorerCore.LogWarning($"Could not parse value: {parseEx.ReflectionExToString()}");
moveSpeedInput.Text = desiredMoveSpeed.ToString();
return;
}
desiredMoveSpeed = parsed;
}
}
internal class FreeCamBehaviour : MonoBehaviour
{
#if CPP
static FreeCamBehaviour()
{
UnhollowerRuntimeLib.ClassInjector.RegisterTypeInIl2Cpp<FreeCamBehaviour>();
}
public FreeCamBehaviour(IntPtr ptr) : base(ptr) { }
#endif
internal void Update()
{
if (FreeCamPanel.inFreeCamMode)
{
if (!FreeCamPanel.ourCamera)
{
FreeCamPanel.EndFreecam();
return;
}
Transform transform = FreeCamPanel.ourCamera.transform;
FreeCamPanel.currentUserCameraPosition = transform.position;
FreeCamPanel.currentUserCameraRotation = transform.rotation;
float moveSpeed = FreeCamPanel.desiredMoveSpeed * Time.deltaTime;
if (InputManager.GetKey(KeyCode.LeftShift) || InputManager.GetKey(KeyCode.RightShift))
moveSpeed *= 10f;
if (InputManager.GetKey(KeyCode.LeftArrow) || InputManager.GetKey(KeyCode.A))
transform.position += transform.right * -1 * moveSpeed;
if (InputManager.GetKey(KeyCode.RightArrow) || InputManager.GetKey(KeyCode.D))
transform.position += transform.right * moveSpeed;
if (InputManager.GetKey(KeyCode.UpArrow) || InputManager.GetKey(KeyCode.W))
transform.position += transform.forward * moveSpeed;
if (InputManager.GetKey(KeyCode.DownArrow) || InputManager.GetKey(KeyCode.S))
transform.position += transform.forward * -1 * moveSpeed;
if (InputManager.GetKey(KeyCode.Space) || InputManager.GetKey(KeyCode.PageUp))
transform.position += transform.up * moveSpeed;
if (InputManager.GetKey(KeyCode.LeftControl) || InputManager.GetKey(KeyCode.PageDown))
transform.position += transform.up * -1 * moveSpeed;
if (InputManager.GetMouseButton(1))
{
Vector3 mouseDelta = InputManager.MousePosition - FreeCamPanel.previousMousePosition;
float newRotationX = transform.localEulerAngles.y + mouseDelta.x * 0.3f;
float newRotationY = transform.localEulerAngles.x - mouseDelta.y * 0.3f;
transform.localEulerAngles = new Vector3(newRotationY, newRotationX, 0f);
}
FreeCamPanel.UpdatePositionInput();
FreeCamPanel.previousMousePosition = InputManager.MousePosition;
}
}
}
}

View File

@ -1,12 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.Config;
using UnityExplorer.Hooks;
using UnityExplorer.UI.Widgets;
using UnityExplorer.UI.Widgets.AutoComplete;
using UniverseLib.UI;
using UniverseLib.UI.Models;
@ -15,7 +9,7 @@ using UniverseLib.UI.Widgets.ScrollView;
namespace UnityExplorer.UI.Panels
{
public class HookManagerPanel : UIPanel
public class HookManagerPanel : UEPanel
{
public enum Pages
{
@ -27,9 +21,12 @@ namespace UnityExplorer.UI.Panels
public override UIManager.Panels PanelType => UIManager.Panels.HookManager;
public override string Name => "Hooks";
public override bool ShowByDefault => false;
public override int MinWidth => 500;
public override int MinHeight => 600;
public override bool ShowByDefault => false;
public override Vector2 DefaultAnchorMin => new(0.5f, 0.5f);
public override Vector2 DefaultAnchorMax => new(0.5f, 0.5f);
public Pages CurrentPage { get; private set; } = Pages.CurrentHooks;
@ -43,11 +40,16 @@ namespace UnityExplorer.UI.Panels
private InputFieldRef AddHooksMethodFilterInput;
private GameObject editorPanel;
public InputFieldScroller EditorInputScroller { get; private set; }
public InputFieldRef EditorInput => EditorInputScroller.InputField;
public Text EditorInputText { get; private set; }
public Text EditorHighlightText { get; private set; }
public HookManagerPanel(UIBase owner) : base(owner)
{
}
private void OnClassInputAddClicked()
{
HookManager.Instance.OnClassSelectedForHooks(this.classSelectorInputField.Text);
@ -79,15 +81,23 @@ namespace UnityExplorer.UI.Panels
public void ResetMethodFilter() => AddHooksMethodFilterInput.Text = string.Empty;
public override void ConstructPanelContent()
public override void SetDefaultSizeAndPosition()
{
base.SetDefaultSizeAndPosition();
this.Rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, MinWidth);
this.Rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, MinHeight);
}
protected override void ConstructPanelContent()
{
// ~~~~~~~~~ Active hooks scroll pool
currentHooksPanel = UIFactory.CreateUIObject("CurrentHooksPanel", this.uiContent);
currentHooksPanel = UIFactory.CreateUIObject("CurrentHooksPanel", this.ContentRoot);
UIFactory.SetLayoutElement(currentHooksPanel, flexibleHeight: 9999, flexibleWidth: 9999);
UIFactory.SetLayoutGroup<VerticalLayoutGroup>(currentHooksPanel, true, true, true, true);
var addRow = UIFactory.CreateHorizontalGroup(currentHooksPanel, "AddRow", false, true, true, true, 4,
GameObject addRow = UIFactory.CreateHorizontalGroup(currentHooksPanel, "AddRow", false, true, true, true, 4,
new Vector4(2, 2, 2, 2), new Color(0.2f, 0.2f, 0.2f));
UIFactory.SetLayoutElement(addRow, minHeight: 30, flexibleWidth: 9999);
@ -95,31 +105,31 @@ namespace UnityExplorer.UI.Panels
UIFactory.SetLayoutElement(classSelectorInputField.Component.gameObject, flexibleWidth: 9999);
new TypeCompleter(typeof(object), classSelectorInputField, true, false);
var addButton = UIFactory.CreateButton(addRow, "AddButton", "Add Hooks");
ButtonRef addButton = UIFactory.CreateButton(addRow, "AddButton", "Add Hooks");
UIFactory.SetLayoutElement(addButton.Component.gameObject, minWidth: 100, minHeight: 25);
addButton.OnClick += OnClassInputAddClicked;
var hooksLabel = UIFactory.CreateLabel(currentHooksPanel, "HooksLabel", "Current Hooks", TextAnchor.MiddleCenter);
Text hooksLabel = UIFactory.CreateLabel(currentHooksPanel, "HooksLabel", "Current Hooks", TextAnchor.MiddleCenter);
UIFactory.SetLayoutElement(hooksLabel.gameObject, minHeight: 30, flexibleWidth: 9999);
HooksScrollPool = UIFactory.CreateScrollPool<HookCell>(currentHooksPanel, "HooksScrollPool",
HooksScrollPool = UIFactory.CreateScrollPool<HookCell>(currentHooksPanel, "HooksScrollPool",
out GameObject hooksScroll, out GameObject hooksContent);
UIFactory.SetLayoutElement(hooksScroll, flexibleHeight: 9999);
HooksScrollPool.Initialize(HookManager.Instance);
// ~~~~~~~~~ Add hooks panel
addHooksPanel = UIFactory.CreateUIObject("AddHooksPanel", this.uiContent);
addHooksPanel = UIFactory.CreateUIObject("AddHooksPanel", this.ContentRoot);
UIFactory.SetLayoutElement(addHooksPanel, flexibleHeight: 9999, flexibleWidth: 9999);
UIFactory.SetLayoutGroup<VerticalLayoutGroup>(addHooksPanel, true, true, true, true);
addHooksLabel = UIFactory.CreateLabel(addHooksPanel, "AddLabel", "NOT SET", TextAnchor.MiddleCenter);
UIFactory.SetLayoutElement(addHooksLabel.gameObject, minHeight: 30, minWidth: 100, flexibleWidth: 9999);
var buttonRow = UIFactory.CreateHorizontalGroup(addHooksPanel, "ButtonRow", false, false, true, true, 5);
GameObject buttonRow = UIFactory.CreateHorizontalGroup(addHooksPanel, "ButtonRow", false, false, true, true, 5);
UIFactory.SetLayoutElement(buttonRow, minHeight: 25, flexibleWidth: 9999);
var doneButton = UIFactory.CreateButton(buttonRow, "DoneButton", "Done", new Color(0.2f, 0.3f, 0.2f));
ButtonRef doneButton = UIFactory.CreateButton(buttonRow, "DoneButton", "Done", new Color(0.2f, 0.3f, 0.2f));
UIFactory.SetLayoutElement(doneButton.Component.gameObject, minHeight: 25, flexibleWidth: 9999);
doneButton.OnClick += HookManager.Instance.DoneAddingHooks;
@ -136,30 +146,30 @@ namespace UnityExplorer.UI.Panels
// ~~~~~~~~~ Hook source editor panel
editorPanel = UIFactory.CreateUIObject("HookSourceEditor", this.uiContent);
editorPanel = UIFactory.CreateUIObject("HookSourceEditor", this.ContentRoot);
UIFactory.SetLayoutElement(editorPanel, flexibleHeight: 9999, flexibleWidth: 9999);
UIFactory.SetLayoutGroup<VerticalLayoutGroup>(editorPanel, true, true, true, true);
var editorLabel = UIFactory.CreateLabel(editorPanel,
"EditorLabel",
Text editorLabel = UIFactory.CreateLabel(editorPanel,
"EditorLabel",
"Edit Harmony patch source as desired. Accepted method names are Prefix, Postfix, Finalizer and Transpiler (can define multiple).\n\n" +
"Hooks are temporary! Please copy the source into your IDE to avoid losing work if you wish to keep it!",
"Hooks are temporary! Please copy the source into your IDE to avoid losing work if you wish to keep it!",
TextAnchor.MiddleLeft);
UIFactory.SetLayoutElement(editorLabel.gameObject, minHeight: 25, flexibleWidth: 9999);
var editorButtonRow = UIFactory.CreateHorizontalGroup(editorPanel, "ButtonRow", false, false, true, true, 5);
GameObject editorButtonRow = UIFactory.CreateHorizontalGroup(editorPanel, "ButtonRow", false, false, true, true, 5);
UIFactory.SetLayoutElement(editorButtonRow, minHeight: 25, flexibleWidth: 9999);
var editorSaveButton = UIFactory.CreateButton(editorButtonRow, "DoneButton", "Save and Return", new Color(0.2f, 0.3f, 0.2f));
ButtonRef editorSaveButton = UIFactory.CreateButton(editorButtonRow, "DoneButton", "Save and Return", new Color(0.2f, 0.3f, 0.2f));
UIFactory.SetLayoutElement(editorSaveButton.Component.gameObject, minHeight: 25, flexibleWidth: 9999);
editorSaveButton.OnClick += HookManager.Instance.EditorInputSave;
var editorDoneButton = UIFactory.CreateButton(editorButtonRow, "DoneButton", "Cancel and Return", new Color(0.2f, 0.2f, 0.2f));
ButtonRef editorDoneButton = UIFactory.CreateButton(editorButtonRow, "DoneButton", "Cancel and Return", new Color(0.2f, 0.2f, 0.2f));
UIFactory.SetLayoutElement(editorDoneButton.Component.gameObject, minHeight: 25, flexibleWidth: 9999);
editorDoneButton.OnClick += HookManager.Instance.EditorInputCancel;
int fontSize = 16;
var inputObj = UIFactory.CreateScrollInputField(editorPanel, "EditorInput", "", out var inputScroller, fontSize);
GameObject inputObj = UIFactory.CreateScrollInputField(editorPanel, "EditorInput", "", out InputFieldScroller inputScroller, fontSize);
EditorInputScroller = inputScroller;
EditorInput.OnValueChanged += HookManager.Instance.OnEditorInputChanged;
@ -171,8 +181,8 @@ namespace UnityExplorer.UI.Panels
EditorInput.PlaceholderText.fontSize = fontSize;
// Lexer highlight text overlay
var highlightTextObj = UIFactory.CreateUIObject("HighlightText", EditorInputText.gameObject);
var highlightTextRect = highlightTextObj.GetComponent<RectTransform>();
GameObject highlightTextObj = UIFactory.CreateUIObject("HighlightText", EditorInputText.gameObject);
RectTransform highlightTextRect = highlightTextObj.GetComponent<RectTransform>();
highlightTextRect.pivot = new Vector2(0, 1);
highlightTextRect.anchorMin = Vector2.zero;
highlightTextRect.anchorMax = Vector2.one;
@ -191,13 +201,5 @@ namespace UnityExplorer.UI.Panels
editorPanel.SetActive(false);
}
protected internal override void DoSetDefaultPosAndAnchors()
{
this.Rect.anchorMin = new Vector2(0.5f, 0.5f);
this.Rect.anchorMax = new Vector2(0.5f, 0.5f);
this.Rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, MinWidth);
this.Rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, MinHeight);
}
}
}

View File

@ -1,27 +1,22 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.Config;
using UnityExplorer.Inspectors;
using UniverseLib.UI;
namespace UnityExplorer.UI.Panels
{
public class InspectorPanel : UIPanel
public class InspectorPanel : UEPanel
{
public static InspectorPanel Instance { get; private set; }
public InspectorPanel() { Instance = this; }
public override string Name => "Inspector";
public override UIManager.Panels PanelType => UIManager.Panels.Inspector;
public override bool ShouldSaveActiveState => false;
public override int MinWidth => 810;
public override int MinHeight => 350;
public override Vector2 DefaultAnchorMin => new(0.35f, 0.175f);
public override Vector2 DefaultAnchorMax => new(0.8f, 0.925f);
public GameObject NavbarHolder;
public Dropdown MouseInspectDropdown;
@ -31,34 +26,31 @@ namespace UnityExplorer.UI.Panels
public static float CurrentPanelWidth => Instance.Rect.rect.width;
public static float CurrentPanelHeight => Instance.Rect.rect.height;
public InspectorPanel(UIBase owner) : base(owner)
{
Instance = this;
}
public override void Update()
{
InspectorManager.Update();
}
public override void OnFinishResize(RectTransform panel)
public override void OnFinishResize()
{
base.OnFinishResize(panel);
base.OnFinishResize();
InspectorManager.PanelWidth = this.Rect.rect.width;
InspectorManager.OnPanelResized(panel.rect.width);
InspectorManager.OnPanelResized(Rect.rect.width);
}
protected internal override void DoSetDefaultPosAndAnchors()
protected override void ConstructPanelContent()
{
Rect.localPosition = Vector2.zero;
Rect.pivot = new Vector2(0f, 1f);
Rect.anchorMin = new Vector2(0.35f, 0.175f);
Rect.anchorMax = new Vector2(0.8f, 0.925f);
}
public override void ConstructPanelContent()
{
var closeHolder = this.TitleBar.transform.Find("CloseHolder").gameObject;
GameObject closeHolder = this.TitleBar.transform.Find("CloseHolder").gameObject;
// Inspect under mouse dropdown on title bar
var mouseDropdown = UIFactory.CreateDropdown(closeHolder, "MouseInspectDropdown", out MouseInspectDropdown, "Mouse Inspect", 14,
GameObject mouseDropdown = UIFactory.CreateDropdown(closeHolder, "MouseInspectDropdown", out MouseInspectDropdown, "Mouse Inspect", 14,
MouseInspector.OnDropdownSelect);
UIFactory.SetLayoutElement(mouseDropdown, minHeight: 25, minWidth: 140);
MouseInspectDropdown.options.Add(new Dropdown.OptionData("Mouse Inspect"));
@ -68,7 +60,7 @@ namespace UnityExplorer.UI.Panels
// add close all button to titlebar
var closeAllBtn = UIFactory.CreateButton(closeHolder.gameObject, "CloseAllBtn", "Close All",
UniverseLib.UI.Models.ButtonRef closeAllBtn = UIFactory.CreateButton(closeHolder.gameObject, "CloseAllBtn", "Close All",
new Color(0.3f, 0.2f, 0.2f));
UIFactory.SetLayoutElement(closeAllBtn.Component.gameObject, minHeight: 25, minWidth: 80);
closeAllBtn.Component.transform.SetSiblingIndex(closeAllBtn.Component.transform.GetSiblingIndex() - 1);
@ -76,19 +68,19 @@ namespace UnityExplorer.UI.Panels
// this.UIRoot.GetComponent<Mask>().enabled = false;
UIFactory.SetLayoutGroup<VerticalLayoutGroup>(this.uiContent, true, true, true, true, 4, padLeft: 5, padRight: 5);
UIFactory.SetLayoutGroup<VerticalLayoutGroup>(this.ContentRoot, true, true, true, true, 4, padLeft: 5, padRight: 5);
this.NavbarHolder = UIFactory.CreateGridGroup(this.uiContent, "Navbar", new Vector2(200, 22), new Vector2(4, 4),
this.NavbarHolder = UIFactory.CreateGridGroup(this.ContentRoot, "Navbar", new Vector2(200, 22), new Vector2(4, 4),
new Color(0.05f, 0.05f, 0.05f));
//UIFactory.SetLayoutElement(NavbarHolder, flexibleWidth: 9999, minHeight: 0, preferredHeight: 0, flexibleHeight: 9999);
NavbarHolder.AddComponent<ContentSizeFitter>().verticalFit = ContentSizeFitter.FitMode.PreferredSize;
this.ContentHolder = UIFactory.CreateVerticalGroup(this.uiContent, "ContentHolder", true, true, true, true, 0, default,
this.ContentHolder = UIFactory.CreateVerticalGroup(this.ContentRoot, "ContentHolder", true, true, true, true, 0, default,
new Color(0.1f, 0.1f, 0.1f));
UIFactory.SetLayoutElement(ContentHolder, flexibleHeight: 9999);
ContentRect = ContentHolder.GetComponent<RectTransform>();
UIManager.SetPanelActive(PanelType, false);
this.SetActive(false);
}
}
}

View File

@ -3,15 +3,12 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.Config;
using UnityExplorer.UI.Widgets;
using UniverseLib;
using UniverseLib.UI;
using UniverseLib.UI.Models;
using UniverseLib.UI.Widgets;
using UniverseLib.UI.Widgets.ScrollView;
using UniverseLib.Utility;
@ -19,7 +16,7 @@ namespace UnityExplorer.UI.Panels
{
// TODO move the logic out of this class into a LogUtil class (also move ExplorerCore.Log into that)
public class LogPanel : UIPanel, ICellPoolDataSource<ConsoleLogCell>
public class LogPanel : UEPanel, ICellPoolDataSource<ConsoleLogCell>
{
public struct LogInfo
{
@ -29,7 +26,7 @@ namespace UnityExplorer.UI.Panels
public LogInfo(string message, LogType type) { this.message = message; this.type = type; }
}
private static readonly List<LogInfo> Logs = new List<LogInfo>();
private static readonly List<LogInfo> Logs = new();
private static string CurrentStreamPath;
public override string Name => "Log";
@ -37,6 +34,9 @@ namespace UnityExplorer.UI.Panels
public override int MinWidth => 350;
public override int MinHeight => 75;
public override Vector2 DefaultAnchorMin => new(0.5f, 0.03f);
public override Vector2 DefaultAnchorMax => new(0.9f, 0.2f);
public override bool ShouldSaveActiveState => true;
public override bool ShowByDefault => true;
@ -44,7 +44,7 @@ namespace UnityExplorer.UI.Panels
private static ScrollPool<ConsoleLogCell> logScrollPool;
public LogPanel()
public LogPanel(UIBase owner) : base(owner)
{
SetupIO();
}
@ -67,16 +67,16 @@ namespace UnityExplorer.UI.Panels
private void SetupIO()
{
var fileName = $"UnityExplorer {DateTime.Now:u}.txt";
string fileName = $"UnityExplorer {DateTime.Now:u}.txt";
fileName = IOUtility.EnsureValidFilename(fileName);
var path = Path.Combine(ExplorerCore.ExplorerFolder, "Logs");
string path = Path.Combine(ExplorerCore.ExplorerFolder, "Logs");
CurrentStreamPath = IOUtility.EnsureValidFilePath(Path.Combine(path, fileName));
// clean old log(s)
var files = Directory.GetFiles(path);
string[] files = Directory.GetFiles(path);
if (files.Length >= 10)
{
var sorted = files.ToList();
List<string> sorted = files.ToList();
// sort by 'datetime.ToString("u")' will put the oldest ones first
sorted.Sort();
for (int i = 0; i < files.Length - 9; i++)
@ -113,7 +113,7 @@ namespace UnityExplorer.UI.Panels
// Cell pool
private static readonly Dictionary<LogType, Color> logColors = new Dictionary<LogType, Color>
private static readonly Dictionary<LogType, Color> logColors = new()
{
{ LogType.Log, Color.white },
{ LogType.Warning, Color.yellow },
@ -122,8 +122,8 @@ namespace UnityExplorer.UI.Panels
{ LogType.Exception, Color.red },
};
private readonly Color logEvenColor = new Color(0.34f, 0.34f, 0.34f);
private readonly Color logOddColor = new Color(0.28f, 0.28f, 0.28f);
private readonly Color logEvenColor = new(0.34f, 0.34f, 0.34f);
private readonly Color logOddColor = new(0.28f, 0.28f, 0.28f);
public void OnCellBorrowed(ConsoleLogCell cell) { }
@ -138,50 +138,42 @@ namespace UnityExplorer.UI.Panels
// Logs are displayed in reverse order (newest at top)
index = Logs.Count - index - 1;
var log = Logs[index];
LogInfo log = Logs[index];
cell.IndexLabel.text = $"{index}:";
cell.Input.Text = log.message;
cell.Input.Component.textComponent.color = logColors[log.type];
var color = index % 2 == 0 ? logEvenColor : logOddColor;
Color color = index % 2 == 0 ? logEvenColor : logOddColor;
RuntimeHelper.SetColorBlock(cell.Input.Component, color);
}
protected internal override void DoSetDefaultPosAndAnchors()
{
Rect.localPosition = Vector2.zero;
Rect.pivot = new Vector2(0f, 1f);
Rect.anchorMin = new Vector2(0.5f, 0.03f);
Rect.anchorMax = new Vector2(0.9f, 0.2f);
}
// UI Construction
public override void ConstructPanelContent()
protected override void ConstructPanelContent()
{
// Log scroll pool
logScrollPool = UIFactory.CreateScrollPool<ConsoleLogCell>(this.uiContent, "Logs", out GameObject scrollObj,
logScrollPool = UIFactory.CreateScrollPool<ConsoleLogCell>(this.ContentRoot, "Logs", out GameObject scrollObj,
out GameObject scrollContent, new Color(0.03f, 0.03f, 0.03f));
UIFactory.SetLayoutElement(scrollObj, flexibleWidth: 9999, flexibleHeight: 9999);
// Buttons and toggles
var optionsRow = UIFactory.CreateUIObject("OptionsRow", this.uiContent);
GameObject optionsRow = UIFactory.CreateUIObject("OptionsRow", this.ContentRoot);
UIFactory.SetLayoutElement(optionsRow, minHeight: 25, flexibleWidth: 9999);
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(optionsRow, false, false, true, true, 5, 2, 2, 2, 2);
var clearButton = UIFactory.CreateButton(optionsRow, "ClearButton", "Clear", new Color(0.2f, 0.2f, 0.2f));
ButtonRef clearButton = UIFactory.CreateButton(optionsRow, "ClearButton", "Clear", new Color(0.2f, 0.2f, 0.2f));
UIFactory.SetLayoutElement(clearButton.Component.gameObject, minHeight: 23, flexibleHeight: 0, minWidth: 60);
clearButton.OnClick += ClearLogs;
clearButton.Component.transform.SetSiblingIndex(1);
var fileButton = UIFactory.CreateButton(optionsRow, "FileButton", "Open Log File", new Color(0.2f, 0.2f, 0.2f));
ButtonRef fileButton = UIFactory.CreateButton(optionsRow, "FileButton", "Open Log File", new Color(0.2f, 0.2f, 0.2f));
UIFactory.SetLayoutElement(fileButton.Component.gameObject, minHeight: 23, flexibleHeight: 0, minWidth: 100);
fileButton.OnClick += OpenLogFile;
fileButton.Component.transform.SetSiblingIndex(2);
var unityToggle = UIFactory.CreateToggle(optionsRow, "UnityLogToggle", out var toggle, out var toggleText);
GameObject unityToggle = UIFactory.CreateToggle(optionsRow, "UnityLogToggle", out Toggle toggle, out Text toggleText);
UIFactory.SetLayoutElement(unityToggle, minHeight: 25, minWidth: 150);
toggleText.text = "Log Unity Debug?";
toggle.isOn = ConfigManager.Log_Unity_Debug.Value;

View File

@ -1,20 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.Generic;
using UnityEngine;
using UnityExplorer.Inspectors.MouseInspectors;
using UnityExplorer.UI.Widgets;
using UniverseLib;
using UniverseLib.UI;
using UniverseLib.UI.Widgets;
using UniverseLib.UI.Widgets.ButtonList;
using UniverseLib.UI.Widgets.ScrollView;
using UniverseLib.Utility;
namespace UnityExplorer.UI.Panels
{
public class MouseInspectorResultsPanel : UIPanel
public class MouseInspectorResultsPanel : UEPanel
{
public override UIManager.Panels PanelType => UIManager.Panels.UIInspectorResults;
@ -22,6 +16,9 @@ namespace UnityExplorer.UI.Panels
public override int MinWidth => 500;
public override int MinHeight => 500;
public override Vector2 DefaultAnchorMin => new(0.5f, 0.5f);
public override Vector2 DefaultAnchorMax => new(0.5f, 0.5f);
public override bool CanDragAndResize => true;
public override bool NavButtonWanted => false;
public override bool ShouldSaveActiveState => false;
@ -30,6 +27,10 @@ namespace UnityExplorer.UI.Panels
private ButtonListHandler<GameObject, ButtonCell> dataHandler;
private ScrollPool<ButtonCell> buttonScrollPool;
public MouseInspectorResultsPanel(UIBase owner) : base(owner)
{
}
public void ShowResults()
{
dataHandler.RefreshData();
@ -53,27 +54,27 @@ namespace UnityExplorer.UI.Panels
if (index >= UiInspector.LastHitObjects.Count)
return;
var obj = UiInspector.LastHitObjects[index];
GameObject obj = UiInspector.LastHitObjects[index];
cell.Button.ButtonText.text = $"<color=cyan>{obj.name}</color> ({obj.transform.GetTransformPath(true)})";
}
public override void ConstructPanelContent()
public override void SetDefaultSizeAndPosition()
{
base.SetDefaultSizeAndPosition();
this.Rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, 500f);
this.Rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 500f);
}
protected override void ConstructPanelContent()
{
dataHandler = new ButtonListHandler<GameObject, ButtonCell>(buttonScrollPool, GetEntries, SetCell, ShouldDisplayCell, OnCellClicked);
buttonScrollPool = UIFactory.CreateScrollPool<ButtonCell>(this.uiContent, "ResultsList", out GameObject scrollObj,
buttonScrollPool = UIFactory.CreateScrollPool<ButtonCell>(this.ContentRoot, "ResultsList", out GameObject scrollObj,
out GameObject scrollContent);
buttonScrollPool.Initialize(dataHandler);
UIFactory.SetLayoutElement(scrollObj, flexibleHeight: 9999);
}
protected internal override void DoSetDefaultPosAndAnchors()
{
this.Rect.anchorMin = new Vector2(0.5f, 0.5f);
this.Rect.anchorMax = new Vector2(0.5f, 0.5f);
this.Rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, 500f);
this.Rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 500f);
}
}
}

View File

@ -1,28 +1,23 @@
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.Config;
using UniverseLib.UI.Models;
using UnityExplorer.ObjectExplorer;
using UnityExplorer.UI.Widgets;
using UniverseLib.UI;
using UniverseLib;
using UniverseLib.UI;
using UniverseLib.UI.Models;
namespace UnityExplorer.UI.Panels
{
public class ObjectExplorerPanel : UIPanel
public class ObjectExplorerPanel : UEPanel
{
public override string Name => "Object Explorer";
public override UIManager.Panels PanelType => UIManager.Panels.ObjectExplorer;
public override int MinWidth => 350;
public override int MinHeight => 200;
public override Vector2 DefaultAnchorMin => new(0.125f, 0.175f);
public override Vector2 DefaultAnchorMax => new(0.325f, 0.925f);
public SceneExplorer SceneExplorer;
public ObjectSearch ObjectSearch;
@ -31,18 +26,22 @@ namespace UnityExplorer.UI.Panels
public override bool ShouldSaveActiveState => true;
public int SelectedTab = 0;
private readonly List<UIModel> tabPages = new List<UIModel>();
private readonly List<ButtonRef> tabButtons = new List<ButtonRef>();
private readonly List<UIModel> tabPages = new();
private readonly List<ButtonRef> tabButtons = new();
public ObjectExplorerPanel(UIBase owner) : base(owner)
{
}
public void SetTab(int tabIndex)
{
if (SelectedTab != -1)
DisableTab(SelectedTab);
var content = tabPages[tabIndex];
UIModel content = tabPages[tabIndex];
content.SetActive(true);
var button = tabButtons[tabIndex];
ButtonRef button = tabButtons[tabIndex];
RuntimeHelper.SetColorBlock(button.Component, UniversalUI.EnabledButtonColor, UniversalUI.EnabledButtonColor * 1.2f);
SelectedTab = tabIndex;
@ -88,28 +87,20 @@ namespace UnityExplorer.UI.Panels
SetTab(SelectedTab);
}
protected internal override void DoSetDefaultPosAndAnchors()
{
Rect.localPosition = Vector2.zero;
Rect.pivot = new Vector2(0f, 1f);
Rect.anchorMin = new Vector2(0.125f, 0.175f);
Rect.anchorMax = new Vector2(0.325f, 0.925f);
}
public override void ConstructPanelContent()
protected override void ConstructPanelContent()
{
// Tab bar
var tabGroup = UIFactory.CreateHorizontalGroup(uiContent, "TabBar", true, true, true, true, 2, new Vector4(2, 2, 2, 2));
GameObject tabGroup = UIFactory.CreateHorizontalGroup(ContentRoot, "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(uiContent);
SceneExplorer.ConstructUI(ContentRoot);
tabPages.Add(SceneExplorer);
// Object search
ObjectSearch = new ObjectSearch(this);
ObjectSearch.ConstructUI(uiContent);
ObjectSearch.ConstructUI(ContentRoot);
tabPages.Add(ObjectSearch);
// set up tabs
@ -117,12 +108,12 @@ namespace UnityExplorer.UI.Panels
AddTabButton(tabGroup, "Object Search");
// default active state: Active
UIManager.SetPanelActive(PanelType, true);
this.SetActive(true);
}
private void AddTabButton(GameObject tabGroup, string label)
{
var button = UIFactory.CreateButton(tabGroup, $"Button_{label}", label);
ButtonRef button = UIFactory.CreateButton(tabGroup, $"Button_{label}", label);
int idx = tabButtons.Count;
//button.onClick.AddListener(() => { SetTab(idx); });

View File

@ -1,32 +1,29 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.Config;
using UnityExplorer.CacheObject;
using UnityExplorer.CacheObject.Views;
using UnityExplorer.UI.Widgets;
using UniverseLib.UI.Widgets;
using UnityExplorer.Config;
using UniverseLib.UI;
using UniverseLib.UI.Widgets.ScrollView;
namespace UnityExplorer.UI.Panels
{
public class OptionsPanel : UIPanel, ICacheObjectController, ICellPoolDataSource<ConfigEntryCell>
public class OptionsPanel : UEPanel, ICacheObjectController, ICellPoolDataSource<ConfigEntryCell>
{
public override string Name => "Options";
public override UIManager.Panels PanelType => UIManager.Panels.Options;
public override int MinWidth => 600;
public override int MinHeight => 200;
public override Vector2 DefaultAnchorMin => new(0.5f, 0.1f);
public override Vector2 DefaultAnchorMax => new(0.5f, 0.85f);
public override bool ShouldSaveActiveState => false;
public override bool ShowByDefault => false;
// Entry holders
private readonly List<CacheConfigEntry> configEntries = new List<CacheConfigEntry>();
private readonly List<CacheConfigEntry> configEntries = new();
// ICacheObjectController
public CacheObjectBase ParentCacheObject => null;
@ -37,14 +34,19 @@ namespace UnityExplorer.UI.Panels
// ICellPoolDataSource
public int ItemCount => configEntries.Count;
public OptionsPanel()
public OptionsPanel(UIBase owner) : base(owner)
{
foreach (var entry in ConfigManager.ConfigElements)
foreach (KeyValuePair<string, IConfigElement> entry in ConfigManager.ConfigElements)
{
var cache = new CacheConfigEntry(entry.Value);
cache.Owner = this;
CacheConfigEntry cache = new(entry.Value)
{
Owner = this
};
configEntries.Add(cache);
}
foreach (CacheConfigEntry config in configEntries)
config.UpdateValueFromSource();
}
public void OnCellBorrowed(ConfigEntryCell cell)
@ -58,32 +60,30 @@ namespace UnityExplorer.UI.Panels
// UI Construction
protected internal override void DoSetDefaultPosAndAnchors()
public override void SetDefaultSizeAndPosition()
{
Rect.localPosition = Vector2.zero;
Rect.pivot = new Vector2(0f, 1f);
Rect.anchorMin = new Vector2(0.5f, 0.1f);
Rect.anchorMax = new Vector2(0.5f, 0.85f);
base.SetDefaultSizeAndPosition();
Rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, 600f);
}
public override void ConstructPanelContent()
protected override void ConstructPanelContent()
{
// Save button
var saveBtn = UIFactory.CreateButton(this.uiContent, "Save", "Save Options", new Color(0.2f, 0.3f, 0.2f));
UniverseLib.UI.Models.ButtonRef saveBtn = UIFactory.CreateButton(this.ContentRoot, "Save", "Save Options", new Color(0.2f, 0.3f, 0.2f));
UIFactory.SetLayoutElement(saveBtn.Component.gameObject, flexibleWidth: 9999, minHeight: 30, flexibleHeight: 0);
saveBtn.OnClick += ConfigManager.Handler.SaveConfig;
// Config entries
var scrollPool = UIFactory.CreateScrollPool<ConfigEntryCell>(this.uiContent, "ConfigEntries", out GameObject scrollObj,
ScrollPool<ConfigEntryCell> scrollPool = UIFactory.CreateScrollPool<ConfigEntryCell>(
this.ContentRoot,
"ConfigEntries",
out GameObject scrollObj,
out GameObject scrollContent);
scrollPool.Initialize(this);
foreach (var config in configEntries)
config.UpdateValueFromSource();
}
}
}

View File

@ -1,492 +0,0 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
using UniverseLib.Input;
using UniverseLib.UI.Models;
using UnityExplorer.UI.Widgets.AutoComplete;
using UniverseLib.UI;
using UniverseLib;
using UniverseLib.Utility;
namespace UnityExplorer.UI.Panels
{
public class PanelDragger
{
private enum MouseState
{
Down,
Held,
NotPressed
}
#region Static
public static bool Resizing { get; private set; }
public static bool ResizePrompting => resizeCursorObj && resizeCursorObj.activeSelf;
public static GameObject resizeCursorObj;
internal static bool wasAnyDragging;
internal static List<PanelDragger> Instances = new();
private static bool handledInstanceThisFrame;
static PanelDragger()
{
UIPanel.OnPanelsReordered += OnPanelsReordered;
}
internal static void ForceEnd()
{
resizeCursorObj.SetActive(false);
wasAnyDragging = false;
Resizing = false;
foreach (var instance in Instances)
{
instance.WasDragging = false;
instance.WasResizing = false;
}
}
public static void OnPanelsReordered()
{
Instances.Sort((a, b) => b.Panel.GetSiblingIndex().CompareTo(a.Panel.GetSiblingIndex()));
// move AutoCompleter to bottom
if (AutoCompleteModal.Instance != null)
{
var idx = Instances.IndexOf(AutoCompleteModal.Instance.Dragger);
Instances.RemoveAt(idx);
Instances.Insert(0, AutoCompleteModal.Instance.Dragger);
}
}
public static void UpdateInstances()
{
if (!DisplayManager.MouseInTargetDisplay)
return;
if (!resizeCursorObj)
CreateCursorUI();
MouseState state;
if (InputManager.GetMouseButtonDown(0))
state = MouseState.Down;
else if (InputManager.GetMouseButton(0))
state = MouseState.Held;
else
state = MouseState.NotPressed;
var mousePos = DisplayManager.MousePosition;
handledInstanceThisFrame = false;
foreach (var instance in Instances)
{
if (!instance.Panel.gameObject.activeSelf)
continue;
instance.Update(state, mousePos);
if (handledInstanceThisFrame)
break;
}
if (wasAnyDragging && state == MouseState.NotPressed)
{
foreach (var instance in Instances)
instance.WasDragging = false;
wasAnyDragging = false;
}
}
#endregion
// Instance
public UIPanel UIPanel { get; private set; }
public bool AllowDragAndResize => UIPanel.CanDragAndResize;
public RectTransform Panel { get; set; }
public event Action<RectTransform> OnFinishResize;
public event Action<RectTransform> OnFinishDrag;
// Dragging
public RectTransform DragableArea { get; set; }
public bool WasDragging { get; set; }
private Vector2 lastDragPosition;
// Resizing
private const int RESIZE_THICKNESS = 10;
private bool WasResizing { get; set; }
private ResizeTypes currentResizeType = ResizeTypes.NONE;
private Vector2 lastResizePos;
private bool WasHoveringResize => resizeCursorObj.activeInHierarchy;
private ResizeTypes lastResizeHoverType;
private Rect totalResizeRect;
public PanelDragger(RectTransform dragArea, RectTransform panelToDrag, UIPanel panel)
{
this.UIPanel = panel;
Instances.Add(this);
DragableArea = dragArea;
Panel = panelToDrag;
UpdateResizeCache();
}
public void Destroy()
{
if (resizeCursorObj)
GameObject.Destroy(resizeCursorObj);
if (Instances.Contains(this))
Instances.Remove(this);
}
private void Update(MouseState state, Vector3 rawMousePos)
{
ResizeTypes type;
Vector3 resizePos = Panel.InverseTransformPoint(rawMousePos);
bool inResizePos = !UIManager.NavBarRect.rect.Contains(UIManager.NavBarRect.InverseTransformPoint(rawMousePos))
&& MouseInResizeArea(resizePos);
Vector3 dragPos = DragableArea.InverseTransformPoint(rawMousePos);
bool inDragPos = DragableArea.rect.Contains(dragPos);
if (WasHoveringResize && resizeCursorObj)
UpdateHoverImagePos();
switch (state)
{
case MouseState.Down:
if (inDragPos || inResizePos)
UIManager.SetPanelActive(Panel, true);
if (inDragPos)
{
if (AllowDragAndResize)
OnBeginDrag();
handledInstanceThisFrame = true;
return;
}
else if (inResizePos)
{
type = GetResizeType(resizePos);
if (type != ResizeTypes.NONE)
OnBeginResize(type);
handledInstanceThisFrame = true;
}
break;
case MouseState.Held:
if (WasDragging)
{
OnDrag();
handledInstanceThisFrame = true;
}
else if (WasResizing)
{
OnResize();
handledInstanceThisFrame = true;
}
break;
case MouseState.NotPressed:
if (AllowDragAndResize && inDragPos)
{
if (WasDragging)
OnEndDrag();
if (WasHoveringResize)
OnHoverResizeEnd();
handledInstanceThisFrame = true;
}
else if (inResizePos || WasResizing)
{
if (WasResizing)
OnEndResize();
type = GetResizeType(resizePos);
if (type != ResizeTypes.NONE)
OnHoverResize(type);
else if (WasHoveringResize)
OnHoverResizeEnd();
handledInstanceThisFrame = true;
}
else if (WasHoveringResize)
OnHoverResizeEnd();
break;
}
return;
}
#region DRAGGING
public void OnBeginDrag()
{
wasAnyDragging = true;
WasDragging = true;
lastDragPosition = DisplayManager.MousePosition;
}
public void OnDrag()
{
var mousePos = DisplayManager.MousePosition;
Vector2 diff = (Vector2)mousePos - lastDragPosition;
lastDragPosition = mousePos;
Panel.localPosition = Panel.localPosition + (Vector3)diff;
UIPanel.EnsureValidPosition(Panel);
}
public void OnEndDrag()
{
WasDragging = false;
OnFinishDrag?.Invoke(Panel);
}
#endregion
#region RESIZE
private readonly Dictionary<ResizeTypes, Rect> m_resizeMask = new()
{
{ ResizeTypes.Top, default },
{ ResizeTypes.Left, default },
{ ResizeTypes.Right, default },
{ ResizeTypes.Bottom, default },
};
[Flags]
public enum ResizeTypes : ulong
{
NONE = 0,
Top = 1,
Left = 2,
Right = 4,
Bottom = 8,
TopLeft = Top | Left,
TopRight = Top | Right,
BottomLeft = Bottom | Left,
BottomRight = Bottom | Right,
}
// private const int HALF_THICKESS = RESIZE_THICKNESS / 2;
private const int DBL_THICKESS = RESIZE_THICKNESS * 2;
private void UpdateResizeCache()
{
totalResizeRect = new Rect(Panel.rect.x - RESIZE_THICKNESS + 1,
Panel.rect.y - RESIZE_THICKNESS + 1,
Panel.rect.width + DBL_THICKESS - 2,
Panel.rect.height + DBL_THICKESS - 2);
// calculate the four cross sections to use as flags
if (AllowDragAndResize)
{
m_resizeMask[ResizeTypes.Bottom] = new Rect(
totalResizeRect.x,
totalResizeRect.y,
totalResizeRect.width,
RESIZE_THICKNESS);
m_resizeMask[ResizeTypes.Left] = new Rect(
totalResizeRect.x,
totalResizeRect.y,
RESIZE_THICKNESS,
totalResizeRect.height);
m_resizeMask[ResizeTypes.Top] = new Rect(
totalResizeRect.x,
Panel.rect.y + Panel.rect.height - 2,
totalResizeRect.width,
RESIZE_THICKNESS);
m_resizeMask[ResizeTypes.Right] = new Rect(
totalResizeRect.x + Panel.rect.width + RESIZE_THICKNESS - 2,
totalResizeRect.y,
RESIZE_THICKNESS,
totalResizeRect.height);
}
}
private bool MouseInResizeArea(Vector2 mousePos)
{
return totalResizeRect.Contains(mousePos);
}
private ResizeTypes GetResizeType(Vector2 mousePos)
{
// Calculate which part of the resize area we're in, if any.
// More readable method commented out below.
int mask = 0;
mask |= (int)ResizeTypes.Top * (m_resizeMask[ResizeTypes.Top].Contains(mousePos) ? 1 : 0);
mask |= (int)ResizeTypes.Bottom * (m_resizeMask[ResizeTypes.Bottom].Contains(mousePos) ? 1 : 0);
mask |= (int)ResizeTypes.Left * (m_resizeMask[ResizeTypes.Left].Contains(mousePos) ? 1 : 0);
mask |= (int)ResizeTypes.Right * (m_resizeMask[ResizeTypes.Right].Contains(mousePos) ? 1 : 0);
//if (m_resizeMask[ResizeTypes.Top].Contains(mousePos))
// mask |= ResizeTypes.Top;
//else if (m_resizeMask[ResizeTypes.Bottom].Contains(mousePos))
// mask |= ResizeTypes.Bottom;
//if (m_resizeMask[ResizeTypes.Left].Contains(mousePos))
// mask |= ResizeTypes.Left;
//else if (m_resizeMask[ResizeTypes.Right].Contains(mousePos))
// mask |= ResizeTypes.Right;
return (ResizeTypes)mask;
}
public void OnHoverResize(ResizeTypes resizeType)
{
if (WasHoveringResize && lastResizeHoverType == resizeType)
return;
// we are entering resize, or the resize type has changed.
//WasHoveringResize = true;
lastResizeHoverType = resizeType;
resizeCursorObj.SetActive(true);
resizeCursorObj.transform.SetAsLastSibling();
// set the rotation for the resize icon
float iconRotation = 0f;
switch (resizeType)
{
case ResizeTypes.TopRight:
case ResizeTypes.BottomLeft:
iconRotation = 45f; break;
case ResizeTypes.Top:
case ResizeTypes.Bottom:
iconRotation = 90f; break;
case ResizeTypes.TopLeft:
case ResizeTypes.BottomRight:
iconRotation = 135f; break;
}
Quaternion rot = resizeCursorObj.transform.rotation;
rot.eulerAngles = new Vector3(0, 0, iconRotation);
resizeCursorObj.transform.rotation = rot;
UpdateHoverImagePos();
}
// update the resize icon position to be above the mouse
private void UpdateHoverImagePos()
{
resizeCursorObj.transform.localPosition = UIManager.UIRootRect.InverseTransformPoint(DisplayManager.MousePosition);
}
public void OnHoverResizeEnd()
{
//WasHoveringResize = false;
resizeCursorObj.SetActive(false);
}
public void OnBeginResize(ResizeTypes resizeType)
{
currentResizeType = resizeType;
lastResizePos = DisplayManager.MousePosition;
WasResizing = true;
Resizing = true;
}
public void OnResize()
{
Vector3 mousePos = DisplayManager.MousePosition;
Vector2 diff = lastResizePos - (Vector2)mousePos;
if ((Vector2)mousePos == lastResizePos)
return;
if (mousePos.x < 0 || mousePos.y < 0 || mousePos.x > DisplayManager.Width || mousePos.y > DisplayManager.Height)
return;
lastResizePos = mousePos;
float diffX = (float)((decimal)diff.x / DisplayManager.Width);
float diffY = (float)((decimal)diff.y / DisplayManager.Height);
Vector2 anchorMin = Panel.anchorMin;
Vector2 anchorMax = Panel.anchorMax;
if (currentResizeType.HasFlag(ResizeTypes.Left))
anchorMin.x -= diffX;
else if (currentResizeType.HasFlag(ResizeTypes.Right))
anchorMax.x -= diffX;
if (currentResizeType.HasFlag(ResizeTypes.Top))
anchorMax.y -= diffY;
else if (currentResizeType.HasFlag(ResizeTypes.Bottom))
anchorMin.y -= diffY;
var prevMin = Panel.anchorMin;
var prevMax = Panel.anchorMax;
Panel.anchorMin = new Vector2(anchorMin.x, anchorMin.y);
Panel.anchorMax = new Vector2(anchorMax.x, anchorMax.y);
if (Panel.rect.width < UIPanel.MinWidth)
{
Panel.anchorMin = new Vector2(prevMin.x, Panel.anchorMin.y);
Panel.anchorMax = new Vector2(prevMax.x, Panel.anchorMax.y);
}
if (Panel.rect.height < UIPanel.MinHeight)
{
Panel.anchorMin = new Vector2(Panel.anchorMin.x, prevMin.y);
Panel.anchorMax = new Vector2(Panel.anchorMax.x, prevMax.y);
}
}
public void OnEndResize()
{
WasResizing = false;
Resizing = false;
try { OnHoverResizeEnd(); } catch { }
UpdateResizeCache();
OnFinishResize?.Invoke(Panel);
}
internal static void CreateCursorUI()
{
try
{
var text = UIFactory.CreateLabel(UIManager.UIRoot, "ResizeCursor", "↔", TextAnchor.MiddleCenter, Color.white, true, 35);
resizeCursorObj = text.gameObject;
var outline = text.gameObject.AddComponent<Outline>();
outline.effectColor = Color.black;
outline.effectDistance = new(1, 1);
RectTransform rect = resizeCursorObj.GetComponent<RectTransform>();
rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, 64);
rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 64);
resizeCursorObj.SetActive(false);
}
catch (Exception e)
{
ExplorerCore.LogWarning("Exception creating Resize Cursor UI!\r\n" + e.ToString());
}
}
#endregion
}
}

264
src/UI/Panels/UEPanel.cs Normal file
View File

@ -0,0 +1,264 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.Config;
using UniverseLib;
using UniverseLib.Input;
using UniverseLib.UI;
using UniverseLib.UI.Models;
using UniverseLib.UI.Panels;
namespace UnityExplorer.UI.Panels
{
public abstract class UEPanel : PanelBase
{
protected UEPanel(UIBase owner) : base(owner) { }
public abstract UIManager.Panels PanelType { get; }
public virtual bool ShowByDefault => false;
public virtual bool ShouldSaveActiveState => true;
public virtual bool NavButtonWanted => true;
public ButtonRef NavButton { get; internal set; }
protected override PanelDragger CreatePanelDragger()
{
return new UEPanelDragger(this);
}
public override void OnFinishDrag()
{
base.OnFinishDrag();
SaveInternalData();
}
public override void OnFinishResize()
{
base.OnFinishResize();
SaveInternalData();
}
public override void SetActive(bool active)
{
if (this.Enabled != active)
{
base.SetActive(active);
if (!ApplyingSaveData)
SaveInternalData();
if (NavButtonWanted && NavButton != null)
{
Color color = active ? UniversalUI.EnabledButtonColor : UniversalUI.DisabledButtonColor;
RuntimeHelper.SetColorBlock(NavButton.Component, color, color * 1.2f);
}
}
if (!active)
{
if (Dragger != null)
this.Dragger.WasDragging = false;
}
else
{
this.UIRoot.transform.SetAsLastSibling();
(this.Owner.Panels as UEPanelManager).DoInvokeOnPanelsReordered();
}
}
// Save Data
public bool ApplyingSaveData { get; set; }
public void SaveInternalData()
{
if (UIManager.Initializing || ApplyingSaveData)
return;
SetSaveDataToConfigValue();
}
private void SetSaveDataToConfigValue()
=> ConfigManager.GetPanelSaveData(this.PanelType).Value = this.ToSaveData();
public virtual string ToSaveData()
{
try
{
return string.Join("|", new string[]
{
$"{ShouldSaveActiveState && Enabled}",
Rect.RectAnchorsToString(),
Rect.RectPositionToString()
});
}
catch (Exception ex)
{
ExplorerCore.LogWarning($"Exception generating Panel save data: {ex}");
return "";
}
}
public virtual void ApplySaveData()
{
string data = ConfigManager.GetPanelSaveData(this.PanelType).Value;
ApplySaveData(data);
}
protected virtual void ApplySaveData(string data)
{
if (string.IsNullOrEmpty(data))
return;
string[] split = data.Split('|');
try
{
Rect.SetAnchorsFromString(split[1]);
Rect.SetPositionFromString(split[2]);
this.SetActive(bool.Parse(split[0]));
}
catch
{
ExplorerCore.LogWarning("Invalid or corrupt panel save data! Restoring to default.");
SetDefaultSizeAndPosition();
SetSaveDataToConfigValue();
}
}
public override void ConstructUI()
{
base.ConstructUI();
if (NavButtonWanted)
{
// create navbar button
NavButton = UIFactory.CreateButton(UIManager.NavbarTabButtonHolder, $"Button_{PanelType}", Name);
GameObject navBtn = NavButton.Component.gameObject;
navBtn.AddComponent<ContentSizeFitter>().horizontalFit = ContentSizeFitter.FitMode.PreferredSize;
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(navBtn, false, true, true, true, 0, 0, 0, 5, 5, TextAnchor.MiddleCenter);
UIFactory.SetLayoutElement(navBtn, minWidth: 80);
RuntimeHelper.SetColorBlock(NavButton.Component, UniversalUI.DisabledButtonColor, UniversalUI.DisabledButtonColor * 1.2f);
NavButton.OnClick += () => { UIManager.TogglePanel(PanelType); };
GameObject txtObj = navBtn.transform.Find("Text").gameObject;
txtObj.AddComponent<ContentSizeFitter>().horizontalFit = ContentSizeFitter.FitMode.PreferredSize;
}
this.SetActive(true);
this.SetActive(false);
this.SetActive(ShowByDefault);
}
protected override void LateConstructUI()
{
ApplyingSaveData = true;
base.LateConstructUI();
// apply panel save data or revert to default
try
{
ApplySaveData();
}
catch (Exception ex)
{
ExplorerCore.Log($"Exception loading panel save data: {ex}");
SetDefaultSizeAndPosition();
}
// simple listener for saving enabled state
this.OnToggleEnabled += (bool val) =>
{
SaveInternalData();
};
ApplyingSaveData = false;
Dragger.OnEndResize();
}
}
#region WINDOW ANCHORS / POSITION SAVE DATA HELPERS
public static class RectSaveExtensions
{
// Window Anchors helpers
internal static string RectAnchorsToString(this RectTransform rect)
{
if (!rect)
throw new ArgumentNullException("rect");
return string.Format(CultureInfo.InvariantCulture, "{0},{1},{2},{3}", new object[]
{
rect.anchorMin.x,
rect.anchorMin.y,
rect.anchorMax.x,
rect.anchorMax.y
});
}
internal static void SetAnchorsFromString(this RectTransform panel, string stringAnchors)
{
if (string.IsNullOrEmpty(stringAnchors))
throw new ArgumentNullException("stringAnchors");
if (stringAnchors.Contains(" "))
// outdated save data, not worth recovering just reset it.
throw new Exception("invalid save data, resetting.");
string[] split = stringAnchors.Split(',');
if (split.Length != 4)
throw new Exception($"stringAnchors split is unexpected length: {split.Length}");
Vector4 anchors;
anchors.x = float.Parse(split[0], CultureInfo.InvariantCulture);
anchors.y = float.Parse(split[1], CultureInfo.InvariantCulture);
anchors.z = float.Parse(split[2], CultureInfo.InvariantCulture);
anchors.w = float.Parse(split[3], CultureInfo.InvariantCulture);
panel.anchorMin = new Vector2(anchors.x, anchors.y);
panel.anchorMax = new Vector2(anchors.z, anchors.w);
}
internal static string RectPositionToString(this RectTransform rect)
{
if (!rect)
throw new ArgumentNullException("rect");
return string.Format(CultureInfo.InvariantCulture, "{0},{1}", new object[]
{
rect.anchoredPosition.x, rect.anchoredPosition.y
});
}
internal static void SetPositionFromString(this RectTransform rect, string stringPosition)
{
if (string.IsNullOrEmpty(stringPosition))
throw new ArgumentNullException(stringPosition);
if (stringPosition.Contains(" "))
// outdated save data, not worth recovering just reset it.
throw new Exception("invalid save data, resetting.");
string[] split = stringPosition.Split(',');
if (split.Length != 2)
throw new Exception($"stringPosition split is unexpected length: {split.Length}");
Vector3 vector = rect.anchoredPosition;
vector.x = float.Parse(split[0], CultureInfo.InvariantCulture);
vector.y = float.Parse(split[1], CultureInfo.InvariantCulture);
rect.anchoredPosition = vector;
}
}
#endregion
}

View File

@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.UI.Widgets.AutoComplete;
using UniverseLib.Input;
using UniverseLib.UI;
using UniverseLib.UI.Panels;
using UniverseLib.Utility;
namespace UnityExplorer.UI.Panels
{
public class UEPanelDragger : PanelDragger
{
public UEPanelDragger(PanelBase uiPanel) : base(uiPanel) { }
protected override bool MouseInResizeArea(Vector2 mousePos)
{
return !UIManager.NavBarRect.rect.Contains(UIManager.NavBarRect.InverseTransformPoint(mousePos))
&& base.MouseInResizeArea(mousePos);
}
}
}

View File

@ -1,423 +0,0 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.Config;
using UniverseLib.Input;
using UnityExplorer.UI.Widgets;
using UniverseLib.UI.Models;
using UniverseLib.UI;
using UniverseLib;
using System.Collections;
namespace UnityExplorer.UI.Panels
{
public abstract class UIPanel : UIBehaviourModel
{
#region STATIC
internal static void InvokeOnPanelsReordered() => OnPanelsReordered?.Invoke();
public static event Action OnPanelsReordered;
public static event Action OnClickedOutsidePanels;
internal static readonly List<UIPanel> instances = new();
internal static readonly Dictionary<int, UIPanel> transformToPanelDict = new();
public static void UpdateFocus()
{
if (PanelDragger.ResizePrompting)
return;
// if the user is clicking
if (DisplayManager.MouseInTargetDisplay
&& (InputManager.GetMouseButtonDown(0) || InputManager.GetMouseButtonDown(1)))
{
int count = UIManager.PanelHolder.transform.childCount;
Vector3 mousePos = DisplayManager.MousePosition;
bool clickedInAny = false;
for (int i = count - 1; i >= 0; i--)
{
// make sure this is a real recognized panel
Transform transform = UIManager.PanelHolder.transform.GetChild(i);
if (!transformToPanelDict.TryGetValue(transform.GetInstanceID(), out UIPanel panel))
continue;
// check if our mouse is clicking inside the panel
Vector3 pos = panel.Rect.InverseTransformPoint(mousePos);
if (!panel.Enabled || !panel.Rect.rect.Contains(pos))
continue;
// if this is not the top panel, reorder and invoke the onchanged event
if (transform.GetSiblingIndex() != count - 1)
{
transform.SetAsLastSibling();
OnPanelsReordered?.Invoke();
}
// panel was found, break
clickedInAny = true;
break;
}
if (!clickedInAny)
OnClickedOutsidePanels?.Invoke();
}
}
#endregion
// INSTANCE
public UIPanel()
{
instances.Add(this);
}
public abstract UIManager.Panels PanelType { get; }
public abstract string Name { get; }
public abstract int MinWidth { get; }
public abstract int MinHeight { get; }
public virtual bool ShowByDefault => false;
public virtual bool ShouldSaveActiveState => true;
public virtual bool CanDragAndResize => true;
public virtual bool NavButtonWanted => true;
public ButtonRef NavButton { get; internal set; }
public PanelDragger Dragger { get; internal set; }
public override GameObject UIRoot => uiRoot;
protected GameObject uiRoot;
protected GameObject uiContent;
public RectTransform Rect { get; private set; }
public GameObject TitleBar { get; private set; }
public virtual void OnFinishResize(RectTransform panel)
{
SaveInternalData();
}
public virtual void OnFinishDrag(RectTransform panel)
{
SaveInternalData();
}
public override void SetActive(bool active)
{
if (this.Enabled != active)
{
base.SetActive(active);
if (!ApplyingSaveData)
SaveInternalData();
if (NavButtonWanted)
{
var color = active ? UniversalUI.EnabledButtonColor : UniversalUI.DisabledButtonColor;
RuntimeHelper.SetColorBlock(NavButton.Component, color, color * 1.2f);
}
}
if (!active)
this.Dragger.WasDragging = false;
else
{
this.UIRoot.transform.SetAsLastSibling();
InvokeOnPanelsReordered();
}
}
public override void Destroy()
{
instances.Remove(this);
base.Destroy();
}
protected internal abstract void DoSetDefaultPosAndAnchors();
public void SetTransformDefaults()
{
DoSetDefaultPosAndAnchors();
}
public void EnsureValidSize()
{
if (Rect.rect.width < MinWidth)
Rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, MinWidth);
if (Rect.rect.height < MinHeight)
Rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, MinHeight);
}
public void EnsureValidPosition() => EnsureValidPosition(this.Rect);
public static void EnsureValidPosition(RectTransform panel)
{
var pos = panel.localPosition;
// Prevent panel going oustide screen bounds
var halfW = DisplayManager.Width * 0.5f;
var halfH = DisplayManager.Height * 0.5f;
pos.x = Math.Max(-halfW - panel.rect.width + 50, Math.Min(pos.x, halfW - 50));
pos.y = Math.Max(-halfH + 50, Math.Min(pos.y, halfH));
panel.localPosition = pos;
}
// Save Data
public bool ApplyingSaveData { get; set; }
public void SaveInternalData()
{
if (UIManager.Initializing)
return;
SetSaveDataToConfigValue();
}
private void SetSaveDataToConfigValue() => ConfigManager.GetPanelSaveData(this.PanelType).Value = this.ToSaveData();
public virtual string ToSaveData()
{
try
{
return string.Join("|", new string[]
{
$"{ShouldSaveActiveState && Enabled}",
Rect.RectAnchorsToString(),
Rect.RectPositionToString()
});
}
catch (Exception ex)
{
ExplorerCore.LogWarning($"Exception generating Panel save data: {ex}");
return "";
}
}
public virtual void ApplySaveData()
{
string data = ConfigManager.GetPanelSaveData(this.PanelType).Value;
ApplySaveData(data);
}
protected virtual void ApplySaveData(string data)
{
if (string.IsNullOrEmpty(data))
return;
var split = data.Split('|');
try
{
Rect.SetAnchorsFromString(split[1]);
Rect.SetPositionFromString(split[2]);
UIManager.SetPanelActive(this.PanelType, bool.Parse(split[0]));
}
catch
{
ExplorerCore.LogWarning("Invalid or corrupt panel save data! Restoring to default.");
SetTransformDefaults();
SetSaveDataToConfigValue();
}
}
// UI Construction
public abstract void ConstructPanelContent();
public void ConstructUI()
{
//this.Enabled = true;
if (NavButtonWanted)
{
// create navbar button
NavButton = UIFactory.CreateButton(UIManager.NavbarTabButtonHolder, $"Button_{PanelType}", Name);
var navBtn = NavButton.Component.gameObject;
navBtn.AddComponent<ContentSizeFitter>().horizontalFit = ContentSizeFitter.FitMode.PreferredSize;
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(navBtn, false, true, true, true, 0, 0, 0, 5, 5, TextAnchor.MiddleCenter);
UIFactory.SetLayoutElement(navBtn, minWidth: 80);
RuntimeHelper.SetColorBlock(NavButton.Component, UniversalUI.DisabledButtonColor, UniversalUI.DisabledButtonColor * 1.2f);
NavButton.OnClick += () => { UIManager.TogglePanel(PanelType); };
var txtObj = navBtn.transform.Find("Text").gameObject;
txtObj.AddComponent<ContentSizeFitter>().horizontalFit = ContentSizeFitter.FitMode.PreferredSize;
}
// create core canvas
uiRoot = UIFactory.CreatePanel(Name, UIManager.PanelHolder, out uiContent);
Rect = this.uiRoot.GetComponent<RectTransform>();
//UIFactory.SetLayoutGroup<VerticalLayoutGroup>(this.uiRoot, false, false, true, true, 0, 2, 2, 2, 2, TextAnchor.UpperLeft);
int id = this.uiRoot.transform.GetInstanceID();
transformToPanelDict.Add(id, this);
UIFactory.SetLayoutGroup<VerticalLayoutGroup>(this.uiContent, false, false, true, true, 2, 2, 2, 2, 2, TextAnchor.UpperLeft);
// Title bar
TitleBar = UIFactory.CreateHorizontalGroup(uiContent, "TitleBar", false, true, true, true, 2,
new Vector4(2, 2, 2, 2), new Color(0.06f, 0.06f, 0.06f));
UIFactory.SetLayoutElement(TitleBar, minHeight: 25, flexibleHeight: 0);
// Title text
var titleTxt = UIFactory.CreateLabel(TitleBar, "TitleBar", Name, TextAnchor.MiddleLeft);
UIFactory.SetLayoutElement(titleTxt.gameObject, minWidth: 250, minHeight: 25, flexibleHeight: 0);
// close button
var closeHolder = UIFactory.CreateUIObject("CloseHolder", TitleBar);
UIFactory.SetLayoutElement(closeHolder, minHeight: 25, flexibleHeight: 0, minWidth: 30, flexibleWidth: 9999);
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(closeHolder, false, false, true, true, 3, childAlignment: TextAnchor.MiddleRight);
var closeBtn = UIFactory.CreateButton(closeHolder, "CloseButton", "—");
UIFactory.SetLayoutElement(closeBtn.Component.gameObject, minHeight: 25, minWidth: 25, flexibleWidth: 0);
RuntimeHelper.SetColorBlock(closeBtn.Component, new Color(0.33f, 0.32f, 0.31f));
closeBtn.OnClick += () =>
{
UIManager.SetPanelActive(this.PanelType, false);
SaveInternalData();
};
if (!CanDragAndResize)
TitleBar.SetActive(false);
// Panel dragger
Dragger = new PanelDragger(TitleBar.GetComponent<RectTransform>(), Rect, this);
Dragger.OnFinishResize += OnFinishResize;
Dragger.OnFinishDrag += OnFinishDrag;
// content (abstract)
ConstructPanelContent();
UIManager.SetPanelActive(this.PanelType, true);
UIManager.SetPanelActive(this.PanelType, false);
UIManager.SetPanelActive(this.PanelType, ShowByDefault);
ApplyingSaveData = true;
SetTransformDefaults();
// apply panel save data or revert to default
try
{
ApplySaveData();
}
catch (Exception ex)
{
ExplorerCore.Log($"Exception loading panel save data: {ex}");
SetTransformDefaults();
}
RuntimeHelper.StartCoroutine(LateSetupCoroutine());
// simple listener for saving enabled state
this.OnToggleEnabled += (bool val) =>
{
SaveInternalData();
};
ApplyingSaveData = false;
}
private IEnumerator LateSetupCoroutine()
{
yield return null;
// ensure initialized position is valid
EnsureValidSize();
EnsureValidPosition(this.Rect);
// update dragger and save data
Dragger.OnEndResize();
}
public override void ConstructUI(GameObject parent) => ConstructUI();
}
#region WINDOW ANCHORS / POSITION HELPERS
public static class RectSaveExtensions
{
// Window Anchors helpers
internal static string RectAnchorsToString(this RectTransform rect)
{
if (!rect)
throw new ArgumentNullException("rect");
return string.Format(CultureInfo.InvariantCulture, "{0},{1},{2},{3}", new object[]
{
rect.anchorMin.x,
rect.anchorMin.y,
rect.anchorMax.x,
rect.anchorMax.y
});
}
internal static void SetAnchorsFromString(this RectTransform panel, string stringAnchors)
{
if (string.IsNullOrEmpty(stringAnchors))
throw new ArgumentNullException("stringAnchors");
if (stringAnchors.Contains(" "))
// outdated save data, not worth recovering just reset it.
throw new Exception("invalid save data, resetting.");
var split = stringAnchors.Split(',');
if (split.Length != 4)
throw new Exception($"stringAnchors split is unexpected length: {split.Length}");
Vector4 anchors;
anchors.x = float.Parse(split[0], CultureInfo.InvariantCulture);
anchors.y = float.Parse(split[1], CultureInfo.InvariantCulture);
anchors.z = float.Parse(split[2], CultureInfo.InvariantCulture);
anchors.w = float.Parse(split[3], CultureInfo.InvariantCulture);
panel.anchorMin = new Vector2(anchors.x, anchors.y);
panel.anchorMax = new Vector2(anchors.z, anchors.w);
}
internal static string RectPositionToString(this RectTransform rect)
{
if (!rect)
throw new ArgumentNullException("rect");
return string.Format(CultureInfo.InvariantCulture, "{0},{1}", new object[]
{
rect.anchoredPosition.x, rect.anchoredPosition.y
});
}
internal static void SetPositionFromString(this RectTransform rect, string stringPosition)
{
if (string.IsNullOrEmpty(stringPosition))
throw new ArgumentNullException(stringPosition);
if (stringPosition.Contains(" "))
// outdated save data, not worth recovering just reset it.
throw new Exception("invalid save data, resetting.");
var split = stringPosition.Split(',');
if (split.Length != 2)
throw new Exception($"stringPosition split is unexpected length: {split.Length}");
Vector3 vector = rect.anchoredPosition;
vector.x = float.Parse(split[0], CultureInfo.InvariantCulture);
vector.y = float.Parse(split[1], CultureInfo.InvariantCulture);
rect.anchoredPosition = vector;
}
}
#endregion
}

39
src/UI/UEPanelManager.cs Normal file
View File

@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityExplorer.UI.Panels;
using UniverseLib.UI;
using UniverseLib.UI.Panels;
namespace UnityExplorer.UI
{
public class UEPanelManager : PanelManager
{
public UEPanelManager(UIBase owner) : base(owner) { }
protected override Vector3 MousePosition => DisplayManager.MousePosition;
protected override Vector2 ScreenDimensions => new(DisplayManager.Width, DisplayManager.Height);
protected override bool MouseInTargetDisplay => DisplayManager.MouseInTargetDisplay;
internal void DoInvokeOnPanelsReordered()
{
InvokeOnPanelsReordered();
}
protected override void SortDraggerHeirarchy()
{
base.SortDraggerHeirarchy();
// move AutoCompleter to first update
if (!UIManager.Initializing && AutoCompleteModal.Instance != null)
{
this.draggerInstances.Remove(AutoCompleteModal.Instance.Dragger);
this.draggerInstances.Insert(0, AutoCompleteModal.Instance.Dragger);
}
}
}
}

View File

@ -10,8 +10,7 @@ using UniverseLib;
using UniverseLib.Input;
using UniverseLib.UI;
using UniverseLib.UI.Models;
using UniverseLib.UI.ObjectPool;
using UniverseLib.UI.Widgets;
using UniverseLib.UI.Panels;
using UniverseLib.UI.Widgets.ScrollView;
using UniverseLib.Utility;
@ -27,10 +26,11 @@ namespace UnityExplorer.UI
Options,
ConsoleLog,
AutoCompleter,
MouseInspector,
//MouseInspector,
UIInspectorResults,
HookManager,
Clipboard
Clipboard,
Freecam
}
public enum VerticalAnchor
@ -48,8 +48,7 @@ namespace UnityExplorer.UI
public static RectTransform UIRootRect { get; private set; }
public static Canvas UICanvas { get; private set; }
internal static GameObject PanelHolder { get; private set; }
internal static readonly Dictionary<Panels, UIPanel> UIPanels = new();
internal static readonly Dictionary<Panels, UEPanel> UIPanels = new();
public static RectTransform NavBarRect;
public static GameObject NavbarTabButtonHolder;
@ -81,7 +80,7 @@ namespace UnityExplorer.UI
internal static void InitUI()
{
UiBase = UniversalUI.RegisterUI(ExplorerCore.GUID, Update);
UiBase = UniversalUI.RegisterUI<ExplorerUIBase>(ExplorerCore.GUID, Update);
UIRootRect = UIRoot.GetComponent<RectTransform>();
UICanvas = UIRoot.GetComponent<Canvas>();
@ -93,36 +92,32 @@ namespace UnityExplorer.UI
lastScreenHeight = display.renderingHeight;
// Create UI.
CreatePanelHolder();
CreateTopNavBar();
// This could be automated with Assembly.GetTypes(),
// but the order is important and I'd have to write something to handle the order.
UIPanels.Add(Panels.AutoCompleter, new AutoCompleteModal());
UIPanels.Add(Panels.ObjectExplorer, new ObjectExplorerPanel());
UIPanels.Add(Panels.Inspector, new InspectorPanel());
UIPanels.Add(Panels.CSConsole, new CSConsolePanel());
UIPanels.Add(Panels.HookManager, new HookManagerPanel());
UIPanels.Add(Panels.Clipboard, new ClipboardPanel());
UIPanels.Add(Panels.ConsoleLog, new LogPanel());
UIPanels.Add(Panels.Options, new OptionsPanel());
UIPanels.Add(Panels.UIInspectorResults, new MouseInspectorResultsPanel());
UIPanels.Add(Panels.MouseInspector, new MouseInspector());
UIPanels.Add(Panels.AutoCompleter, new AutoCompleteModal(UiBase));
UIPanels.Add(Panels.ObjectExplorer, new ObjectExplorerPanel(UiBase));
UIPanels.Add(Panels.Inspector, new InspectorPanel(UiBase));
UIPanels.Add(Panels.CSConsole, new CSConsolePanel(UiBase));
UIPanels.Add(Panels.HookManager, new HookManagerPanel(UiBase));
UIPanels.Add(Panels.Freecam, new FreeCamPanel(UiBase));
UIPanels.Add(Panels.Clipboard, new ClipboardPanel(UiBase));
UIPanels.Add(Panels.ConsoleLog, new LogPanel(UiBase));
UIPanels.Add(Panels.Options, new OptionsPanel(UiBase));
UIPanels.Add(Panels.UIInspectorResults, new MouseInspectorResultsPanel(UiBase));
foreach (var panel in UIPanels.Values)
panel.ConstructUI();
MouseInspector.inspectorUIBase = UniversalUI.RegisterUI(MouseInspector.UIBaseGUID, null);
new MouseInspector(MouseInspector.inspectorUIBase);
// Call some initialize methods
Notification.Init();
ConsoleController.Init();
// Add this listener to prevent ScrollPool doing anything while we are resizing panels
ScrollPool<ICell>.writingLockedListeners.Add(() => !PanelDragger.Resizing);
// Set default menu visibility
ShowMenu = !ConfigManager.Hide_On_Startup.Value;
// Failsafe fix, in some games all dropdowns displayed values are blank on startup for some reason.
foreach (var dropdown in UIRoot.GetComponentsInChildren<Dropdown>(true))
foreach (Dropdown dropdown in UIRoot.GetComponentsInChildren<Dropdown>(true))
dropdown.RefreshShownValue();
Initializing = false;
@ -146,10 +141,6 @@ namespace UnityExplorer.UI
if (InputManager.GetKeyDown(ConfigManager.Force_Unlock_Toggle.Value))
UniverseLib.Config.ConfigManager.Force_Unlock_Mouse = !UniverseLib.Config.ConfigManager.Force_Unlock_Mouse;
// update focused panel
UIPanel.UpdateFocus();
PanelDragger.UpdateInstances();
// update the timescale value
if (!timeInput.Component.isFocused && lastTimeScale != Time.timeScale)
{
@ -167,40 +158,33 @@ namespace UnityExplorer.UI
}
// check screen dimension change
var display = DisplayManager.ActiveDisplay;
Display display = DisplayManager.ActiveDisplay;
if (display.renderingWidth != lastScreenWidth || display.renderingHeight != lastScreenHeight)
OnScreenDimensionsChanged();
}
// Panels
public static UIPanel GetPanel(Panels panel) => UIPanels[panel];
public static UEPanel GetPanel(Panels panel) => UIPanels[panel];
public static T GetPanel<T>(Panels panel) where T : UIPanel => (T)UIPanels[panel];
public static T GetPanel<T>(Panels panel) where T : UEPanel => (T)UIPanels[panel];
public static void TogglePanel(Panels panel)
{
var uiPanel = GetPanel(panel);
UEPanel uiPanel = GetPanel(panel);
SetPanelActive(panel, !uiPanel.Enabled);
}
public static void SetPanelActive(Panels panelType, bool active)
{
GetPanel(panelType)
.SetActive(active);
GetPanel(panelType).SetActive(active);
}
public static void SetPanelActive(UIPanel panel, bool active)
public static void SetPanelActive(UEPanel panel, bool active)
{
panel.SetActive(active);
}
internal static void SetPanelActive(Transform transform, bool value)
{
if (UIPanel.transformToPanelDict.TryGetValue(transform.GetInstanceID(), out UIPanel panel))
panel.SetActive(value);
}
// navbar
public static void SetNavBarAnchor()
@ -227,14 +211,14 @@ namespace UnityExplorer.UI
private static void OnScreenDimensionsChanged()
{
var display = DisplayManager.ActiveDisplay;
Display display = DisplayManager.ActiveDisplay;
lastScreenWidth = display.renderingWidth;
lastScreenHeight = display.renderingHeight;
foreach (var panel in UIPanels)
foreach (KeyValuePair<Panels, UEPanel> panel in UIPanels)
{
panel.Value.EnsureValidSize();
UIPanel.EnsureValidPosition(panel.Value.Rect);
panel.Value.EnsureValidPosition();
panel.Value.Dragger.OnEndResize();
}
}
@ -287,23 +271,9 @@ namespace UnityExplorer.UI
// UI Construction
private static void CreatePanelHolder()
{
PanelHolder = new GameObject("PanelHolder");
PanelHolder.transform.SetParent(UIRoot.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();
}
private static void CreateTopNavBar()
{
var navbarPanel = UIFactory.CreateUIObject("MainNavbar", UIRoot);
GameObject navbarPanel = UIFactory.CreateUIObject("MainNavbar", UIRoot);
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(navbarPanel, false, false, true, true, 5, 4, 4, 4, 4, TextAnchor.MiddleCenter);
navbarPanel.AddComponent<Image>().color = new Color(0.1f, 0.1f, 0.1f);
NavBarRect = navbarPanel.GetComponent<RectTransform>();
@ -319,9 +289,9 @@ namespace UnityExplorer.UI
// UnityExplorer title
string titleTxt = $"{ExplorerCore.NAME} <i><color=grey>{ExplorerCore.VERSION}</color></i>";
var title = UIFactory.CreateLabel(navbarPanel, "Title", titleTxt, TextAnchor.MiddleLeft, default, true, 17);
UIFactory.SetLayoutElement(title.gameObject, minWidth: 170, flexibleWidth: 0);
string titleTxt = $"UE <i><color=grey>{ExplorerCore.VERSION}</color></i>";
Text title = UIFactory.CreateLabel(navbarPanel, "Title", titleTxt, TextAnchor.MiddleCenter, default, true, 14);
UIFactory.SetLayoutElement(title.gameObject, minWidth: 75, flexibleWidth: 0);
// panel tabs
@ -331,7 +301,7 @@ namespace UnityExplorer.UI
// Time controls
var timeLabel = UIFactory.CreateLabel(navbarPanel, "TimeLabel", "Time:", TextAnchor.MiddleRight, Color.grey);
Text timeLabel = UIFactory.CreateLabel(navbarPanel, "TimeLabel", "Time:", TextAnchor.MiddleRight, Color.grey);
UIFactory.SetLayoutElement(timeLabel.gameObject, minHeight: 25, minWidth: 50);
timeInput = UIFactory.CreateInputField(navbarPanel, "TimeInput", "timeScale");

View File

@ -2,8 +2,7 @@
using System.Collections.Generic;
using System.Collections.Specialized;
using UnityExplorer.CacheObject.IValues;
using UniverseLib;
using UniverseLib.UI;
using UnityExplorer.UI.Panels;
using UniverseLib.UI.Models;
using UniverseLib.Utility;
@ -30,8 +29,8 @@ namespace UnityExplorer.UI.Widgets.AutoComplete
public InputFieldRef InputField { get; }
public bool AnchorToCaretPosition => false;
private readonly List<Suggestion> suggestions = new List<Suggestion>();
private readonly HashSet<string> suggestedValues = new HashSet<string>();
private readonly List<Suggestion> suggestions = new();
private readonly HashSet<string> suggestedValues = new();
private OrderedDictionary enumValues;
@ -58,7 +57,7 @@ namespace UnityExplorer.UI.Widgets.AutoComplete
private string GetLastSplitInput(string fullInput)
{
string ret = fullInput;
int lastSplit = fullInput.LastIndexOf(',');
if (lastSplit >= 0)
{
@ -139,13 +138,13 @@ namespace UnityExplorer.UI.Widgets.AutoComplete
for (int i = 0; i < this.enumValues.Count; i++)
{
var enumValue = (CachedEnumValue)enumValues[i];
CachedEnumValue enumValue = (CachedEnumValue)enumValues[i];
if (enumValue.Name.ContainsIgnoreCase(value))
AddSuggestion(enumValue.Name);
}
}
internal static readonly Dictionary<string, string> sharedValueToLabel = new Dictionary<string, string>(4096);
internal static readonly Dictionary<string, string> sharedValueToLabel = new(4096);
void AddSuggestion(string value)
{

View File

@ -1,11 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
using UniverseLib.UI;
using UniverseLib.UI.Models;
using UniverseLib.UI.Models;
namespace UnityExplorer.UI.Widgets.AutoComplete
{

View File

@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEngine;
namespace UnityExplorer.UI.Widgets.AutoComplete
namespace UnityExplorer.UI.Widgets.AutoComplete
{
public struct Suggestion
{

View File

@ -1,9 +1,8 @@
using HarmonyLib;
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using UnityExplorer.UI.Panels;
using UniverseLib;
using UniverseLib.UI;
using UniverseLib.UI.Models;
using UniverseLib.Utility;
@ -67,10 +66,10 @@ namespace UnityExplorer.UI.Widgets.AutoComplete
else
{
allowedTypes = new();
foreach (var entry in ReflectionUtility.AllTypes)
foreach (KeyValuePair<string, Type> entry in ReflectionUtility.AllTypes)
{
// skip <PrivateImplementationDetails> and <AnonymousClass> classes
var type = entry.Value;
Type type = entry.Value;
if (type.FullName.Contains("PrivateImplementationDetails")
|| type.FullName.Contains("DisplayClass")
|| type.FullName.Contains('<'))
@ -126,7 +125,7 @@ namespace UnityExplorer.UI.Widgets.AutoComplete
if (ReflectionUtility.GetTypeByName(value) is Type t && allowedTypes.Contains(t))
AddSuggestion(t);
foreach (var entry in allowedTypes)
foreach (Type entry in allowedTypes)
{
if (entry.FullName.ContainsIgnoreCase(value))
AddSuggestion(entry);

View File

@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.UI.Widgets.AutoComplete;
using UniverseLib.UI;
@ -41,8 +37,10 @@ namespace UnityExplorer.UI.Widgets
inputField.Component.lineType = InputField.LineType.MultiLineNewline;
inputField.UIRoot.AddComponent<ContentSizeFitter>().verticalFit = ContentSizeFitter.FitMode.PreferredSize;
typeCompleter = new TypeCompleter(typeof(object), this.inputField);
typeCompleter.Enabled = false;
typeCompleter = new TypeCompleter(typeof(object), this.inputField)
{
Enabled = false
};
CreateSpecialContent();

View File

@ -1,16 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.UI;
using UniverseLib.UI.Models;
using UnityExplorer.UI.Widgets.AutoComplete;
using UniverseLib.UI;
using UniverseLib;
using UnityExplorer.CacheObject;
using UniverseLib.UI;
using UniverseLib.UI.Models;
using UniverseLib.UI.ObjectPool;
using UniverseLib.Utility;
@ -48,14 +43,14 @@ namespace UnityExplorer.UI.Widgets
public void OnReturnToPool()
{
foreach (var widget in paramHandlers)
foreach (ParameterHandler widget in paramHandlers)
{
widget.OnReturned();
Pool<ParameterHandler>.Return(widget);
}
paramHandlers = null;
foreach (var widget in genericHandlers)
foreach (GenericArgumentHandler widget in genericHandlers)
{
widget.OnReturned();
Pool<GenericArgumentHandler>.Return(widget);
@ -111,9 +106,9 @@ namespace UnityExplorer.UI.Widgets
{
for (int i = 0; i < genericArguments.Length; i++)
{
var type = genericArguments[i];
Type type = genericArguments[i];
var holder = genericHandlers[i] = Pool<GenericArgumentHandler>.Borrow();
GenericArgumentHandler holder = genericHandlers[i] = Pool<GenericArgumentHandler>.Borrow();
holder.UIRoot.transform.SetParent(this.genericArgumentsHolder.transform, false);
holder.OnBorrowed(this, type);
}
@ -123,9 +118,9 @@ namespace UnityExplorer.UI.Widgets
{
for (int i = 0; i < parameters.Length; i++)
{
var param = parameters[i];
ParameterInfo param = parameters[i];
var holder = paramHandlers[i] = Pool<ParameterHandler>.Borrow();
ParameterHandler holder = paramHandlers[i] = Pool<ParameterHandler>.Borrow();
holder.UIRoot.transform.SetParent(this.parametersHolder.transform, false);
holder.OnBorrowed(this, param);
}
@ -142,7 +137,7 @@ namespace UnityExplorer.UI.Widgets
// generic args
this.genericArgumentsHolder = UIFactory.CreateUIObject("GenericHolder", UIRoot);
UIFactory.SetLayoutElement(genericArgumentsHolder, flexibleWidth: 1000);
var genericsTitle = UIFactory.CreateLabel(genericArgumentsHolder, "GenericsTitle", "Generic Arguments", TextAnchor.MiddleLeft);
Text genericsTitle = UIFactory.CreateLabel(genericArgumentsHolder, "GenericsTitle", "Generic Arguments", TextAnchor.MiddleLeft);
UIFactory.SetLayoutElement(genericsTitle.gameObject, minHeight: 25, flexibleWidth: 1000);
UIFactory.SetLayoutGroup<VerticalLayoutGroup>(genericArgumentsHolder, false, false, true, true, 3);
UIFactory.SetLayoutElement(genericArgumentsHolder, minHeight: 25, flexibleHeight: 750, minWidth: 50, flexibleWidth: 9999);
@ -151,14 +146,14 @@ namespace UnityExplorer.UI.Widgets
// args
this.parametersHolder = UIFactory.CreateUIObject("ArgHolder", UIRoot);
UIFactory.SetLayoutElement(parametersHolder, flexibleWidth: 1000);
var argsTitle = UIFactory.CreateLabel(parametersHolder, "ArgsTitle", "Arguments", TextAnchor.MiddleLeft);
Text argsTitle = UIFactory.CreateLabel(parametersHolder, "ArgsTitle", "Arguments", TextAnchor.MiddleLeft);
UIFactory.SetLayoutElement(argsTitle.gameObject, minHeight: 25, flexibleWidth: 1000);
UIFactory.SetLayoutGroup<VerticalLayoutGroup>(parametersHolder, false, false, true, true, 3);
UIFactory.SetLayoutElement(parametersHolder, minHeight: 25, flexibleHeight: 750, minWidth: 50, flexibleWidth: 9999);
//argHolder.AddComponent<ContentSizeFitter>().verticalFit = ContentSizeFitter.FitMode.PreferredSize;
// evaluate button
var evalButton = UIFactory.CreateButton(UIRoot, "EvaluateButton", "Evaluate", new Color(0.2f, 0.2f, 0.2f));
ButtonRef evalButton = UIFactory.CreateButton(UIRoot, "EvaluateButton", "Evaluate", new Color(0.2f, 0.2f, 0.2f));
UIFactory.SetLayoutElement(evalButton.Component.gameObject, minHeight: 25, minWidth: 150, flexibleWidth: 0);
evalButton.OnClick += () =>
{

View File

@ -1,6 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UniverseLib;
using UniverseLib.Utility;
@ -20,10 +18,10 @@ namespace UnityExplorer.UI.Widgets
typeCompleter.BaseType = genericType;
typeCompleter.CacheTypes();
var constraints = genericType.GetGenericParameterConstraints();
Type[] constraints = genericType.GetGenericParameterConstraints();
typeCompleter.GenericConstraints = constraints;
var sb = new StringBuilder($"<color={SignatureHighlighter.CONST}>{genericType.Name}</color>");
StringBuilder sb = new($"<color={SignatureHighlighter.CONST}>{genericType.Name}</color>");
for (int j = 0; j < constraints.Length; j++)
{

View File

@ -1,11 +1,8 @@
using HarmonyLib;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Reflection;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.CacheObject.IValues;
using UnityExplorer.UI.Panels;
using UnityExplorer.UI.Widgets.AutoComplete;
using UniverseLib;
@ -38,7 +35,7 @@ namespace UnityExplorer.UI.Widgets
if (paramType.IsByRef)
paramType = paramType.GetElementType();
this.argNameLabel.text =
this.argNameLabel.text =
$"{SignatureHighlighter.Parse(paramType, false)} <color={SignatureHighlighter.LOCAL_ARG}>{paramInfo.Name}</color>";
if (ParseUtility.CanParse(paramType) || typeof(Type).IsAssignableFrom(paramType))
@ -105,7 +102,7 @@ namespace UnityExplorer.UI.Widgets
if (usingBasicLabel)
return basicValue;
var input = this.inputField.Text;
string input = this.inputField.Text;
if (typeof(Type).IsAssignableFrom(paramType))
return ReflectionUtility.GetTypeByName(input);

View File

@ -1,59 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
namespace UnityExplorer.UI.Widgets
{
public class CachedTransform
{
public TransformTree Tree { get; }
public Transform Value { get; private set; }
public int InstanceID { get; }
public CachedTransform Parent { get; internal set; }
public int Depth { get; internal set; }
public int ChildCount { get; internal set; }
public string Name { get; internal set; }
public bool Enabled { get; internal set; }
public int SiblingIndex { get; internal set; }
public bool Expanded => Tree.IsTransformExpanded(InstanceID);
public CachedTransform(TransformTree tree, Transform transform, int depth, CachedTransform parent = null)
{
InstanceID = transform.GetInstanceID();
Tree = tree;
Value = transform;
Parent = parent;
SiblingIndex = transform.GetSiblingIndex();
Update(transform, depth);
}
public bool Update(Transform transform, int depth)
{
bool changed = false;
if (Value != transform
|| depth != Depth
|| ChildCount != transform.childCount
|| Name != transform.name
|| Enabled != transform.gameObject.activeSelf
|| SiblingIndex != transform.GetSiblingIndex())
{
changed = true;
Value = transform;
Depth = depth;
ChildCount = transform.childCount;
Name = transform.name;
Enabled = transform.gameObject.activeSelf;
SiblingIndex = transform.GetSiblingIndex();
}
return changed;
}
}
}

View File

@ -1,209 +0,0 @@
using HarmonyLib;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.Inspectors;
using UnityExplorer.UI.Widgets;
using UniverseLib;
using UniverseLib.UI;
using UniverseLib.UI.Models;
using UniverseLib.UI.Widgets;
using UniverseLib.UI.Widgets.ScrollView;
using UniverseLib.Utility;
namespace UnityExplorer.UI.Widgets
{
public class TransformCell : ICell
{
public float DefaultHeight => 25f;
public bool Enabled => enabled;
private bool enabled;
public Action<CachedTransform> OnExpandToggled;
public Action<CachedTransform> OnEnableToggled;
public Action<GameObject> OnGameObjectClicked;
public CachedTransform cachedTransform;
public GameObject UIRoot { get; set; }
public RectTransform Rect { get; set; }
public ButtonRef ExpandButton;
public ButtonRef NameButton;
public Toggle EnabledToggle;
public InputFieldRef SiblingIndex;
public LayoutElement spacer;
public void Enable()
{
enabled = true;
UIRoot.SetActive(true);
}
public void Disable()
{
enabled = false;
UIRoot.SetActive(false);
}
public void ConfigureCell(CachedTransform cached)
{
if (cached == null)
{
ExplorerCore.LogWarning("Setting TransformTree cell but the CachedTransform is null!");
return;
}
if (!Enabled)
Enable();
cachedTransform = cached;
spacer.minWidth = cached.Depth * 15;
if (cached.Value)
{
string name = cached.Value.name?.Trim();
if (string.IsNullOrEmpty(name))
name = "<i><color=grey>untitled</color></i>";
NameButton.ButtonText.text = name;
NameButton.ButtonText.color = cached.Value.gameObject.activeSelf ? Color.white : Color.grey;
EnabledToggle.Set(cached.Value.gameObject.activeSelf, false);
if (!cached.Value.parent)
SiblingIndex.GameObject.SetActive(false);
else
{
SiblingIndex.GameObject.SetActive(true);
if (!SiblingIndex.Component.isFocused)
SiblingIndex.Text = cached.Value.GetSiblingIndex().ToString();
}
int childCount = cached.Value.childCount;
if (childCount > 0)
{
NameButton.ButtonText.text = $"<color=grey>[{childCount}]</color> {NameButton.ButtonText.text}";
ExpandButton.Component.interactable = true;
ExpandButton.ButtonText.text = cached.Expanded ? "▼" : "►";
ExpandButton.ButtonText.color = cached.Expanded ? new Color(0.5f, 0.5f, 0.5f) : new Color(0.3f, 0.3f, 0.3f);
}
else
{
ExpandButton.Component.interactable = false;
ExpandButton.ButtonText.text = "▪";
ExpandButton.ButtonText.color = new Color(0.3f, 0.3f, 0.3f);
}
}
else
{
NameButton.ButtonText.text = $"[Destroyed]";
NameButton.ButtonText.color = Color.red;
SiblingIndex.GameObject.SetActive(false);
}
}
public void OnMainButtonClicked()
{
if (cachedTransform.Value)
OnGameObjectClicked?.Invoke(cachedTransform.Value.gameObject);
else
ExplorerCore.LogWarning("The object was destroyed!");
}
public void OnExpandClicked()
{
OnExpandToggled?.Invoke(cachedTransform);
}
private void OnEnableClicked(bool value)
{
OnEnableToggled?.Invoke(cachedTransform);
}
private void OnSiblingIndexEndEdit(string input)
{
if (this.cachedTransform == null || !this.cachedTransform.Value)
return;
if (int.TryParse(input.Trim(), out int index))
this.cachedTransform.Value.SetSiblingIndex(index);
this.SiblingIndex.Text = this.cachedTransform.Value.GetSiblingIndex().ToString();
}
public GameObject CreateContent(GameObject parent)
{
UIRoot = UIFactory.CreateUIObject("TransformCell", parent);
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(UIRoot, false, false, true, true, 2, childAlignment: TextAnchor.MiddleCenter);
Rect = UIRoot.GetComponent<RectTransform>();
Rect.anchorMin = new Vector2(0, 1);
Rect.anchorMax = new Vector2(0, 1);
Rect.pivot = new Vector2(0.5f, 1);
Rect.sizeDelta = new Vector2(25, 25);
UIFactory.SetLayoutElement(UIRoot, minWidth: 100, flexibleWidth: 9999, minHeight: 25, flexibleHeight: 0);
GameObject spacerObj = UIFactory.CreateUIObject("Spacer", UIRoot, new Vector2(0, 0));
UIFactory.SetLayoutElement(spacerObj, minWidth: 0, flexibleWidth: 0, minHeight: 0, flexibleHeight: 0);
this.spacer = spacerObj.GetComponent<LayoutElement>();
// Expand arrow
ExpandButton = UIFactory.CreateButton(this.UIRoot, "ExpandButton", "►");
UIFactory.SetLayoutElement(ExpandButton.Component.gameObject, minWidth: 15, flexibleWidth: 0, minHeight: 25, flexibleHeight: 0);
// Enabled toggle
GameObject toggleObj = UIFactory.CreateToggle(UIRoot, "BehaviourToggle", out EnabledToggle, out Text behavText, default, 17, 17);
UIFactory.SetLayoutElement(toggleObj, minHeight: 17, flexibleHeight: 0, minWidth: 17);
EnabledToggle.onValueChanged.AddListener(OnEnableClicked);
// Name button
GameObject nameBtnHolder = UIFactory.CreateHorizontalGroup(this.UIRoot, "NameButtonHolder",
false, false, true, true, childAlignment: TextAnchor.MiddleLeft);
UIFactory.SetLayoutElement(nameBtnHolder, flexibleWidth: 9999, minHeight: 25, flexibleHeight: 0);
nameBtnHolder.AddComponent<Mask>().showMaskGraphic = false;
NameButton = UIFactory.CreateButton(nameBtnHolder, "NameButton", "Name", null);
UIFactory.SetLayoutElement(NameButton.Component.gameObject, flexibleWidth: 9999, minHeight: 25, flexibleHeight: 0);
Text nameLabel = NameButton.Component.GetComponentInChildren<Text>();
nameLabel.horizontalOverflow = HorizontalWrapMode.Overflow;
nameLabel.alignment = TextAnchor.MiddleLeft;
// Sibling index input
SiblingIndex = UIFactory.CreateInputField(this.UIRoot, "SiblingIndexInput", string.Empty);
SiblingIndex.Component.textComponent.fontSize = 11;
SiblingIndex.Component.textComponent.alignment = TextAnchor.MiddleRight;
Image siblingImage = SiblingIndex.GameObject.GetComponent<Image>();
siblingImage.color = new(0f, 0f, 0f, 0.25f);
UIFactory.SetLayoutElement(SiblingIndex.GameObject, 35, 20, 0, 0);
SiblingIndex.Component.GetOnEndEdit().AddListener(OnSiblingIndexEndEdit);
// Setup selectables
Color normal = new(0.11f, 0.11f, 0.11f);
Color highlight = new(0.25f, 0.25f, 0.25f);
Color pressed = new(0.05f, 0.05f, 0.05f);
Color disabled = new(1, 1, 1, 0);
RuntimeHelper.SetColorBlock(ExpandButton.Component, normal, highlight, pressed, disabled);
RuntimeHelper.SetColorBlock(NameButton.Component, normal, highlight, pressed, disabled);
NameButton.OnClick += OnMainButtonClicked;
ExpandButton.OnClick += OnExpandClicked;
UIRoot.SetActive(false);
return this.UIRoot;
}
}
}

View File

@ -1,369 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
using UnityEngine;
using UniverseLib;
using UniverseLib.UI.Widgets.ScrollView;
using UniverseLib.Utility;
namespace UnityExplorer.UI.Widgets
{
public class TransformTree : ICellPoolDataSource<TransformCell>
{
public Func<IEnumerable<GameObject>> GetRootEntriesMethod;
public Action<GameObject> OnClickOverrideHandler;
public ScrollPool<TransformCell> ScrollPool;
// IMPORTANT CAVEAT WITH OrderedDictionary:
// While the performance is mostly good, there are two methods we should NEVER use:
// - Remove(object)
// - set_Item[object]
// These two methods have extremely bad performance due to using IndexOfKey(), which iterates the whole dictionary.
// Currently we do not use either of these methods, so everything should be constant time lookups.
// We DO make use of get_Item[object], get_Item[index], Add, Insert, Contains and RemoveAt, which OrderedDictionary meets our needs for.
/// <summary>
/// Key: UnityEngine.Transform instance ID<br/>
/// Value: CachedTransform
/// </summary>
internal readonly OrderedDictionary cachedTransforms = new();
// for keeping track of which actual transforms are expanded or not, outside of the cache data.
private readonly HashSet<int> expandedInstanceIDs = new();
private readonly HashSet<int> autoExpandedIDs = new();
// state for Traverse parse
private readonly HashSet<int> visited = new();
private bool needRefreshUI;
private int displayIndex;
int prevDisplayIndex;
private Coroutine refreshCoroutine;
private readonly Stopwatch traversedThisFrame = new();
// ScrollPool item count. PrevDisplayIndex is the highest index + 1 from our last traverse.
public int ItemCount => prevDisplayIndex;
// Search filter
public bool Filtering => !string.IsNullOrEmpty(currentFilter);
private bool wasFiltering;
public string CurrentFilter
{
get => currentFilter;
set
{
currentFilter = value ?? "";
if (!wasFiltering && Filtering)
wasFiltering = true;
else if (wasFiltering && !Filtering)
{
wasFiltering = false;
autoExpandedIDs.Clear();
}
}
}
private string currentFilter;
public TransformTree(ScrollPool<TransformCell> scrollPool, Func<IEnumerable<GameObject>> getRootEntriesMethod)
{
ScrollPool = scrollPool;
GetRootEntriesMethod = getRootEntriesMethod;
}
// Initialize and reset
// Must be called externally from owner of this TransformTree
public void Init()
{
ScrollPool.Initialize(this);
}
// Called to completely reset the tree, ie. switching inspected GameObject
public void Rebuild()
{
autoExpandedIDs.Clear();
expandedInstanceIDs.Clear();
RefreshData(true, true, true, false);
}
// Called to completely wipe our data (ie, GameObject inspector returning to pool)
public void Clear()
{
this.cachedTransforms.Clear();
displayIndex = 0;
autoExpandedIDs.Clear();
expandedInstanceIDs.Clear();
this.ScrollPool.Refresh(true, true);
if (refreshCoroutine != null)
{
RuntimeHelper.StopCoroutine(refreshCoroutine);
refreshCoroutine = null;
}
}
// Checks if the given Instance ID is expanded or not
public bool IsTransformExpanded(int instanceID)
{
return Filtering ? autoExpandedIDs.Contains(instanceID)
: expandedInstanceIDs.Contains(instanceID);
}
// Jumps to a specific Transform in the tree and highlights it.
public void JumpAndExpandToTransform(Transform transform)
{
// make sure all parents of the object are expanded
var parent = transform.parent;
while (parent)
{
int pid = parent.GetInstanceID();
if (!expandedInstanceIDs.Contains(pid))
expandedInstanceIDs.Add(pid);
parent = parent.parent;
}
// Refresh cached transforms (no UI rebuild yet).
// Stop existing coroutine and do it oneshot.
RefreshData(false, false, true, true);
int transformID = transform.GetInstanceID();
// find the index of our transform in the list and jump to it
int idx;
for (idx = 0; idx < cachedTransforms.Count; idx++)
{
var cache = (CachedTransform)cachedTransforms[idx];
if (cache.InstanceID == transformID)
break;
}
ScrollPool.JumpToIndex(idx, OnCellJumpedTo);
}
private void OnCellJumpedTo(TransformCell cell)
{
RuntimeHelper.StartCoroutine(HighlightCellCoroutine(cell));
}
private IEnumerator HighlightCellCoroutine(TransformCell cell)
{
var button = cell.NameButton.Component;
button.StartColorTween(new Color(0.2f, 0.3f, 0.2f), false);
float start = Time.realtimeSinceStartup;
while (Time.realtimeSinceStartup - start < 1.5f)
yield return null;
button.OnDeselect(null);
}
// Perform a Traverse and optionally refresh the ScrollPool as well.
// If oneShot, then this happens instantly with no yield.
public void RefreshData(bool andRefreshUI, bool jumpToTop, bool stopExistingCoroutine, bool oneShot)
{
if (refreshCoroutine != null)
{
if (stopExistingCoroutine)
{
RuntimeHelper.StopCoroutine(refreshCoroutine);
refreshCoroutine = null;
}
else
return;
}
visited.Clear();
displayIndex = 0;
needRefreshUI = false;
traversedThisFrame.Reset();
traversedThisFrame.Start();
refreshCoroutine = RuntimeHelper.StartCoroutine(RefreshCoroutine(andRefreshUI, jumpToTop, oneShot));
}
IEnumerator RefreshCoroutine(bool andRefreshUI, bool jumpToTop, bool oneShot)
{
// Instead of doing string.IsNullOrEmpty(CurrentFilter) many times, let's just do it once per update.
bool filtering = Filtering;
IEnumerable<GameObject> rootObjects = GetRootEntriesMethod();
foreach (var gameObj in rootObjects)
{
if (!gameObj)
continue;
IEnumerator enumerator = Traverse(gameObj.transform, null, 0, oneShot, filtering);
while (enumerator.MoveNext())
{
if (!oneShot)
yield return enumerator.Current;
}
}
// Prune displayed transforms that we didnt visit in that traverse
for (int i = cachedTransforms.Count - 1; i >= 0; i--)
{
if (traversedThisFrame.ElapsedMilliseconds > 2)
{
yield return null;
traversedThisFrame.Reset();
traversedThisFrame.Start();
}
var cached = (CachedTransform)cachedTransforms[i];
if (!visited.Contains(cached.InstanceID))
{
cachedTransforms.RemoveAt(i);
needRefreshUI = true;
}
}
if (andRefreshUI && needRefreshUI)
ScrollPool.Refresh(true, jumpToTop);
prevDisplayIndex = displayIndex;
refreshCoroutine = null;
}
// Recursive method to check a Transform and its children (if expanded).
// Parent and depth can be null/default.
private IEnumerator Traverse(Transform transform, CachedTransform parent, int depth, bool oneShot, bool filtering)
{
if (traversedThisFrame.ElapsedMilliseconds > 2)
{
yield return null;
traversedThisFrame.Reset();
traversedThisFrame.Start();
}
int instanceID = transform.GetInstanceID();
// Unlikely, but since this method is async it could theoretically happen in extremely rare circumstances
if (visited.Contains(instanceID))
yield break;
if (filtering)
{
if (!FilterHierarchy(transform))
yield break;
if (!autoExpandedIDs.Contains(instanceID))
autoExpandedIDs.Add(instanceID);
}
visited.Add(instanceID);
CachedTransform cached;
if (cachedTransforms.Contains(instanceID))
{
cached = (CachedTransform)cachedTransforms[(object)instanceID];
int prevSiblingIdx = cached.SiblingIndex;
if (cached.Update(transform, depth))
{
needRefreshUI = true;
// If the sibling index changed, we need to shuffle it in our cached transforms list.
if (prevSiblingIdx != cached.SiblingIndex)
{
cachedTransforms.Remove(instanceID);
if (cachedTransforms.Count <= displayIndex)
cachedTransforms.Add(instanceID, cached);
else
cachedTransforms.Insert(displayIndex, instanceID, cached);
}
}
}
else
{
needRefreshUI = true;
cached = new CachedTransform(this, transform, depth, parent);
if (cachedTransforms.Count <= displayIndex)
cachedTransforms.Add(instanceID, cached);
else
cachedTransforms.Insert(displayIndex, instanceID, cached);
}
displayIndex++;
if (IsTransformExpanded(instanceID) && cached.Value.childCount > 0)
{
for (int i = 0; i < transform.childCount; i++)
{
var enumerator = Traverse(transform.GetChild(i), cached, depth + 1, oneShot, filtering);
while (enumerator.MoveNext())
{
if (!oneShot)
yield return enumerator.Current;
}
}
}
}
private bool FilterHierarchy(Transform obj)
{
if (obj.name.ContainsIgnoreCase(currentFilter))
return true;
if (obj.childCount <= 0)
return false;
for (int i = 0; i < obj.childCount; i++)
if (FilterHierarchy(obj.GetChild(i)))
return true;
return false;
}
public void SetCell(TransformCell cell, int index)
{
if (index < cachedTransforms.Count)
{
cell.ConfigureCell((CachedTransform)cachedTransforms[index]);
if (Filtering)
{
if (cell.cachedTransform.Name.ContainsIgnoreCase(currentFilter))
cell.NameButton.ButtonText.color = Color.green;
}
}
else
cell.Disable();
}
public void OnCellBorrowed(TransformCell cell)
{
cell.OnExpandToggled += OnCellExpandToggled;
cell.OnGameObjectClicked += OnGameObjectClicked;
cell.OnEnableToggled += OnCellEnableToggled;
}
private void OnGameObjectClicked(GameObject obj)
{
if (OnClickOverrideHandler != null)
OnClickOverrideHandler.Invoke(obj);
else
InspectorManager.Inspect(obj);
}
public void OnCellExpandToggled(CachedTransform cache)
{
var instanceID = cache.InstanceID;
if (expandedInstanceIDs.Contains(instanceID))
expandedInstanceIDs.Remove(instanceID);
else
expandedInstanceIDs.Add(instanceID);
RefreshData(true, false, true, true);
}
public void OnCellEnableToggled(CachedTransform cache)
{
cache.Value.gameObject.SetActive(!cache.Value.gameObject.activeSelf);
RefreshData(true, false, true, true);
}
}
}

View File

@ -1,8 +1,6 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
@ -273,7 +271,7 @@ namespace UnityExplorer.UI.Widgets
}
}
#region SavWav
#region SavWav
// Copyright (c) 2012 Calvin Rien
// http://the.darktable.com
@ -404,6 +402,6 @@ namespace UnityExplorer.UI.Widgets
stream.Seek(0, SeekOrigin.Begin);
}
#endregion
#endregion
}
}

Some files were not shown because too many files have changed in this diff Show More