Compare commits

..

7 Commits
3.2.9 ... 3.3.0

Author SHA1 Message Date
b2cbdc1802 Update README.md 2021-03-30 21:31:12 +11:00
3501a28fd1 Restore UnlockMouse config, adjust config saving 2021-03-30 21:23:45 +11:00
40f698122d Revert colorblock changes 2021-03-30 19:55:18 +11:00
0555a644b7 3.3.0 rewrite
* Huge restructure/rewrite. No real changes to any functionality, just a cleaner and more manageable project.
2021-03-30 19:50:04 +11:00
f66a04c93f Update README.md 2021-03-26 23:34:06 +11:00
8f07255d1b Update README.md 2021-03-26 23:12:31 +11:00
46f35129c5 3.2.10
* The following preferences are now persistent between sessions: Active Menu Page, Scene Explorer Hide State, Debug Console Hide State
* The "Resize Cursor" is now just a `↔` Text label instead of a sprite.
* Added support for Unity 5.2+ games (previously was only supporting 5.6)
2021-03-26 19:49:53 +11:00
95 changed files with 4326 additions and 5696 deletions

View File

@ -13,13 +13,6 @@
<img src="https://img.shields.io/github/downloads/sinai-dev/Explorer/total.svg" /> <img src="https://img.shields.io/github/downloads/sinai-dev/Explorer/total.svg" />
</p> </p>
- [Releases](#releases)
- [Features](#features)
- [How to install](#how-to-install)
- [Mod Config](#mod-config)
- [Building](#building)
- [Acknowledgments](#acknowledgments)
## Releases ## Releases
| Mod Loader | IL2CPP | Mono | | Mod Loader | IL2CPP | Mono |
@ -31,6 +24,29 @@
\* BepInEx 6.X Mono release may not work on all games yet. \* BepInEx 6.X Mono release may not work on all games yet.
## How to install
### BepInEx
0. Install [BepInEx](https://github.com/BepInEx/BepInEx) for your game. For IL2CPP you should use [BepInEx 6 (Bleeding Edge)](https://builds.bepis.io/projects/bepinex_be), for Mono you should use [BepInEx 5](https://github.com/BepInEx/BepInEx/releases) (until Mono support stabilizes in BepInEx 6).
1. Download the UnityExplorer release for BepInEx IL2CPP or Mono above.
2. Take the `UnityExplorer.BIE.___.dll` file and put it in `[GameFolder]\BepInEx\plugins\`
3. In IL2CPP, you will need to download the [Unity libs](https://github.com/LavaGang/Unity-Runtime-Libraries) for the game's Unity version and put them in the `BepInEx\unity-libs\` folder.
### MelonLoader
0. Install [MelonLoader](https://github.com/HerpDerpinstine/MelonLoader) 0.3+ for your game. Version 0.3 is currently in pre-release, so you must "Enable ALPHA Releases" in your MelonLoader Installer settings to see the option for it.
1. Download the UnityExplorer release for MelonLoader IL2CPP or Mono above.
2. Take the `UnityExplorer.ML.___.dll` file and put it in the `[GameFolder]\Mods\` folder.
### Standalone
The standalone release is based on the BepInEx build, so it requires Harmony 2.0 (or HarmonyX) to function properly.
0. Load the DLL from your mod or inject it. You must also make sure `0Harmony.dll` is loaded, and `UnhollowerBaseLib.dll` for IL2CPP as well.
1. Create an instance of Unity Explorer with `UnityExplorer.ExplorerStandalone.CreateInstance();`
2. Optionally subscribe to the `ExplorerStandalone.OnLog` event to handle logging if you wish.
## Features ## Features
<p align="center"> <p align="center">
@ -72,42 +88,20 @@ However, you cannot define a class and run it both at the same time. You must ei
You can also make use of the helper methods in the console to simplify some tasks, which you can see listed when the console has nothing entered for input. These methods are **not** accessible within any temporary classes you define, they can only be used in the expression context. You can also make use of the helper methods in the console to simplify some tasks, which you can see listed when the console has nothing entered for input. These methods are **not** accessible within any temporary classes you define, they can only be used in the expression context.
## How to install ### Logging
### BepInEx
Note: For IL2CPP you should use [BepInEx 6 (Bleeding Edge)](https://builds.bepis.io/projects/bepinex_be), for Mono you should use [BepInEx 5](https://github.com/BepInEx/BepInEx/releases) (until Mono support stabilizes in BepInEx 6).
0. Install [BepInEx](https://github.com/BepInEx/BepInEx) for your game.
1. Download the UnityExplorer release for BepInEx IL2CPP or Mono above.
2. Take the `UnityExplorer.BIE.___.dll` file and put it in `[GameFolder]\BepInEx\plugins\`
3. In IL2CPP, it is highly recommended to get the base Unity libs for the game's Unity version and put them in the `BepInEx\unity-libs\` folder.
### MelonLoader
Note: You must use version 0.3 of MelonLoader or greater. Version 0.3 is currently in pre-release, so you must opt-in from your MelonLoader installer (enable alpha releases).
0. Install [MelonLoader](https://github.com/HerpDerpinstine/MelonLoader) for your game.
1. Download the UnityExplorer release for MelonLoader IL2CPP or Mono above.
2. Take the contents of the release and put it in the `[GameFolder]\Mods\` folder. It should look like `[GameFolder]\Mods\UnityExplorer.ML.___.dll`
### Standalone
The standalone release is based on the BepInEx build, so it requires Harmony 2.0 (or HarmonyX) to function properly.
0. Load the DLL from your mod or inject it. You must also make sure that the required libraries (Harmony, Unhollower for Il2Cpp, etc) are loaded.
1. Create an instance of Unity Explorer with `ExplorerStandalone.CreateInstance();`
2. Optionally subscribe to the `ExplorerStandalone.OnLog` event to handle logging if you wish.
## Logging
Explorer saves all logs to disk (only keeps the most recent 10 logs). They can be found in a "UnityExplorer" folder in the same place as where you put the DLL file. Explorer saves all logs to disk (only keeps the most recent 10 logs). They can be found in a "UnityExplorer" folder in the same place as where you put the DLL file.
These logs are also visible in the Debug Console part of the UI. These logs are also visible in the Debug Console part of the UI.
## Settings ### Settings
You can change the settings via the "Options" page of the main menu, or directly from the config file (generated after first launch). The config file will be found either inside a "UnityExplorer" folder in the same directory as where you put the DLL file, or for BepInEx it will be at `BepInEx\config\UnityExplorer\`. You can change the settings via the "Options" page of the main menu, or directly from the config file.
Depending on the release you are using, the config file will be found at:
* BepInEx: `BepInEx\config\com.sinai.unityexplorer.cfg`
* MelonLoader: `UserData\MelonPreferences.cfg`
* Standalone `{DLL_location}\UnityExplorer\config.ini`
`Main Menu Toggle` (KeyCode) `Main Menu Toggle` (KeyCode)
* Default: `F7` * Default: `F7`
@ -136,13 +130,12 @@ You can change the settings via the "Options" page of the main menu, or directly
## Building ## Building
If you'd like to build this yourself, all you need to do is download this repository and build from Visual Studio. Building the project should be straight-forward, the references are all inside the `lib\` folder.
1. Open the `src\UnityExplorer.sln` project. 1. Open the `src\UnityExplorer.sln` project in Visual Studio.
2. Select `Solution 'UnityExplorer' (1 of 1 project)` in the Solution Explorer panel, and set the <b>Active config</b> property to the version you want to build, then build it. Alternatively, use "Batch Build" and select all releases. 2. Select `Solution 'UnityExplorer' (1 of 1 project)` in the Solution Explorer panel, and set the <b>Active config</b> property to the version you want to build, then build it. Alternatively, use "Batch Build" and select all releases.
3. The DLLs are built to the `Release\` folder in the root of the repository. 3. The DLLs are built to the `Release\` folder in the root of the repository.
4. If ILRepack complains about an error, just change the Active config to a different release and then back again. This sometimes happens for the first time you build the project.
The references are all inside the `lib\` folder, if you need to change them for some reason then you can replace them there.
## Acknowledgments ## Acknowledgments

Binary file not shown.

Binary file not shown.

View File

@ -1,14 +1,12 @@
using System; using System;
using Mono.CSharp; using Mono.CSharp;
using UnityExplorer.UI;
using UnityExplorer.UI.Main;
using UnityExplorer.Core.Inspectors;
using UnityExplorer.UI.Main.CSConsole;
using System.Collections; using System.Collections;
using UnityEngine; using UnityEngine;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using UnityExplorer.Core.Runtime; using UnityExplorer.Core.Runtime;
using UnityExplorer.UI.Main.CSConsole;
using UnityExplorer.UI.Main.Home;
namespace UnityExplorer.Core.CSharp namespace UnityExplorer.Core.CSharp
{ {

View File

@ -4,7 +4,6 @@ using System.Linq;
using System.Reflection; using System.Reflection;
using UnityEngine; using UnityEngine;
using UnityExplorer.Core; using UnityExplorer.Core;
using UnityExplorer.Core.Unity;
using UnityExplorer.UI.Main.CSConsole; using UnityExplorer.UI.Main.CSConsole;
namespace UnityExplorer.Core.CSharp namespace UnityExplorer.Core.CSharp
@ -47,8 +46,8 @@ namespace UnityExplorer.Core.CSharp
// ~~~~ Static ~~~~ // ~~~~ Static ~~~~
public static HashSet<string> Namespaces => m_namspaces ?? GetNamespaces(); public static HashSet<string> Namespaces => m_namespaces ?? GetNamespaces();
private static HashSet<string> m_namspaces; private static HashSet<string> m_namespaces;
public static HashSet<string> Keywords => m_keywords ?? (m_keywords = new HashSet<string>(CSLexerHighlighter.validKeywordMatcher.Keywords)); public static HashSet<string> Keywords => m_keywords ?? (m_keywords = new HashSet<string>(CSLexerHighlighter.validKeywordMatcher.Keywords));
private static HashSet<string> m_keywords; private static HashSet<string> m_keywords;
@ -63,7 +62,7 @@ namespace UnityExplorer.Core.CSharp
.Where(x => x.IsPublic && !string.IsNullOrEmpty(x.Namespace)) .Where(x => x.IsPublic && !string.IsNullOrEmpty(x.Namespace))
.Select(x => x.Namespace)); .Select(x => x.Namespace));
return m_namspaces = set; return m_namespaces = set;
IEnumerable<Type> GetTypes(Assembly asm) => asm.TryGetTypes(); IEnumerable<Type> GetTypes(Assembly asm) => asm.TryGetTypes();
} }

View File

@ -0,0 +1,64 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace UnityExplorer.Core.Config
{
public class ConfigElement<T> : IConfigElement
{
public string Name { get; }
public string Description { get; }
public bool IsInternal { get; }
public Type ElementType => typeof(T);
public Action<T> OnValueChanged;
public Action OnValueChangedNotify { get; set; }
public T Value
{
get => m_value;
set => SetValue(value);
}
private T m_value;
object IConfigElement.BoxedValue
{
get => m_value;
set => SetValue((T)value);
}
public ConfigElement(string name, string description, T defaultValue, bool isInternal)
{
Name = name;
Description = description;
m_value = defaultValue;
IsInternal = isInternal;
ConfigManager.RegisterConfigElement(this);
}
private void SetValue(T value)
{
if ((m_value == null && value == null) || m_value.Equals(value))
return;
m_value = value;
ConfigManager.Handler.SetConfigValue(this, value);
OnValueChanged?.Invoke(value);
OnValueChangedNotify?.Invoke();
}
object IConfigElement.GetLoaderConfigValue() => GetLoaderConfigValue();
public T GetLoaderConfigValue()
{
return ConfigManager.Handler.GetConfigValue(this);
}
}
}

View File

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace UnityExplorer.Core.Config
{
public abstract class ConfigHandler
{
public abstract void RegisterConfigElement<T>(ConfigElement<T> element);
public abstract void SetConfigValue<T>(ConfigElement<T> element, T value);
public abstract T GetConfigValue<T>(ConfigElement<T> element);
public abstract void Init();
public abstract void LoadConfig();
public abstract void SaveConfig();
public virtual void OnAnyConfigChanged() { }
}
}

View File

@ -0,0 +1,181 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityExplorer.UI.Main;
using UnityExplorer.UI.Main.Home;
namespace UnityExplorer.Core.Config
{
public static class ConfigManager
{
// Each Mod Loader has its own ConfigHandler.
// See the UnityExplorer.Loader namespace for the implementations.
public static ConfigHandler Handler { get; private set; }
public static ConfigElement<KeyCode> Main_Menu_Toggle;
public static ConfigElement<bool> Force_Unlock_Mouse;
public static ConfigElement<int> Default_Page_Limit;
public static ConfigElement<string> Default_Output_Path;
public static ConfigElement<bool> Log_Unity_Debug;
public static ConfigElement<bool> Hide_On_Startup;
public static ConfigElement<string> Last_Window_Anchors;
public static ConfigElement<int> Last_Active_Tab;
public static ConfigElement<bool> Last_DebugConsole_State;
public static ConfigElement<bool> Last_SceneExplorer_State;
internal static readonly Dictionary<string, IConfigElement> ConfigElements = new Dictionary<string, IConfigElement>();
public static void Init(ConfigHandler configHandler)
{
Handler = configHandler;
Handler.Init();
CreateConfigElements();
Handler.LoadConfig();
SceneExplorer.OnToggleShow += SceneExplorer_OnToggleShow;
PanelDragger.OnFinishResize += PanelDragger_OnFinishResize;
MainMenu.OnActiveTabChanged += MainMenu_OnActiveTabChanged;
DebugConsole.OnToggleShow += DebugConsole_OnToggleShow;
}
internal static void RegisterConfigElement<T>(ConfigElement<T> configElement)
{
Handler.RegisterConfigElement(configElement);
ConfigElements.Add(configElement.Name, configElement);
}
private static void CreateConfigElements()
{
Main_Menu_Toggle = new ConfigElement<KeyCode>("Main Menu Toggle",
"The UnityEngine.KeyCode to toggle the UnityExplorer Menu.",
KeyCode.F7,
false);
Force_Unlock_Mouse = new ConfigElement<bool>("Force Unlock Mouse",
"Force the Cursor to be unlocked (visible) when the UnityExplorer menu is open.",
true,
false);
Default_Page_Limit = new ConfigElement<int>("Default Page Limit",
"The default maximum number of elements per 'page' in UnityExplorer.",
25,
false);
Default_Output_Path = new ConfigElement<string>("Default Output Path",
"The default output path when exporting things from UnityExplorer.",
Path.Combine(ExplorerCore.Loader.ExplorerFolder, "Output"),
false);
Log_Unity_Debug = new ConfigElement<bool>("Log Unity Debug",
"Should UnityEngine.Debug.Log messages be printed to UnityExplorer's log?",
false,
false);
Hide_On_Startup = new ConfigElement<bool>("Hide On Startup",
"Should UnityExplorer be hidden on startup?",
false,
false);
Last_Window_Anchors = new ConfigElement<string>("Last_Window_Anchors",
"For internal use, the last anchors of the UnityExplorer window.",
DEFAULT_WINDOW_ANCHORS,
true);
Last_Active_Tab = new ConfigElement<int>("Last_Active_Tab",
"For internal use, the last active tab index.",
0,
true);
Last_DebugConsole_State = new ConfigElement<bool>("Last_DebugConsole_State",
"For internal use, the collapsed state of the Debug Console.",
true,
true);
Last_SceneExplorer_State = new ConfigElement<bool>("Last_SceneExplorer_State",
"For internal use, the collapsed state of the Scene Explorer.",
true,
true);
}
// Internal config callback listeners
private static void PanelDragger_OnFinishResize(RectTransform rect)
{
Last_Window_Anchors.Value = RectAnchorsToString(rect);
Handler.OnAnyConfigChanged();
}
private static void MainMenu_OnActiveTabChanged(int page)
{
Last_Active_Tab.Value = page;
Handler.OnAnyConfigChanged();
}
private static void DebugConsole_OnToggleShow(bool showing)
{
Last_DebugConsole_State.Value = showing;
Handler.OnAnyConfigChanged();
}
private static void SceneExplorer_OnToggleShow(bool showing)
{
Last_SceneExplorer_State.Value = showing;
Handler.OnAnyConfigChanged();
}
// Window Anchors helpers
private const string DEFAULT_WINDOW_ANCHORS = "0.25,0.10,0.78,0.95";
internal static CultureInfo _enCulture = new CultureInfo("en-US");
internal static string RectAnchorsToString(this RectTransform rect)
{
try
{
return string.Format(_enCulture, "{0},{1},{2},{3}", new object[]
{
rect.anchorMin.x,
rect.anchorMin.y,
rect.anchorMax.x,
rect.anchorMax.y
});
}
catch
{
return DEFAULT_WINDOW_ANCHORS;
}
}
internal static void SetAnchorsFromString(this RectTransform panel, string stringAnchors)
{
Vector4 anchors;
try
{
var split = stringAnchors.Split(',');
if (split.Length != 4)
throw new Exception();
anchors.x = float.Parse(split[0], _enCulture);
anchors.y = float.Parse(split[1], _enCulture);
anchors.z = float.Parse(split[2], _enCulture);
anchors.w = float.Parse(split[3], _enCulture);
}
catch
{
anchors = new Vector4(0.25f, 0.1f, 0.78f, 0.95f);
}
panel.anchorMin = new Vector2(anchors.x, anchors.y);
panel.anchorMax = new Vector2(anchors.z, anchors.w);
}
}
}

View File

@ -1,171 +0,0 @@
using System;
using System.IO;
using UnityEngine;
using IniParser;
using IniParser.Parser;
using UnityExplorer.UI;
using System.Globalization;
namespace UnityExplorer.Core.Config
{
public class ExplorerConfig
{
public static ExplorerConfig Instance;
internal static readonly IniDataParser _parser = new IniDataParser();
internal static readonly string INI_PATH = Path.Combine(ExplorerCore.Loader.ConfigFolder, "config.ini");
internal static CultureInfo _enCulture = new CultureInfo("en-US");
static ExplorerConfig()
{
_parser.Configuration.CommentString = "#";
PanelDragger.OnFinishResize += PanelDragger_OnFinishResize;
}
// Actual configs
public KeyCode Main_Menu_Toggle = KeyCode.F7;
public bool Force_Unlock_Mouse = true;
public int Default_Page_Limit = 25;
public string Default_Output_Path = Path.Combine(ExplorerCore.EXPLORER_FOLDER, "Output");
public bool Log_Unity_Debug = false;
public bool Hide_On_Startup = false;
public string Window_Anchors = DEFAULT_WINDOW_ANCHORS;
private const string DEFAULT_WINDOW_ANCHORS = "0.25,0.10,0.78,0.95";
public static event Action OnConfigChanged;
internal static void InvokeConfigChanged()
{
OnConfigChanged?.Invoke();
}
public static void OnLoad()
{
Instance = new ExplorerConfig();
if (LoadSettings())
return;
SaveSettings();
}
public static bool LoadSettings()
{
if (!File.Exists(INI_PATH))
return false;
string ini = File.ReadAllText(INI_PATH);
var data = _parser.Parse(ini);
foreach (var config in data.Sections["Config"])
{
switch (config.KeyName)
{
case nameof(Main_Menu_Toggle):
Instance.Main_Menu_Toggle = (KeyCode)Enum.Parse(typeof(KeyCode), config.Value);
break;
case nameof(Force_Unlock_Mouse):
Instance.Force_Unlock_Mouse = bool.Parse(config.Value);
break;
case nameof(Default_Page_Limit):
Instance.Default_Page_Limit = int.Parse(config.Value);
break;
case nameof(Log_Unity_Debug):
Instance.Log_Unity_Debug = bool.Parse(config.Value);
break;
case nameof(Default_Output_Path):
Instance.Default_Output_Path = config.Value;
break;
case nameof(Hide_On_Startup):
Instance.Hide_On_Startup = bool.Parse(config.Value);
break;
case nameof(Window_Anchors):
Instance.Window_Anchors = config.Value;
break;
}
}
return true;
}
public static void SaveSettings()
{
var data = new IniParser.Model.IniData();
data.Sections.AddSection("Config");
var sec = data.Sections["Config"];
sec.AddKey(nameof(Main_Menu_Toggle), Instance.Main_Menu_Toggle.ToString());
sec.AddKey(nameof(Force_Unlock_Mouse), Instance.Force_Unlock_Mouse.ToString());
sec.AddKey(nameof(Default_Page_Limit), Instance.Default_Page_Limit.ToString());
sec.AddKey(nameof(Log_Unity_Debug), Instance.Log_Unity_Debug.ToString());
sec.AddKey(nameof(Default_Output_Path), Instance.Default_Output_Path);
sec.AddKey(nameof(Hide_On_Startup), Instance.Hide_On_Startup.ToString());
sec.AddKey(nameof(Window_Anchors), GetWindowAnchorsString());
if (!Directory.Exists(ExplorerCore.Loader.ConfigFolder))
Directory.CreateDirectory(ExplorerCore.Loader.ConfigFolder);
File.WriteAllText(INI_PATH, data.ToString());
}
// ============ Window Anchors specific stuff ============== //
private static void PanelDragger_OnFinishResize()
{
Instance.Window_Anchors = GetWindowAnchorsString();
SaveSettings();
}
internal Vector4 GetWindowAnchorsVector()
{
try
{
var split = Window_Anchors.Split(',');
if (split.Length != 4)
throw new Exception();
Vector4 ret = Vector4.zero;
ret.x = float.Parse(split[0], _enCulture);
ret.y = float.Parse(split[1], _enCulture);
ret.z = float.Parse(split[2], _enCulture);
ret.w = float.Parse(split[3], _enCulture);
return ret;
}
catch
{
return DefaultWindowAnchors();
}
}
internal static string GetWindowAnchorsString()
{
try
{
var rect = PanelDragger.Instance.Panel;
return string.Format(_enCulture, "{0},{1},{2},{3}", new object[]
{
rect.anchorMin.x,
rect.anchorMin.y,
rect.anchorMax.x,
rect.anchorMax.y
});
}
catch
{
return DEFAULT_WINDOW_ANCHORS;
}
}
internal static Vector4 DefaultWindowAnchors()
{
Instance.Window_Anchors = DEFAULT_WINDOW_ANCHORS;
return new Vector4(0.25f, 0.1f, 0.78f, 0.95f);
}
}
}

View File

@ -0,0 +1,19 @@
using System;
namespace UnityExplorer.Core.Config
{
public interface IConfigElement
{
string Name { get; }
string Description { get; }
bool IsInternal { get; }
Type ElementType { get; }
object BoxedValue { get; set; }
object GetLoaderConfigValue();
Action OnValueChangedNotify { get; set; }
}
}

View File

@ -6,30 +6,29 @@ using UnityExplorer.Core.Input;
using BF = System.Reflection.BindingFlags; using BF = System.Reflection.BindingFlags;
using UnityExplorer.Core.Config; using UnityExplorer.Core.Config;
using UnityExplorer.Core; using UnityExplorer.Core;
using UnityExplorer.UI;
#if ML #if ML
using Harmony; using Harmony;
#else #else
using HarmonyLib; using HarmonyLib;
#endif #endif
namespace UnityExplorer.UI.Utility namespace UnityExplorer.Core.Input
{ {
public class CursorUnlocker public class CursorUnlocker
{ {
public static bool Unlock public static bool Unlock
{ {
get => m_forceUnlock; get => m_forceUnlock;
set => SetForceUnlock(value); set
{
m_forceUnlock = value;
UpdateCursorControl();
}
} }
private static bool m_forceUnlock; private static bool m_forceUnlock;
private static void SetForceUnlock(bool unlock) public static bool ShouldActuallyUnlock => UIManager.ShowMenu && Unlock;
{
m_forceUnlock = unlock;
UpdateCursorControl();
}
public static bool ShouldForceMouse => UIManager.ShowMenu && Unlock;
private static CursorLockMode m_lastLockMode; private static CursorLockMode m_lastLockMode;
private static bool m_lastVisibleState; private static bool m_lastVisibleState;
@ -43,16 +42,12 @@ namespace UnityExplorer.UI.Utility
public static void Init() public static void Init()
{ {
ExplorerConfig.OnConfigChanged += ModConfig_OnConfigChanged;
SetupPatches(); SetupPatches();
Unlock = true; UpdateCursorControl();
}
internal static void ModConfig_OnConfigChanged() Unlock = true;
{ ConfigManager.Force_Unlock_Mouse.OnValueChanged += (bool val) => { Unlock = val; };
Unlock = ExplorerConfig.Instance.Force_Unlock_Mouse;
} }
private static void SetupPatches() private static void SetupPatches()
@ -67,11 +62,9 @@ namespace UnityExplorer.UI.Utility
// Get current cursor state and enable cursor // Get current cursor state and enable cursor
try try
{ {
//m_lastLockMode = Cursor.lockState;
m_lastLockMode = (CursorLockMode?)typeof(Cursor).GetProperty("lockState", BF.Public | BF.Static)?.GetValue(null, null) m_lastLockMode = (CursorLockMode?)typeof(Cursor).GetProperty("lockState", BF.Public | BF.Static)?.GetValue(null, null)
?? CursorLockMode.None; ?? CursorLockMode.None;
//m_lastVisibleState = Cursor.visible;
m_lastVisibleState = (bool?)typeof(Cursor).GetProperty("visible", BF.Public | BF.Static)?.GetValue(null, null) m_lastVisibleState = (bool?)typeof(Cursor).GetProperty("visible", BF.Public | BF.Static)?.GetValue(null, null)
?? false; ?? false;
} }
@ -105,7 +98,7 @@ namespace UnityExplorer.UI.Utility
{ {
var harmony = ExplorerCore.Loader.HarmonyInstance; var harmony = ExplorerCore.Loader.HarmonyInstance;
System.Reflection.PropertyInfo prop = type.GetProperty(property); var prop = type.GetProperty(property);
if (setter) // setter is prefix if (setter) // setter is prefix
{ {
@ -128,7 +121,7 @@ namespace UnityExplorer.UI.Utility
try try
{ {
m_currentlySettingCursor = true; m_currentlySettingCursor = true;
if (ShouldForceMouse) if (ShouldActuallyUnlock)
{ {
Cursor.lockState = CursorLockMode.None; Cursor.lockState = CursorLockMode.None;
Cursor.visible = true; Cursor.visible = true;
@ -202,10 +195,8 @@ namespace UnityExplorer.UI.Utility
m_lastEventSystem = value; m_lastEventSystem = value;
m_lastInputModule = value?.currentInputModule; m_lastInputModule = value?.currentInputModule;
if (UIManager.ShowMenu) if (ShouldActuallyUnlock)
{
value = UIManager.EventSys; value = UIManager.EventSys;
}
} }
} }
@ -220,10 +211,8 @@ namespace UnityExplorer.UI.Utility
{ {
m_lastLockMode = value; m_lastLockMode = value;
if (ShouldForceMouse) if (ShouldActuallyUnlock)
{
value = CursorLockMode.None; value = CursorLockMode.None;
}
} }
} }
@ -234,10 +223,8 @@ namespace UnityExplorer.UI.Utility
{ {
m_lastVisibleState = value; m_lastVisibleState = value;
if (ShouldForceMouse) if (ShouldActuallyUnlock)
{
value = true; value = true;
}
} }
} }
} }

View File

@ -56,6 +56,8 @@ namespace UnityExplorer.Core.Input
m_inputModule = new NoInput(); m_inputModule = new NoInput();
CurrentType = InputType.None; CurrentType = InputType.None;
} }
CursorUnlocker.Init();
} }
} }
} }

View File

@ -1,138 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UnityExplorer.Core.Unity;
using UnityExplorer.UI;
using UnityExplorer.UI.Main;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using UnityExplorer.Core.Inspectors.Reflection;
using UnityExplorer.Core.Runtime;
using UnityExplorer.UI.Main.Home;
namespace UnityExplorer.Core.Inspectors
{
public class InspectorManager
{
public static InspectorManager Instance { get; private set; }
internal static InspectorManagerUI UI;
public InspectorManager()
{
Instance = this;
UI = new InspectorManagerUI();
UI.ConstructInspectorPane();
}
public InspectorBase m_activeInspector;
public readonly List<InspectorBase> m_currentInspectors = new List<InspectorBase>();
public void Update()
{
for (int i = 0; i < m_currentInspectors.Count; i++)
{
if (i >= m_currentInspectors.Count)
break;
m_currentInspectors[i].Update();
}
}
public void Inspect(object obj, CacheObjectBase parentMember = null)
{
obj = ReflectionProvider.Instance.Cast(obj, ReflectionProvider.Instance.GetActualType(obj));
UnityEngine.Object unityObj = obj as UnityEngine.Object;
if (obj.IsNullOrDestroyed(false))
{
return;
}
// check if currently inspecting this object
foreach (InspectorBase tab in m_currentInspectors)
{
if (ReferenceEquals(obj, tab.Target))
{
SetInspectorTab(tab);
return;
}
#if CPP
else if (unityObj && tab.Target is UnityEngine.Object uTabObj)
{
if (unityObj.m_CachedPtr == uTabObj.m_CachedPtr)
{
SetInspectorTab(tab);
return;
}
}
#endif
}
InspectorBase inspector;
if (obj is GameObject go)
inspector = new GameObjectInspector(go);
else
inspector = new InstanceInspector(obj);
if (inspector is ReflectionInspector ri)
ri.ParentMember = parentMember;
m_currentInspectors.Add(inspector);
SetInspectorTab(inspector);
}
public void Inspect(Type type)
{
if (type == null)
{
ExplorerCore.LogWarning("The provided type was null!");
return;
}
foreach (var tab in m_currentInspectors.Where(x => x is StaticInspector))
{
if (ReferenceEquals(tab.Target as Type, type))
{
SetInspectorTab(tab);
return;
}
}
var inspector = new StaticInspector(type);
m_currentInspectors.Add(inspector);
SetInspectorTab(inspector);
}
public void SetInspectorTab(InspectorBase inspector)
{
MainMenu.Instance.SetPage(HomePage.Instance);
if (m_activeInspector == inspector)
return;
UnsetInspectorTab();
m_activeInspector = inspector;
inspector.SetActive();
UI.OnSetInspectorTab(inspector);
}
public void UnsetInspectorTab()
{
if (m_activeInspector == null)
return;
m_activeInspector.SetInactive();
UI.OnUnsetInspectorTab();
m_activeInspector = null;
}
}
}

View File

@ -1,101 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UnityExplorer.UI;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.Core.Runtime;
using UnityExplorer.Core.Unity;
using UnityExplorer.UI.Main.Home.Inspectors;
namespace UnityExplorer.Core.Inspectors
{
public class GameObjectInspector : InspectorBase
{
public override string TabLabel => $" <color=cyan>[G]</color> {TargetGO?.name}";
public static GameObjectInspector ActiveInstance { get; private set; }
public GameObject TargetGO;
public GameObjectInspectorUI UIModule;
// sub modules
internal static ChildList s_childList;
internal static ComponentList s_compList;
internal static GameObjectControls s_controls;
internal static bool m_UIConstructed;
public GameObjectInspector(GameObject target) : base(target)
{
ActiveInstance = this;
TargetGO = target;
if (!TargetGO)
{
ExplorerCore.LogWarning("Target GameObject is null!");
return;
}
// one UI is used for all gameobject inspectors. no point recreating it.
if (!m_UIConstructed)
{
m_UIConstructed = true;
s_childList = new ChildList();
s_compList = new ComponentList();
s_controls = new GameObjectControls();
UIModule.ConstructUI();
}
}
public override void SetActive()
{
base.SetActive();
ActiveInstance = this;
}
public override void SetInactive()
{
base.SetInactive();
ActiveInstance = null;
}
internal void ChangeInspectorTarget(GameObject newTarget)
{
if (!newTarget)
return;
this.Target = this.TargetGO = newTarget;
}
// Update
public override void Update()
{
base.Update();
if (m_pendingDestroy || !this.IsActive)
return;
UIModule.RefreshTopInfo();
s_childList.RefreshChildObjectList();
s_compList.RefreshComponentList();
s_controls.RefreshControls();
if (GameObjectControls.s_sliderChangedWanted)
GameObjectControls.UpdateSliderControl();
}
public override void CreateUIModule()
{
base.BaseUI = UIModule = new GameObjectInspectorUI();
}
}
}

View File

@ -1,54 +0,0 @@
using System;
using System.Reflection;
using UnityEngine;
using UnityExplorer.UI;
using UnityEngine.UI;
using System.IO;
using UnityExplorer.Core.Runtime;
using UnityExplorer.UI.Main.Home.Inspectors;
namespace UnityExplorer.Core.Inspectors.Reflection
{
public enum MemberScopes
{
All,
Instance,
Static
}
public class InstanceInspector : ReflectionInspector
{
public override string TabLabel => $" <color=cyan>[R]</color> {base.TabLabel}";
internal MemberScopes m_scopeFilter;
internal Button m_lastActiveScopeButton;
public InstanceInspector(object target) : base(target) { }
internal InstanceInspectorUI InstanceUI;
public void CreateInstanceUIModule()
{
InstanceUI = new InstanceInspectorUI(this);
}
internal void OnScopeFilterClicked(MemberScopes type, Button button)
{
if (m_lastActiveScopeButton)
{
var lastColors = m_lastActiveScopeButton.colors;
lastColors.normalColor = new Color(0.2f, 0.2f, 0.2f);
m_lastActiveScopeButton.colors = lastColors;
}
m_scopeFilter = type;
m_lastActiveScopeButton = button;
var colors = m_lastActiveScopeButton.colors;
colors.normalColor = new Color(0.2f, 0.6f, 0.2f);
m_lastActiveScopeButton.colors = colors;
FilterMembers(null, true);
base.ReflectionUI.m_sliderScroller.m_slider.value = 1f;
}
}
}

View File

@ -11,7 +11,7 @@ namespace UnityExplorer.Core
{ {
public static class ReflectionUtility public static class ReflectionUtility
{ {
public static BF CommonFlags = BF.Public | BF.Instance | BF.NonPublic | BF.Static; public const BF CommonFlags = BF.Public | BF.Instance | BF.NonPublic | BF.Static;
/// <summary> /// <summary>
/// Helper for IL2CPP to get the underlying true Type (Unhollowed) of the object. /// Helper for IL2CPP to get the underlying true Type (Unhollowed) of the object.
@ -32,7 +32,7 @@ namespace UnityExplorer.Core
/// <param name="obj">The object to cast</param> /// <param name="obj">The object to cast</param>
/// <returns>The object, cast to the underlying Type if possible, otherwise the original object.</returns> /// <returns>The object, cast to the underlying Type if possible, otherwise the original object.</returns>
public static object Cast(this object obj) public static object Cast(this object obj)
=> Cast(obj, GetType(obj)); => ReflectionProvider.Instance.Cast(obj, GetType(obj));
/// <summary> /// <summary>
/// Cast an object to a Type, if possible. /// Cast an object to a Type, if possible.
@ -59,7 +59,10 @@ namespace UnityExplorer.Core
public static bool IsDictionary(this Type t) public static bool IsDictionary(this Type t)
=> ReflectionProvider.Instance.IsAssignableFrom(typeof(IDictionary), t); => ReflectionProvider.Instance.IsAssignableFrom(typeof(IDictionary), t);
public static bool LoadModule(string module) /// <summary>
/// [INTERNAL] Used to load Unhollowed DLLs in IL2CPP.
/// </summary>
internal static bool LoadModule(string module)
=> ReflectionProvider.Instance.LoadModule(module); => ReflectionProvider.Instance.LoadModule(module);
// cache for GetTypeByName // cache for GetTypeByName

View File

@ -2,6 +2,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace UnityExplorer.Core.Runtime.Il2Cpp namespace UnityExplorer.Core.Runtime.Il2Cpp
@ -9,6 +10,9 @@ namespace UnityExplorer.Core.Runtime.Il2Cpp
[SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "External methods")] [SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "External methods")]
public static class ICallManager public static class ICallManager
{ {
[DllImport("GameAssembly", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern IntPtr il2cpp_resolve_icall([MarshalAs(UnmanagedType.LPStr)] string name);
private static readonly Dictionary<string, Delegate> iCallCache = new Dictionary<string, Delegate>(); private static readonly Dictionary<string, Delegate> iCallCache = new Dictionary<string, Delegate>();
/// <summary> /// <summary>
@ -26,9 +30,7 @@ namespace UnityExplorer.Core.Runtime.Il2Cpp
IntPtr ptr = il2cpp_resolve_icall(signature); IntPtr ptr = il2cpp_resolve_icall(signature);
if (ptr == IntPtr.Zero) if (ptr == IntPtr.Zero)
{ throw new MissingMethodException($"Could not find any iCall with the signature '{signature}'!");
throw new MissingMethodException($"Could not resolve internal call by name '{signature}'!");
}
Delegate iCall = Marshal.GetDelegateForFunctionPointer(ptr, typeof(T)); Delegate iCall = Marshal.GetDelegateForFunctionPointer(ptr, typeof(T));
iCallCache.Add(signature, iCall); iCallCache.Add(signature, iCall);
@ -36,8 +38,35 @@ namespace UnityExplorer.Core.Runtime.Il2Cpp
return (T)iCall; return (T)iCall;
} }
[DllImport("GameAssembly", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] private static readonly Dictionary<string, Delegate> s_unreliableCache = new Dictionary<string, Delegate>();
public static extern IntPtr il2cpp_resolve_icall([MarshalAs(UnmanagedType.LPStr)] string name);
/// <summary>
/// Get an iCall which may be one of multiple different signatures (ie, it changed in different Unity versions).
/// Each possible signature must have the same Type pattern, it can only vary by name.
/// </summary>
public static T GetICallUnreliable<T>(IEnumerable<string> possibleSignatures) where T : Delegate
{
// use the first possible signature as the 'key'.
string key = possibleSignatures.First();
if (s_unreliableCache.ContainsKey(key))
return (T)s_unreliableCache[key];
T iCall;
IntPtr ptr;
foreach (var sig in possibleSignatures)
{
ptr = il2cpp_resolve_icall(sig);
if (ptr != IntPtr.Zero)
{
iCall = (T)Marshal.GetDelegateForFunctionPointer(ptr, typeof(T));
s_unreliableCache.Add(key, iCall);
return iCall;
}
}
throw new MissingMethodException($"Could not find any iCall from list of provided signatures starting with '{key}'!");
}
} }
} }
#endif #endif

View File

@ -11,6 +11,8 @@ using UnityEngine;
using UnityEngine.Events; using UnityEngine.Events;
using UnityEngine.SceneManagement; using UnityEngine.SceneManagement;
using System.Collections; using System.Collections;
using UnityEngine.UI;
using UnityExplorer.Core.Input;
namespace UnityExplorer.Core.Runtime.Il2Cpp namespace UnityExplorer.Core.Runtime.Il2Cpp
{ {
@ -33,7 +35,7 @@ namespace UnityExplorer.Core.Runtime.Il2Cpp
var addMethod = typeof(Application).GetMethod("add_logMessageReceived", BF.Static | BF.Public, null, new[] { logType }, null); var addMethod = typeof(Application).GetMethod("add_logMessageReceived", BF.Static | BF.Public, null, new[] { logType }, null);
addMethod.Invoke(null, new[] addMethod.Invoke(null, new[]
{ {
castMethod.Invoke(null, new[] { new Action<string, string, LogType>(ExplorerCore.Instance.OnUnityLog) }) castMethod.Invoke(null, new[] { new Action<string, string, LogType>(Application_logMessageReceived) })
}); });
} }
catch catch
@ -42,11 +44,20 @@ namespace UnityExplorer.Core.Runtime.Il2Cpp
} }
} }
private void Application_logMessageReceived(string condition, string stackTrace, LogType type)
{
ExplorerCore.Log(condition, type, true);
}
public override void StartConsoleCoroutine(IEnumerator routine) public override void StartConsoleCoroutine(IEnumerator routine)
{ {
Il2CppCoroutine.Start(routine); Il2CppCoroutine.Start(routine);
} }
// Unity API Handlers
// LayerMask.LayerToName
internal delegate IntPtr d_LayerToName(int layer); internal delegate IntPtr d_LayerToName(int layer);
public override string LayerToName(int layer) public override string LayerToName(int layer)
@ -55,20 +66,25 @@ namespace UnityExplorer.Core.Runtime.Il2Cpp
return IL2CPP.Il2CppStringToManaged(iCall.Invoke(layer)); return IL2CPP.Il2CppStringToManaged(iCall.Invoke(layer));
} }
// Resources.FindObjectsOfTypeAll
internal delegate IntPtr d_FindObjectsOfTypeAll(IntPtr type); internal delegate IntPtr d_FindObjectsOfTypeAll(IntPtr type);
public override UnityEngine.Object[] FindObjectsOfTypeAll(Type type) public override UnityEngine.Object[] FindObjectsOfTypeAll(Type type)
{ {
var iCall = ICallManager.GetICall<d_FindObjectsOfTypeAll>("UnityEngine.Resources::FindObjectsOfTypeAll"); var iCall = ICallManager.GetICallUnreliable<d_FindObjectsOfTypeAll>(new[]
var cppType = Il2CppType.From(type); {
"UnityEngine.Resources::FindObjectsOfTypeAll",
"UnityEngine.ResourcesAPIInternal::FindObjectsOfTypeAll" // Unity 2020+ updated to this
});
return new Il2CppReferenceArray<UnityEngine.Object>(iCall.Invoke(cppType.Pointer)); return new Il2CppReferenceArray<UnityEngine.Object>(iCall.Invoke(Il2CppType.From(type).Pointer));
} }
public override int GetSceneHandle(Scene scene) public override int GetSceneHandle(Scene scene)
=> scene.handle; => scene.handle;
//Scene.GetRootGameObjects(); // Scene.GetRootGameObjects();
internal delegate void d_GetRootGameObjects(int handle, IntPtr list); internal delegate void d_GetRootGameObjects(int handle, IntPtr list);
@ -93,7 +109,7 @@ namespace UnityExplorer.Core.Runtime.Il2Cpp
return list.ToArray(); return list.ToArray();
} }
//Scene.rootCount; // Scene.rootCount
internal delegate int d_GetRootCountInternal(int handle); internal delegate int d_GetRootCountInternal(int handle);
@ -104,10 +120,23 @@ namespace UnityExplorer.Core.Runtime.Il2Cpp
return ICallManager.GetICall<d_GetRootCountInternal>("UnityEngine.SceneManagement.Scene::GetRootCountInternal") return ICallManager.GetICall<d_GetRootCountInternal>("UnityEngine.SceneManagement.Scene::GetRootCountInternal")
.Invoke(handle); .Invoke(handle);
} }
// Custom check for il2cpp input pointer event
public override void CheckInputPointerEvent()
{
// Some IL2CPP games behave weird with multiple UI Input Systems, some fixes for them.
var evt = InputManager.InputPointerEvent;
if (evt != null)
{
if (!evt.eligibleForClick && evt.selectedObject)
evt.eligibleForClick = true;
}
}
} }
} }
public static class UnityEventExtensions public static class Il2CppExtensions
{ {
public static void AddListener(this UnityEvent action, Action listener) public static void AddListener(this UnityEvent action, Action listener)
{ {
@ -118,6 +147,9 @@ public static class UnityEventExtensions
{ {
action.AddListener(listener); action.AddListener(listener);
} }
public static void SetChildControlHeight(this HorizontalOrVerticalLayoutGroup group, bool value) => group.childControlHeight = value;
public static void SetChildControlWidth(this HorizontalOrVerticalLayoutGroup group, bool value) => group.childControlWidth = value;
} }
#endif #endif

View File

@ -5,7 +5,6 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using UnhollowerBaseLib; using UnhollowerBaseLib;
using UnityExplorer.Core.Unity;
using UnhollowerRuntimeLib; using UnhollowerRuntimeLib;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Reflection; using System.Reflection;
@ -109,6 +108,7 @@ namespace UnityExplorer.Core.Runtime.Il2Cpp
Type ret = Type.GetType(name); Type ret = Type.GetType(name);
// Thanks to Slaynash for this deobfuscation snippet!
if (ret == null) if (ret == null)
{ {
string baseName = cppType.FullName; string baseName = cppType.FullName;

View File

@ -6,7 +6,9 @@ using System.Linq;
using System.Reflection; using System.Reflection;
using System.Text; using System.Text;
using UnityEngine; using UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement; using UnityEngine.SceneManagement;
using UnityEngine.UI;
using UnityExplorer.Core; using UnityExplorer.Core;
using UnityExplorer.Core.CSharp; using UnityExplorer.Core.CSharp;
@ -22,9 +24,12 @@ namespace UnityExplorer.Core.Runtime.Mono
public override void SetupEvents() public override void SetupEvents()
{ {
Application.logMessageReceived += ExplorerCore.Instance.OnUnityLog; Application.logMessageReceived += Application_logMessageReceived;
//SceneManager.sceneLoaded += ExplorerCore.Instance.OnSceneLoaded1; }
//SceneManager.activeSceneChanged += ExplorerCore.Instance.OnSceneLoaded2;
private void Application_logMessageReceived(string condition, string stackTrace, LogType type)
{
ExplorerCore.Log(condition, type, true);
} }
public override void StartConsoleCoroutine(IEnumerator routine) public override void StartConsoleCoroutine(IEnumerator routine)
@ -54,15 +59,50 @@ namespace UnityExplorer.Core.Runtime.Mono
{ {
return scene.rootCount; return scene.rootCount;
} }
public override void CheckInputPointerEvent()
{
// Not necessary afaik
}
} }
} }
public static class MonoExtensions public static class MonoExtensions
{ {
public static void AddListener(this UnityEvent _event, Action listener)
{
_event.AddListener(new UnityAction(listener));
}
public static void AddListener<T>(this UnityEvent<T> _event, Action<T> listener)
{
_event.AddListener(new UnityAction<T>(listener));
}
public static void Clear(this StringBuilder sb) public static void Clear(this StringBuilder sb)
{ {
sb.Remove(0, sb.Length); sb.Remove(0, sb.Length);
} }
private static PropertyInfo pi_childControlHeight;
public static void SetChildControlHeight(this HorizontalOrVerticalLayoutGroup group, bool value)
{
if (pi_childControlHeight == null)
pi_childControlHeight = group.GetType().GetProperty("childControlHeight");
pi_childControlHeight?.SetValue(group, value, null);
}
private static PropertyInfo pi_childControlWidth;
public static void SetChildControlWidth(this HorizontalOrVerticalLayoutGroup group, bool value)
{
if (pi_childControlWidth == null)
pi_childControlWidth = group.GetType().GetProperty("childControlWidth");
pi_childControlWidth?.SetValue(group, value, null);
}
} }
#endif #endif

View File

@ -5,6 +5,7 @@ using System.Linq;
using System.Text; using System.Text;
using UnityEngine; using UnityEngine;
using UnityEngine.SceneManagement; using UnityEngine.SceneManagement;
using UnityEngine.UI;
namespace UnityExplorer.Core.Runtime namespace UnityExplorer.Core.Runtime
{ {
@ -50,5 +51,7 @@ namespace UnityExplorer.Core.Runtime
public abstract GameObject[] GetRootGameObjects(Scene scene); public abstract GameObject[] GetRootGameObjects(Scene scene);
public abstract int GetRootCount(Scene scene); public abstract int GetRootCount(Scene scene);
public abstract void CheckInputPointerEvent();
} }
} }

View File

@ -1,204 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UnityExplorer.UI;
using UnityExplorer.UI.Main;
using UnityExplorer.UI.Reusable;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using UnityExplorer.Core.Runtime;
using UnityExplorer.UI.Main.Home;
namespace UnityExplorer.Core.Inspectors
{
public class SceneExplorer
{
public static SceneExplorer Instance;
public static SceneExplorerUI UI;
internal static Action OnToggleShow;
public SceneExplorer()
{
Instance = this;
UI = new SceneExplorerUI();
UI.ConstructScenePane();
}
private const float UPDATE_INTERVAL = 1f;
private float m_timeOfLastSceneUpdate;
// private int m_currentSceneHandle = -1;
public static Scene DontDestroyScene => DontDestroyObject.scene;
internal Scene m_currentScene;
internal Scene[] m_currentScenes = new Scene[0];
internal GameObject[] m_allObjects = new GameObject[0];
internal GameObject m_selectedSceneObject;
internal int m_lastCount;
internal static GameObject DontDestroyObject
{
get
{
if (!s_dontDestroyObject)
{
s_dontDestroyObject = new GameObject("DontDestroyMe");
GameObject.DontDestroyOnLoad(s_dontDestroyObject);
}
return s_dontDestroyObject;
}
}
internal static GameObject s_dontDestroyObject;
public void Init()
{
RefreshSceneSelector();
}
public void Update()
{
if (SceneExplorerUI.Hiding || Time.realtimeSinceStartup - m_timeOfLastSceneUpdate < UPDATE_INTERVAL)
{
return;
}
RefreshSceneSelector();
if (!m_selectedSceneObject)
{
if (m_currentScene != default)
{
var rootObjects = RuntimeProvider.Instance.GetRootGameObjects(m_currentScene);
SetSceneObjectList(rootObjects);
}
}
else
{
RefreshSelectedSceneObject();
}
}
private void RefreshSceneSelector()
{
var newNames = new List<string>();
var newScenes = new List<Scene>();
if (m_currentScenes == null)
m_currentScenes = new Scene[0];
bool anyChange = SceneManager.sceneCount != m_currentScenes.Length - 1;
for (int i = 0; i < SceneManager.sceneCount; i++)
{
Scene scene = SceneManager.GetSceneAt(i);
if (scene == default)
continue;
int handle = RuntimeProvider.Instance.GetSceneHandle(scene);
if (!anyChange && !m_currentScenes.Any(it => handle == RuntimeProvider.Instance.GetSceneHandle(it)))
anyChange = true;
newScenes.Add(scene);
newNames.Add(scene.name);
}
if (anyChange)
{
newNames.Add("DontDestroyOnLoad");
newScenes.Add(DontDestroyScene);
m_currentScenes = newScenes.ToArray();
UI.OnActiveScenesChanged(newNames);
SetTargetScene(newScenes[0]);
SearchPage.Instance.OnSceneChange();
}
}
public void SetTargetScene(int index)
=> SetTargetScene(m_currentScenes[index]);
public void SetTargetScene(Scene scene)
{
if (scene == default)
return;
m_currentScene = scene;
var rootObjs = RuntimeProvider.Instance.GetRootGameObjects(scene);
SetSceneObjectList(rootObjs);
m_selectedSceneObject = null;
UI.OnSceneSelected();
}
public void SetSceneObjectParent()
{
if (!m_selectedSceneObject || !m_selectedSceneObject.transform.parent?.gameObject)
{
m_selectedSceneObject = null;
SetTargetScene(m_currentScene);
}
else
{
SetTargetObject(m_selectedSceneObject.transform.parent.gameObject);
}
}
public void SetTargetObject(GameObject obj)
{
if (!obj)
return;
UI.OnGameObjectSelected(obj);
m_selectedSceneObject = obj;
RefreshSelectedSceneObject();
}
private void RefreshSelectedSceneObject()
{
GameObject[] list = new GameObject[m_selectedSceneObject.transform.childCount];
for (int i = 0; i < m_selectedSceneObject.transform.childCount; i++)
{
list[i] = m_selectedSceneObject.transform.GetChild(i).gameObject;
}
SetSceneObjectList(list);
}
private void SetSceneObjectList(GameObject[] objects)
{
m_allObjects = objects;
RefreshSceneObjectList();
}
internal void RefreshSceneObjectList()
{
m_timeOfLastSceneUpdate = Time.realtimeSinceStartup;
UI.RefreshSceneObjectList(m_allObjects, out int newCount);
m_lastCount = newCount;
}
internal static void InspectSelectedGameObject()
{
InspectorManager.Instance.Inspect(Instance.m_selectedSceneObject);
}
internal static void InvokeOnToggleShow()
{
OnToggleShow?.Invoke();
}
}
}

View File

@ -3,7 +3,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
namespace UnityExplorer.Search namespace UnityExplorer.Core.Search
{ {
internal enum ChildFilter internal enum ChildFilter
{ {

View File

@ -3,7 +3,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
namespace UnityExplorer.Search namespace UnityExplorer.Core.Search
{ {
internal enum SceneFilter internal enum SceneFilter
{ {

View File

@ -3,7 +3,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
namespace UnityExplorer.Search namespace UnityExplorer.Core.Search
{ {
internal enum SearchContext internal enum SearchContext
{ {

View File

@ -4,11 +4,11 @@ using System.Linq;
using System.Reflection; using System.Reflection;
using System.Text; using System.Text;
using UnityEngine; using UnityEngine;
using UnityExplorer.Core;
using UnityExplorer.Core.Runtime; using UnityExplorer.Core.Runtime;
using UnityExplorer.UI.Main; using UnityExplorer.UI.Main;
using UnityExplorer.UI.Main.Search;
namespace UnityExplorer.Search namespace UnityExplorer.Core.Search
{ {
public static class SearchProvider public static class SearchProvider
{ {

View File

@ -1,290 +0,0 @@
//using System.Collections;
//using System.Collections.Generic;
//using UnityExplorer.UI;
//using UnityEngine;
//using System;
//using System.Runtime.InteropServices;
//using System.Text;
//using UnityExplorer.Core.Runtime;
//namespace UnityExplorer.Core.Tests
//{
// internal enum TestByteEnum : byte
// {
// One,
// Two,
// Three,
// TwoFiftyFive = 255,
// }
// public static class StaticTestClass
// {
// public static int StaticProperty => 5;
// public static int StaticField = 69;
// public static List<string> StaticList = new List<string>
// {
// "one",
// "two",
// "three",
// };
// public static void StaticMethod() { }
// }
// public class TestClass
// {
// internal static TestByteEnum testingByte = TestByteEnum.One;
// public string AAALongString = @"1
//2
//3
//4
//5";
// public Vector2 AATestVector2 = new Vector2(1, 2);
// public Vector3 AATestVector3 = new Vector3(1, 2, 3);
// public Vector4 AATestVector4 = new Vector4(1, 2, 3, 4);
// public Rect AATestRect = new Rect(1, 2, 3, 4);
// public Color AATestColor = new Color(0.1f, 0.2f, 0.3f, 0.4f);
// public bool ATestBoolMethod() => false;
// public bool this[int index]
// {
// get => index % 2 == 0;
// set => m_thisBool = value;
// }
// internal bool m_thisBool;
// static int testInt;
// public static List<string> ExceptionList
// {
// get
// {
// testInt++;
// if (testInt % 2 == 0)
// throw new Exception("its even");
// else
// return new List<string> { "one" };
// }
// }
// static bool abool;
// public static bool ATestExceptionBool
// {
// get
// {
// abool = !abool;
// if (!abool)
// throw new Exception("false");
// else
// return true;
// }
// }
// public static string ExceptionString => throw new NotImplementedException();
// public static string ANullString = null;
// public static float ATestFloat = 420.69f;
// public static int ATestInt = -1;
// public static string ATestString = "hello world";
// public static uint ATestUInt = 1u;
// public static byte ATestByte = 255;
// public static ulong AReadonlyUlong = 82934UL;
// public static TestClass Instance => m_instance ?? (m_instance = new TestClass());
// private static TestClass m_instance;
// public object AmbigObject;
// public List<List<List<string>>> ANestedNestedList = new List<List<List<string>>>
// {
// new List<List<string>>
// {
// new List<string>
// {
// "one",
// "two",
// },
// new List<string>
// {
// "three",
// "four"
// }
// },
// new List<List<string>>
// {
// new List<string>
// {
// "five",
// "six"
// }
// }
// };
// public static bool SetOnlyProperty
// {
// set => m_setOnlyProperty = value;
// }
// private static bool m_setOnlyProperty;
// public static bool ReadSetOnlyProperty => m_setOnlyProperty;
// public Texture2D TestTexture;
// public static Sprite TestSprite;
//#if CPP
// public static Il2CppSystem.Collections.Generic.HashSet<string> CppHashSetTest;
// public static Il2CppSystem.Collections.Generic.List<string> CppStringTest;
// public static Il2CppSystem.Collections.IList CppIList;
// //public static Il2CppSystem.Collections.Generic.Dictionary<string, string> CppDictTest;
// //public static Il2CppSystem.Collections.Generic.Dictionary<int, float> CppDictTest2;
//#endif
// public TestClass()
// {
// int a = 0;
// foreach (var list in ANestedNestedList)
// {
// foreach (var list2 in list)
// {
// for (int i = 0; i < 33; i++)
// list2.Add(a++.ToString());
// }
// }
//#if CPP
// //TextureSpriteTest();
// CppHashSetTest = new Il2CppSystem.Collections.Generic.HashSet<string>();
// CppHashSetTest.Add("1");
// CppHashSetTest.Add("2");
// CppHashSetTest.Add("3");
// CppStringTest = new Il2CppSystem.Collections.Generic.List<string>();
// CppStringTest.Add("1");
// CppStringTest.Add("2");
// //CppDictTest = new Il2CppSystem.Collections.Generic.Dictionary<string, string>();
// //CppDictTest.Add("key1", "value1");
// //CppDictTest.Add("key2", "value2");
// //CppDictTest.Add("key3", "value3");
// //CppDictTest2 = new Il2CppSystem.Collections.Generic.Dictionary<int, float>();
// //CppDictTest2.Add(0, 0.5f);
// //CppDictTest2.Add(1, 0.5f);
// //CppDictTest2.Add(2, 0.5f);
//#endif
// }
// //private void TextureSpriteTest()
// //{
// // TestTexture = new Texture2D(32, 32, TextureFormat.ARGB32, false)
// // {
// // name = "TestTexture"
// // };
// // TestSprite = TextureUtilProvider.Instance.CreateSprite(TestTexture);
// // GameObject.DontDestroyOnLoad(TestTexture);
// // GameObject.DontDestroyOnLoad(TestSprite);
// // // test loading a tex from file
// // if (System.IO.File.Exists(@"D:\Downloads\test.png"))
// // {
// // var dataToLoad = System.IO.File.ReadAllBytes(@"D:\Downloads\test.png");
// // ExplorerCore.Log($"Tex load success: {TestTexture.LoadImage(dataToLoad, false)}");
// // }
// //}
// //public static string TestRefInOutGeneric<T>(ref string arg0, in int arg1, out string arg2) where T : Component
// //{
// // arg2 = "this is arg2";
// // return $"T: '{typeof(T).FullName}', ref arg0: '{arg0}', in arg1: '{arg1}', out arg2: '{arg2}'";
// //}
// // test a non-generic dictionary
// public Hashtable TestNonGenericDict()
// {
// return new Hashtable
// {
// { "One", 1 },
// { "Two", 2 },
// { "Three", 3 },
// };
// }
// // test HashSets
// public static HashSet<string> HashSetTest = new HashSet<string>
// {
// "One",
// "Two",
// "Three"
// };
// // Test indexed parameter
// public string this[int arg0, string arg1]
// {
// get
// {
// return $"arg0: {arg0}, arg1: {arg1}";
// }
// }
// // Test basic list
// public static List<string> TestList = new List<string>
// {
// "1",
// "2",
// "3",
// "etc..."
// };
// // Test a nested dictionary
// public static Dictionary<int, Dictionary<string, int>> NestedDictionary = new Dictionary<int, Dictionary<string, int>>
// {
// {
// 1,
// new Dictionary<string, int>
// {
// {
// "Sub 1", 123
// },
// {
// "Sub 2", 456
// },
// }
// },
// {
// 2,
// new Dictionary<string, int>
// {
// {
// "Sub 3", 789
// },
// {
// "Sub 4", 000
// },
// }
// },
// };
// // Test a basic method
// public static Color TestMethod(float r, float g, float b, float a)
// {
// return new Color(r, g, b, a);
// }
// // A method with default arguments
// public static Vector3 TestDefaultArgs(float arg0, float arg1, float arg2 = 5.0f)
// {
// return new Vector3(arg0, arg1, arg2);
// }
// }
//}

View File

@ -1,46 +0,0 @@
using System.Globalization;
using UnityEngine;
namespace UnityExplorer.Core.Unity
{
public static class ColorHelper
{
/// <summary>
/// Converts Color to 6-digit RGB hex code (without # symbol). Eg, RGBA(1,0,0,1) -> FF0000
/// </summary>
public static string ToHex(this Color color)
{
byte r = (byte)Mathf.Clamp(Mathf.RoundToInt(color.r * 255f), 0, 255);
byte g = (byte)Mathf.Clamp(Mathf.RoundToInt(color.g * 255f), 0, 255);
byte b = (byte)Mathf.Clamp(Mathf.RoundToInt(color.b * 255f), 0, 255);
return $"{r:X2}{g:X2}{b:X2}";
}
/// <summary>
/// Assumes the string is a 6-digit RGB Hex color code, which it will parse into a UnityEngine.Color.
/// Eg, FF0000 -> RGBA(1,0,0,1)
/// </summary>
public static Color ToColor(this string _string)
{
_string = _string.Replace("#", "");
if (_string.Length != 6)
return Color.magenta;
var r = byte.Parse(_string.Substring(0, 2), NumberStyles.HexNumber);
var g = byte.Parse(_string.Substring(2, 2), NumberStyles.HexNumber);
var b = byte.Parse(_string.Substring(4, 2), NumberStyles.HexNumber);
var color = new Color
{
r = (float)(r / (decimal)255),
g = (float)(g / (decimal)255),
b = (float)(b / (decimal)255),
a = 1
};
return color;
}
}
}

View File

@ -1,62 +0,0 @@
using UnityEngine;
namespace UnityExplorer.Core.Unity
{
public static class UnityHelper
{
private static Camera m_mainCamera;
public static Camera MainCamera
{
get
{
if (!m_mainCamera)
{
m_mainCamera = Camera.main;
}
return m_mainCamera;
}
}
public static bool IsNullOrDestroyed(this object obj, bool suppressWarning = true)
{
var unityObj = obj as Object;
if (obj == null)
{
if (!suppressWarning)
ExplorerCore.LogWarning("The target instance is null!");
return true;
}
else if (obj is Object)
{
if (!unityObj)
{
if (!suppressWarning)
ExplorerCore.LogWarning("The target UnityEngine.Object was destroyed!");
return true;
}
}
return false;
}
public static string ToStringLong(this Vector3 vec)
{
return $"{vec.x:F3}, {vec.y:F3}, {vec.z:F3}";
}
public static string GetTransformPath(this Transform t, bool includeThisName = false)
{
string path = includeThisName ? t.transform.name : "";
while (t.parent != null)
{
t = t.parent;
path = $"{t.name}/{path}";
}
return path;
}
}
}

View File

@ -0,0 +1,103 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using UnityEngine;
using Object = UnityEngine.Object;
namespace UnityExplorer.Core.Unity
{
public static class UnityHelpers
{
/// <summary>
/// Check if an object is null, and if it's a UnityEngine.Object then also check if it was destroyed.
/// </summary>
public static bool IsNullOrDestroyed(this object obj, bool suppressWarning = true)
{
var unityObj = obj as Object;
if (obj == null)
{
if (!suppressWarning)
ExplorerCore.LogWarning("The target instance is null!");
return true;
}
else if (obj is Object)
{
if (!unityObj)
{
if (!suppressWarning)
ExplorerCore.LogWarning("The target UnityEngine.Object was destroyed!");
return true;
}
}
return false;
}
/// <summary>
/// Print a nice {X, Y, Z} output of the Vector3, formatted to 3 decimal places.
/// </summary>
public static string ToStringPretty(this Vector3 vec)
{
return $"{vec.x:F3}, {vec.y:F3}, {vec.z:F3}";
}
/// <summary>
/// Get the full Transform heirarchy path for this provided Transform.
/// </summary>
public static string GetTransformPath(this Transform transform, bool includeSelf = false)
{
string path = includeSelf
? transform.transform.name
: "";
while (transform.parent)
{
transform = transform.parent;
path = $"{transform.name}/{path}";
}
return path;
}
/// <summary>
/// Converts Color to 6-digit RGB hex code (without # symbol). Eg, RGBA(1,0,0,1) -> FF0000
/// </summary>
public static string ToHex(this Color color)
{
byte r = (byte)Mathf.Clamp(Mathf.RoundToInt(color.r * 255f), 0, 255);
byte g = (byte)Mathf.Clamp(Mathf.RoundToInt(color.g * 255f), 0, 255);
byte b = (byte)Mathf.Clamp(Mathf.RoundToInt(color.b * 255f), 0, 255);
return $"{r:X2}{g:X2}{b:X2}";
}
/// <summary>
/// Assumes the string is a 6-digit RGB Hex color code, which it will parse into a UnityEngine.Color.
/// Eg, FF0000 -> RGBA(1,0,0,1)
/// </summary>
public static Color ToColor(this string _string)
{
_string = _string.Replace("#", "");
if (_string.Length != 6)
return Color.magenta;
var r = byte.Parse(_string.Substring(0, 2), NumberStyles.HexNumber);
var g = byte.Parse(_string.Substring(2, 2), NumberStyles.HexNumber);
var b = byte.Parse(_string.Substring(4, 2), NumberStyles.HexNumber);
var color = new Color
{
r = (float)(r / (decimal)255),
g = (float)(g / (decimal)255),
b = (float)(b / (decimal)255),
a = 1
};
return color;
}
}
}

View File

@ -1,126 +1,93 @@
using System; using System;
using System.IO; using System.IO;
using System.Reflection;
using UnityEngine; using UnityEngine;
using UnityEngine.SceneManagement;
using UnityExplorer.Core.Config; using UnityExplorer.Core.Config;
using UnityExplorer.Core.Unity;
using UnityExplorer.Core.Input; using UnityExplorer.Core.Input;
using UnityExplorer.Core.Inspectors;
using UnityExplorer.Core.Runtime; using UnityExplorer.Core.Runtime;
using UnityExplorer.UI; using UnityExplorer.UI;
using UnityExplorer.UI.Main; using UnityExplorer.UI.Main;
using UnityExplorer.UI.Utility;
namespace UnityExplorer namespace UnityExplorer
{ {
public class ExplorerCore public class ExplorerCore
{ {
public const string NAME = "UnityExplorer"; public const string NAME = "UnityExplorer";
public const string VERSION = "3.2.9"; public const string VERSION = "3.3.0";
public const string AUTHOR = "Sinai"; public const string AUTHOR = "Sinai";
public const string GUID = "com.sinai.unityexplorer"; public const string GUID = "com.sinai.unityexplorer";
public static ExplorerCore Instance { get; private set; } public static ExplorerCore Instance { get; private set; }
public static IExplorerLoader Loader => public static IExplorerLoader Loader { get; private set; }
#if ML
ExplorerMelonMod.Instance;
#elif BIE
ExplorerBepInPlugin.Instance;
#elif STANDALONE
ExplorerStandalone.Instance;
#endif
public static string EXPLORER_FOLDER => Loader.ExplorerFolder; // Prevent using ctor, must use Init method.
private ExplorerCore() { }
public ExplorerCore() public static void Init(IExplorerLoader loader)
{ {
if (Instance != null) if (Instance != null)
{ {
Log("An instance of Explorer is already active!"); Log("An instance of UnityExplorer is already active!");
return; return;
} }
Instance = this; Loader = loader;
Instance = new ExplorerCore();
if (!Directory.Exists(EXPLORER_FOLDER)) if (!Directory.Exists(Loader.ExplorerFolder))
Directory.CreateDirectory(EXPLORER_FOLDER); Directory.CreateDirectory(Loader.ExplorerFolder);
ExplorerConfig.OnLoad(); ConfigManager.Init(Loader.ConfigHandler);
RuntimeProvider.Init(); RuntimeProvider.Init();
InputManager.Init(); InputManager.Init();
CursorUnlocker.Init(); UIManager.Init();
UIManager.ShowMenu = true;
Log($"{NAME} {VERSION} initialized."); Log($"{NAME} {VERSION} initialized.");
} }
public static void Update() public static void Update()
{ {
UIManager.CheckUIInit(); UIManager.Update();
if (InspectUnderMouse.Enabled)
InspectUnderMouse.UpdateInspect();
else
UIManager.Update();
} }
public void OnUnityLog(string message, string stackTrace, LogType type) public static void Log(object message)
=> Log(message, LogType.Log, false);
public static void LogWarning(object message)
=> Log(message, LogType.Warning, false);
public static void LogError(object message)
=> Log(message, LogType.Error, false);
internal static void Log(object message, LogType logType, bool isFromUnity = false)
{ {
if (!DebugConsole.LogUnity) if (isFromUnity && !ConfigManager.Log_Unity_Debug.Value)
return; return;
message = $"[UNITY] {message}"; string log = message?.ToString() ?? "";
switch (type) switch (logType)
{ {
case LogType.Assert: case LogType.Assert:
case LogType.Log: case LogType.Log:
Log(message, true); Loader.OnLogMessage(log);
DebugConsole.Log(log, Color.white);
break; break;
case LogType.Warning: case LogType.Warning:
LogWarning(message, true); Loader.OnLogWarning(log);
DebugConsole.Log(log, Color.yellow);
break; break;
case LogType.Exception:
case LogType.Error: case LogType.Error:
LogError(message, true); case LogType.Exception:
Loader.OnLogError(log);
DebugConsole.Log(log, Color.red);
break; break;
} }
} }
public static void Log(object message, bool unity = false)
{
DebugConsole.Log(message?.ToString());
if (unity)
return;
Loader.OnLogMessage(message);
}
public static void LogWarning(object message, bool unity = false)
{
DebugConsole.Log(message?.ToString(), "FFFF00");
if (unity)
return;
Loader.OnLogWarning(message);
}
public static void LogError(object message, bool unity = false)
{
DebugConsole.Log(message?.ToString(), "FF0000");
if (unity)
return;
Loader.OnLogError(message);
}
} }
} }

View File

@ -1,22 +1,20 @@
<?xml version="1.0" encoding="utf-8" ?> <?xml version="1.0" encoding="utf-8" ?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="ILRepacker" AfterTargets="Build">
<Target Name="ILRepacker" AfterTargets="Build">
<ItemGroup> <ItemGroup>
<InputAssemblies Include="$(OutputPath)$(AssemblyName).dll" /> <InputAssemblies Include="$(OutputPath)$(AssemblyName).dll" />
<InputAssemblies Include="..\lib\mcs.dll" /> <InputAssemblies Include="..\lib\mcs.dll" />
<InputAssemblies Include="..\lib\INIFileParser.dll" /> <InputAssemblies Include="..\lib\INIFileParser.dll" Condition="'$(IsStandalone)' == 'true'"/>
</ItemGroup> </ItemGroup>
<ILRepack
<ILRepack Parallel="true"
Parallel="true" Internalize="true"
Internalize="true" DebugInfo="false"
DebugInfo="false" LibraryPath="..\lib\"
LibraryPath="..\lib\" InputAssemblies="@(InputAssemblies)"
InputAssemblies="@(InputAssemblies)" TargetKind="Dll"
TargetKind="Dll" OutputFile="$(OutputPath)$(AssemblyName).dll" />
OutputFile="$(OutputPath)$(AssemblyName).dll" </Target>
/>
</Target>
</Project> </Project>

View File

@ -0,0 +1,69 @@
#if BIE
using BepInEx.Configuration;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityExplorer.Core.Config;
namespace UnityExplorer.Loader.BIE
{
public class BepInExConfigHandler : ConfigHandler
{
private ConfigFile Config => ExplorerBepInPlugin.Instance.Config;
private const string CTG_NAME = "UnityExplorer";
public override void Init()
{
// Not necessary
}
public override void RegisterConfigElement<T>(ConfigElement<T> config)
{
var entry = Config.Bind(CTG_NAME, config.Name, config.Value, config.Description);
entry.SettingChanged += (object o, EventArgs e) =>
{
config.Value = entry.Value;
};
}
public override T GetConfigValue<T>(ConfigElement<T> element)
{
if (Config.TryGetEntry(CTG_NAME, element.Name, out ConfigEntry<T> configEntry))
return configEntry.Value;
else
throw new Exception("Could not get config entry '" + element.Name + "'");
}
public override void SetConfigValue<T>(ConfigElement<T> element, T value)
{
if (Config.TryGetEntry(CTG_NAME, element.Name, out ConfigEntry<T> configEntry))
configEntry.Value = value;
else
ExplorerCore.Log("Could not get config entry '" + element.Name + "'");
}
public override void LoadConfig()
{
foreach (var entry in ConfigManager.ConfigElements)
{
var key = entry.Key;
var def = new ConfigDefinition(CTG_NAME, key);
if (Config.ContainsKey(def) && Config[def] is ConfigEntryBase configEntry)
{
var config = entry.Value;
config.BoxedValue = configEntry.BoxedValue;
}
}
}
public override void SaveConfig()
{
// not required
}
}
}
#endif

View File

@ -0,0 +1,106 @@
#if BIE
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using UnityExplorer.Core.Config;
using UnityExplorer.Loader.BIE;
using UnityEngine;
#if CPP
using BepInEx.IL2CPP;
using UnhollowerRuntimeLib;
#endif
namespace UnityExplorer
{
[BepInPlugin(ExplorerCore.GUID, "UnityExplorer", ExplorerCore.VERSION)]
public class ExplorerBepInPlugin :
#if MONO
BaseUnityPlugin
#else
BasePlugin
#endif
, IExplorerLoader
{
public static ExplorerBepInPlugin Instance;
public ManualLogSource LogSource
#if MONO
=> Logger;
#else
=> Log;
#endif
public ConfigHandler ConfigHandler => _configHandler;
private BepInExConfigHandler _configHandler;
public Harmony HarmonyInstance => s_harmony;
private static readonly Harmony s_harmony = new Harmony(ExplorerCore.GUID);
public string ExplorerFolder => Path.Combine(Paths.PluginPath, ExplorerCore.NAME);
public string ConfigFolder => Path.Combine(Paths.ConfigPath, ExplorerCore.NAME);
public Action<object> OnLogMessage => LogSource.LogMessage;
public Action<object> OnLogWarning => LogSource.LogWarning;
public Action<object> OnLogError => LogSource.LogError;
// Init common to Mono and Il2Cpp
internal void UniversalInit()
{
Instance = this;
_configHandler = new BepInExConfigHandler();
}
#if MONO // Mono-specific
internal void Awake()
{
UniversalInit();
ExplorerCore.Init(this);
}
internal void Update()
{
ExplorerCore.Update();
}
#else // Il2Cpp-specific
public override void Load()
{
UniversalInit();
ClassInjector.RegisterTypeInIl2Cpp<ExplorerBehaviour>();
var obj = new GameObject(
"ExplorerBehaviour",
new Il2CppSystem.Type[] { Il2CppType.Of<ExplorerBehaviour>() }
);
obj.hideFlags = HideFlags.HideAndDontSave;
GameObject.DontDestroyOnLoad(obj);
ExplorerCore.Init(this);
}
// BepInEx Il2Cpp mod class doesn't have monobehaviour methods yet, so wrap them in a dummy.
public class ExplorerBehaviour : MonoBehaviour
{
public ExplorerBehaviour(IntPtr ptr) : base(ptr) { }
internal void Awake()
{
Instance.LogSource.LogMessage("ExplorerBehaviour.Awake");
}
internal void Update()
{
ExplorerCore.Update();
}
}
#endif
}
}
#endif

View File

@ -1,41 +0,0 @@
#if BIE5
using System;
using System.IO;
using System.Reflection;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
namespace UnityExplorer
{
[BepInPlugin(ExplorerCore.GUID, "UnityExplorer", ExplorerCore.VERSION)]
public class ExplorerBepInPlugin : BaseUnityPlugin, IExplorerLoader
{
public static ExplorerBepInPlugin Instance;
public static ManualLogSource Logging => Instance?.Logger;
public Harmony HarmonyInstance => s_harmony;
private static readonly Harmony s_harmony = new Harmony(ExplorerCore.GUID);
public string ExplorerFolder => Path.Combine(Paths.PluginPath, ExplorerCore.NAME);
public string ConfigFolder => Path.Combine(Paths.ConfigPath, ExplorerCore.NAME);
public Action<object> OnLogMessage => (object log) => { Logging?.LogMessage(log?.ToString() ?? ""); };
public Action<object> OnLogWarning => (object log) => { Logging?.LogWarning(log?.ToString() ?? ""); };
public Action<object> OnLogError => (object log) => { Logging?.LogError(log?.ToString() ?? ""); };
internal void Awake()
{
Instance = this;
new ExplorerCore();
}
internal void Update()
{
ExplorerCore.Update();
}
}
}
#endif

View File

@ -1,104 +0,0 @@
#if BIE6
using System;
using System.IO;
using System.Reflection;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using UnityExplorer.UI.Main;
#if CPP
using UnhollowerRuntimeLib;
using BepInEx.IL2CPP;
#endif
namespace UnityExplorer
{
#if MONO
[BepInPlugin(ExplorerCore.GUID, "UnityExplorer", ExplorerCore.VERSION)]
public class ExplorerBepInPlugin : BaseUnityPlugin, IExplorerLoader
{
public static ExplorerBepInPlugin Instance;
public static ManualLogSource Logging => Instance?.Logger;
public Harmony HarmonyInstance => s_harmony;
private static readonly Harmony s_harmony = new Harmony(ExplorerCore.GUID);
public string ExplorerFolder => Path.Combine(Paths.PluginPath, ExplorerCore.NAME);
public string ConfigFolder => Path.Combine(Paths.ConfigPath, ExplorerCore.NAME);
public Action<object> OnLogMessage => (object log) => { Logging?.LogMessage(log?.ToString() ?? ""); };
public Action<object> OnLogWarning => (object log) => { Logging?.LogWarning(log?.ToString() ?? ""); };
public Action<object> OnLogError => (object log) => { Logging?.LogError(log?.ToString() ?? ""); };
internal void Awake()
{
Instance = this;
new ExplorerCore();
}
internal void Update()
{
ExplorerCore.Update();
}
}
#endif
#if CPP
[BepInPlugin(ExplorerCore.GUID, "UnityExplorer", ExplorerCore.VERSION)]
public class ExplorerBepInPlugin : BasePlugin, IExplorerLoader
{
public static ExplorerBepInPlugin Instance;
public static ManualLogSource Logging => Instance?.Log;
public Harmony HarmonyInstance => s_harmony;
private static readonly Harmony s_harmony = new Harmony(ExplorerCore.GUID);
public string ExplorerFolder => Path.Combine(Paths.PluginPath, ExplorerCore.NAME);
public string ConfigFolder => Path.Combine(Paths.ConfigPath, ExplorerCore.NAME);
public Action<object> OnLogMessage => (object log) => { Logging?.LogMessage(log?.ToString() ?? ""); };
public Action<object> OnLogWarning => (object log) => { Logging?.LogWarning(log?.ToString() ?? ""); };
public Action<object> OnLogError => (object log) => { Logging?.LogError(log?.ToString() ?? ""); };
// Init
public override void Load()
{
Instance = this;
ClassInjector.RegisterTypeInIl2Cpp<ExplorerBehaviour>();
var obj = new GameObject(
"ExplorerBehaviour",
new Il2CppSystem.Type[] { Il2CppType.Of<ExplorerBehaviour>() }
);
obj.hideFlags = HideFlags.HideAndDontSave;
GameObject.DontDestroyOnLoad(obj);
new ExplorerCore();
}
// BepInEx Il2Cpp mod class doesn't have monobehaviour methods yet, so wrap them in a dummy.
public class ExplorerBehaviour : MonoBehaviour
{
public ExplorerBehaviour(IntPtr ptr) : base(ptr) { }
internal void Awake()
{
Logging.LogMessage("ExplorerBehaviour.Awake");
}
internal void Update()
{
ExplorerCore.Update();
}
}
}
#endif
}
#endif

View File

@ -2,6 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using UnityExplorer.Core.Config;
namespace UnityExplorer namespace UnityExplorer
{ {
@ -10,6 +11,7 @@ namespace UnityExplorer
string ExplorerFolder { get; } string ExplorerFolder { get; }
string ConfigFolder { get; } string ConfigFolder { get; }
ConfigHandler ConfigHandler { get; }
Action<object> OnLogMessage { get; } Action<object> OnLogMessage { get; }
Action<object> OnLogWarning { get; } Action<object> OnLogWarning { get; }

View File

@ -2,7 +2,10 @@
using System; using System;
using System.IO; using System.IO;
using MelonLoader; using MelonLoader;
using UnityEngine;
using UnityExplorer; using UnityExplorer;
using UnityExplorer.Core.Config;
using UnityExplorer.Loader.ML;
[assembly: MelonInfo(typeof(ExplorerMelonMod), ExplorerCore.NAME, ExplorerCore.VERSION, ExplorerCore.AUTHOR)] [assembly: MelonInfo(typeof(ExplorerMelonMod), ExplorerCore.NAME, ExplorerCore.VERSION, ExplorerCore.AUTHOR)]
[assembly: MelonGame(null, null)] [assembly: MelonGame(null, null)]
@ -16,28 +19,27 @@ namespace UnityExplorer
public string ExplorerFolder => Path.Combine("Mods", ExplorerCore.NAME); public string ExplorerFolder => Path.Combine("Mods", ExplorerCore.NAME);
public string ConfigFolder => ExplorerFolder; public string ConfigFolder => ExplorerFolder;
public Action<object> OnLogMessage => (object log) => { MelonLogger.Msg(log?.ToString() ?? ""); }; public ConfigHandler ConfigHandler => _configHandler;
public Action<object> OnLogWarning => (object log) => { MelonLogger.Warning(log?.ToString() ?? ""); }; public MelonLoaderConfigHandler _configHandler;
public Action<object> OnLogError => (object log) => { MelonLogger.Error(log?.ToString() ?? ""); };
public Action<object> OnLogMessage => MelonLogger.Msg;
public Action<object> OnLogWarning => MelonLogger.Warning;
public Action<object> OnLogError => MelonLogger.Error;
public Harmony.HarmonyInstance HarmonyInstance => Instance.Harmony; public Harmony.HarmonyInstance HarmonyInstance => Instance.Harmony;
public override void OnApplicationStart() public override void OnApplicationStart()
{ {
Instance = this; Instance = this;
_configHandler = new MelonLoaderConfigHandler();
new ExplorerCore(); ExplorerCore.Init(this);
} }
public override void OnUpdate() public override void OnUpdate()
{ {
ExplorerCore.Update(); ExplorerCore.Update();
} }
//public override void OnSceneWasLoaded(int buildIndex, string sceneName)
//{
// ExplorerCore.Instance.OnSceneLoaded();
//}
} }
} }
#endif #endif

View File

@ -0,0 +1,98 @@
#if ML
using MelonLoader;
using MelonLoader.Tomlyn.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityExplorer.Core.Config;
namespace UnityExplorer.Loader.ML
{
public class MelonLoaderConfigHandler : ConfigHandler
{
internal const string CTG_NAME = "UnityExplorer";
internal MelonPreferences_Category prefCategory;
public override void Init()
{
prefCategory = MelonPreferences.CreateCategory(CTG_NAME, $"{CTG_NAME} Settings");
MelonPreferences.Mapper.RegisterMapper(KeycodeReader, KeycodeWriter);
}
public override void LoadConfig()
{
foreach (var entry in ConfigManager.ConfigElements)
{
var key = entry.Key;
if (prefCategory.GetEntry(key) is MelonPreferences_Entry)
{
var config = entry.Value;
config.BoxedValue = config.GetLoaderConfigValue();
}
}
}
public override void RegisterConfigElement<T>(ConfigElement<T> config)
{
var entry = prefCategory.CreateEntry(config.Name, config.Value, null, config.IsInternal) as MelonPreferences_Entry<T>;
entry.OnValueChangedUntyped += () =>
{
if ((entry.Value == null && config.Value == null) || config.Value.Equals(entry.Value))
return;
config.Value = entry.Value;
};
}
public override void SetConfigValue<T>(ConfigElement<T> config, T value)
{
if (prefCategory.GetEntry<T>(config.Name) is MelonPreferences_Entry<T> entry)
{
entry.Value = value;
entry.Save();
}
}
public override T GetConfigValue<T>(ConfigElement<T> config)
{
if (prefCategory.GetEntry<T>(config.Name) is MelonPreferences_Entry<T> entry)
return entry.Value;
return default;
}
public override void SaveConfig()
{
MelonPreferences.Save();
}
public static KeyCode KeycodeReader(TomlObject value)
{
try
{
KeyCode kc = (KeyCode)Enum.Parse(typeof(KeyCode), (value as TomlString).Value);
if (kc == default)
throw new Exception();
return kc;
}
catch
{
return KeyCode.F7;
}
}
public static TomlObject KeycodeWriter(KeyCode value)
{
return MelonPreferences.Mapper.ToToml(value.ToString());
}
}
}
#endif

View File

@ -4,6 +4,8 @@ using System;
using System.IO; using System.IO;
using System.Reflection; using System.Reflection;
using UnityEngine; using UnityEngine;
using UnityExplorer.Core.Config;
using UnityExplorer.Loader.STANDALONE;
#if CPP #if CPP
using UnhollowerRuntimeLib; using UnhollowerRuntimeLib;
#endif #endif
@ -13,20 +15,27 @@ namespace UnityExplorer
public class ExplorerStandalone : IExplorerLoader public class ExplorerStandalone : IExplorerLoader
{ {
/// <summary> /// <summary>
/// Call this to initialize UnityExplorer. Optionally, also subscribe to the 'OnLog' event to handle logging. /// Call this to initialize UnityExplorer without adding a log listener.
/// </summary> /// </summary>
/// <returns>The new (or active, if one exists) instance of ExplorerStandalone.</returns> /// <returns>The new (or active, if one exists) instance of ExplorerStandalone.</returns>
public static ExplorerStandalone CreateInstance() public static ExplorerStandalone CreateInstance()
=> CreateInstance(null);
/// <summary>
/// Call this to initialize UnityExplorer and add a listener for UnityExplorer's log messages.
/// </summary>
/// <param name="logListener">Your log listener to handle UnityExplorer logs.</param>
/// <returns>The new (or active, if one exists) instance of ExplorerStandalone.</returns>
public static ExplorerStandalone CreateInstance(Action<string, LogType> logListener)
{ {
if (Instance != null) if (Instance != null)
return Instance; return Instance;
return new ExplorerStandalone(); OnLog += logListener;
}
private ExplorerStandalone() var instance = new ExplorerStandalone();
{ instance.Init();
Init(); return instance;
} }
public static ExplorerStandalone Instance { get; private set; } public static ExplorerStandalone Instance { get; private set; }
@ -39,6 +48,9 @@ namespace UnityExplorer
public Harmony HarmonyInstance => s_harmony; public Harmony HarmonyInstance => s_harmony;
public static readonly Harmony s_harmony = new Harmony(ExplorerCore.GUID); public static readonly Harmony s_harmony = new Harmony(ExplorerCore.GUID);
public ConfigHandler ConfigHandler => _configHandler;
private StandaloneConfigHandler _configHandler;
public string ExplorerFolder public string ExplorerFolder
{ {
get get
@ -70,6 +82,8 @@ namespace UnityExplorer
private void Init() private void Init()
{ {
Instance = this; Instance = this;
_configHandler = new StandaloneConfigHandler();
#if CPP #if CPP
ClassInjector.RegisterTypeInIl2Cpp<ExplorerBehaviour>(); ClassInjector.RegisterTypeInIl2Cpp<ExplorerBehaviour>();
@ -81,13 +95,13 @@ namespace UnityExplorer
var obj = new GameObject( var obj = new GameObject(
"ExplorerBehaviour", "ExplorerBehaviour",
new Type[] { typeof(ExplorerBehaviour) } new Type[] { typeof(ExplorerBehaviour) }
); );
#endif #endif
obj.hideFlags = HideFlags.HideAndDontSave;
GameObject.DontDestroyOnLoad(obj); GameObject.DontDestroyOnLoad(obj);
obj.hideFlags = HideFlags.HideAndDontSave;
new ExplorerCore(); ExplorerCore.Init(this);
} }
public class ExplorerBehaviour : MonoBehaviour public class ExplorerBehaviour : MonoBehaviour

View File

@ -0,0 +1,108 @@
#if STANDALONE
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityExplorer.Core.Config;
using IniParser.Parser;
using System.IO;
using UnityEngine;
namespace UnityExplorer.Loader.STANDALONE
{
public class StandaloneConfigHandler : ConfigHandler
{
internal static IniDataParser _parser;
internal static string INI_PATH;
public override void Init()
{
INI_PATH = Path.Combine(ExplorerCore.Loader.ConfigFolder, "config.ini");
_parser = new IniDataParser();
_parser.Configuration.CommentString = "#";
}
public override void LoadConfig()
{
if (!TryLoadConfig())
SaveConfig();
}
public override void RegisterConfigElement<T>(ConfigElement<T> element)
{
// Not necessary
}
public override void SetConfigValue<T>(ConfigElement<T> element, T value)
{
// Not necessary, just save.
SaveConfig();
}
public override T GetConfigValue<T>(ConfigElement<T> element)
{
// Not necessary, just return the value.
return element.Value;
}
public bool TryLoadConfig()
{
try
{
if (!File.Exists(INI_PATH))
return false;
string ini = File.ReadAllText(INI_PATH);
var data = _parser.Parse(ini);
foreach (var config in data.Sections["Config"])
{
if (ConfigManager.ConfigElements.TryGetValue(config.KeyName, out IConfigElement configElement))
configElement.BoxedValue = StringToConfigValue(config.Value, configElement.ElementType);
}
return true;
}
catch
{
return false;
}
}
public object StringToConfigValue(string value, Type elementType)
{
if (elementType == typeof(KeyCode))
return (KeyCode)Enum.Parse(typeof(KeyCode), value);
else if (elementType == typeof(bool))
return bool.Parse(value);
else if (elementType == typeof(int))
return int.Parse(value);
else
return value;
}
public override void OnAnyConfigChanged()
{
SaveConfig();
}
public override void SaveConfig()
{
var data = new IniParser.Model.IniData();
data.Sections.AddSection("Config");
var sec = data.Sections["Config"];
foreach (var entry in ConfigManager.ConfigElements)
sec.AddKey(entry.Key, entry.Value.BoxedValue.ToString());
if (!Directory.Exists(ExplorerCore.Loader.ConfigFolder))
Directory.CreateDirectory(ExplorerCore.Loader.ConfigFolder);
File.WriteAllText(INI_PATH, data.ToString());
}
}
}
#endif

Binary file not shown.

View File

@ -0,0 +1,102 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.Core.Config;
using UnityExplorer.UI.InteractiveValues;
namespace UnityExplorer.UI.CacheObject
{
public class CacheConfigEntry : CacheObjectBase
{
public IConfigElement RefConfig { get; }
public override Type FallbackType => RefConfig.ElementType;
public override bool HasEvaluated => true;
public override bool HasParameters => false;
public override bool IsMember => false;
public override bool CanWrite => true;
public CacheConfigEntry(IConfigElement config, GameObject parent)
{
RefConfig = config;
m_parentContent = parent;
config.OnValueChangedNotify += () => { UpdateValue(); };
CreateIValue(config.BoxedValue, config.ElementType);
}
public override void CreateIValue(object value, Type fallbackType)
{
IValue = InteractiveValue.Create(value, fallbackType);
IValue.Owner = this;
IValue.m_mainContentParent = m_rightGroup;
IValue.m_subContentParent = this.m_subContent;
}
public override void UpdateValue()
{
IValue.Value = RefConfig.BoxedValue;
base.UpdateValue();
}
public override void SetValue()
{
RefConfig.BoxedValue = IValue.Value;
ConfigManager.Handler.OnAnyConfigChanged();
}
internal GameObject m_leftGroup;
internal GameObject m_rightGroup;
internal override void ConstructUI()
{
base.ConstructUI();
var vertGroup = UIFactory.CreateVerticalGroup(m_mainContent, "ConfigHolder", true, false, true, true, 5, new Vector4(2, 2, 2, 2));
var horiGroup = UIFactory.CreateHorizontalGroup(vertGroup, "ConfigEntryHolder", true, false, true, true);
UIFactory.SetLayoutElement(horiGroup, minHeight: 30, flexibleHeight: 0);
// left group
m_leftGroup = UIFactory.CreateHorizontalGroup(horiGroup, "ConfigTitleGroup", false, false, true, true, 4, default, new Color(1, 1, 1, 0));
UIFactory.SetLayoutElement(m_leftGroup, minHeight: 25, flexibleHeight: 0, minWidth: 125, flexibleWidth: 200);
// config entry label
var configLabel = UIFactory.CreateLabel(m_leftGroup, "ConfigLabel", this.RefConfig.Name, TextAnchor.MiddleLeft);
var leftRect = configLabel.GetComponent<RectTransform>();
leftRect.anchorMin = Vector2.zero;
leftRect.anchorMax = Vector2.one;
leftRect.offsetMin = Vector2.zero;
leftRect.offsetMax = Vector2.zero;
leftRect.sizeDelta = Vector2.zero;
UIFactory.SetLayoutElement(configLabel.gameObject, minWidth: 250, minHeight: 25, flexibleWidth: 0, flexibleHeight: 0);
// right group
m_rightGroup = UIFactory.CreateVerticalGroup(horiGroup, "ConfigValueGroup", false, false, true, true, 2, new Vector4(4,2,0,0),
new Color(1, 1, 1, 0));
UIFactory.SetLayoutElement(m_rightGroup, minHeight: 25, minWidth: 150, flexibleHeight: 0, flexibleWidth: 5000);
if (IValue != null)
{
IValue.m_mainContentParent = m_rightGroup;
IValue.m_subContentParent = this.m_subContent;
}
// Config description label
UIFactory.CreateLabel(vertGroup, "Description", $"<i>{RefConfig.Description}</i>", TextAnchor.MiddleLeft, Color.grey);
m_subContent.transform.SetAsLastSibling();
}
}
}

View File

@ -6,8 +6,9 @@ using System.Text;
using UnityExplorer.UI; using UnityExplorer.UI;
using UnityEngine; using UnityEngine;
using UnityEngine.UI; using UnityEngine.UI;
using UnityExplorer.UI.InteractiveValues;
namespace UnityExplorer.Core.Inspectors.Reflection namespace UnityExplorer.UI.CacheObject
{ {
public class CacheEnumerated : CacheObjectBase public class CacheEnumerated : CacheObjectBase
{ {
@ -44,18 +45,11 @@ namespace UnityExplorer.Core.Inspectors.Reflection
{ {
base.ConstructUI(); base.ConstructUI();
var rowObj = UIFactory.CreateHorizontalGroup(m_mainContent, new Color(1, 1, 1, 0)); var rowObj = UIFactory.CreateHorizontalGroup(m_mainContent, "CacheEnumeratedGroup", false, true, true, true, 0, new Vector4(0,0,5,2),
var rowGroup = rowObj.GetComponent<HorizontalLayoutGroup>(); new Color(1, 1, 1, 0));
rowGroup.padding.left = 5;
rowGroup.padding.right = 2;
var indexLabelObj = UIFactory.CreateLabel(rowObj, TextAnchor.MiddleLeft); var indexLabel = UIFactory.CreateLabel(rowObj, "IndexLabel", $"{this.Index}:", TextAnchor.MiddleLeft);
var indexLayout = indexLabelObj.AddComponent<LayoutElement>(); UIFactory.SetLayoutElement(indexLabel.gameObject, minWidth: 20, flexibleWidth: 30, minHeight: 25);
indexLayout.minWidth = 20;
indexLayout.flexibleWidth = 30;
indexLayout.minHeight = 25;
var indexText = indexLabelObj.GetComponent<Text>();
indexText.text = this.Index + ":";
IValue.m_mainContentParent = rowObj; IValue.m_mainContentParent = rowObj;
} }

View File

@ -6,7 +6,7 @@ using System.Reflection;
using UnityExplorer.UI; using UnityExplorer.UI;
using UnityEngine; using UnityEngine;
namespace UnityExplorer.Core.Inspectors.Reflection namespace UnityExplorer.UI.CacheObject
{ {
public class CacheField : CacheMember public class CacheField : CacheMember
{ {

View File

@ -5,13 +5,14 @@ using System.Reflection;
using UnityEngine; using UnityEngine;
using UnityEngine.UI; using UnityEngine.UI;
using UnityExplorer.UI; using UnityExplorer.UI;
using UnityExplorer.UI.Reusable;
using UnityExplorer.Core.Unity; using UnityExplorer.Core.Unity;
using UnityExplorer.Core.Runtime; using UnityExplorer.Core.Runtime;
using UnityExplorer.Core; using UnityExplorer.Core;
using UnityExplorer.UI.Utility; using UnityExplorer.UI.Utility;
using UnityExplorer.UI.InteractiveValues;
using UnityExplorer.UI.Main.Home.Inspectors.Reflection;
namespace UnityExplorer.Core.Inspectors.Reflection namespace UnityExplorer.UI.CacheObject
{ {
public abstract class CacheMember : CacheObjectBase public abstract class CacheMember : CacheObjectBase
{ {
@ -214,75 +215,46 @@ namespace UnityExplorer.Core.Inspectors.Reflection
{ {
base.ConstructUI(); base.ConstructUI();
var topGroupObj = UIFactory.CreateHorizontalGroup(m_mainContent, new Color(1, 1, 1, 0)); var topGroupObj = UIFactory.CreateHorizontalGroup(m_mainContent, "CacheMemberGroup", false, false, true, true, 10, new Vector4(0, 0, 3, 3),
new Color(1, 1, 1, 0));
m_topRowRect = topGroupObj.GetComponent<RectTransform>(); m_topRowRect = topGroupObj.GetComponent<RectTransform>();
var topLayout = topGroupObj.AddComponent<LayoutElement>();
topLayout.minHeight = 25; UIFactory.SetLayoutElement(topGroupObj, minHeight: 25, flexibleHeight: 0, minWidth: 300, flexibleWidth: 5000);
topLayout.flexibleHeight = 0;
topLayout.minWidth = 300;
topLayout.flexibleWidth = 5000;
var topGroup = topGroupObj.GetComponent<HorizontalLayoutGroup>();
topGroup.childForceExpandHeight = false;
topGroup.childForceExpandWidth = false;
topGroup.childControlHeight = true;
topGroup.childControlWidth = true;
topGroup.spacing = 10;
topGroup.padding.left = 3;
topGroup.padding.right = 3;
topGroup.padding.top = 0;
topGroup.padding.bottom = 0;
// left group // left group
m_leftGroup = UIFactory.CreateHorizontalGroup(topGroupObj, new Color(1, 1, 1, 0)); m_leftGroup = UIFactory.CreateHorizontalGroup(topGroupObj, "LeftGroup", false, true, true, true, 4, default, new Color(1, 1, 1, 0));
var leftLayout = m_leftGroup.AddComponent<LayoutElement>(); UIFactory.SetLayoutElement(m_leftGroup, minHeight: 25, flexibleHeight: 0, minWidth: 125, flexibleWidth: 200);
leftLayout.minHeight = 25;
leftLayout.flexibleHeight = 0;
leftLayout.minWidth = 125;
leftLayout.flexibleWidth = 200;
var leftGroup = m_leftGroup.GetComponent<HorizontalLayoutGroup>();
leftGroup.childForceExpandHeight = true;
leftGroup.childForceExpandWidth = false;
leftGroup.childControlHeight = true;
leftGroup.childControlWidth = true;
leftGroup.spacing = 4;
// member label // member label
var labelObj = UIFactory.CreateLabel(m_leftGroup, TextAnchor.MiddleLeft); m_memLabelText = UIFactory.CreateLabel(m_leftGroup, "MemLabelText", RichTextName, TextAnchor.MiddleLeft);
var leftRect = labelObj.GetComponent<RectTransform>(); m_memLabelText.horizontalOverflow = HorizontalWrapMode.Wrap;
var leftRect = m_memLabelText.GetComponent<RectTransform>();
leftRect.anchorMin = Vector2.zero; leftRect.anchorMin = Vector2.zero;
leftRect.anchorMax = Vector2.one; leftRect.anchorMax = Vector2.one;
leftRect.offsetMin = Vector2.zero; leftRect.offsetMin = Vector2.zero;
leftRect.offsetMax = Vector2.zero; leftRect.offsetMax = Vector2.zero;
leftRect.sizeDelta = Vector2.zero; leftRect.sizeDelta = Vector2.zero;
m_leftLayout = labelObj.AddComponent<LayoutElement>(); m_leftLayout = m_memLabelText.gameObject.AddComponent<LayoutElement>();
m_leftLayout.preferredWidth = 125; m_leftLayout.preferredWidth = 125;
m_leftLayout.minHeight = 25; m_leftLayout.minHeight = 25;
m_leftLayout.flexibleHeight = 100; m_leftLayout.flexibleHeight = 100;
var labelFitter = labelObj.AddComponent<ContentSizeFitter>(); var labelFitter = m_memLabelText.gameObject.AddComponent<ContentSizeFitter>();
labelFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize; labelFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
labelFitter.horizontalFit = ContentSizeFitter.FitMode.PreferredSize; labelFitter.horizontalFit = ContentSizeFitter.FitMode.PreferredSize;
m_memLabelText = labelObj.GetComponent<Text>();
m_memLabelText.horizontalOverflow = HorizontalWrapMode.Wrap;
m_memLabelText.text = this.RichTextName;
// right group // right group
m_rightGroup = UIFactory.CreateVerticalGroup(topGroupObj, new Color(1, 1, 1, 0)); m_rightGroup = UIFactory.CreateVerticalGroup(topGroupObj, "RightGroup", false, true, true, true, 2, new Vector4(4,2,0,0),
new Color(1, 1, 1, 0));
m_rightLayout = m_rightGroup.AddComponent<LayoutElement>(); m_rightLayout = m_rightGroup.AddComponent<LayoutElement>();
m_rightLayout.minHeight = 25; m_rightLayout.minHeight = 25;
m_rightLayout.flexibleHeight = 480; m_rightLayout.flexibleHeight = 480;
m_rightLayout.minWidth = 125; m_rightLayout.minWidth = 125;
m_rightLayout.flexibleWidth = 5000; m_rightLayout.flexibleWidth = 5000;
var rightGroup = m_rightGroup.GetComponent<VerticalLayoutGroup>();
rightGroup.childForceExpandHeight = true;
rightGroup.childForceExpandWidth = false;
rightGroup.childControlHeight = true;
rightGroup.childControlWidth = true;
rightGroup.spacing = 2;
rightGroup.padding.top = 4;
rightGroup.padding.bottom = 2;
ConstructArgInput(out GameObject argsHolder); ConstructArgInput(out GameObject argsHolder);
@ -297,27 +269,17 @@ namespace UnityExplorer.Core.Inspectors.Reflection
if (HasParameters) if (HasParameters)
{ {
argsHolder = UIFactory.CreateVerticalGroup(m_rightGroup, new Color(1, 1, 1, 0)); argsHolder = UIFactory.CreateVerticalGroup(m_rightGroup, "ArgsHolder", true, false, true, true, 4, new Color(1, 1, 1, 0));
var argsGroup = argsHolder.GetComponent<VerticalLayoutGroup>();
argsGroup.spacing = 4;
if (this is CacheMethod cm && cm.GenericArgs.Length > 0) if (this is CacheMethod cm && cm.GenericArgs.Length > 0)
{
cm.ConstructGenericArgInput(argsHolder); cm.ConstructGenericArgInput(argsHolder);
}
// todo normal args
if (m_arguments.Length > 0) if (m_arguments.Length > 0)
{ {
var titleObj = UIFactory.CreateLabel(argsHolder, TextAnchor.MiddleLeft); UIFactory.CreateLabel(argsHolder, "ArgumentsLabel", "Arguments:", TextAnchor.MiddleLeft);
var titleText = titleObj.GetComponent<Text>();
titleText.text = "<b>Arguments:</b>";
for (int i = 0; i < m_arguments.Length; i++) for (int i = 0; i < m_arguments.Length; i++)
{
AddArgRow(i, argsHolder); AddArgRow(i, argsHolder);
}
} }
argsHolder.SetActive(false); argsHolder.SetActive(false);
@ -328,30 +290,16 @@ namespace UnityExplorer.Core.Inspectors.Reflection
{ {
var arg = m_arguments[i]; var arg = m_arguments[i];
var rowObj = UIFactory.CreateHorizontalGroup(parent, new Color(1, 1, 1, 0)); var rowObj = UIFactory.CreateHorizontalGroup(parent, "ArgRow", true, false, true, true, 4, default, new Color(1, 1, 1, 0));
var rowLayout = rowObj.AddComponent<LayoutElement>(); UIFactory.SetLayoutElement(rowObj, minHeight: 25, flexibleWidth: 5000);
rowLayout.minHeight = 25;
rowLayout.flexibleWidth = 5000;
var rowGroup = rowObj.GetComponent<HorizontalLayoutGroup>();
rowGroup.childForceExpandHeight = false;
rowGroup.childForceExpandWidth = true;
rowGroup.spacing = 4;
var argLabelObj = UIFactory.CreateLabel(rowObj, TextAnchor.MiddleLeft);
var argLabelLayout = argLabelObj.AddComponent<LayoutElement>();
argLabelLayout.minHeight = 25;
var argText = argLabelObj.GetComponent<Text>();
var argTypeTxt = SignatureHighlighter.ParseFullSyntax(arg.ParameterType, false); var argTypeTxt = SignatureHighlighter.ParseFullSyntax(arg.ParameterType, false);
argText.text = $"{argTypeTxt} <color={SignatureHighlighter.LOCAL_ARG}>{arg.Name}</color>"; var argLabel = UIFactory.CreateLabel(rowObj, "ArgLabel", $"{argTypeTxt} <color={SignatureHighlighter.LOCAL_ARG}>{arg.Name}</color>",
TextAnchor.MiddleLeft);
UIFactory.SetLayoutElement(argLabel.gameObject, minHeight: 25);
var argInputObj = UIFactory.CreateInputField(rowObj, 14, (int)TextAnchor.MiddleLeft, 1); var argInputObj = UIFactory.CreateInputField(rowObj, "ArgInput", "...", 14, (int)TextAnchor.MiddleLeft, 1);
var argInputLayout = argInputObj.AddComponent<LayoutElement>(); UIFactory.SetLayoutElement(argInputObj, flexibleWidth: 1200, preferredWidth: 150, minWidth: 20, minHeight: 25, flexibleHeight: 0);
argInputLayout.flexibleWidth = 1200;
argInputLayout.preferredWidth = 150;
argInputLayout.minWidth = 20;
argInputLayout.minHeight = 25;
argInputLayout.flexibleHeight = 0;
//argInputLayout.layoutPriority = 2;
var argInput = argInputObj.GetComponent<InputField>(); var argInput = argInputObj.GetComponent<InputField>();
argInput.onValueChanged.AddListener((string val) => { m_argumentInput[i] = val; }); argInput.onValueChanged.AddListener((string val) => { m_argumentInput[i] = val; });
@ -367,38 +315,29 @@ namespace UnityExplorer.Core.Inspectors.Reflection
{ {
if (HasParameters) if (HasParameters)
{ {
var evalGroupObj = UIFactory.CreateHorizontalGroup(m_rightGroup, new Color(1, 1, 1, 0)); var evalGroupObj = UIFactory.CreateHorizontalGroup(m_rightGroup, "EvalGroup", false, false, true, true, 5,
var evalGroup = evalGroupObj.GetComponent<HorizontalLayoutGroup>(); default, new Color(1, 1, 1, 0));
evalGroup.childForceExpandWidth = false; UIFactory.SetLayoutElement(evalGroupObj, minHeight: 25, flexibleHeight: 0, flexibleWidth: 5000);
evalGroup.childForceExpandHeight = false;
evalGroup.spacing = 5;
var evalGroupLayout = evalGroupObj.AddComponent<LayoutElement>();
evalGroupLayout.minHeight = 25;
evalGroupLayout.flexibleHeight = 0;
evalGroupLayout.flexibleWidth = 5000;
var evalButtonObj = UIFactory.CreateButton(evalGroupObj, new Color(0.4f, 0.4f, 0.4f)); var colors = new ColorBlock();
var evalLayout = evalButtonObj.AddComponent<LayoutElement>(); colors.normalColor = new Color(0.4f, 0.4f, 0.4f);
evalLayout.minWidth = 100;
evalLayout.minHeight = 22;
evalLayout.flexibleWidth = 0;
var evalText = evalButtonObj.GetComponentInChildren<Text>();
evalText.text = $"Evaluate ({ParamCount})";
var evalButton = evalButtonObj.GetComponent<Button>();
var colors = evalButton.colors;
colors.highlightedColor = new Color(0.4f, 0.7f, 0.4f); colors.highlightedColor = new Color(0.4f, 0.7f, 0.4f);
evalButton.colors = colors; colors.pressedColor = new Color(0.3f, 0.3f, 0.3f);
var cancelButtonObj = UIFactory.CreateButton(evalGroupObj, new Color(0.3f, 0.3f, 0.3f)); var evalButton = UIFactory.CreateButton(evalGroupObj,
var cancelLayout = cancelButtonObj.AddComponent<LayoutElement>(); "EvalButton",
cancelLayout.minWidth = 100; $"Evaluate ({ParamCount})",
cancelLayout.minHeight = 22; null,
cancelLayout.flexibleWidth = 0; colors);
var cancelText = cancelButtonObj.GetComponentInChildren<Text>();
cancelText.text = "Close";
cancelButtonObj.SetActive(false); UIFactory.SetLayoutElement(evalButton.gameObject, minWidth: 100, minHeight: 22, flexibleWidth: 0);
var evalText = evalButton.GetComponentInChildren<Text>();
var cancelButton = UIFactory.CreateButton(evalGroupObj, "CancelButton", "Close", null, new Color(0.3f, 0.3f, 0.3f));
UIFactory.SetLayoutElement(cancelButton.gameObject, minWidth: 100, minHeight: 22, flexibleWidth: 0);
cancelButton.gameObject.SetActive(false);
evalButton.onClick.AddListener(() => evalButton.onClick.AddListener(() =>
{ {
@ -411,7 +350,7 @@ namespace UnityExplorer.Core.Inspectors.Reflection
colors.normalColor = new Color(0.3f, 0.6f, 0.3f); colors.normalColor = new Color(0.3f, 0.6f, 0.3f);
evalButton.colors = colors; evalButton.colors = colors;
cancelButtonObj.SetActive(true); cancelButton.gameObject.SetActive(true);
} }
else else
{ {
@ -422,10 +361,9 @@ namespace UnityExplorer.Core.Inspectors.Reflection
} }
}); });
var cancelButton = cancelButtonObj.GetComponent<Button>();
cancelButton.onClick.AddListener(() => cancelButton.onClick.AddListener(() =>
{ {
cancelButtonObj.SetActive(false); cancelButton.gameObject.SetActive(false);
argsHolder.SetActive(false); argsHolder.SetActive(false);
m_isEvaluating = false; m_isEvaluating = false;
@ -439,24 +377,13 @@ namespace UnityExplorer.Core.Inspectors.Reflection
{ {
// simple method evaluate button // simple method evaluate button
var evalButtonObj = UIFactory.CreateButton(m_rightGroup, new Color(0.3f, 0.6f, 0.3f)); var colors = new ColorBlock();
var evalLayout = evalButtonObj.AddComponent<LayoutElement>(); colors.normalColor = new Color(0.4f, 0.4f, 0.4f);
evalLayout.minWidth = 100;
evalLayout.minHeight = 22;
evalLayout.flexibleWidth = 0;
var evalText = evalButtonObj.GetComponentInChildren<Text>();
evalText.text = "Evaluate";
var evalButton = evalButtonObj.GetComponent<Button>();
var colors = evalButton.colors;
colors.highlightedColor = new Color(0.4f, 0.7f, 0.4f); colors.highlightedColor = new Color(0.4f, 0.7f, 0.4f);
evalButton.colors = colors; colors.pressedColor = new Color(0.3f, 0.3f, 0.3f);
evalButton.onClick.AddListener(OnMainEvaluateButton); var evalButton = UIFactory.CreateButton(m_rightGroup, "EvalButton", "Evaluate", () => { (this as CacheMethod).Evaluate(); }, colors);
void OnMainEvaluateButton() UIFactory.SetLayoutElement(evalButton.gameObject, minWidth: 100, minHeight: 22, flexibleWidth: 0);
{
(this as CacheMethod).Evaluate();
}
} }
} }

View File

@ -9,7 +9,7 @@ using UnityExplorer.Core.Unity;
using UnityExplorer.Core; using UnityExplorer.Core;
using UnityExplorer.UI.Utility; using UnityExplorer.UI.Utility;
namespace UnityExplorer.Core.Inspectors.Reflection namespace UnityExplorer.UI.CacheObject
{ {
public class CacheMethod : CacheMember public class CacheMethod : CacheMember
{ {
@ -130,14 +130,10 @@ namespace UnityExplorer.Core.Inspectors.Reflection
internal void ConstructGenericArgInput(GameObject parent) internal void ConstructGenericArgInput(GameObject parent)
{ {
var titleObj = UIFactory.CreateLabel(parent, TextAnchor.MiddleLeft); UIFactory.CreateLabel(parent, "GenericArgLabel", "Generic Arguments:", TextAnchor.MiddleLeft);
var titleText = titleObj.GetComponent<Text>();
titleText.text = "<b>Generic Arguments:</b>";
for (int i = 0; i < GenericArgs.Length; i++) for (int i = 0; i < GenericArgs.Length; i++)
{
AddGenericArgRow(i, parent); AddGenericArgRow(i, parent);
}
} }
internal void AddGenericArgRow(int i, GameObject parent) internal void AddGenericArgRow(int i, GameObject parent)
@ -158,33 +154,18 @@ namespace UnityExplorer.Core.Inspectors.Reflection
else else
constrainTxt = $"Any"; constrainTxt = $"Any";
var rowObj = UIFactory.CreateHorizontalGroup(parent, new Color(1, 1, 1, 0)); var rowObj = UIFactory.CreateHorizontalGroup(parent, "ArgRowObj", false, true, true, true, 4, default, new Color(1, 1, 1, 0));
var rowLayout = rowObj.AddComponent<LayoutElement>(); UIFactory.SetLayoutElement(rowObj, minHeight: 25, flexibleWidth: 5000);
rowLayout.minHeight = 25;
rowLayout.flexibleWidth = 5000;
var rowGroup = rowObj.GetComponent<HorizontalLayoutGroup>();
rowGroup.childForceExpandHeight = true;
rowGroup.spacing = 4;
var argLabelObj = UIFactory.CreateLabel(rowObj, TextAnchor.MiddleLeft); var argLabelObj = UIFactory.CreateLabel(rowObj, "ArgLabelObj", $"{constrainTxt} <color={SignatureHighlighter.CONST_VAR}>{arg.Name}</color>",
//var argLayout = argLabelObj.AddComponent<LayoutElement>(); TextAnchor.MiddleLeft);
//argLayout.minWidth = 20;
var argText = argLabelObj.GetComponent<Text>();
argText.text = $"{constrainTxt} <color={SignatureHighlighter.CONST_VAR}>{arg.Name}</color>";
var argInputObj = UIFactory.CreateInputField(rowObj, 14, (int)TextAnchor.MiddleLeft, 1); var argInputObj = UIFactory.CreateInputField(rowObj, "ArgInput", "...", 14, (int)TextAnchor.MiddleLeft, 1);
var argInputLayout = argInputObj.AddComponent<LayoutElement>(); UIFactory.SetLayoutElement(argInputObj, flexibleWidth: 1200);
argInputLayout.flexibleWidth = 1200;
var argInput = argInputObj.GetComponent<InputField>(); var argInput = argInputObj.GetComponent<InputField>();
argInput.onValueChanged.AddListener((string val) => { m_genericArgInput[i] = val; }); argInput.onValueChanged.AddListener((string val) => { m_genericArgInput[i] = val; });
//var constraintLabelObj = UIFactory.CreateLabel(rowObj, TextAnchor.MiddleLeft);
//var constraintLayout = constraintLabelObj.AddComponent<LayoutElement>();
//constraintLayout.minWidth = 60;
//constraintLayout.flexibleWidth = 100;
//var constraintText = constraintLabelObj.GetComponent<Text>();
//constraintText.text = ;
} }
#endregion #endregion

View File

@ -4,12 +4,12 @@ using System.Linq;
using System.Reflection; using System.Reflection;
using UnityEngine; using UnityEngine;
using UnityExplorer.UI; using UnityExplorer.UI;
using UnityExplorer.UI.Reusable;
using UnityExplorer.Core.Unity; using UnityExplorer.Core.Unity;
using UnityEngine.UI; using UnityEngine.UI;
using UnityExplorer.Core; using UnityExplorer.Core;
using UnityExplorer.UI.InteractiveValues;
namespace UnityExplorer.Core.Inspectors.Reflection namespace UnityExplorer.UI.CacheObject
{ {
public abstract class CacheObjectBase public abstract class CacheObjectBase
{ {
@ -86,33 +86,18 @@ namespace UnityExplorer.Core.Inspectors.Reflection
{ {
m_constructedUI = true; m_constructedUI = true;
m_mainContent = UIFactory.CreateVerticalGroup(m_parentContent, new Color(0.1f, 0.1f, 0.1f)); m_mainContent = UIFactory.CreateVerticalGroup(m_parentContent, "CacheObjectBase.MainContent", true, true, true, true, 0, default,
m_mainContent.name = "CacheObjectBase.MainContent"; new Color(0.1f, 0.1f, 0.1f));
m_mainRect = m_mainContent.GetComponent<RectTransform>(); m_mainRect = m_mainContent.GetComponent<RectTransform>();
m_mainRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 25); m_mainRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 25);
var mainGroup = m_mainContent.GetComponent<VerticalLayoutGroup>();
mainGroup.childForceExpandWidth = true; UIFactory.SetLayoutElement(m_mainContent, minHeight: 25, flexibleHeight: 9999, minWidth: 200, flexibleWidth: 5000);
mainGroup.childControlWidth = true;
mainGroup.childForceExpandHeight = true;
mainGroup.childControlHeight = true;
var mainLayout = m_mainContent.AddComponent<LayoutElement>();
mainLayout.minHeight = 25;
mainLayout.flexibleHeight = 9999;
mainLayout.minWidth = 200;
mainLayout.flexibleWidth = 5000;
// subcontent // subcontent
m_subContent = UIFactory.CreateVerticalGroup(m_mainContent, new Color(0.085f, 0.085f, 0.085f)); m_subContent = UIFactory.CreateVerticalGroup(m_mainContent, "CacheObjectBase.SubContent", true, false, true, true, 0, default,
m_subContent.name = "CacheObjectBase.SubContent"; new Color(0.085f, 0.085f, 0.085f));
var subGroup = m_subContent.GetComponent<VerticalLayoutGroup>(); UIFactory.SetLayoutElement(m_subContent, minHeight: 30, flexibleHeight: 9999, minWidth: 125, flexibleWidth: 9000);
subGroup.childForceExpandWidth = true;
subGroup.childForceExpandHeight = false;
var subLayout = m_subContent.AddComponent<LayoutElement>();
subLayout.minHeight = 30;
subLayout.flexibleHeight = 9999;
subLayout.minWidth = 125;
subLayout.flexibleWidth = 9000;
m_subContent.SetActive(false); m_subContent.SetActive(false);

View File

@ -6,9 +6,9 @@ using System.Text;
using UnityExplorer.UI; using UnityExplorer.UI;
using UnityEngine; using UnityEngine;
using UnityEngine.UI; using UnityEngine.UI;
using UnityExplorer.UI.InteractiveValues;
namespace UnityExplorer.UI.CacheObject
namespace UnityExplorer.Core.Inspectors.Reflection
{ {
public enum PairTypes public enum PairTypes
{ {
@ -50,18 +50,11 @@ namespace UnityExplorer.Core.Inspectors.Reflection
{ {
base.ConstructUI(); base.ConstructUI();
var rowObj = UIFactory.CreateHorizontalGroup(m_mainContent, new Color(1, 1, 1, 0)); var rowObj = UIFactory.CreateHorizontalGroup(m_mainContent, "PairedGroup", false, false, true, true, 0, new Vector4(0,0,5,2),
var rowGroup = rowObj.GetComponent<HorizontalLayoutGroup>(); new Color(1, 1, 1, 0));
rowGroup.padding.left = 5;
rowGroup.padding.right = 2; var indexLabel = UIFactory.CreateLabel(rowObj, "IndexLabel", $"{this.PairType} {this.Index}:", TextAnchor.MiddleLeft);
UIFactory.SetLayoutElement(indexLabel.gameObject, minWidth: 80, flexibleWidth: 30, minHeight: 25);
var indexLabelObj = UIFactory.CreateLabel(rowObj, TextAnchor.MiddleLeft);
var indexLayout = indexLabelObj.AddComponent<LayoutElement>();
indexLayout.minWidth = 80;
indexLayout.flexibleWidth = 30;
indexLayout.minHeight = 25;
var indexText = indexLabelObj.GetComponent<Text>();
indexText.text = $"{this.PairType} {this.Index}:";
IValue.m_mainContentParent = rowObj; IValue.m_mainContentParent = rowObj;
} }

View File

@ -7,7 +7,7 @@ using UnityExplorer.UI;
using UnityExplorer.Core.Unity; using UnityExplorer.Core.Unity;
using UnityEngine; using UnityEngine;
namespace UnityExplorer.Core.Inspectors.Reflection namespace UnityExplorer.UI.CacheObject
{ {
public class CacheProperty : CacheMember public class CacheProperty : CacheMember
{ {

View File

@ -6,8 +6,9 @@ using UnityEngine;
using UnityEngine.UI; using UnityEngine.UI;
using UnityExplorer.Core.Unity; using UnityExplorer.Core.Unity;
using UnityExplorer.UI; using UnityExplorer.UI;
using UnityExplorer.UI.CacheObject;
namespace UnityExplorer.Core.Inspectors.Reflection namespace UnityExplorer.UI.InteractiveValues
{ {
public class InteractiveBool : InteractiveValue public class InteractiveBool : InteractiveValue
{ {
@ -87,27 +88,22 @@ namespace UnityExplorer.Core.Inspectors.Reflection
if (Owner.CanWrite) if (Owner.CanWrite)
{ {
var toggleObj = UIFactory.CreateToggle(m_valueContent, out m_toggle, out _, new Color(0.1f, 0.1f, 0.1f)); var toggleObj = UIFactory.CreateToggle(m_valueContent, "InteractiveBoolToggle", out m_toggle, out _, new Color(0.1f, 0.1f, 0.1f));
var toggleLayout = toggleObj.AddComponent<LayoutElement>(); UIFactory.SetLayoutElement(toggleObj, minWidth: 24);
toggleLayout.minWidth = 24;
m_toggle.onValueChanged.AddListener(OnToggleValueChanged); m_toggle.onValueChanged.AddListener(OnToggleValueChanged);
m_baseLabel.transform.SetAsLastSibling(); m_baseLabel.transform.SetAsLastSibling();
var applyBtnObj = UIFactory.CreateButton(m_valueContent, new Color(0.2f, 0.2f, 0.2f)); m_applyBtn = UIFactory.CreateButton(m_valueContent,
var applyLayout = applyBtnObj.AddComponent<LayoutElement>(); "ApplyButton",
applyLayout.minWidth = 50; "Apply",
applyLayout.minHeight = 25; () => { Owner.SetValue(); },
applyLayout.flexibleWidth = 0; new Color(0.2f, 0.2f, 0.2f));
m_applyBtn = applyBtnObj.GetComponent<Button>();
m_applyBtn.onClick.AddListener(() => { Owner.SetValue(); });
var applyText = applyBtnObj.GetComponentInChildren<Text>(); UIFactory.SetLayoutElement(m_applyBtn.gameObject, minWidth: 50, minHeight: 25, flexibleWidth: 0);
applyText.text = "Apply";
toggleObj.SetActive(false); toggleObj.SetActive(false);
applyBtnObj.SetActive(false); m_applyBtn.gameObject.SetActive(false);
} }
} }
} }

View File

@ -8,13 +8,15 @@ using UnityEngine.UI;
using UnityExplorer.Core.Config; using UnityExplorer.Core.Config;
using UnityExplorer.Core.Unity; using UnityExplorer.Core.Unity;
using UnityExplorer.UI; using UnityExplorer.UI;
using UnityExplorer.UI.Reusable;
using System.Reflection; using System.Reflection;
using UnityExplorer.UI.CacheObject;
using UnityExplorer.Core;
using UnityExplorer.UI.Utility;
#if CPP #if CPP
using CppDictionary = Il2CppSystem.Collections.IDictionary; using CppDictionary = Il2CppSystem.Collections.IDictionary;
#endif #endif
namespace UnityExplorer.Core.Inspectors.Reflection namespace UnityExplorer.UI.InteractiveValues
{ {
public class InteractiveDictionary : InteractiveValue public class InteractiveDictionary : InteractiveValue
{ {
@ -35,7 +37,6 @@ namespace UnityExplorer.Core.Inspectors.Reflection
public override bool WantInspectBtn => false; public override bool WantInspectBtn => false;
public override bool HasSubContent => true; public override bool HasSubContent => true;
// todo fix for il2cpp
public override bool SubContentWanted public override bool SubContentWanted
{ {
get get
@ -59,7 +60,7 @@ namespace UnityExplorer.Core.Inspectors.Reflection
= new List<KeyValuePair<CachePaired, CachePaired>>(); = new List<KeyValuePair<CachePaired, CachePaired>>();
internal readonly KeyValuePair<CachePaired, CachePaired>[] m_displayedEntries internal readonly KeyValuePair<CachePaired, CachePaired>[] m_displayedEntries
= new KeyValuePair<CachePaired, CachePaired>[ExplorerConfig.Instance.Default_Page_Limit]; = new KeyValuePair<CachePaired, CachePaired>[ConfigManager.Default_Page_Limit.Value];
internal bool m_recacheWanted = true; internal bool m_recacheWanted = true;
@ -217,7 +218,7 @@ namespace UnityExplorer.Core.Inspectors.Reflection
private IDictionary EnumerateWithReflection() private IDictionary EnumerateWithReflection()
{ {
var valueType = Value?.GetType() ?? FallbackType; var valueType = ReflectionUtility.GetType(Value);
// get keys and values // get keys and values
var keys = valueType.GetProperty("Keys").GetValue(Value, null); var keys = valueType.GetProperty("Keys").GetValue(Value, null);
@ -283,38 +284,23 @@ namespace UnityExplorer.Core.Inspectors.Reflection
m_pageHandler.ConstructUI(m_subContentParent); m_pageHandler.ConstructUI(m_subContentParent);
m_pageHandler.OnPageChanged += OnPageTurned; m_pageHandler.OnPageChanged += OnPageTurned;
var scrollObj = UIFactory.CreateVerticalGroup(this.m_subContentParent, new Color(0.08f, 0.08f, 0.08f)); m_listContent = UIFactory.CreateVerticalGroup(m_subContentParent, "DictionaryContent", true, true, true, true, 2, new Vector4(5,5,5,5),
m_listContent = scrollObj; new Color(0.08f, 0.08f, 0.08f));
var scrollRect = scrollObj.GetComponent<RectTransform>(); var scrollRect = m_listContent.GetComponent<RectTransform>();
scrollRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 0); scrollRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 0);
m_listLayout = Owner.m_mainContent.GetComponent<LayoutElement>(); m_listLayout = Owner.m_mainContent.GetComponent<LayoutElement>();
m_listLayout.minHeight = 25; m_listLayout.minHeight = 25;
m_listLayout.flexibleHeight = 0; m_listLayout.flexibleHeight = 0;
Owner.m_mainRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 25); Owner.m_mainRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 25);
var scrollGroup = m_listContent.GetComponent<VerticalLayoutGroup>(); var contentFitter = m_listContent.AddComponent<ContentSizeFitter>();
scrollGroup.childForceExpandHeight = true;
scrollGroup.childControlHeight = true;
scrollGroup.spacing = 2;
scrollGroup.padding.top = 5;
scrollGroup.padding.left = 5;
scrollGroup.padding.right = 5;
scrollGroup.padding.bottom = 5;
var contentFitter = scrollObj.AddComponent<ContentSizeFitter>();
contentFitter.horizontalFit = ContentSizeFitter.FitMode.Unconstrained; contentFitter.horizontalFit = ContentSizeFitter.FitMode.Unconstrained;
contentFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize; contentFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
} }
//internal void AddRowHolder()
//{
// var obj = UIFactory.CreateHorizontalGroup(m_listContent, new Color(0.15f, 0.15f, 0.15f));
// m_rowHolders.Add(obj);
//}
#endregion #endregion
} }
} }

View File

@ -7,7 +7,7 @@ using UnityEngine.UI;
using UnityExplorer.Core.Unity; using UnityExplorer.Core.Unity;
using UnityExplorer.UI; using UnityExplorer.UI;
namespace UnityExplorer.Core.Inspectors.Reflection namespace UnityExplorer.UI.InteractiveValues
{ {
public class InteractiveEnum : InteractiveValue public class InteractiveEnum : InteractiveValue
{ {
@ -136,32 +136,18 @@ namespace UnityExplorer.Core.Inspectors.Reflection
if (Owner.CanWrite) if (Owner.CanWrite)
{ {
var groupObj = UIFactory.CreateHorizontalGroup(m_subContentParent, new Color(1, 1, 1, 0)); var groupObj = UIFactory.CreateHorizontalGroup(m_subContentParent, "InteractiveEnumGroup", false, true, true, true, 5,
var group = groupObj.GetComponent<HorizontalLayoutGroup>(); new Vector4(3,3,3,3),new Color(1, 1, 1, 0));
group.padding.top = 3;
group.padding.left = 3;
group.padding.right = 3;
group.padding.bottom = 3;
group.spacing = 5;
// apply button // apply button
var applyObj = UIFactory.CreateButton(groupObj, new Color(0.3f, 0.3f, 0.3f)); var apply = UIFactory.CreateButton(groupObj, "ApplyButton", "Apply", SetValueFromDropdown, new Color(0.3f, 0.3f, 0.3f));
var applyLayout = applyObj.AddComponent<LayoutElement>(); UIFactory.SetLayoutElement(apply.gameObject, minHeight: 25, minWidth: 50);
applyLayout.minHeight = 25;
applyLayout.minWidth = 50;
var applyText = applyObj.GetComponentInChildren<Text>();
applyText.text = "Apply";
var applyBtn = applyObj.GetComponent<Button>();
applyBtn.onClick.AddListener(SetValueFromDropdown);
// dropdown // dropdown
var dropdownObj = UIFactory.CreateDropdown(groupObj, out m_dropdown); var dropdownObj = UIFactory.CreateDropdown(groupObj, out m_dropdown, "<notset>", 14, null);
var dropLayout = dropdownObj.AddComponent<LayoutElement>(); UIFactory.SetLayoutElement(dropdownObj, minWidth: 150, minHeight: 25, flexibleWidth: 120);
dropLayout.minWidth = 150;
dropLayout.minHeight = 25;
dropLayout.flexibleWidth = 120;
foreach (var kvp in m_values) foreach (var kvp in m_values)
{ {

View File

@ -9,9 +9,10 @@ using UnityEngine.UI;
using UnityExplorer.Core.Config; using UnityExplorer.Core.Config;
using UnityExplorer.Core.Unity; using UnityExplorer.Core.Unity;
using UnityExplorer.UI; using UnityExplorer.UI;
using UnityExplorer.UI.Reusable; using UnityExplorer.UI.CacheObject;
using UnityExplorer.UI.Utility;
namespace UnityExplorer.Core.Inspectors.Reflection namespace UnityExplorer.UI.InteractiveValues
{ {
public class InteractiveEnumerable : InteractiveValue public class InteractiveEnumerable : InteractiveValue
{ {
@ -46,7 +47,7 @@ namespace UnityExplorer.Core.Inspectors.Reflection
internal readonly Type m_baseEntryType; internal readonly Type m_baseEntryType;
internal readonly List<CacheEnumerated> m_entries = new List<CacheEnumerated>(); internal readonly List<CacheEnumerated> m_entries = new List<CacheEnumerated>();
internal readonly CacheEnumerated[] m_displayedEntries = new CacheEnumerated[ExplorerConfig.Instance.Default_Page_Limit]; internal readonly CacheEnumerated[] m_displayedEntries = new CacheEnumerated[ConfigManager.Default_Page_Limit.Value];
internal bool m_recacheWanted = true; internal bool m_recacheWanted = true;
public override void OnValueUpdated() public override void OnValueUpdated()
@ -257,10 +258,10 @@ namespace UnityExplorer.Core.Inspectors.Reflection
m_pageHandler.ConstructUI(m_subContentParent); m_pageHandler.ConstructUI(m_subContentParent);
m_pageHandler.OnPageChanged += OnPageTurned; m_pageHandler.OnPageChanged += OnPageTurned;
var scrollObj = UIFactory.CreateVerticalGroup(this.m_subContentParent, new Color(0.08f, 0.08f, 0.08f)); m_listContent = UIFactory.CreateVerticalGroup(this.m_subContentParent, "EnumerableContent", true, true, true, true, 2, new Vector4(5,5,5,5),
m_listContent = scrollObj; new Color(0.08f, 0.08f, 0.08f));
var scrollRect = scrollObj.GetComponent<RectTransform>(); var scrollRect = m_listContent.GetComponent<RectTransform>();
scrollRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 0); scrollRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 0);
m_listLayout = Owner.m_mainContent.GetComponent<LayoutElement>(); m_listLayout = Owner.m_mainContent.GetComponent<LayoutElement>();
@ -268,16 +269,7 @@ namespace UnityExplorer.Core.Inspectors.Reflection
m_listLayout.flexibleHeight = 0; m_listLayout.flexibleHeight = 0;
Owner.m_mainRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 25); Owner.m_mainRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 25);
var scrollGroup = m_listContent.GetComponent<VerticalLayoutGroup>(); var contentFitter = m_listContent.AddComponent<ContentSizeFitter>();
scrollGroup.childForceExpandHeight = true;
scrollGroup.childControlHeight = true;
scrollGroup.spacing = 2;
scrollGroup.padding.top = 5;
scrollGroup.padding.left = 5;
scrollGroup.padding.right = 5;
scrollGroup.padding.bottom = 5;
var contentFitter = scrollObj.AddComponent<ContentSizeFitter>();
contentFitter.horizontalFit = ContentSizeFitter.FitMode.Unconstrained; contentFitter.horizontalFit = ContentSizeFitter.FitMode.Unconstrained;
contentFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize; contentFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
} }

View File

@ -7,7 +7,7 @@ using UnityEngine.UI;
using UnityExplorer.Core.Unity; using UnityExplorer.Core.Unity;
using UnityExplorer.UI; using UnityExplorer.UI;
namespace UnityExplorer.Core.Inspectors.Reflection namespace UnityExplorer.UI.InteractiveValues
{ {
public class InteractiveFlags : InteractiveEnum public class InteractiveFlags : InteractiveEnum
{ {
@ -94,35 +94,18 @@ namespace UnityExplorer.Core.Inspectors.Reflection
if (Owner.CanWrite) if (Owner.CanWrite)
{ {
var groupObj = UIFactory.CreateVerticalGroup(m_subContentParent, new Color(1, 1, 1, 0)); var groupObj = UIFactory.CreateVerticalGroup(m_subContentParent, "InteractiveFlagsContent", false, true, true, true, 5,
var group = groupObj.GetComponent<VerticalLayoutGroup>(); new Vector4(3,3,3,3), new Color(1, 1, 1, 0));
group.childForceExpandHeight = true;
group.childForceExpandWidth = false;
group.childControlHeight = true;
group.childControlWidth = true;
group.padding.top = 3;
group.padding.left = 3;
group.padding.right = 3;
group.padding.bottom = 3;
group.spacing = 5;
// apply button // apply button
var applyObj = UIFactory.CreateButton(groupObj, new Color(0.3f, 0.3f, 0.3f)); var apply = UIFactory.CreateButton(groupObj, "ApplyButton", "Apply", SetValueFromToggles, new Color(0.3f, 0.3f, 0.3f));
var applyLayout = applyObj.AddComponent<LayoutElement>(); UIFactory.SetLayoutElement(apply.gameObject, minWidth: 50, minHeight: 25);
applyLayout.minHeight = 25;
applyLayout.minWidth = 50;
var applyText = applyObj.GetComponentInChildren<Text>();
applyText.text = "Apply";
var applyBtn = applyObj.GetComponent<Button>();
applyBtn.onClick.AddListener(SetValueFromToggles);
// toggles // toggles
for (int i = 0; i < m_values.Length; i++) for (int i = 0; i < m_values.Length; i++)
{
AddToggle(i, groupObj); AddToggle(i, groupObj);
}
} }
} }
@ -130,11 +113,8 @@ namespace UnityExplorer.Core.Inspectors.Reflection
{ {
var value = m_values[index]; var value = m_values[index];
var toggleObj = UIFactory.CreateToggle(groupObj, out Toggle toggle, out Text text, new Color(0.1f, 0.1f, 0.1f)); var toggleObj = UIFactory.CreateToggle(groupObj, "FlagToggle", out Toggle toggle, out Text text, new Color(0.1f, 0.1f, 0.1f));
var toggleLayout = toggleObj.AddComponent<LayoutElement>(); UIFactory.SetLayoutElement(toggleObj, minWidth: 100, flexibleWidth: 2000, minHeight: 25);
toggleLayout.minWidth = 100;
toggleLayout.flexibleWidth = 2000;
toggleLayout.minHeight = 25;
m_toggles[index] = toggle; m_toggles[index] = toggle;

View File

@ -9,8 +9,9 @@ using UnityExplorer.Core.Unity;
using UnityExplorer.UI; using UnityExplorer.UI;
using UnityExplorer.Core; using UnityExplorer.Core;
using UnityExplorer.UI.Utility; using UnityExplorer.UI.Utility;
using UnityExplorer.UI.CacheObject;
namespace UnityExplorer.Core.Inspectors.Reflection namespace UnityExplorer.UI.InteractiveValues
{ {
public class InteractiveNumber : InteractiveValue public class InteractiveNumber : InteractiveValue
{ {
@ -101,27 +102,16 @@ namespace UnityExplorer.Core.Inspectors.Reflection
labelLayout.minWidth = 50; labelLayout.minWidth = 50;
labelLayout.flexibleWidth = 0; labelLayout.flexibleWidth = 0;
var inputObj = UIFactory.CreateInputField(m_valueContent); var inputObj = UIFactory.CreateInputField(m_valueContent, "InteractiveNumberInput", "...");
var inputLayout = inputObj.AddComponent<LayoutElement>(); UIFactory.SetLayoutElement(inputObj, minWidth: 120, minHeight: 25, flexibleWidth: 0);
inputLayout.minWidth = 120;
inputLayout.minHeight = 25;
inputLayout.flexibleWidth = 0;
m_valueInput = inputObj.GetComponent<InputField>(); m_valueInput = inputObj.GetComponent<InputField>();
m_valueInput.gameObject.SetActive(false); m_valueInput.gameObject.SetActive(false);
if (Owner.CanWrite) if (Owner.CanWrite)
{ {
var applyBtnObj = UIFactory.CreateButton(m_valueContent, new Color(0.2f, 0.2f, 0.2f)); m_applyBtn = UIFactory.CreateButton(m_valueContent, "ApplyButton", "Apply", OnApplyClicked, new Color(0.2f, 0.2f, 0.2f));
var applyLayout = applyBtnObj.AddComponent<LayoutElement>(); UIFactory.SetLayoutElement(m_applyBtn.gameObject, minWidth: 50, minHeight: 25, flexibleWidth: 0);
applyLayout.minWidth = 50;
applyLayout.minHeight = 25;
applyLayout.flexibleWidth = 0;
m_applyBtn = applyBtnObj.GetComponent<Button>();
m_applyBtn.onClick.AddListener(OnApplyClicked);
var applyText = applyBtnObj.GetComponentInChildren<Text>();
applyText.text = "Apply";
} }
} }
} }

View File

@ -8,8 +8,9 @@ using UnityEngine.UI;
using UnityExplorer.Core.Unity; using UnityExplorer.Core.Unity;
using UnityExplorer.UI; using UnityExplorer.UI;
using UnityExplorer.UI.Utility; using UnityExplorer.UI.Utility;
using UnityExplorer.UI.CacheObject;
namespace UnityExplorer.Core.Inspectors.Reflection namespace UnityExplorer.UI.InteractiveValues
{ {
public class InteractiveString : InteractiveValue public class InteractiveString : InteractiveValue
{ {
@ -114,32 +115,23 @@ namespace UnityExplorer.Core.Inspectors.Reflection
m_labelLayout = m_baseLabel.gameObject.GetComponent<LayoutElement>(); m_labelLayout = m_baseLabel.gameObject.GetComponent<LayoutElement>();
var readonlyInputObj = UIFactory.CreateLabel(m_valueContent, TextAnchor.MiddleLeft); m_readonlyInput = UIFactory.CreateLabel(m_valueContent, "ReadonlyLabel", "<notset>", TextAnchor.MiddleLeft);
m_readonlyInput = readonlyInputObj.GetComponent<Text>();
m_readonlyInput.horizontalOverflow = HorizontalWrapMode.Overflow; m_readonlyInput.horizontalOverflow = HorizontalWrapMode.Overflow;
var testFitter = readonlyInputObj.AddComponent<ContentSizeFitter>(); var testFitter = m_readonlyInput.gameObject.AddComponent<ContentSizeFitter>();
testFitter.verticalFit = ContentSizeFitter.FitMode.MinSize; testFitter.verticalFit = ContentSizeFitter.FitMode.MinSize;
var labelLayout = readonlyInputObj.AddComponent<LayoutElement>(); UIFactory.SetLayoutElement(m_readonlyInput.gameObject, minHeight: 25, preferredHeight: 25, flexibleHeight: 0);
labelLayout.minHeight = 25;
labelLayout.preferredHeight = 25;
labelLayout.flexibleHeight = 0;
} }
public override void ConstructSubcontent() public override void ConstructSubcontent()
{ {
base.ConstructSubcontent(); base.ConstructSubcontent();
var groupObj = UIFactory.CreateVerticalGroup(m_subContentParent, new Color(1, 1, 1, 0)); var groupObj = UIFactory.CreateVerticalGroup(m_subContentParent, "SubContent", true, false, true, true, 4, new Vector4(3,3,3,3),
var group = groupObj.GetComponent<VerticalLayoutGroup>(); new Color(1, 1, 1, 0));
group.spacing = 4;
group.padding.top = 3;
group.padding.left = 3;
group.padding.right = 3;
group.padding.bottom = 3;
m_hiddenObj = UIFactory.CreateLabel(groupObj, TextAnchor.MiddleLeft); m_hiddenObj = UIFactory.CreateLabel(groupObj, "HiddenLabel", "", TextAnchor.MiddleLeft).gameObject;
m_hiddenObj.SetActive(false); m_hiddenObj.SetActive(false);
var hiddenText = m_hiddenObj.GetComponent<Text>(); var hiddenText = m_hiddenObj.GetComponent<Text>();
hiddenText.color = Color.clear; hiddenText.color = Color.clear;
@ -148,23 +140,11 @@ namespace UnityExplorer.Core.Inspectors.Reflection
hiddenText.supportRichText = false; hiddenText.supportRichText = false;
var hiddenFitter = m_hiddenObj.AddComponent<ContentSizeFitter>(); var hiddenFitter = m_hiddenObj.AddComponent<ContentSizeFitter>();
hiddenFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize; hiddenFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
var hiddenLayout = m_hiddenObj.AddComponent<LayoutElement>(); UIFactory.SetLayoutElement(m_hiddenObj, minHeight: 25, flexibleHeight: 500, minWidth: 250, flexibleWidth: 9000);
hiddenLayout.minHeight = 25; UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(m_hiddenObj, true, true, true, true);
hiddenLayout.flexibleHeight = 500;
hiddenLayout.minWidth = 250;
hiddenLayout.flexibleWidth = 9000;
var hiddenGroup = m_hiddenObj.AddComponent<HorizontalLayoutGroup>();
hiddenGroup.childForceExpandWidth = true;
hiddenGroup.childControlWidth = true;
hiddenGroup.childForceExpandHeight = true;
hiddenGroup.childControlHeight = true;
var inputObj = UIFactory.CreateInputField(m_hiddenObj, 14, 3); var inputObj = UIFactory.CreateInputField(m_hiddenObj, "StringInputField", "...", 14, 3);
var inputLayout = inputObj.AddComponent<LayoutElement>(); UIFactory.SetLayoutElement(inputObj, minWidth: 120, minHeight: 25, flexibleWidth: 5000, flexibleHeight: 5000);
inputLayout.minWidth = 120;
inputLayout.minHeight = 25;
inputLayout.flexibleWidth = 5000;
inputLayout.flexibleHeight = 5000;
m_valueInput = inputObj.GetComponent<InputField>(); m_valueInput = inputObj.GetComponent<InputField>();
m_valueInput.lineType = InputField.LineType.MultiLineNewline; m_valueInput.lineType = InputField.LineType.MultiLineNewline;
@ -182,17 +162,8 @@ namespace UnityExplorer.Core.Inspectors.Reflection
if (Owner.CanWrite) if (Owner.CanWrite)
{ {
var applyBtnObj = UIFactory.CreateButton(groupObj, new Color(0.2f, 0.2f, 0.2f)); var apply = UIFactory.CreateButton(groupObj, "ApplyButton", "Apply", OnApplyClicked, new Color(0.2f, 0.2f, 0.2f));
var applyLayout = applyBtnObj.AddComponent<LayoutElement>(); UIFactory.SetLayoutElement(apply.gameObject, minWidth: 50, minHeight: 25, flexibleWidth: 0);
applyLayout.minWidth = 50;
applyLayout.minHeight = 25;
applyLayout.flexibleWidth = 0;
var applyBtn = applyBtnObj.GetComponent<Button>();
applyBtn.onClick.AddListener(OnApplyClicked);
var applyText = applyBtnObj.GetComponentInChildren<Text>();
applyText.text = "Apply";
} }
else else
{ {

View File

@ -7,7 +7,7 @@ using UnityEngine.UI;
using UnityExplorer.Core.Unity; using UnityExplorer.Core.Unity;
using UnityExplorer.UI; using UnityExplorer.UI;
namespace UnityExplorer.Core.Inspectors.Reflection namespace UnityExplorer.UI.InteractiveValues
{ {
#region IStructInfo helper #region IStructInfo helper
@ -225,17 +225,7 @@ namespace UnityExplorer.Core.Inspectors.Reflection
return; return;
if (StructInfo != null) if (StructInfo != null)
{
DestroySubContent(); DestroySubContent();
//// changing types, destroy subcontent
//for (int i = 0; i < m_subContentParent.transform.childCount; i++)
//{
// var child = m_subContentParent.transform.GetChild(i);
// GameObject.Destroy(child.gameObject);
//}
//m_UIConstructed = false;
}
m_lastStructType = type; m_lastStructType = type;
@ -266,68 +256,38 @@ namespace UnityExplorer.Core.Inspectors.Reflection
return; return;
} }
var editorContainer = UIFactory.CreateVerticalGroup(m_subContentParent, new Color(0.08f, 0.08f, 0.08f)); var editorContainer = UIFactory.CreateVerticalGroup(m_subContentParent, "EditorContent", false, true, true, true, 2, new Vector4(4,4,4,4),
var editorGroup = editorContainer.GetComponent<VerticalLayoutGroup>(); new Color(0.08f, 0.08f, 0.08f));
editorGroup.childForceExpandWidth = false;
editorGroup.padding.top = 4;
editorGroup.padding.right = 4;
editorGroup.padding.left = 4;
editorGroup.padding.bottom = 4;
editorGroup.spacing = 2;
m_inputs = new InputField[StructInfo.FieldNames.Length]; m_inputs = new InputField[StructInfo.FieldNames.Length];
for (int i = 0; i < StructInfo.FieldNames.Length; i++) for (int i = 0; i < StructInfo.FieldNames.Length; i++)
{
AddEditorRow(i, editorContainer); AddEditorRow(i, editorContainer);
}
if (Owner.CanWrite) if (Owner.CanWrite)
{ {
var applyBtnObj = UIFactory.CreateButton(editorContainer, new Color(0.2f, 0.2f, 0.2f)); var applyBtn = UIFactory.CreateButton(editorContainer, "ApplyButton", "Apply", OnSetValue, new Color(0.2f, 0.2f, 0.2f));
var applyLayout = applyBtnObj.AddComponent<LayoutElement>(); UIFactory.SetLayoutElement(applyBtn.gameObject, minWidth: 175, minHeight: 25, flexibleWidth: 0);
applyLayout.minWidth = 175;
applyLayout.minHeight = 25;
applyLayout.flexibleWidth = 0;
var m_applyBtn = applyBtnObj.GetComponent<Button>();
m_applyBtn.onClick.AddListener(OnSetValue);
void OnSetValue() void OnSetValue()
{ {
Owner.SetValue(); Owner.SetValue();
RefreshUIForValue(); RefreshUIForValue();
} }
var applyText = applyBtnObj.GetComponentInChildren<Text>();
applyText.text = "Apply";
} }
} }
internal void AddEditorRow(int index, GameObject groupObj) internal void AddEditorRow(int index, GameObject groupObj)
{ {
var rowObj = UIFactory.CreateHorizontalGroup(groupObj, new Color(1, 1, 1, 0)); var rowObj = UIFactory.CreateHorizontalGroup(groupObj, "EditorRow", false, true, true, true, 5, default, new Color(1, 1, 1, 0));
var rowGroup = rowObj.GetComponent<HorizontalLayoutGroup>();
rowGroup.childForceExpandHeight = true;
rowGroup.childForceExpandWidth = false;
rowGroup.spacing = 5;
var label = UIFactory.CreateLabel(rowObj, TextAnchor.MiddleRight); var label = UIFactory.CreateLabel(rowObj, "RowLabel", $"{StructInfo.FieldNames[index]}:", TextAnchor.MiddleRight, Color.cyan);
var labelLayout = label.AddComponent<LayoutElement>(); UIFactory.SetLayoutElement(label.gameObject, minWidth: 50, flexibleWidth: 0, minHeight: 25);
labelLayout.minWidth = 50;
labelLayout.flexibleWidth = 0; var inputFieldObj = UIFactory.CreateInputField(rowObj, "InputField", "...", 14, 3, 1);
labelLayout.minHeight = 25; UIFactory.SetLayoutElement(inputFieldObj, minWidth: 120, minHeight: 25, flexibleWidth: 0);
var labelText = label.GetComponent<Text>();
labelText.text = $"{StructInfo.FieldNames[index]}:";
labelText.color = Color.cyan;
var inputFieldObj = UIFactory.CreateInputField(rowObj, 14, 3, 1);
var inputField = inputFieldObj.GetComponent<InputField>(); var inputField = inputFieldObj.GetComponent<InputField>();
inputField.characterValidation = InputField.CharacterValidation.Decimal;
var inputLayout = inputFieldObj.AddComponent<LayoutElement>();
inputLayout.flexibleWidth = 0;
inputLayout.minWidth = 120;
inputLayout.minHeight = 25;
m_inputs[index] = inputField; m_inputs[index] = inputField;
inputField.onValueChanged.AddListener((string val) => { Value = StructInfo.SetValue(ref this.Value, index, float.Parse(val)); }); inputField.onValueChanged.AddListener((string val) => { Value = StructInfo.SetValue(ref this.Value, index, float.Parse(val)); });

View File

@ -10,8 +10,10 @@ using UnityExplorer.Core.Unity;
using UnityExplorer.Core.Runtime; using UnityExplorer.Core.Runtime;
using UnityExplorer.UI; using UnityExplorer.UI;
using UnityExplorer.UI.Utility; using UnityExplorer.UI.Utility;
using UnityExplorer.UI.CacheObject;
using UnityExplorer.UI.Main.Home;
namespace UnityExplorer.Core.Inspectors.Reflection namespace UnityExplorer.UI.InteractiveValues
{ {
public class InteractiveValue public class InteractiveValue
{ {
@ -302,69 +304,42 @@ namespace UnityExplorer.Core.Inspectors.Reflection
{ {
m_UIConstructed = true; m_UIConstructed = true;
m_valueContent = UIFactory.CreateHorizontalGroup(parent, new Color(1, 1, 1, 0)); m_valueContent = UIFactory.CreateHorizontalGroup(parent, $"InteractiveValue_{this.GetType().Name}", false, false, true, true, 4, default,
m_valueContent.name = "InteractiveValue.ValueContent"; new Color(1, 1, 1, 0), TextAnchor.UpperLeft);
var mainRect = m_valueContent.GetComponent<RectTransform>(); var mainRect = m_valueContent.GetComponent<RectTransform>();
mainRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 25); mainRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 25);
var mainGroup = m_valueContent.GetComponent<HorizontalLayoutGroup>();
mainGroup.childForceExpandWidth = false;
mainGroup.childControlWidth = true;
mainGroup.childForceExpandHeight = false;
mainGroup.childControlHeight = true;
mainGroup.spacing = 4;
mainGroup.childAlignment = TextAnchor.UpperLeft;
var mainLayout = m_valueContent.AddComponent<LayoutElement>();
mainLayout.flexibleWidth = 9000;
mainLayout.minWidth = 175;
mainLayout.minHeight = 25;
mainLayout.flexibleHeight = 0;
// subcontent expand button TODO UIFactory.SetLayoutElement(m_valueContent, flexibleWidth: 9000, minWidth: 175, minHeight: 25, flexibleHeight: 0);
// subcontent expand button
if (HasSubContent) if (HasSubContent)
{ {
var subBtnObj = UIFactory.CreateButton(m_valueContent, new Color(0.3f, 0.3f, 0.3f)); m_subExpandBtn = UIFactory.CreateButton(m_valueContent, "ExpandSubcontentButton", "▲", ToggleSubcontent, new Color(0.3f, 0.3f, 0.3f));
var btnLayout = subBtnObj.AddComponent<LayoutElement>(); UIFactory.SetLayoutElement(m_subExpandBtn.gameObject, minHeight: 25, minWidth: 25, flexibleWidth: 0, flexibleHeight: 0);
btnLayout.minHeight = 25;
btnLayout.minWidth = 25;
btnLayout.flexibleWidth = 0;
btnLayout.flexibleHeight = 0;
var btnText = subBtnObj.GetComponentInChildren<Text>();
btnText.text = "▲";
m_subExpandBtn = subBtnObj.GetComponent<Button>();
m_subExpandBtn.onClick.AddListener(() =>
{
ToggleSubcontent();
});
} }
// inspect button // inspect button
m_inspectButton = UIFactory.CreateButton(m_valueContent, new Color(0.3f, 0.3f, 0.3f, 0.2f)); var inspectBtn = UIFactory.CreateButton(m_valueContent,
var inspectLayout = m_inspectButton.AddComponent<LayoutElement>(); "InspectButton",
inspectLayout.minWidth = 60; "Inspect",
inspectLayout.minHeight = 25; () =>
inspectLayout.flexibleHeight = 0; {
inspectLayout.flexibleWidth = 0; if (!Value.IsNullOrDestroyed(false))
var inspectText = m_inspectButton.GetComponentInChildren<Text>(); InspectorManager.Instance.Inspect(this.Value, this.Owner);
inspectText.text = "Inspect"; },
var inspectBtn = m_inspectButton.GetComponent<Button>(); new Color(0.3f, 0.3f, 0.3f, 0.2f));
inspectBtn.onClick.AddListener(OnInspectClicked); m_inspectButton = inspectBtn.gameObject;
void OnInspectClicked() UIFactory.SetLayoutElement(m_inspectButton, minWidth: 60, minHeight: 25, flexibleWidth: 0, flexibleHeight: 0);
{
if (!Value.IsNullOrDestroyed(false))
InspectorManager.Instance.Inspect(this.Value, this.Owner);
}
m_inspectButton.SetActive(false); m_inspectButton.SetActive(false);
// value label // value label
var labelObj = UIFactory.CreateLabel(m_valueContent, TextAnchor.MiddleLeft); m_baseLabel = UIFactory.CreateLabel(m_valueContent, "ValueLabel", "<not set>", TextAnchor.MiddleLeft);
m_baseLabel = labelObj.GetComponent<Text>(); UIFactory.SetLayoutElement(m_baseLabel.gameObject, flexibleWidth: 9000, minHeight: 25);
var labelLayout = labelObj.AddComponent<LayoutElement>();
labelLayout.flexibleWidth = 9000;
labelLayout.minHeight = 25;
m_subContentParent = subGroup; m_subContentParent = subGroup;
} }

View File

@ -19,7 +19,6 @@ namespace UnityExplorer.UI.Main.CSConsole
private const int UPDATES_PER_BATCH = 100; private const int UPDATES_PER_BATCH = 100;
public static GameObject m_mainObj; public static GameObject m_mainObj;
//private static RectTransform m_thisRect;
private static readonly List<GameObject> m_suggestionButtons = new List<GameObject>(); private static readonly List<GameObject> m_suggestionButtons = new List<GameObject>();
private static readonly List<Text> m_suggestionTexts = new List<Text>(); private static readonly List<Text> m_suggestionTexts = new List<Text>();
@ -137,7 +136,7 @@ namespace UnityExplorer.UI.Main.CSConsole
if (!editor.InputField.isFocused) if (!editor.InputField.isFocused)
return; return;
var textGen = editor.InputText.cachedTextGenerator; var textGen = editor.InputText.cachedTextGenerator;
int caretPos = editor.m_lastCaretPos; int caretPos = editor.m_lastCaretPos;
@ -256,7 +255,7 @@ namespace UnityExplorer.UI.Main.CSConsole
{ {
var parent = UIManager.CanvasRoot; var parent = UIManager.CanvasRoot;
var obj = UIFactory.CreateScrollView(parent, out GameObject content, out _, new Color(0.1f, 0.1f, 0.1f, 0.95f)); var obj = UIFactory.CreateScrollView(parent, "AutoCompleterScrollView", out GameObject content, out _, new Color(0.1f, 0.1f, 0.1f, 0.95f));
m_mainObj = obj; m_mainObj = obj;
@ -269,43 +268,36 @@ namespace UnityExplorer.UI.Main.CSConsole
mainRect.offsetMax = Vector2.zero; mainRect.offsetMax = Vector2.zero;
var mainGroup = content.GetComponent<VerticalLayoutGroup>(); var mainGroup = content.GetComponent<VerticalLayoutGroup>();
mainGroup.childControlHeight = false; mainGroup.SetChildControlHeight(false);
mainGroup.childControlWidth = true; mainGroup.SetChildControlWidth(true);
mainGroup.childForceExpandHeight = false; mainGroup.childForceExpandHeight = false;
mainGroup.childForceExpandWidth = true; mainGroup.childForceExpandWidth = true;
ColorBlock btnColors = new ColorBlock();
btnColors.normalColor = new Color(0f, 0f, 0f, 0f);
btnColors.highlightedColor = new Color(0.2f, 0.2f, 0.2f, 1.0f);
for (int i = 0; i < MAX_LABELS; i++) for (int i = 0; i < MAX_LABELS; i++)
{ {
var buttonObj = UIFactory.CreateButton(content); var btn = UIFactory.CreateButton(content, "AutoCompleteButton", "", null, btnColors);
Button btn = buttonObj.GetComponent<Button>();
ColorBlock btnColors = btn.colors;
btnColors.normalColor = new Color(0f, 0f, 0f, 0f);
btnColors.highlightedColor = new Color(0.2f, 0.2f, 0.2f, 1.0f);
btn.colors = btnColors;
var nav = btn.navigation; var nav = btn.navigation;
nav.mode = Navigation.Mode.Vertical; nav.mode = Navigation.Mode.Vertical;
btn.navigation = nav; btn.navigation = nav;
var btnLayout = buttonObj.AddComponent<LayoutElement>(); UIFactory.SetLayoutElement(btn.gameObject, minHeight: 20);
btnLayout.minHeight = 20;
var text = btn.GetComponentInChildren<Text>(); var text = btn.GetComponentInChildren<Text>();
text.alignment = TextAnchor.MiddleLeft; text.alignment = TextAnchor.MiddleLeft;
text.color = Color.white; text.color = Color.white;
var hiddenChild = UIFactory.CreateUIObject("HiddenText", buttonObj); var hiddenChild = UIFactory.CreateUIObject("HiddenText", btn.gameObject);
hiddenChild.SetActive(false); hiddenChild.SetActive(false);
var hiddenText = hiddenChild.AddComponent<Text>(); var hiddenText = hiddenChild.AddComponent<Text>();
m_hiddenSuggestionTexts.Add(hiddenText); m_hiddenSuggestionTexts.Add(hiddenText);
btn.onClick.AddListener(UseAutocompleteButton); btn.onClick.AddListener(() => { CSharpConsole.Instance.UseAutocomplete(hiddenText.text); });
void UseAutocompleteButton() m_suggestionButtons.Add(btn.gameObject);
{
CSharpConsole.Instance.UseAutocomplete(hiddenText.text);
}
m_suggestionButtons.Add(buttonObj);
m_suggestionTexts.Add(text); m_suggestionTexts.Add(text);
} }
} }

View File

@ -40,24 +40,12 @@ namespace UnityExplorer.UI.Main.CSConsole
{ {
'[', ']', '(', ')', '{', '}', ';', ':', ',', '.' '[', ']', '(', ')', '{', '}', ';', ':', ',', '.'
}; };
public static CommentMatch commentMatcher = new CommentMatch(); public static CommentMatch commentMatcher = new CommentMatch();
public static SymbolMatch symbolMatcher = new SymbolMatch(); public static SymbolMatch symbolMatcher = new SymbolMatch();
public static NumberMatch numberMatcher = new NumberMatch(); public static NumberMatch numberMatcher = new NumberMatch();
public static StringMatch stringMatcher = new StringMatch(); public static StringMatch stringMatcher = new StringMatch();
public static KeywordMatch validKeywordMatcher = new KeywordMatch();
public static KeywordMatch validKeywordMatcher = new KeywordMatch
{
highlightColor = new Color(0.33f, 0.61f, 0.83f, 1.0f),
Keywords = new[] { "add", "as", "ascending", "await", "bool", "break", "by", "byte",
"case", "catch", "char", "checked", "const", "continue", "decimal", "default", "descending", "do", "dynamic",
"else", "equals", "false", "finally", "float", "for", "foreach", "from", "global", "goto", "group",
"if", "in", "int", "into", "is", "join", "let", "lock", "long", "new", "null", "object", "on", "orderby", "out",
"ref", "remove", "return", "sbyte", "select", "short", "sizeof", "stackalloc", "string",
"switch", "throw", "true", "try", "typeof", "uint", "ulong", "ushort", "var", "where", "while", "yield",
"abstract", "async", "base", "class", "delegate", "enum", "explicit", "extern", "fixed", "get",
"implicit", "interface", "internal", "namespace", "operator", "override", "params", "private", "protected", "public",
"using", "partial", "readonly", "sealed", "set", "static", "struct", "this", "unchecked", "unsafe", "value", "virtual", "volatile", "void"}
};
// ~~~~~~~ ctor ~~~~~~~ // ~~~~~~~ ctor ~~~~~~~

View File

@ -9,10 +9,10 @@ using UnityExplorer.Core.Input;
using UnityEngine; using UnityEngine;
using UnityEngine.EventSystems; using UnityEngine.EventSystems;
using UnityEngine.UI; using UnityEngine.UI;
using UnityExplorer.UI.Reusable;
using UnityExplorer.UI.Main.CSConsole; using UnityExplorer.UI.Main.CSConsole;
using UnityExplorer.Core; using UnityExplorer.Core;
using UnityExplorer.Core.Unity; using UnityExplorer.Core.Unity;
using UnityExplorer.UI.Utility;
#if CPP #if CPP
using UnityExplorer.Core.Runtime.Il2Cpp; using UnityExplorer.Core.Runtime.Il2Cpp;
#endif #endif
@ -361,7 +361,7 @@ The following helper methods are available:
string ret = ""; string ret = "";
foreach (LexerMatchInfo match in highlightLexer.GetMatches(inputText)) foreach (var match in highlightLexer.GetMatches(inputText))
{ {
for (int i = offset; i < match.startIndex; i++) for (int i = offset; i < match.startIndex; i++)
ret += inputText[i]; ret += inputText[i];
@ -456,101 +456,62 @@ The following helper methods are available:
public void ConstructUI() public void ConstructUI()
{ {
Content = UIFactory.CreateUIObject("C# Console", MainMenu.Instance.PageViewport); Content = UIFactory.CreateVerticalGroup(MainMenu.Instance.PageViewport, "CSharpConsole", true, true, true, true);
UIFactory.SetLayoutElement(Content, preferredHeight: 500, flexibleHeight: 9000);
var mainLayout = Content.AddComponent<LayoutElement>(); #region TOP BAR
mainLayout.preferredHeight = 500;
mainLayout.flexibleHeight = 9000;
var mainGroup = Content.AddComponent<VerticalLayoutGroup>();
mainGroup.childControlHeight = true;
mainGroup.childControlWidth = true;
mainGroup.childForceExpandHeight = true;
mainGroup.childForceExpandWidth = true;
#region TOP BAR
// Main group object // Main group object
var topBarObj = UIFactory.CreateHorizontalGroup(Content); var topBarObj = UIFactory.CreateHorizontalGroup(Content, "TopBar", true, true, true, true, 10, new Vector4(8, 8, 30, 30),
LayoutElement topBarLayout = topBarObj.AddComponent<LayoutElement>(); default, TextAnchor.LowerCenter);
topBarLayout.minHeight = 50; UIFactory.SetLayoutElement(topBarObj, minHeight: 50, flexibleHeight: 0);
topBarLayout.flexibleHeight = 0;
var topBarGroup = topBarObj.GetComponent<HorizontalLayoutGroup>(); // Top label
topBarGroup.padding.left = 30;
topBarGroup.padding.right = 30;
topBarGroup.padding.top = 8;
topBarGroup.padding.bottom = 8;
topBarGroup.spacing = 10;
topBarGroup.childForceExpandHeight = true;
topBarGroup.childForceExpandWidth = true;
topBarGroup.childControlWidth = true;
topBarGroup.childControlHeight = true;
topBarGroup.childAlignment = TextAnchor.LowerCenter;
var topBarLabel = UIFactory.CreateLabel(topBarObj, TextAnchor.MiddleLeft); var topBarLabel = UIFactory.CreateLabel(topBarObj, "TopLabel", "C# Console", TextAnchor.MiddleLeft, default, true, 25);
var topBarLabelLayout = topBarLabel.AddComponent<LayoutElement>(); UIFactory.SetLayoutElement(topBarLabel.gameObject, preferredWidth: 150, flexibleWidth: 5000);
topBarLabelLayout.preferredWidth = 150;
topBarLabelLayout.flexibleWidth = 5000;
var topBarText = topBarLabel.GetComponent<Text>();
topBarText.text = "C# Console";
topBarText.fontSize = 20;
// Enable Ctrl+R toggle // Enable Ctrl+R toggle
var ctrlRToggleObj = UIFactory.CreateToggle(topBarObj, out Toggle ctrlRToggle, out Text ctrlRToggleText); var ctrlRToggleObj = UIFactory.CreateToggle(topBarObj, "CtrlRToggle", out Toggle ctrlRToggle, out Text ctrlRToggleText);
ctrlRToggle.onValueChanged.AddListener(CtrlRToggleCallback); ctrlRToggle.onValueChanged.AddListener((bool val) => { EnableCtrlRShortcut = val; });
void CtrlRToggleCallback(bool val)
{
EnableCtrlRShortcut = val;
}
ctrlRToggleText.text = "Run on Ctrl+R"; ctrlRToggleText.text = "Run on Ctrl+R";
ctrlRToggleText.alignment = TextAnchor.UpperLeft; ctrlRToggleText.alignment = TextAnchor.UpperLeft;
var ctrlRLayout = ctrlRToggleObj.AddComponent<LayoutElement>(); UIFactory.SetLayoutElement(ctrlRToggleObj, minWidth: 140, flexibleWidth: 0, minHeight: 25);
ctrlRLayout.minWidth = 140;
ctrlRLayout.flexibleWidth = 0;
ctrlRLayout.minHeight = 25;
// Enable Suggestions toggle // Enable Suggestions toggle
var suggestToggleObj = UIFactory.CreateToggle(topBarObj, out Toggle suggestToggle, out Text suggestToggleText); var suggestToggleObj = UIFactory.CreateToggle(topBarObj, "SuggestionToggle", out Toggle suggestToggle, out Text suggestToggleText);
suggestToggle.onValueChanged.AddListener(SuggestToggleCallback); suggestToggle.onValueChanged.AddListener((bool val) =>
void SuggestToggleCallback(bool val)
{ {
EnableAutocompletes = val; EnableAutocompletes = val;
AutoCompleter.Update(); AutoCompleter.Update();
} });
suggestToggleText.text = "Suggestions"; suggestToggleText.text = "Suggestions";
suggestToggleText.alignment = TextAnchor.UpperLeft; suggestToggleText.alignment = TextAnchor.UpperLeft;
var suggestLayout = suggestToggleObj.AddComponent<LayoutElement>();
suggestLayout.minWidth = 120; UIFactory.SetLayoutElement(suggestToggleObj, minWidth: 120, flexibleWidth: 0, minHeight: 25);
suggestLayout.flexibleWidth = 0;
suggestLayout.minHeight = 25;
// Enable Auto-indent toggle // Enable Auto-indent toggle
var autoIndentToggleObj = UIFactory.CreateToggle(topBarObj, out Toggle autoIndentToggle, out Text autoIndentToggleText); var autoIndentToggleObj = UIFactory.CreateToggle(topBarObj, "IndentToggle", out Toggle autoIndentToggle, out Text autoIndentToggleText);
autoIndentToggle.onValueChanged.AddListener(OnIndentChanged); autoIndentToggle.onValueChanged.AddListener((bool val) => EnableAutoIndent = val);
void OnIndentChanged(bool val) => EnableAutoIndent = val;
autoIndentToggleText.text = "Auto-indent on Enter"; autoIndentToggleText.text = "Auto-indent on Enter";
autoIndentToggleText.alignment = TextAnchor.UpperLeft; autoIndentToggleText.alignment = TextAnchor.UpperLeft;
var autoIndentLayout = autoIndentToggleObj.AddComponent<LayoutElement>(); UIFactory.SetLayoutElement(autoIndentToggleObj, minWidth: 180, flexibleWidth: 0, minHeight: 25);
autoIndentLayout.minWidth = 180;
autoIndentLayout.flexibleWidth = 0;
autoIndentLayout.minHeight = 25;
#endregion #endregion
#region CONSOLE INPUT #region CONSOLE INPUT
int fontSize = 16; int fontSize = 16;
var inputObj = UIFactory.CreateSrollInputField(Content, out InputFieldScroller consoleScroll, fontSize); var inputObj = UIFactory.CreateSrollInputField(Content, "ConsoleInput", STARTUP_TEXT, out InputFieldScroller consoleScroll, fontSize);
var inputField = consoleScroll.inputField; var inputField = consoleScroll.inputField;
@ -560,7 +521,6 @@ The following helper methods are available:
mainTextInput.color = new Color(1, 1, 1, 0.5f); mainTextInput.color = new Color(1, 1, 1, 0.5f);
var placeHolderText = inputField.placeholder.GetComponent<Text>(); var placeHolderText = inputField.placeholder.GetComponent<Text>();
placeHolderText.text = STARTUP_TEXT;
placeHolderText.fontSize = fontSize; placeHolderText.fontSize = fontSize;
var highlightTextObj = UIFactory.CreateUIObject("HighlightText", mainTextObj.gameObject); var highlightTextObj = UIFactory.CreateUIObject("HighlightText", mainTextObj.gameObject);
@ -579,58 +539,26 @@ The following helper methods are available:
#region COMPILE BUTTON BAR #region COMPILE BUTTON BAR
var horozGroupObj = UIFactory.CreateHorizontalGroup(Content, new Color(1, 1, 1, 0)); var horozGroupObj = UIFactory.CreateHorizontalGroup(Content, "BigButtons", true, true, true, true, 0, new Vector4(2,2,2,2),
var horozGroup = horozGroupObj.GetComponent<HorizontalLayoutGroup>(); new Color(1, 1, 1, 0));
horozGroup.padding.left = 2;
horozGroup.padding.top = 2;
horozGroup.padding.right = 2;
horozGroup.padding.bottom = 2;
var resetBtnObj = UIFactory.CreateButton(horozGroupObj); var resetButton = UIFactory.CreateButton(horozGroupObj, "ResetButton", "Reset", () => ResetConsole(), "666666".ToColor());
var resetBtnLayout = resetBtnObj.AddComponent<LayoutElement>(); var resetBtnText = resetButton.GetComponentInChildren<Text>();
resetBtnLayout.preferredWidth = 80;
resetBtnLayout.flexibleWidth = 0;
resetBtnLayout.minHeight = 45;
resetBtnLayout.flexibleHeight = 0;
var resetButton = resetBtnObj.GetComponent<Button>();
var resetBtnColors = resetButton.colors;
resetBtnColors.normalColor = "666666".ToColor();
resetButton.colors = resetBtnColors;
var resetBtnText = resetBtnObj.GetComponentInChildren<Text>();
resetBtnText.text = "Reset";
resetBtnText.fontSize = 18; resetBtnText.fontSize = 18;
resetBtnText.color = Color.white; UIFactory.SetLayoutElement(resetButton.gameObject, preferredWidth: 80, flexibleWidth: 0, minHeight: 45, flexibleHeight: 0);
// Set compile button callback now that we have the Input Field reference var compileButton = UIFactory.CreateButton(horozGroupObj, "CompileButton", "Compile", CompileCallback,
resetButton.onClick.AddListener(ResetCallback); new Color(14f / 255f, 80f / 255f, 14f / 255f));
void ResetCallback() var btnText = compileButton.GetComponentInChildren<Text>();
{
ResetConsole();
}
var compileBtnObj = UIFactory.CreateButton(horozGroupObj);
var compileBtnLayout = compileBtnObj.AddComponent<LayoutElement>();
compileBtnLayout.preferredWidth = 80;
compileBtnLayout.flexibleWidth = 0;
compileBtnLayout.minHeight = 45;
compileBtnLayout.flexibleHeight = 0;
var compileButton = compileBtnObj.GetComponent<Button>();
var compileBtnColors = compileButton.colors;
compileBtnColors.normalColor = new Color(14f / 255f, 80f / 255f, 14f / 255f);
compileButton.colors = compileBtnColors;
var btnText = compileBtnObj.GetComponentInChildren<Text>();
btnText.text = "Run";
btnText.fontSize = 18; btnText.fontSize = 18;
btnText.color = Color.white; UIFactory.SetLayoutElement(compileButton.gameObject, preferredWidth: 80, flexibleWidth: 0, minHeight: 45, flexibleHeight: 0);
// Set compile button callback now that we have the Input Field reference
compileButton.onClick.AddListener(CompileCallback);
void CompileCallback() void CompileCallback()
{ {
if (!string.IsNullOrEmpty(inputField.text)) if (!string.IsNullOrEmpty(inputField.text))
{
Evaluate(inputField.text.Trim()); Evaluate(inputField.text.Trim());
} else
ExplorerCore.Log("Cannot evaluate empty input!");
} }
#endregion #endregion

View File

@ -7,10 +7,18 @@ namespace UnityExplorer.UI.Main.CSConsole.Lexer
// This class just contains common implementations. // This class just contains common implementations.
public class KeywordMatch : Matcher public class KeywordMatch : Matcher
{ {
public string[] Keywords; public string[] Keywords = new[] {"add", "as", "ascending", "await", "bool", "break", "by", "byte",
"case", "catch", "char", "checked", "const", "continue", "decimal", "default", "descending", "do", "dynamic",
"else", "equals", "false", "finally", "float", "for", "foreach", "from", "global", "goto", "group",
"if", "in", "int", "into", "is", "join", "let", "lock", "long", "new", "null", "object", "on", "orderby", "out",
"ref", "remove", "return", "sbyte", "select", "short", "sizeof", "stackalloc", "string",
"switch", "throw", "true", "try", "typeof", "uint", "ulong", "ushort", "var", "where", "while", "yield",
"abstract", "async", "base", "class", "delegate", "enum", "explicit", "extern", "fixed", "get",
"implicit", "interface", "internal", "namespace", "operator", "override", "params", "private", "protected", "public",
"using", "partial", "readonly", "sealed", "set", "static", "struct", "this", "unchecked", "unsafe", "value", "virtual", "volatile", "void" };
public override Color HighlightColor => highlightColor; public override Color HighlightColor => highlightColor;
public Color highlightColor; public Color highlightColor = new Color(0.33f, 0.61f, 0.83f, 1.0f);
private readonly HashSet<string> shortlist = new HashSet<string>(); private readonly HashSet<string> shortlist = new HashSet<string>();
private readonly Stack<string> removeList = new Stack<string>(); private readonly Stack<string> removeList = new Stack<string>();

View File

@ -3,10 +3,10 @@ using System.Collections.Generic;
using UnityEngine; using UnityEngine;
using UnityEngine.UI; using UnityEngine.UI;
using UnityExplorer.Core.Config; using UnityExplorer.Core.Config;
using UnityExplorer.UI.Reusable;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using UnityExplorer.Core.Unity; using UnityExplorer.Core.Unity;
using UnityExplorer.UI.Utility;
namespace UnityExplorer.UI.Main namespace UnityExplorer.UI.Main
{ {
@ -14,7 +14,7 @@ namespace UnityExplorer.UI.Main
{ {
public static DebugConsole Instance { get; private set; } public static DebugConsole Instance { get; private set; }
public static bool LogUnity { get; set; } = ExplorerConfig.Instance.Log_Unity_Debug; public static bool LogUnity { get; set; }
//public static bool SaveToDisk { get; set; } = ModConfig.Instance.Save_Logs_To_Disk; //public static bool SaveToDisk { get; set; } = ModConfig.Instance.Save_Logs_To_Disk;
internal static StreamWriter s_streamWriter; internal static StreamWriter s_streamWriter;
@ -32,9 +32,13 @@ namespace UnityExplorer.UI.Main
public DebugConsole(GameObject parent) public DebugConsole(GameObject parent)
{ {
Instance = this; Instance = this;
LogUnity = ConfigManager.Log_Unity_Debug.Value;
ConstructUI(parent); ConstructUI(parent);
if (!ConfigManager.Last_DebugConsole_State.Value)
ToggleShow();
// append messages that logged before we were set up // append messages that logged before we were set up
string preAppend = ""; string preAppend = "";
for (int i = s_preInitMessages.Count - 1; i >= 0; i--) for (int i = s_preInitMessages.Count - 1; i >= 0; i--)
@ -48,10 +52,7 @@ namespace UnityExplorer.UI.Main
// set up IO // set up IO
//if (!SaveToDisk) var path = Path.Combine(ExplorerCore.Loader.ExplorerFolder, "Logs");
// return;
var path = ExplorerCore.EXPLORER_FOLDER + @"\Logs";
if (!Directory.Exists(path)) if (!Directory.Exists(path))
Directory.CreateDirectory(path); Directory.CreateDirectory(path);
@ -80,6 +81,34 @@ namespace UnityExplorer.UI.Main
s_streamWriter.WriteLine(msg); s_streamWriter.WriteLine(msg);
} }
public static bool Hiding;
private GameObject m_logAreaObj;
private Text m_hideBtnText;
private LayoutElement m_mainLayout;
public static Action<bool> OnToggleShow;
public void ToggleShow()
{
if (m_logAreaObj.activeSelf)
{
Hiding = true;
m_logAreaObj.SetActive(false);
m_hideBtnText.text = "Show";
m_mainLayout.minHeight = 30;
}
else
{
Hiding = false;
m_logAreaObj.SetActive(true);
m_hideBtnText.text = "Hide";
m_mainLayout.minHeight = 190;
}
OnToggleShow?.Invoke(!Hiding);
}
public static string RemoveInvalidFilenameChars(string s) public static string RemoveInvalidFilenameChars(string s)
{ {
var invalid = Path.GetInvalidFileNameChars(); var invalid = Path.GetInvalidFileNameChars();
@ -109,7 +138,7 @@ namespace UnityExplorer.UI.Main
if (hexColor != null) if (hexColor != null)
message = $"<color=#{hexColor}>{message}</color>"; message = $"<color=#{hexColor}>{message}</color>";
if (Instance?.m_textInput) if (Instance?.m_textInput)
{ {
var input = Instance.m_textInput; var input = Instance.m_textInput;
@ -126,184 +155,82 @@ namespace UnityExplorer.UI.Main
public void ConstructUI(GameObject parent) public void ConstructUI(GameObject parent)
{ {
var mainObj = UIFactory.CreateVerticalGroup(parent, new Color(0.1f, 0.1f, 0.1f, 1.0f)); var mainObj = UIFactory.CreateVerticalGroup(parent, "DebugConsole", true, true, true, true, 0, default, new Color(0.1f, 0.1f, 0.1f, 1.0f));
var mainGroup = mainObj.GetComponent<VerticalLayoutGroup>();
mainGroup.childControlHeight = true;
mainGroup.childControlWidth = true;
mainGroup.childForceExpandHeight = true;
mainGroup.childForceExpandWidth = true;
var mainImage = mainObj.GetComponent<Image>(); var mainImage = mainObj.GetComponent<Image>();
mainImage.maskable = true; mainImage.maskable = true;
var mask = mainObj.AddComponent<Mask>(); var mask = mainObj.AddComponent<Mask>();
mask.showMaskGraphic = true; mask.showMaskGraphic = true;
var mainLayout = mainObj.AddComponent<LayoutElement>(); m_mainLayout = mainObj.AddComponent<LayoutElement>();
mainLayout.minHeight = 190; m_mainLayout.minHeight = 190;
mainLayout.flexibleHeight = 0; m_mainLayout.flexibleHeight = 0;
#region LOG AREA #region LOG AREA
var logAreaObj = UIFactory.CreateHorizontalGroup(mainObj); m_logAreaObj = UIFactory.CreateHorizontalGroup(mainObj, "LogArea", true, true, true, true);
var logAreaGroup = logAreaObj.GetComponent<HorizontalLayoutGroup>(); UIFactory.SetLayoutElement(m_logAreaObj, preferredHeight: 190, flexibleHeight: 0);
logAreaGroup.childControlHeight = true;
logAreaGroup.childControlWidth = true;
logAreaGroup.childForceExpandHeight = true;
logAreaGroup.childForceExpandWidth = true;
var logAreaLayout = logAreaObj.AddComponent<LayoutElement>(); var inputScrollerObj = UIFactory.CreateSrollInputField(m_logAreaObj,
logAreaLayout.preferredHeight = 190; "DebugConsoleOutput",
logAreaLayout.flexibleHeight = 0; "<no output>",
out InputFieldScroller inputScroll,
var inputScrollerObj = UIFactory.CreateSrollInputField(logAreaObj, out InputFieldScroller inputScroll, 14, new Color(0.05f, 0.05f, 0.05f)); 14,
new Color(0.05f, 0.05f, 0.05f));
inputScroll.inputField.textComponent.font = UIManager.ConsoleFont; inputScroll.inputField.textComponent.font = UIManager.ConsoleFont;
inputScroll.inputField.readOnly = true; inputScroll.inputField.readOnly = true;
m_textInput = inputScroll.inputField; m_textInput = inputScroll.inputField;
#endregion #endregion
#region BOTTOM BAR #region BOTTOM BAR
var bottomBarObj = UIFactory.CreateHorizontalGroup(mainObj); var bottomBarObj = UIFactory.CreateHorizontalGroup(mainObj, "BottomBar", false, true, true, true, 10, new Vector4(2,2,10,10),
LayoutElement topBarLayout = bottomBarObj.AddComponent<LayoutElement>(); default, TextAnchor.MiddleLeft);
topBarLayout.minHeight = 30; UIFactory.SetLayoutElement(bottomBarObj, minHeight: 30, flexibleHeight: 0);
topBarLayout.flexibleHeight = 0;
var bottomGroup = bottomBarObj.GetComponent<HorizontalLayoutGroup>();
bottomGroup.padding.left = 10;
bottomGroup.padding.right = 10;
bottomGroup.padding.top = 2;
bottomGroup.padding.bottom = 2;
bottomGroup.spacing = 10;
bottomGroup.childForceExpandHeight = true;
bottomGroup.childForceExpandWidth = false;
bottomGroup.childControlWidth = true;
bottomGroup.childControlHeight = true;
bottomGroup.childAlignment = TextAnchor.MiddleLeft;
// Debug Console label // Debug Console label
var bottomLabel = UIFactory.CreateLabel(bottomBarObj, TextAnchor.MiddleLeft); var bottomLabel = UIFactory.CreateLabel(bottomBarObj, "DebugConsoleLabel", "Debug Console", TextAnchor.MiddleLeft);
var topBarLabelLayout = bottomLabel.AddComponent<LayoutElement>(); bottomLabel.fontStyle = FontStyle.Bold;
topBarLabelLayout.minWidth = 100; UIFactory.SetLayoutElement(bottomLabel.gameObject, minWidth: 100, flexibleWidth: 0);
topBarLabelLayout.flexibleWidth = 0;
var topBarText = bottomLabel.GetComponent<Text>();
topBarText.fontStyle = FontStyle.Bold;
topBarText.text = "Debug Console";
topBarText.fontSize = 14;
// Hide button // Hide button
var hideButtonObj = UIFactory.CreateButton(bottomBarObj); var hideButton = UIFactory.CreateButton(bottomBarObj, "HideButton", "Hide", ToggleShow);
UIFactory.SetLayoutElement(hideButton.gameObject, minWidth: 80, flexibleWidth: 0);
var hideBtnText = hideButtonObj.GetComponentInChildren<Text>(); m_hideBtnText = hideButton.GetComponentInChildren<Text>();
hideBtnText.text = "Hide";
var hideButton = hideButtonObj.GetComponent<Button>();
hideButton.onClick.AddListener(HideCallback);
void HideCallback()
{
if (logAreaObj.activeSelf)
{
logAreaObj.SetActive(false);
hideBtnText.text = "Show";
mainLayout.minHeight = 30;
}
else
{
logAreaObj.SetActive(true);
hideBtnText.text = "Hide";
mainLayout.minHeight = 190;
}
}
var hideBtnColors = hideButton.colors;
//hideBtnColors.normalColor = new Color(160f / 255f, 140f / 255f, 40f / 255f);
hideButton.colors = hideBtnColors;
var hideBtnLayout = hideButtonObj.AddComponent<LayoutElement>();
hideBtnLayout.minWidth = 80;
hideBtnLayout.flexibleWidth = 0;
// Clear button // Clear button
var clearButtonObj = UIFactory.CreateButton(bottomBarObj); var clearButton = UIFactory.CreateButton(bottomBarObj, "ClearButton", "Clear", () =>
var clearBtnText = clearButtonObj.GetComponentInChildren<Text>();
clearBtnText.text = "Clear";
var clearButton = clearButtonObj.GetComponent<Button>();
clearButton.onClick.AddListener(ClearCallback);
void ClearCallback()
{ {
m_textInput.text = ""; m_textInput.text = "";
AllMessages.Clear(); AllMessages.Clear();
} });
UIFactory.SetLayoutElement(clearButton.gameObject, minWidth: 80, flexibleWidth: 0);
var clearBtnColors = clearButton.colors;
//clearBtnColors.normalColor = new Color(160f/255f, 140f/255f, 40f/255f);
clearButton.colors = clearBtnColors;
var clearBtnLayout = clearButtonObj.AddComponent<LayoutElement>();
clearBtnLayout.minWidth = 80;
clearBtnLayout.flexibleWidth = 0;
// Unity log toggle // Unity log toggle
var unityToggleObj = UIFactory.CreateToggle(bottomBarObj, out Toggle unityToggle, out Text unityToggleText); var unityToggleObj = UIFactory.CreateToggle(bottomBarObj, "UnityLogToggle", out Toggle unityToggle, out Text unityToggleText);
unityToggle.onValueChanged.AddListener(ToggleLogUnity); unityToggle.onValueChanged.AddListener((bool val) =>
{
LogUnity = val;
ConfigManager.Log_Unity_Debug.Value = val;
ConfigManager.Handler.SaveConfig();
});
unityToggle.isOn = LogUnity; unityToggle.isOn = LogUnity;
unityToggleText.text = "Print Unity Debug?"; unityToggleText.text = "Print Unity Debug?";
unityToggleText.alignment = TextAnchor.MiddleLeft; unityToggleText.alignment = TextAnchor.MiddleLeft;
void ToggleLogUnity(bool val) UIFactory.SetLayoutElement(unityToggleObj, minWidth: 170, flexibleWidth: 0);
{
LogUnity = val;
ExplorerConfig.Instance.Log_Unity_Debug = val;
ExplorerConfig.SaveSettings();
}
var unityToggleLayout = unityToggleObj.AddComponent<LayoutElement>();
unityToggleLayout.minWidth = 170;
unityToggleLayout.flexibleWidth = 0;
var unityToggleRect = unityToggleObj.transform.Find("Background").GetComponent<RectTransform>(); var unityToggleRect = unityToggleObj.transform.Find("Background").GetComponent<RectTransform>();
var pos = unityToggleRect.localPosition; var pos = unityToggleRect.localPosition;
pos.y = -4; pos.y = -4;
unityToggleRect.localPosition = pos; unityToggleRect.localPosition = pos;
// // Save to disk button
// var saveToDiskObj = UIFactory.CreateToggle(bottomBarObj, out Toggle diskToggle, out Text diskToggleText);
// diskToggle.onValueChanged.AddListener(ToggleDisk);
// diskToggle.isOn = SaveToDisk;
// diskToggleText.text = "Save logs to 'Mods\\UnityExplorer\\Logs'?";
// diskToggleText.alignment = TextAnchor.MiddleLeft;
// void ToggleDisk(bool val)
// {
// SaveToDisk = val;
// ModConfig.Instance.Save_Logs_To_Disk = val;
// ModConfig.SaveSettings();
// }
// var diskToggleLayout = saveToDiskObj.AddComponent<LayoutElement>();
// diskToggleLayout.minWidth = 340;
// diskToggleLayout.flexibleWidth = 0;
// var saveToDiskRect = saveToDiskObj.transform.Find("Background").GetComponent<RectTransform>();
// pos = unityToggleRect.localPosition;
// pos.y = -8;
// saveToDiskRect.localPosition = pos;
#endregion #endregion
} }
} }

View File

@ -3,9 +3,8 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using UnityEngine; using UnityEngine;
using UnityEngine.UI; using UnityEngine.UI;
using UnityExplorer.Core.Inspectors;
namespace UnityExplorer.UI.Main namespace UnityExplorer.UI.Main.Home
{ {
public class HomePage : BaseMenuPage public class HomePage : BaseMenuPage
{ {
@ -38,17 +37,7 @@ namespace UnityExplorer.UI.Main
{ {
GameObject parent = MainMenu.Instance.PageViewport; GameObject parent = MainMenu.Instance.PageViewport;
Content = UIFactory.CreateHorizontalGroup(parent); Content = UIFactory.CreateHorizontalGroup(parent, "HomePage", true, true, true, true, 3, new Vector4(1,1,1,1)).gameObject;
var mainGroup = Content.GetComponent<HorizontalLayoutGroup>();
mainGroup.padding.left = 1;
mainGroup.padding.right = 1;
mainGroup.padding.top = 1;
mainGroup.padding.bottom = 1;
mainGroup.spacing = 3;
mainGroup.childForceExpandHeight = true;
mainGroup.childForceExpandWidth = true;
mainGroup.childControlHeight = true;
mainGroup.childControlWidth = true;
} }
} }
} }

View File

@ -11,9 +11,8 @@ using UnityExplorer.Core.Input;
using UnityExplorer.Core.Runtime; using UnityExplorer.Core.Runtime;
using UnityExplorer.UI; using UnityExplorer.UI;
using UnityExplorer.UI.Main; using UnityExplorer.UI.Main;
using UnityExplorer.UI.Main.Home.Inspectors;
namespace UnityExplorer.Core.Inspectors namespace UnityExplorer.UI.Main.Home
{ {
public class InspectUnderMouse public class InspectUnderMouse
{ {
@ -23,50 +22,53 @@ namespace UnityExplorer.Core.Inspectors
UI UI
} }
public static bool Enabled { get; set; } public static bool Inspecting { get; set; }
public static MouseInspectMode Mode { get; set; } public static MouseInspectMode Mode { get; set; }
private static GameObject s_lastHit; private static GameObject s_lastHit;
private static Vector3 s_lastMousePos; private static Vector3 s_lastMousePos;
internal static MouseInspectorUI UI;
static InspectUnderMouse()
{
UI = new MouseInspectorUI();
}
private static readonly List<Graphic> _wasDisabledGraphics = new List<Graphic>(); private static readonly List<Graphic> _wasDisabledGraphics = new List<Graphic>();
private static readonly List<CanvasGroup> _wasDisabledCanvasGroups = new List<CanvasGroup>(); private static readonly List<CanvasGroup> _wasDisabledCanvasGroups = new List<CanvasGroup>();
private static readonly List<GameObject> _objectsAddedCastersTo = new List<GameObject>(); private static readonly List<GameObject> _objectsAddedCastersTo = new List<GameObject>();
internal static Camera MainCamera;
internal static GraphicRaycaster[] graphicRaycasters;
public static void Init()
{
ConstructUI();
}
public static void StartInspect(MouseInspectMode mode) public static void StartInspect(MouseInspectMode mode)
{ {
MainCamera = Camera.main;
if (!MainCamera)
return;
Mode = mode; Mode = mode;
Enabled = true; Inspecting = true;
MainMenu.Instance.MainPanel.SetActive(false); MainMenu.Instance.MainPanel.SetActive(false);
UI.s_UIContent.SetActive(true); s_UIContent.SetActive(true);
if (mode == MouseInspectMode.UI) if (mode == MouseInspectMode.UI)
{
SetupUIRaycast(); SetupUIRaycast();
}
} }
internal static void ClearHitData() internal static void ClearHitData()
{ {
s_lastHit = null; s_lastHit = null;
UI.s_objNameLabel.text = "No hits..."; s_objNameLabel.text = "No hits...";
UI.s_objPathLabel.text = ""; s_objPathLabel.text = "";
} }
public static void StopInspect() public static void StopInspect()
{ {
Enabled = false; Inspecting = false;
MainMenu.Instance.MainPanel.SetActive(true); MainMenu.Instance.MainPanel.SetActive(true);
UI.s_UIContent.SetActive(false); s_UIContent.SetActive(false);
if (Mode == MouseInspectMode.UI) if (Mode == MouseInspectMode.UI)
StopUIInspect(); StopUIInspect();
@ -74,8 +76,6 @@ namespace UnityExplorer.Core.Inspectors
ClearHitData(); ClearHitData();
} }
internal static GraphicRaycaster[] m_gCasters;
public static void UpdateInspect() public static void UpdateInspect()
{ {
if (InputManager.GetKeyDown(KeyCode.Escape)) if (InputManager.GetKeyDown(KeyCode.Escape))
@ -89,9 +89,6 @@ namespace UnityExplorer.Core.Inspectors
if (mousePos != s_lastMousePos) if (mousePos != s_lastMousePos)
UpdatePosition(mousePos); UpdatePosition(mousePos);
if (!UnityHelper.MainCamera)
return;
// actual inspect raycast // actual inspect raycast
switch (Mode) switch (Mode)
@ -109,10 +106,10 @@ namespace UnityExplorer.Core.Inspectors
var inversePos = UIManager.CanvasRoot.transform.InverseTransformPoint(mousePos); var inversePos = UIManager.CanvasRoot.transform.InverseTransformPoint(mousePos);
UI.s_mousePosLabel.text = $"<color=grey>Mouse Position:</color> {mousePos.ToString()}"; s_mousePosLabel.text = $"<color=grey>Mouse Position:</color> {mousePos.ToString()}";
float yFix = mousePos.y < 120 ? 80 : -80; float yFix = mousePos.y < 120 ? 80 : -80;
UI.s_UIContent.transform.localPosition = new Vector3(inversePos.x, inversePos.y + yFix, 0); s_UIContent.transform.localPosition = new Vector3(inversePos.x, inversePos.y + yFix, 0);
} }
internal static void OnHitGameObject(GameObject obj) internal static void OnHitGameObject(GameObject obj)
@ -120,8 +117,8 @@ namespace UnityExplorer.Core.Inspectors
if (obj != s_lastHit) if (obj != s_lastHit)
{ {
s_lastHit = obj; s_lastHit = obj;
UI.s_objNameLabel.text = $"<b>Click to Inspect:</b> <color=cyan>{obj.name}</color>"; s_objNameLabel.text = $"<b>Click to Inspect:</b> <color=cyan>{obj.name}</color>";
UI.s_objPathLabel.text = $"Path: {obj.transform.GetTransformPath(true)}"; s_objPathLabel.text = $"Path: {obj.transform.GetTransformPath(true)}";
} }
if (InputManager.GetMouseButtonDown(0)) if (InputManager.GetMouseButtonDown(0))
@ -135,7 +132,7 @@ namespace UnityExplorer.Core.Inspectors
internal static void RaycastWorld(Vector2 mousePos) internal static void RaycastWorld(Vector2 mousePos)
{ {
var ray = UnityHelper.MainCamera.ScreenPointToRay(mousePos); var ray = MainCamera.ScreenPointToRay(mousePos);
Physics.Raycast(ray, out RaycastHit hit, 1000f); Physics.Raycast(ray, out RaycastHit hit, 1000f);
if (hit.transform) if (hit.transform)
@ -169,10 +166,10 @@ namespace UnityExplorer.Core.Inspectors
// recache Graphic Raycasters each time we start // recache Graphic Raycasters each time we start
var casters = RuntimeProvider.Instance.FindObjectsOfTypeAll(typeof(GraphicRaycaster)); var casters = RuntimeProvider.Instance.FindObjectsOfTypeAll(typeof(GraphicRaycaster));
m_gCasters = new GraphicRaycaster[casters.Length]; graphicRaycasters = new GraphicRaycaster[casters.Length];
for (int i = 0; i < casters.Length; i++) for (int i = 0; i < casters.Length; i++)
{ {
m_gCasters[i] = casters[i].Cast(typeof(GraphicRaycaster)) as GraphicRaycaster; graphicRaycasters[i] = casters[i].Cast(typeof(GraphicRaycaster)) as GraphicRaycaster;
} }
// enable raycastTarget on Graphics // enable raycastTarget on Graphics
@ -215,7 +212,7 @@ namespace UnityExplorer.Core.Inspectors
int highestLayer = int.MinValue; int highestLayer = int.MinValue;
int highestOrder = int.MinValue; int highestOrder = int.MinValue;
int highestDepth = int.MinValue; int highestDepth = int.MinValue;
foreach (var gr in m_gCasters) foreach (var gr in graphicRaycasters)
{ {
gr.Raycast(ped, list); gr.Raycast(ped, list);
@ -223,6 +220,9 @@ namespace UnityExplorer.Core.Inspectors
{ {
foreach (var hit in list) foreach (var hit in list)
{ {
// Manual trying to determine which object is "on top".
// Not perfect, but not terrible.
if (!hit.gameObject) if (!hit.gameObject)
continue; continue;
@ -232,15 +232,13 @@ namespace UnityExplorer.Core.Inspectors
if (hit.gameObject.GetComponent<Graphic>() is Graphic graphic && graphic.color.a == 0f) if (hit.gameObject.GetComponent<Graphic>() is Graphic graphic && graphic.color.a == 0f)
continue; continue;
//ExplorerCore.Log("Hit: " + hit.gameObject.name + ", depth: " + hit.depth + ", layer: " + hit.sortingLayer + ", order: " + hit.sortingOrder);
if (hit.sortingLayer < highestLayer) if (hit.sortingLayer < highestLayer)
continue; continue;
if (hit.sortingLayer > highestLayer) if (hit.sortingLayer > highestLayer)
{ {
highestLayer = hit.sortingLayer; highestLayer = hit.sortingLayer;
highestOrder = int.MinValue; highestDepth = int.MinValue;
} }
if (hit.depth < highestDepth) if (hit.depth < highestDepth)
@ -290,5 +288,46 @@ namespace UnityExplorer.Core.Inspectors
_wasDisabledCanvasGroups.Clear(); _wasDisabledCanvasGroups.Clear();
_wasDisabledGraphics.Clear(); _wasDisabledGraphics.Clear();
} }
#region UI
internal static Text s_objNameLabel;
internal static Text s_objPathLabel;
internal static Text s_mousePosLabel;
internal static GameObject s_UIContent;
internal static void ConstructUI()
{
s_UIContent = UIFactory.CreatePanel("InspectUnderMouse_UI", out GameObject content);
var baseRect = s_UIContent.GetComponent<RectTransform>();
var half = new Vector2(0.5f, 0.5f);
baseRect.anchorMin = half;
baseRect.anchorMax = half;
baseRect.pivot = half;
baseRect.sizeDelta = new Vector2(700, 150);
var group = content.GetComponent<VerticalLayoutGroup>();
group.childForceExpandHeight = true;
// Title text
UIFactory.CreateLabel(content, "InspectLabel", "<b>Mouse Inspector</b> (press <b>ESC</b> to cancel)", TextAnchor.MiddleCenter);
s_mousePosLabel = UIFactory.CreateLabel(content, "MousePosLabel", "Mouse Position:", TextAnchor.MiddleCenter);
s_objNameLabel = UIFactory.CreateLabel(content, "HitLabelObj", "No hits...", TextAnchor.MiddleLeft);
s_objNameLabel.horizontalOverflow = HorizontalWrapMode.Overflow;
s_objPathLabel = UIFactory.CreateLabel(content, "PathLabel", "", TextAnchor.MiddleLeft);
s_objPathLabel.fontStyle = FontStyle.Italic;
s_objPathLabel.horizontalOverflow = HorizontalWrapMode.Wrap;
UIFactory.SetLayoutElement(s_objPathLabel.gameObject, minHeight: 75);
s_UIContent.SetActive(false);
}
#endregion
} }
} }

View File

@ -0,0 +1,222 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UnityExplorer.Core.Unity;
using UnityExplorer.UI;
using UnityExplorer.UI.Main;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using UnityExplorer.Core.Runtime;
using UnityExplorer.UI.Main.Home;
using UnityExplorer.UI.Main.Home.Inspectors;
using UnityExplorer.UI.CacheObject;
using UnityExplorer.UI.Main.Home.Inspectors.GameObjects;
using UnityExplorer.UI.Main.Home.Inspectors.Reflection;
namespace UnityExplorer.UI.Main.Home
{
public class InspectorManager
{
public static InspectorManager Instance { get; private set; }
public InspectorManager()
{
Instance = this;
ConstructInspectorPane();
}
public InspectorBase m_activeInspector;
public readonly List<InspectorBase> m_currentInspectors = new List<InspectorBase>();
public void Update()
{
for (int i = 0; i < m_currentInspectors.Count; i++)
{
if (i >= m_currentInspectors.Count)
break;
m_currentInspectors[i].Update();
}
}
public void Inspect(object obj, CacheObjectBase parentMember = null)
{
obj = ReflectionProvider.Instance.Cast(obj, ReflectionProvider.Instance.GetActualType(obj));
UnityEngine.Object unityObj = obj as UnityEngine.Object;
if (obj.IsNullOrDestroyed(false))
{
return;
}
// check if currently inspecting this object
foreach (InspectorBase tab in m_currentInspectors)
{
if (ReferenceEquals(obj, tab.Target))
{
SetInspectorTab(tab);
return;
}
#if CPP
else if (unityObj && tab.Target is UnityEngine.Object uTabObj)
{
if (unityObj.m_CachedPtr == uTabObj.m_CachedPtr)
{
SetInspectorTab(tab);
return;
}
}
#endif
}
InspectorBase inspector;
if (obj is GameObject go)
inspector = new GameObjectInspector(go);
else
inspector = new InstanceInspector(obj);
if (inspector is ReflectionInspector ri)
ri.ParentMember = parentMember;
m_currentInspectors.Add(inspector);
SetInspectorTab(inspector);
}
public void Inspect(Type type)
{
if (type == null)
{
ExplorerCore.LogWarning("The provided type was null!");
return;
}
foreach (var tab in m_currentInspectors.Where(x => x is StaticInspector))
{
if (ReferenceEquals(tab.Target as Type, type))
{
SetInspectorTab(tab);
return;
}
}
var inspector = new StaticInspector(type);
m_currentInspectors.Add(inspector);
SetInspectorTab(inspector);
}
public void SetInspectorTab(InspectorBase inspector)
{
MainMenu.Instance.SetPage(HomePage.Instance);
if (m_activeInspector == inspector)
return;
UnsetInspectorTab();
m_activeInspector = inspector;
inspector.SetActive();
OnSetInspectorTab(inspector);
}
public void UnsetInspectorTab()
{
if (m_activeInspector == null)
return;
m_activeInspector.SetInactive();
OnUnsetInspectorTab();
m_activeInspector = null;
}
public static GameObject m_tabBarContent;
public static GameObject m_inspectorContent;
public void OnSetInspectorTab(InspectorBase inspector)
{
Color activeColor = new Color(0, 0.25f, 0, 1);
ColorBlock colors = inspector.m_tabButton.colors;
colors.normalColor = activeColor;
colors.highlightedColor = activeColor;
inspector.m_tabButton.colors = colors;
}
public void OnUnsetInspectorTab()
{
ColorBlock colors = m_activeInspector.m_tabButton.colors;
colors.normalColor = new Color(0.2f, 0.2f, 0.2f, 1);
colors.highlightedColor = new Color(0.1f, 0.3f, 0.1f, 1);
m_activeInspector.m_tabButton.colors = colors;
}
public void ConstructInspectorPane()
{
var mainObj = UIFactory.CreateVerticalGroup(HomePage.Instance.Content,
"InspectorManager_Root",
true, true, true, true,
4,
new Vector4(4,4,4,4));
UIFactory.SetLayoutElement(mainObj, preferredHeight: 400, flexibleHeight: 9000, preferredWidth: 620, flexibleWidth: 9000);
var topRowObj = UIFactory.CreateHorizontalGroup(mainObj, "TopRow", false, true, true, true, 15);
var inspectorTitle = UIFactory.CreateLabel(topRowObj, "Title", "Inspector", TextAnchor.MiddleLeft, default, true, 25);
UIFactory.SetLayoutElement(inspectorTitle.gameObject, minHeight: 30, flexibleHeight: 0, minWidth: 90, flexibleWidth: 20000);
ConstructToolbar(topRowObj);
// inspector tab bar
m_tabBarContent = UIFactory.CreateGridGroup(mainObj, "TabHolder", new Vector2(185, 20), new Vector2(5, 2), new Color(0.1f, 0.1f, 0.1f, 1));
var gridGroup = m_tabBarContent.GetComponent<GridLayoutGroup>();
gridGroup.padding.top = 3;
gridGroup.padding.left = 3;
gridGroup.padding.right = 3;
gridGroup.padding.bottom = 3;
// inspector content area
m_inspectorContent = UIFactory.CreateVerticalGroup(mainObj, "InspectorContent",
true, true, true, true,
0,
new Vector4(2,2,2,2),
new Color(0.1f, 0.1f, 0.1f));
UIFactory.SetLayoutElement(m_inspectorContent, preferredHeight: 900, flexibleHeight: 10000, preferredWidth: 600, flexibleWidth: 10000);
}
private static void ConstructToolbar(GameObject topRowObj)
{
// invisible group
UIFactory.CreateHorizontalGroup(topRowObj, "Toolbar", false, false, true, true, 10, new Vector4(2, 2, 2, 2), new Color(1,1,1,0));
// inspect under mouse button
AddMouseInspectButton(topRowObj, InspectUnderMouse.MouseInspectMode.UI);
AddMouseInspectButton(topRowObj, InspectUnderMouse.MouseInspectMode.World);
}
private static void AddMouseInspectButton(GameObject topRowObj, InspectUnderMouse.MouseInspectMode mode)
{
string lbl = "Mouse Inspect";
if (mode == InspectUnderMouse.MouseInspectMode.UI)
lbl += " (UI)";
var inspectObj = UIFactory.CreateButton(topRowObj,
lbl,
lbl,
() => { InspectUnderMouse.StartInspect(mode); },
new Color(0.2f, 0.2f, 0.2f));
UIFactory.SetLayoutElement(inspectObj.gameObject, minWidth: 120, flexibleWidth: 0);
}
}
}

View File

@ -1,158 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.Core.Inspectors;
using UnityExplorer.UI.Main;
namespace UnityExplorer.UI.Main.Home
{
public class InspectorManagerUI
{
public GameObject m_tabBarContent;
public GameObject m_inspectorContent;
public void OnSetInspectorTab(InspectorBase inspector)
{
Color activeColor = new Color(0, 0.25f, 0, 1);
ColorBlock colors = inspector.BaseUI.tabButton.colors;
colors.normalColor = activeColor;
colors.highlightedColor = activeColor;
inspector.BaseUI.tabButton.colors = colors;
}
public void OnUnsetInspectorTab()
{
ColorBlock colors = InspectorManager.Instance.m_activeInspector.BaseUI.tabButton.colors;
colors.normalColor = new Color(0.2f, 0.2f, 0.2f, 1);
colors.highlightedColor = new Color(0.1f, 0.3f, 0.1f, 1);
InspectorManager.Instance.m_activeInspector.BaseUI.tabButton.colors = colors;
}
public void ConstructInspectorPane()
{
var mainObj = UIFactory.CreateVerticalGroup(HomePage.Instance.Content, new Color(72f / 255f, 72f / 255f, 72f / 255f));
LayoutElement mainLayout = mainObj.AddComponent<LayoutElement>();
mainLayout.preferredHeight = 400;
mainLayout.flexibleHeight = 9000;
mainLayout.preferredWidth = 620;
mainLayout.flexibleWidth = 9000;
var mainGroup = mainObj.GetComponent<VerticalLayoutGroup>();
mainGroup.childForceExpandHeight = true;
mainGroup.childForceExpandWidth = true;
mainGroup.childControlHeight = true;
mainGroup.childControlWidth = true;
mainGroup.spacing = 4;
mainGroup.padding.left = 4;
mainGroup.padding.right = 4;
mainGroup.padding.top = 4;
mainGroup.padding.bottom = 4;
var topRowObj = UIFactory.CreateHorizontalGroup(mainObj, new Color(1, 1, 1, 0));
var topRowGroup = topRowObj.GetComponent<HorizontalLayoutGroup>();
topRowGroup.childForceExpandWidth = false;
topRowGroup.childControlWidth = true;
topRowGroup.childForceExpandHeight = true;
topRowGroup.childControlHeight = true;
topRowGroup.spacing = 15;
var inspectorTitle = UIFactory.CreateLabel(topRowObj, TextAnchor.MiddleLeft);
Text title = inspectorTitle.GetComponent<Text>();
title.text = "Inspector";
title.fontSize = 20;
var titleLayout = inspectorTitle.AddComponent<LayoutElement>();
titleLayout.minHeight = 30;
titleLayout.flexibleHeight = 0;
titleLayout.minWidth = 90;
titleLayout.flexibleWidth = 20000;
ConstructToolbar(topRowObj);
// inspector tab bar
m_tabBarContent = UIFactory.CreateGridGroup(mainObj, new Vector2(185, 20), new Vector2(5, 2), new Color(0.1f, 0.1f, 0.1f, 1));
var gridGroup = m_tabBarContent.GetComponent<GridLayoutGroup>();
gridGroup.padding.top = 3;
gridGroup.padding.left = 3;
gridGroup.padding.right = 3;
gridGroup.padding.bottom = 3;
// inspector content area
m_inspectorContent = UIFactory.CreateVerticalGroup(mainObj, new Color(0.1f, 0.1f, 0.1f));
var inspectorGroup = m_inspectorContent.GetComponent<VerticalLayoutGroup>();
inspectorGroup.childForceExpandHeight = true;
inspectorGroup.childForceExpandWidth = true;
inspectorGroup.childControlHeight = true;
inspectorGroup.childControlWidth = true;
m_inspectorContent = UIFactory.CreateVerticalGroup(mainObj, new Color(0.1f, 0.1f, 0.1f));
var contentGroup = m_inspectorContent.GetComponent<VerticalLayoutGroup>();
contentGroup.childForceExpandHeight = true;
contentGroup.childForceExpandWidth = true;
contentGroup.childControlHeight = true;
contentGroup.childControlWidth = true;
contentGroup.padding.top = 2;
contentGroup.padding.left = 2;
contentGroup.padding.right = 2;
contentGroup.padding.bottom = 2;
var contentLayout = m_inspectorContent.AddComponent<LayoutElement>();
contentLayout.preferredHeight = 900;
contentLayout.flexibleHeight = 10000;
contentLayout.preferredWidth = 600;
contentLayout.flexibleWidth = 10000;
}
private static void ConstructToolbar(GameObject topRowObj)
{
var invisObj = UIFactory.CreateHorizontalGroup(topRowObj, new Color(1, 1, 1, 0));
var invisGroup = invisObj.GetComponent<HorizontalLayoutGroup>();
invisGroup.childForceExpandWidth = false;
invisGroup.childForceExpandHeight = false;
invisGroup.childControlWidth = true;
invisGroup.childControlHeight = true;
invisGroup.padding.top = 2;
invisGroup.padding.bottom = 2;
invisGroup.padding.left = 2;
invisGroup.padding.right = 2;
invisGroup.spacing = 10;
// inspect under mouse button
AddMouseInspectButton(topRowObj, InspectUnderMouse.MouseInspectMode.UI);
AddMouseInspectButton(topRowObj, InspectUnderMouse.MouseInspectMode.World);
}
private static void AddMouseInspectButton(GameObject topRowObj, InspectUnderMouse.MouseInspectMode mode)
{
var inspectObj = UIFactory.CreateButton(topRowObj);
var inspectLayout = inspectObj.AddComponent<LayoutElement>();
inspectLayout.minWidth = 120;
inspectLayout.flexibleWidth = 0;
var inspectText = inspectObj.GetComponentInChildren<Text>();
inspectText.text = "Mouse Inspect";
inspectText.fontSize = 13;
if (mode == InspectUnderMouse.MouseInspectMode.UI)
inspectText.text += " (UI)";
var inspectBtn = inspectObj.GetComponent<Button>();
var inspectColors = inspectBtn.colors;
inspectColors.normalColor = new Color(0.2f, 0.2f, 0.2f);
inspectBtn.colors = inspectColors;
inspectBtn.onClick.AddListener(OnInspectMouseClicked);
void OnInspectMouseClicked()
{
InspectUnderMouse.StartInspect(mode);
}
}
}
}

View File

@ -1,15 +1,12 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using UnityExplorer.Core.Unity; using System.Text;
using UnityExplorer.UI;
using UnityExplorer.UI.Reusable;
using UnityEngine; using UnityEngine;
using UnityEngine.UI; using UnityEngine.UI;
using UnityExplorer.Core.Input; using UnityExplorer.UI.Utility;
using UnityExplorer.Core.Inspectors;
namespace UnityExplorer.UI.Main.Home.Inspectors namespace UnityExplorer.UI.Main.Home.Inspectors.GameObjects
{ {
public class ChildList public class ChildList
{ {
@ -139,29 +136,15 @@ namespace UnityExplorer.UI.Main.Home.Inspectors
internal void ConstructChildList(GameObject parent) internal void ConstructChildList(GameObject parent)
{ {
var vertGroupObj = UIFactory.CreateVerticalGroup(parent, new Color(1, 1, 1, 0)); var vertGroupObj = UIFactory.CreateVerticalGroup(parent, "ChildListGroup", false, true, true, true, 5, default, new Color(1, 1, 1, 0));
var vertGroup = vertGroupObj.GetComponent<VerticalLayoutGroup>(); UIFactory.SetLayoutElement(vertGroupObj, minWidth: 120, flexibleWidth: 25000, minHeight: 200, flexibleHeight: 5000);
vertGroup.childForceExpandHeight = true;
vertGroup.childForceExpandWidth = false;
vertGroup.childControlWidth = true;
vertGroup.spacing = 5;
var vertLayout = vertGroupObj.AddComponent<LayoutElement>();
vertLayout.minWidth = 120;
vertLayout.flexibleWidth = 25000;
vertLayout.minHeight = 200;
vertLayout.flexibleHeight = 5000;
var childTitleObj = UIFactory.CreateLabel(vertGroupObj, TextAnchor.MiddleLeft); var childTitle = UIFactory.CreateLabel(vertGroupObj, "ChildListTitle", "Children:", TextAnchor.MiddleLeft, Color.grey, true, 14);
var childTitleText = childTitleObj.GetComponent<Text>(); UIFactory.SetLayoutElement(childTitle.gameObject, minHeight: 30);
childTitleText.text = "Children";
childTitleText.color = Color.grey;
childTitleText.fontSize = 14;
var childTitleLayout = childTitleObj.AddComponent<LayoutElement>();
childTitleLayout.minHeight = 30;
var childrenScrollObj = UIFactory.CreateScrollView(vertGroupObj, out s_childListContent, out SliderScrollbar scroller, new Color(0.07f, 0.07f, 0.07f)); var childrenScrollObj = UIFactory.CreateScrollView(vertGroupObj, "ChildListScrollView", out s_childListContent,
var contentLayout = childrenScrollObj.GetComponent<LayoutElement>(); out SliderScrollbar scroller, new Color(0.07f, 0.07f, 0.07f));
contentLayout.minHeight = 50; UIFactory.SetLayoutElement(childrenScrollObj, minHeight: 50);
s_childListPageHandler = new PageHandler(scroller); s_childListPageHandler = new PageHandler(scroller);
s_childListPageHandler.ConstructUI(vertGroupObj); s_childListPageHandler.ConstructUI(vertGroupObj);
@ -172,46 +155,38 @@ namespace UnityExplorer.UI.Main.Home.Inspectors
{ {
int thisIndex = s_childListTexts.Count; int thisIndex = s_childListTexts.Count;
GameObject btnGroupObj = UIFactory.CreateHorizontalGroup(s_childListContent, new Color(0.07f, 0.07f, 0.07f)); var btnGroupObj = UIFactory.CreateHorizontalGroup(s_childListContent, "ChildButtonGroup", true, false, true, true,
HorizontalLayoutGroup btnGroup = btnGroupObj.GetComponent<HorizontalLayoutGroup>(); 0, default, new Color(0.07f, 0.07f, 0.07f));
btnGroup.childForceExpandWidth = true; UIFactory.SetLayoutElement(btnGroupObj, flexibleWidth: 320, minHeight: 25, flexibleHeight: 0);
btnGroup.childControlWidth = true;
btnGroup.childForceExpandHeight = false;
btnGroup.childControlHeight = true;
LayoutElement btnLayout = btnGroupObj.AddComponent<LayoutElement>();
btnLayout.flexibleWidth = 320;
btnLayout.minHeight = 25;
btnLayout.flexibleHeight = 0;
btnGroupObj.AddComponent<Mask>(); btnGroupObj.AddComponent<Mask>();
var toggleObj = UIFactory.CreateToggle(btnGroupObj, out Toggle toggle, out Text toggleText, new Color(0.3f, 0.3f, 0.3f)); var toggleObj = UIFactory.CreateToggle(btnGroupObj, "Toggle", out Toggle toggle, out Text toggleText, new Color(0.3f, 0.3f, 0.3f));
var toggleLayout = toggleObj.AddComponent<LayoutElement>(); UIFactory.SetLayoutElement(toggleObj, minHeight: 25, minWidth: 25);
toggleLayout.minHeight = 25;
toggleLayout.minWidth = 25;
toggleText.text = ""; toggleText.text = "";
toggle.isOn = false; toggle.isOn = false;
s_childListToggles.Add(toggle); s_childListToggles.Add(toggle);
toggle.onValueChanged.AddListener((bool val) => { OnToggleClicked(thisIndex, val); }); toggle.onValueChanged.AddListener((bool val) => { OnToggleClicked(thisIndex, val); });
GameObject mainButtonObj = UIFactory.CreateButton(btnGroupObj); ColorBlock mainColors = new ColorBlock();
LayoutElement mainBtnLayout = mainButtonObj.AddComponent<LayoutElement>();
mainBtnLayout.minHeight = 25;
mainBtnLayout.flexibleHeight = 0;
mainBtnLayout.minWidth = 25;
mainBtnLayout.flexibleWidth = 999;
Button mainBtn = mainButtonObj.GetComponent<Button>();
ColorBlock mainColors = mainBtn.colors;
mainColors.normalColor = new Color(0.07f, 0.07f, 0.07f); mainColors.normalColor = new Color(0.07f, 0.07f, 0.07f);
mainColors.highlightedColor = new Color(0.2f, 0.2f, 0.2f, 1); mainColors.highlightedColor = new Color(0.2f, 0.2f, 0.2f, 1);
mainBtn.colors = mainColors; mainColors.pressedColor = new Color(0.05f, 0.05f, 0.05f);
mainBtn.onClick.AddListener(() => { OnChildListObjectClicked(thisIndex); });
Text mainText = mainButtonObj.GetComponentInChildren<Text>(); var mainBtn = UIFactory.CreateButton(btnGroupObj,
"MainButton",
"<notset>",
() => { OnChildListObjectClicked(thisIndex); },
mainColors);
UIFactory.SetLayoutElement(mainBtn.gameObject, minHeight: 25, flexibleHeight: 0, minWidth: 25, flexibleWidth: 9999);
Text mainText = mainBtn.GetComponentInChildren<Text>();
mainText.alignment = TextAnchor.MiddleLeft; mainText.alignment = TextAnchor.MiddleLeft;
mainText.horizontalOverflow = HorizontalWrapMode.Overflow; mainText.horizontalOverflow = HorizontalWrapMode.Overflow;
mainText.resizeTextForBestFit = true; mainText.resizeTextForBestFit = true;
mainText.resizeTextMaxSize = 14; mainText.resizeTextMaxSize = 14;
mainText.resizeTextMinSize = 10; mainText.resizeTextMinSize = 10;
s_childListTexts.Add(mainText); s_childListTexts.Add(mainText);
} }

View File

@ -1,16 +1,13 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using UnityExplorer.UI; using System.Text;
using UnityExplorer.UI.Reusable;
using UnityEngine; using UnityEngine;
using UnityEngine.UI; using UnityEngine.UI;
using UnityExplorer.Core.Input;
using UnityExplorer.Core; using UnityExplorer.Core;
using UnityExplorer.UI.Utility; using UnityExplorer.UI.Utility;
using UnityExplorer.Core.Inspectors;
namespace UnityExplorer.UI.Main.Home.Inspectors namespace UnityExplorer.UI.Main.Home.Inspectors.GameObjects
{ {
public class ComponentList public class ComponentList
{ {
@ -137,34 +134,20 @@ namespace UnityExplorer.UI.Main.Home.Inspectors
} }
#region UI CONSTRUCTION #region UI CONSTRUCTION
internal void ConstructCompList(GameObject parent) internal void ConstructCompList(GameObject parent)
{ {
var vertGroupObj = UIFactory.CreateVerticalGroup(parent, new Color(1, 1, 1, 0)); var vertGroupObj = UIFactory.CreateVerticalGroup(parent, "ComponentList", false, true, true, true, 5, default, new Color(1, 1, 1, 0));
var vertGroup = vertGroupObj.GetComponent<VerticalLayoutGroup>(); UIFactory.SetLayoutElement(vertGroupObj, minWidth: 120, flexibleWidth: 25000, minHeight: 200, flexibleHeight: 5000);
vertGroup.childForceExpandHeight = true;
vertGroup.childForceExpandWidth = false;
vertGroup.childControlWidth = true;
vertGroup.spacing = 5;
var vertLayout = vertGroupObj.AddComponent<LayoutElement>();
vertLayout.minWidth = 120;
vertLayout.flexibleWidth = 25000;
vertLayout.minHeight = 200;
vertLayout.flexibleHeight = 5000;
var compTitleObj = UIFactory.CreateLabel(vertGroupObj, TextAnchor.MiddleLeft); var compTitle = UIFactory.CreateLabel(vertGroupObj, "ComponentsTitle", "Components:", TextAnchor.MiddleLeft, Color.grey);
var compTitleText = compTitleObj.GetComponent<Text>(); UIFactory.SetLayoutElement(compTitle.gameObject, minHeight: 30);
compTitleText.text = "Components";
compTitleText.color = Color.grey;
compTitleText.fontSize = 14;
var childTitleLayout = compTitleObj.AddComponent<LayoutElement>();
childTitleLayout.minHeight = 30;
var compScrollObj = UIFactory.CreateScrollView(vertGroupObj, out s_compListContent, out SliderScrollbar scroller, new Color(0.07f, 0.07f, 0.07f)); var compScrollObj = UIFactory.CreateScrollView(vertGroupObj, "ComponentListScrollView", out s_compListContent,
var contentLayout = compScrollObj.AddComponent<LayoutElement>(); out SliderScrollbar scroller, new Color(0.07f, 0.07f, 0.07f));
contentLayout.minHeight = 50;
contentLayout.flexibleHeight = 5000; UIFactory.SetLayoutElement(compScrollObj, minHeight: 50, flexibleHeight: 5000);
s_compListPageHandler = new PageHandler(scroller); s_compListPageHandler = new PageHandler(scroller);
s_compListPageHandler.ConstructUI(vertGroupObj); s_compListPageHandler.ConstructUI(vertGroupObj);
@ -175,26 +158,15 @@ namespace UnityExplorer.UI.Main.Home.Inspectors
{ {
int thisIndex = s_compListTexts.Count; int thisIndex = s_compListTexts.Count;
GameObject groupObj = UIFactory.CreateHorizontalGroup(s_compListContent, new Color(0.07f, 0.07f, 0.07f)); GameObject groupObj = UIFactory.CreateHorizontalGroup(s_compListContent, "CompListButton", true, false, true, true, 0, default,
HorizontalLayoutGroup group = groupObj.GetComponent<HorizontalLayoutGroup>(); new Color(0.07f, 0.07f, 0.07f), TextAnchor.MiddleLeft);
group.childForceExpandWidth = true; UIFactory.SetLayoutElement(groupObj, minWidth: 25, flexibleWidth: 999, minHeight: 25, flexibleHeight: 0);
group.childControlWidth = true;
group.childForceExpandHeight = false;
group.childControlHeight = true;
group.childAlignment = TextAnchor.MiddleLeft;
LayoutElement groupLayout = groupObj.AddComponent<LayoutElement>();
groupLayout.minWidth = 25;
groupLayout.flexibleWidth = 999;
groupLayout.minHeight = 25;
groupLayout.flexibleHeight = 0;
groupObj.AddComponent<Mask>(); groupObj.AddComponent<Mask>();
// Behaviour enabled toggle // Behaviour enabled toggle
var toggleObj = UIFactory.CreateToggle(groupObj, out Toggle toggle, out Text toggleText, new Color(0.3f, 0.3f, 0.3f)); var toggleObj = UIFactory.CreateToggle(groupObj, "EnabledToggle", out Toggle toggle, out Text toggleText, new Color(0.3f, 0.3f, 0.3f));
var toggleLayout = toggleObj.AddComponent<LayoutElement>(); UIFactory.SetLayoutElement(toggleObj, minWidth: 25, minHeight: 25);
toggleLayout.minHeight = 25;
toggleLayout.minWidth = 25;
toggleText.text = ""; toggleText.text = "";
toggle.isOn = true; toggle.isOn = true;
s_compToggles.Add(toggle); s_compToggles.Add(toggle);
@ -202,35 +174,31 @@ namespace UnityExplorer.UI.Main.Home.Inspectors
// Main component button // Main component button
GameObject mainButtonObj = UIFactory.CreateButton(groupObj); ColorBlock mainColors = new ColorBlock();
LayoutElement mainBtnLayout = mainButtonObj.AddComponent<LayoutElement>();
mainBtnLayout.minHeight = 25;
mainBtnLayout.flexibleHeight = 0;
mainBtnLayout.minWidth = 25;
mainBtnLayout.flexibleWidth = 999;
Button mainBtn = mainButtonObj.GetComponent<Button>();
ColorBlock mainColors = mainBtn.colors;
mainColors.normalColor = new Color(0.07f, 0.07f, 0.07f); mainColors.normalColor = new Color(0.07f, 0.07f, 0.07f);
mainColors.highlightedColor = new Color(0.2f, 0.2f, 0.2f, 1); mainColors.highlightedColor = new Color(0.2f, 0.2f, 0.2f, 1);
mainBtn.colors = mainColors; mainColors.pressedColor = new Color(0.05f, 0.05f, 0.05f);
mainBtn.onClick.AddListener(() => { OnCompListObjectClicked(thisIndex); });
var mainBtn = UIFactory.CreateButton(groupObj,
"MainButton",
"<notset>",
() => { OnCompListObjectClicked(thisIndex); },
mainColors);
UIFactory.SetLayoutElement(mainBtn.gameObject, minHeight: 25, flexibleHeight: 0, minWidth: 25, flexibleWidth: 999);
// Component button text // Component button text
Text mainText = mainButtonObj.GetComponentInChildren<Text>(); Text mainText = mainBtn.GetComponentInChildren<Text>();
mainText.alignment = TextAnchor.MiddleLeft; mainText.alignment = TextAnchor.MiddleLeft;
mainText.horizontalOverflow = HorizontalWrapMode.Overflow; mainText.horizontalOverflow = HorizontalWrapMode.Overflow;
//mainText.color = SyntaxColors.Class_Instance.ToColor();
mainText.resizeTextForBestFit = true; mainText.resizeTextForBestFit = true;
mainText.resizeTextMaxSize = 14; mainText.resizeTextMaxSize = 14;
mainText.resizeTextMinSize = 8; mainText.resizeTextMinSize = 8;
s_compListTexts.Add(mainText); s_compListTexts.Add(mainText);
// TODO remove component button
} }
#endregion
#endregion
} }
} }

View File

@ -1,14 +1,13 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using UnityExplorer.UI; using System.Text;
using UnityEngine; using UnityEngine;
using UnityEngine.UI; using UnityEngine.UI;
using UnityExplorer.Core.Input; using UnityExplorer.Core.Input;
using UnityExplorer.Core.Unity; using UnityExplorer.Core.Unity;
using UnityExplorer.Core.Inspectors;
namespace UnityExplorer.UI.Main.Home.Inspectors namespace UnityExplorer.UI.Main.Home.Inspectors.GameObjects
{ {
public class GameObjectControls public class GameObjectControls
{ {
@ -19,6 +18,24 @@ namespace UnityExplorer.UI.Main.Home.Inspectors
Instance = this; Instance = this;
} }
internal static bool Showing;
internal static void ToggleVisibility() => SetVisibility(!Showing);
internal static void SetVisibility(bool show)
{
if (show == Showing)
return;
Showing = show;
m_hideShowLabel.text = show ? "Hide" : "Show";
m_contentObj.SetActive(show);
}
internal static GameObject m_contentObj;
internal static Text m_hideShowLabel;
private static InputField s_setParentInput; private static InputField s_setParentInput;
private static ControlEditor s_positionControl; private static ControlEditor s_positionControl;
@ -59,22 +76,22 @@ namespace UnityExplorer.UI.Main.Home.Inspectors
{ {
var go = GameObjectInspector.ActiveInstance.TargetGO; var go = GameObjectInspector.ActiveInstance.TargetGO;
s_positionControl.fullValue.text = go.transform.position.ToStringLong(); s_positionControl.fullValue.text = go.transform.position.ToStringPretty();
s_positionControl.values[0].text = go.transform.position.x.ToString("F3"); s_positionControl.values[0].text = go.transform.position.x.ToString("F3");
s_positionControl.values[1].text = go.transform.position.y.ToString("F3"); s_positionControl.values[1].text = go.transform.position.y.ToString("F3");
s_positionControl.values[2].text = go.transform.position.z.ToString("F3"); s_positionControl.values[2].text = go.transform.position.z.ToString("F3");
s_localPosControl.fullValue.text = go.transform.localPosition.ToStringLong(); s_localPosControl.fullValue.text = go.transform.localPosition.ToStringPretty();
s_localPosControl.values[0].text = go.transform.localPosition.x.ToString("F3"); s_localPosControl.values[0].text = go.transform.localPosition.x.ToString("F3");
s_localPosControl.values[1].text = go.transform.localPosition.y.ToString("F3"); s_localPosControl.values[1].text = go.transform.localPosition.y.ToString("F3");
s_localPosControl.values[2].text = go.transform.localPosition.z.ToString("F3"); s_localPosControl.values[2].text = go.transform.localPosition.z.ToString("F3");
s_rotationControl.fullValue.text = go.transform.eulerAngles.ToStringLong(); s_rotationControl.fullValue.text = go.transform.eulerAngles.ToStringPretty();
s_rotationControl.values[0].text = go.transform.eulerAngles.x.ToString("F3"); s_rotationControl.values[0].text = go.transform.eulerAngles.x.ToString("F3");
s_rotationControl.values[1].text = go.transform.eulerAngles.y.ToString("F3"); s_rotationControl.values[1].text = go.transform.eulerAngles.y.ToString("F3");
s_rotationControl.values[2].text = go.transform.eulerAngles.z.ToString("F3"); s_rotationControl.values[2].text = go.transform.eulerAngles.z.ToString("F3");
s_scaleControl.fullValue.text = go.transform.localScale.ToStringLong(); s_scaleControl.fullValue.text = go.transform.localScale.ToStringPretty();
s_scaleControl.values[0].text = go.transform.localScale.x.ToString("F3"); s_scaleControl.values[0].text = go.transform.localScale.x.ToString("F3");
s_scaleControl.values[1].text = go.transform.localScale.y.ToString("F3"); s_scaleControl.values[1].text = go.transform.localScale.y.ToString("F3");
s_scaleControl.values[2].text = go.transform.localScale.z.ToString("F3"); s_scaleControl.values[2].text = go.transform.localScale.z.ToString("F3");
@ -244,184 +261,79 @@ namespace UnityExplorer.UI.Main.Home.Inspectors
internal void ConstructControls(GameObject parent) internal void ConstructControls(GameObject parent)
{ {
var controlsObj = UIFactory.CreateVerticalGroup(parent, new Color(0.07f, 0.07f, 0.07f)); var mainGroup = UIFactory.CreateVerticalGroup(parent, "ControlsGroup", false, false, true, true, 5, new Vector4(4,4,4,4),
var controlsGroup = controlsObj.GetComponent<VerticalLayoutGroup>(); new Color(0.07f, 0.07f, 0.07f));
controlsGroup.childForceExpandWidth = false;
controlsGroup.childControlWidth = true;
controlsGroup.childForceExpandHeight = false;
controlsGroup.spacing = 5;
controlsGroup.padding.top = 4;
controlsGroup.padding.left = 4;
controlsGroup.padding.right = 4;
controlsGroup.padding.bottom = 4;
// ~~~~~~ Top row ~~~~~~ // ~~~~~~ Top row ~~~~~~
var topRow = UIFactory.CreateHorizontalGroup(controlsObj, new Color(1, 1, 1, 0)); var topRow = UIFactory.CreateHorizontalGroup(mainGroup, "TopRow", false, false, true, true, 5, default, new Color(1, 1, 1, 0));
var topRowGroup = topRow.GetComponent<HorizontalLayoutGroup>();
topRowGroup.childForceExpandWidth = false;
topRowGroup.childControlWidth = true;
topRowGroup.childForceExpandHeight = false;
topRowGroup.childControlHeight = true;
topRowGroup.spacing = 5;
var hideButtonObj = UIFactory.CreateButton(topRow); var hideButton = UIFactory.CreateButton(topRow, "ToggleShowButton", "Show", ToggleVisibility, new Color(0.16f, 0.16f, 0.16f));
var hideButton = hideButtonObj.GetComponent<Button>(); UIFactory.SetLayoutElement(hideButton.gameObject, minWidth: 40, flexibleWidth: 0, minHeight: 25, flexibleHeight: 0);
var hideColors = hideButton.colors; m_hideShowLabel = hideButton.GetComponentInChildren<Text>();
hideColors.normalColor = new Color(0.16f, 0.16f, 0.16f);
hideButton.colors = hideColors;
var hideText = hideButtonObj.GetComponentInChildren<Text>();
hideText.text = "Show";
hideText.fontSize = 14;
var hideButtonLayout = hideButtonObj.AddComponent<LayoutElement>();
hideButtonLayout.minWidth = 40;
hideButtonLayout.flexibleWidth = 0;
hideButtonLayout.minHeight = 25;
hideButtonLayout.flexibleHeight = 0;
var topTitle = UIFactory.CreateLabel(topRow, TextAnchor.MiddleLeft); var topTitle = UIFactory.CreateLabel(topRow, "ControlsLabel", "Controls", TextAnchor.MiddleLeft);
var topText = topTitle.GetComponent<Text>(); UIFactory.SetLayoutElement(topTitle.gameObject, minWidth: 100, flexibleWidth: 9500, minHeight: 25);
topText.text = "Controls";
var titleLayout = topTitle.AddComponent<LayoutElement>();
titleLayout.minWidth = 100;
titleLayout.flexibleWidth = 9500;
titleLayout.minHeight = 25;
//// ~~~~~~~~ Content ~~~~~~~~ // //// ~~~~~~~~ Content ~~~~~~~~ //
var contentObj = UIFactory.CreateVerticalGroup(controlsObj, new Color(1, 1, 1, 0)); m_contentObj = UIFactory.CreateVerticalGroup(mainGroup, "ContentGroup", true, false, true, true, 5, default, new Color(1, 1, 1, 0));
var contentGroup = contentObj.GetComponent<VerticalLayoutGroup>();
contentGroup.childForceExpandHeight = false;
contentGroup.childControlHeight = true;
contentGroup.spacing = 5;
contentGroup.childForceExpandWidth = true;
contentGroup.childControlWidth = true;
// ~~ add hide button callback now that we have scroll reference ~~
hideButton.onClick.AddListener(OnHideClicked);
void OnHideClicked()
{
if (hideText.text == "Show")
{
hideText.text = "Hide";
contentObj.SetActive(true);
}
else
{
hideText.text = "Show";
contentObj.SetActive(false);
}
}
// transform controls // transform controls
ConstructVector3Editor(contentObj, "Position", ControlType.position, out s_positionControl); ConstructVector3Editor(m_contentObj, "Position", ControlType.position, out s_positionControl);
ConstructVector3Editor(contentObj, "Local Position", ControlType.localPosition, out s_localPosControl); ConstructVector3Editor(m_contentObj, "Local Position", ControlType.localPosition, out s_localPosControl);
ConstructVector3Editor(contentObj, "Rotation", ControlType.eulerAngles, out s_rotationControl); ConstructVector3Editor(m_contentObj, "Rotation", ControlType.eulerAngles, out s_rotationControl);
ConstructVector3Editor(contentObj, "Scale", ControlType.localScale, out s_scaleControl); ConstructVector3Editor(m_contentObj, "Scale", ControlType.localScale, out s_scaleControl);
// set parent // set parent
ConstructSetParent(contentObj); ConstructSetParent(m_contentObj);
// bottom row buttons // bottom row buttons
ConstructBottomButtons(contentObj); ConstructBottomButtons(m_contentObj);
// set controls content inactive now that content is made (otherwise TMP font size goes way too big?) // set controls content inactive now that content is made (otherwise TMP font size goes way too big?)
contentObj.SetActive(false); m_contentObj.SetActive(false);
} }
internal void ConstructSetParent(GameObject contentObj) internal void ConstructSetParent(GameObject contentObj)
{ {
var setParentGroupObj = UIFactory.CreateHorizontalGroup(contentObj, new Color(1, 1, 1, 0)); var setParentGroupObj = UIFactory.CreateHorizontalGroup(contentObj, "SetParentRow", false, false, true, true, 5, default,
var setParentGroup = setParentGroupObj.GetComponent<HorizontalLayoutGroup>(); new Color(1, 1, 1, 0));
setParentGroup.childForceExpandHeight = false; UIFactory.SetLayoutElement(setParentGroupObj, minHeight: 25, flexibleHeight: 0);
setParentGroup.childControlHeight = true;
setParentGroup.childForceExpandWidth = false;
setParentGroup.childControlWidth = true;
setParentGroup.spacing = 5;
var setParentLayout = setParentGroupObj.AddComponent<LayoutElement>();
setParentLayout.minHeight = 25;
setParentLayout.flexibleHeight = 0;
var setParentLabelObj = UIFactory.CreateLabel(setParentGroupObj, TextAnchor.MiddleLeft); var title = UIFactory.CreateLabel(setParentGroupObj, "SetParentLabel", "Set Parent:", TextAnchor.MiddleLeft, Color.grey);
var setParentLabel = setParentLabelObj.GetComponent<Text>(); UIFactory.SetLayoutElement(title.gameObject, minWidth: 110, minHeight: 25, flexibleHeight: 0);
setParentLabel.text = "Set Parent:";
setParentLabel.color = Color.grey;
setParentLabel.fontSize = 14;
var setParentLabelLayout = setParentLabelObj.AddComponent<LayoutElement>();
setParentLabelLayout.minWidth = 110;
setParentLabelLayout.minHeight = 25;
setParentLabelLayout.flexibleWidth = 0;
var setParentInputObj = UIFactory.CreateInputField(setParentGroupObj); var inputFieldObj = UIFactory.CreateInputField(setParentGroupObj, "SetParentInputField", "Enter a GameObject name or path...");
s_setParentInput = setParentInputObj.GetComponent<InputField>(); s_setParentInput = inputFieldObj.GetComponent<InputField>();
var placeholderInput = s_setParentInput.placeholder.GetComponent<Text>(); UIFactory.SetLayoutElement(inputFieldObj, minHeight: 25, preferredWidth: 400, flexibleWidth: 9999);
placeholderInput.text = "Enter a GameObject name or path...";
var setParentInputLayout = setParentInputObj.AddComponent<LayoutElement>();
setParentInputLayout.minHeight = 25;
setParentInputLayout.preferredWidth = 400;
setParentInputLayout.flexibleWidth = 9999;
var applyButtonObj = UIFactory.CreateButton(setParentGroupObj); var applyButton = UIFactory.CreateButton(setParentGroupObj, "SetParentButton", "Apply", OnSetParentClicked);
var applyButton = applyButtonObj.GetComponent<Button>(); UIFactory.SetLayoutElement(applyButton.gameObject, minWidth: 55, flexibleWidth: 0, minHeight: 25, flexibleHeight: 0);
applyButton.onClick.AddListener(OnSetParentClicked);
var applyText = applyButtonObj.GetComponentInChildren<Text>();
applyText.text = "Apply";
var applyLayout = applyButtonObj.AddComponent<LayoutElement>();
applyLayout.minWidth = 55;
applyLayout.flexibleWidth = 0;
applyLayout.minHeight = 25;
applyLayout.flexibleHeight = 0;
} }
internal void ConstructVector3Editor(GameObject parent, string title, ControlType type, out ControlEditor editor) internal void ConstructVector3Editor(GameObject parent, string titleText, ControlType type, out ControlEditor editor)
{ {
editor = new ControlEditor(); editor = new ControlEditor();
var topBarObj = UIFactory.CreateHorizontalGroup(parent, new Color(1, 1, 1, 0)); var topBarObj = UIFactory.CreateHorizontalGroup(parent, "Vector3Editor", false, false, true, true, 5, default, new Color(1, 1, 1, 0));
var topGroup = topBarObj.GetComponent<HorizontalLayoutGroup>(); UIFactory.SetLayoutElement(topBarObj, minHeight: 25, flexibleHeight: 0);
topGroup.childForceExpandWidth = false;
topGroup.childControlWidth = true;
topGroup.childForceExpandHeight = false;
topGroup.childControlHeight = true;
topGroup.spacing = 5;
var topLayout = topBarObj.AddComponent<LayoutElement>();
topLayout.minHeight = 25;
topLayout.flexibleHeight = 0;
var titleObj = UIFactory.CreateLabel(topBarObj, TextAnchor.MiddleLeft); var title = UIFactory.CreateLabel(topBarObj, "Title", titleText, TextAnchor.MiddleLeft, Color.grey);
var titleText = titleObj.GetComponent<Text>(); UIFactory.SetLayoutElement(title.gameObject, minWidth: 110, flexibleWidth: 0, minHeight: 25);
titleText.text = title;
titleText.color = Color.grey;
titleText.fontSize = 14;
var titleLayout = titleObj.AddComponent<LayoutElement>();
titleLayout.minWidth = 110;
titleLayout.flexibleWidth = 0;
titleLayout.minHeight = 25;
// expand button // expand button
var expandButtonObj = UIFactory.CreateButton(topBarObj); var expandButton = UIFactory.CreateButton(topBarObj, "ExpandArrow", "▼");
var expandButton = expandButtonObj.GetComponent<Button>(); var expandText = expandButton.GetComponentInChildren<Text>();
var expandText = expandButtonObj.GetComponentInChildren<Text>();
expandText.text = "▼";
expandText.fontSize = 12; expandText.fontSize = 12;
var btnLayout = expandButtonObj.AddComponent<LayoutElement>(); UIFactory.SetLayoutElement(expandButton.gameObject, minWidth: 35, flexibleWidth: 0, minHeight: 25, flexibleHeight: 0);
btnLayout.minWidth = 35;
btnLayout.flexibleWidth = 0;
btnLayout.minHeight = 25;
btnLayout.flexibleHeight = 0;
// readonly value input // readonly value input
var valueInputObj = UIFactory.CreateInputField(topBarObj); var valueInputObj = UIFactory.CreateInputField(topBarObj, "ValueInput", "...");
var valueInput = valueInputObj.GetComponent<InputField>(); var valueInput = valueInputObj.GetComponent<InputField>();
valueInput.readOnly = true; valueInput.readOnly = true;
//valueInput.richText = true; UIFactory.SetLayoutElement(valueInputObj, minHeight: 25, flexibleHeight: 0, preferredWidth: 400, flexibleWidth: 9999);
//valueInput.isRichTextEditingAllowed = true;
var valueInputLayout = valueInputObj.AddComponent<LayoutElement>();
valueInputLayout.minHeight = 25;
valueInputLayout.flexibleHeight = 0;
valueInputLayout.preferredWidth = 400;
valueInputLayout.flexibleWidth = 9999;
editor.fullValue = valueInput; editor.fullValue = valueInput;
@ -459,86 +371,42 @@ namespace UnityExplorer.UI.Main.Home.Inspectors
internal GameObject ConstructEditorRow(GameObject parent, ControlEditor editor, ControlType type, VectorValue vectorValue) internal GameObject ConstructEditorRow(GameObject parent, ControlEditor editor, ControlType type, VectorValue vectorValue)
{ {
var rowObject = UIFactory.CreateHorizontalGroup(parent, new Color(1, 1, 1, 0)); var rowObject = UIFactory.CreateHorizontalGroup(parent, "EditorRow", false, false, true, true, 5, default, new Color(1, 1, 1, 0));
var rowGroup = rowObject.GetComponent<HorizontalLayoutGroup>(); UIFactory.SetLayoutElement(rowObject, minHeight: 25, flexibleHeight: 0, minWidth: 100);
rowGroup.childForceExpandWidth = false;
rowGroup.childControlWidth = true;
rowGroup.childForceExpandHeight = false;
rowGroup.childControlHeight = true;
rowGroup.spacing = 5;
var rowLayout = rowObject.AddComponent<LayoutElement>();
rowLayout.minHeight = 25;
rowLayout.flexibleHeight = 0;
rowLayout.minWidth = 100;
// Value labels // Value labels
var labelObj = UIFactory.CreateLabel(rowObject, TextAnchor.MiddleLeft); var valueTitle = UIFactory.CreateLabel(rowObject, "ValueTitle", $"{vectorValue.ToString().ToUpper()}:", TextAnchor.MiddleLeft, Color.cyan);
var labelText = labelObj.GetComponent<Text>(); UIFactory.SetLayoutElement(valueTitle.gameObject, minHeight: 25, flexibleHeight: 0, minWidth: 25, flexibleWidth: 0);
labelText.color = Color.cyan;
labelText.text = $"{vectorValue.ToString().ToUpper()}:";
labelText.fontSize = 14;
labelText.resizeTextMaxSize = 14;
labelText.resizeTextForBestFit = true;
var labelLayout = labelObj.AddComponent<LayoutElement>();
labelLayout.minHeight = 25;
labelLayout.flexibleHeight = 0;
labelLayout.minWidth = 25;
labelLayout.flexibleWidth = 0;
// actual value label // actual value label
var valueLabelObj = UIFactory.CreateLabel(rowObject, TextAnchor.MiddleLeft); var valueLabel = UIFactory.CreateLabel(rowObject, "ValueLabel", "<notset>", TextAnchor.MiddleLeft);
var valueLabel = valueLabelObj.GetComponent<Text>();
editor.values[(int)vectorValue] = valueLabel; editor.values[(int)vectorValue] = valueLabel;
var valueLabelLayout = valueLabelObj.AddComponent<LayoutElement>(); UIFactory.SetLayoutElement(valueLabel.gameObject, minWidth: 85, flexibleWidth: 0, minHeight: 25);
valueLabelLayout.minWidth = 85;
valueLabelLayout.flexibleWidth = 0;
valueLabelLayout.minHeight = 25;
// input field // input field
var inputHolder = UIFactory.CreateVerticalGroup(rowObject, new Color(1, 1, 1, 0)); var inputHolder = UIFactory.CreateVerticalGroup(rowObject, "InputFieldGroup", false, false, true, true, 0, default, new Color(1, 1, 1, 0));
var inputHolderGroup = inputHolder.GetComponent<VerticalLayoutGroup>();
inputHolderGroup.childForceExpandHeight = false;
inputHolderGroup.childControlHeight = true;
inputHolderGroup.childForceExpandWidth = false;
inputHolderGroup.childControlWidth = true;
var inputObj = UIFactory.CreateInputField(inputHolder); var inputObj = UIFactory.CreateInputField(inputHolder, "InputField", "...");
var input = inputObj.GetComponent<InputField>(); var input = inputObj.GetComponent<InputField>();
input.characterValidation = InputField.CharacterValidation.Decimal; //input.characterValidation = InputField.CharacterValidation.Decimal;
var inputLayout = inputObj.AddComponent<LayoutElement>(); UIFactory.SetLayoutElement(inputObj, minHeight: 25, flexibleHeight: 0, minWidth: 90, flexibleWidth: 50);
inputLayout.minHeight = 25;
inputLayout.flexibleHeight = 0;
inputLayout.minWidth = 90;
inputLayout.flexibleWidth = 50;
editor.inputs[(int)vectorValue] = input; editor.inputs[(int)vectorValue] = input;
// apply button // apply button
var applyBtnObj = UIFactory.CreateButton(rowObject); var applyBtn = UIFactory.CreateButton(rowObject, "ApplyButton", "Apply", () => { OnVectorControlInputApplied(type, vectorValue); });
var applyBtn = applyBtnObj.GetComponent<Button>(); UIFactory.SetLayoutElement(applyBtn.gameObject, minWidth: 60, minHeight: 25);
var applyText = applyBtnObj.GetComponentInChildren<Text>();
applyText.text = "Apply";
applyText.fontSize = 14;
var applyLayout = applyBtnObj.AddComponent<LayoutElement>();
applyLayout.minWidth = 60;
applyLayout.minHeight = 25;
applyBtn.onClick.AddListener(() => { OnVectorControlInputApplied(type, vectorValue); });
// Slider // Slider
var sliderObj = UIFactory.CreateSlider(rowObject); var sliderObj = UIFactory.CreateSlider(rowObject, "VectorSlider", out Slider slider);
UIFactory.SetLayoutElement(sliderObj, minHeight: 20, flexibleHeight: 0, minWidth: 200, flexibleWidth: 9000);
sliderObj.transform.Find("Fill Area").gameObject.SetActive(false); sliderObj.transform.Find("Fill Area").gameObject.SetActive(false);
var sliderLayout = sliderObj.AddComponent<LayoutElement>();
sliderLayout.minHeight = 20;
sliderLayout.flexibleHeight = 0;
sliderLayout.minWidth = 200;
sliderLayout.flexibleWidth = 9000;
var slider = sliderObj.GetComponent<Slider>();
var sliderColors = slider.colors; var sliderColors = slider.colors;
sliderColors.normalColor = new Color(0.65f, 0.65f, 0.65f); sliderColors.normalColor = new Color(0.65f, 0.65f, 0.65f);
slider.colors = sliderColors; slider.colors = sliderColors;
@ -553,24 +421,10 @@ namespace UnityExplorer.UI.Main.Home.Inspectors
internal void ConstructBottomButtons(GameObject contentObj) internal void ConstructBottomButtons(GameObject contentObj)
{ {
var bottomRow = UIFactory.CreateHorizontalGroup(contentObj, new Color(1, 1, 1, 0)); var bottomRow = UIFactory.CreateHorizontalGroup(contentObj, "BottomButtons", true, true, false, false, 4, default, new Color(1, 1, 1, 0));
var bottomGroup = bottomRow.GetComponent<HorizontalLayoutGroup>();
bottomGroup.childForceExpandWidth = true;
bottomGroup.childControlWidth = true;
bottomGroup.spacing = 4;
var bottomLayout = bottomRow.AddComponent<LayoutElement>();
bottomLayout.minHeight = 25;
var instantiateBtnObj = UIFactory.CreateButton(bottomRow, new Color(0.2f, 0.2f, 0.2f)); var instantiateBtn = UIFactory.CreateButton(bottomRow, "InstantiateBtn", "Instantiate", InstantiateBtn, new Color(0.2f, 0.2f, 0.2f));
var instantiateBtn = instantiateBtnObj.GetComponent<Button>(); UIFactory.SetLayoutElement(instantiateBtn.gameObject, minWidth: 150);
instantiateBtn.onClick.AddListener(InstantiateBtn);
var instantiateText = instantiateBtnObj.GetComponentInChildren<Text>();
instantiateText.text = "Instantiate";
instantiateText.fontSize = 14;
var instantiateLayout = instantiateBtnObj.AddComponent<LayoutElement>();
instantiateLayout.minWidth = 150;
void InstantiateBtn() void InstantiateBtn()
{ {
@ -582,16 +436,9 @@ namespace UnityExplorer.UI.Main.Home.Inspectors
InspectorManager.Instance.Inspect(clone); InspectorManager.Instance.Inspect(clone);
} }
var dontDestroyBtnObj = UIFactory.CreateButton(bottomRow, new Color(0.2f, 0.2f, 0.2f)); var dontDestroyBtn = UIFactory.CreateButton(bottomRow, "DontDestroyButton", "Set DontDestroyOnLoad", DontDestroyOnLoadBtn,
var dontDestroyBtn = dontDestroyBtnObj.GetComponent<Button>(); new Color(0.2f, 0.2f, 0.2f));
UIFactory.SetLayoutElement(dontDestroyBtn.gameObject, flexibleWidth: 5000);
dontDestroyBtn.onClick.AddListener(DontDestroyOnLoadBtn);
var dontDestroyText = dontDestroyBtnObj.GetComponentInChildren<Text>();
dontDestroyText.text = "Set DontDestroyOnLoad";
dontDestroyText.fontSize = 14;
var dontDestroyLayout = dontDestroyBtnObj.AddComponent<LayoutElement>();
dontDestroyLayout.flexibleWidth = 5000;
void DontDestroyOnLoadBtn() void DontDestroyOnLoadBtn()
{ {
@ -602,17 +449,10 @@ namespace UnityExplorer.UI.Main.Home.Inspectors
GameObject.DontDestroyOnLoad(go); GameObject.DontDestroyOnLoad(go);
} }
var destroyBtnObj = UIFactory.CreateButton(bottomRow, new Color(0.2f, 0.2f, 0.2f)); var destroyBtn = UIFactory.CreateButton(bottomRow, "DestroyButton", "Destroy", DestroyBtn, new Color(0.2f, 0.2f, 0.2f));
var destroyBtn = destroyBtnObj.GetComponent<Button>(); UIFactory.SetLayoutElement(destroyBtn.gameObject, minWidth: 150);
var destroyText = destroyBtn.GetComponentInChildren<Text>();
destroyBtn.onClick.AddListener(DestroyBtn);
var destroyText = destroyBtnObj.GetComponentInChildren<Text>();
destroyText.text = "Destroy";
destroyText.fontSize = 14;
destroyText.color = Color.red; destroyText.color = Color.red;
var destroyLayout = destroyBtnObj.AddComponent<LayoutElement>();
destroyLayout.minWidth = 150;
void DestroyBtn() void DestroyBtn()
{ {
@ -624,6 +464,6 @@ namespace UnityExplorer.UI.Main.Home.Inspectors
} }
} }
#endregion #endregion
} }
} }

View File

@ -0,0 +1,350 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.Core.Runtime;
using UnityExplorer.Core.Unity;
namespace UnityExplorer.UI.Main.Home.Inspectors.GameObjects
{
public class GameObjectInspector : InspectorBase
{
public override string TabLabel => $" <color=cyan>[G]</color> {TargetGO?.name}";
public static GameObjectInspector ActiveInstance { get; private set; }
public GameObject TargetGO;
// sub modules
internal static ChildList s_childList;
internal static ComponentList s_compList;
internal static GameObjectControls s_controls;
internal static bool m_UIConstructed;
public GameObjectInspector(GameObject target) : base(target)
{
ActiveInstance = this;
TargetGO = target;
if (!TargetGO)
{
ExplorerCore.LogWarning("Target GameObject is null!");
return;
}
// one UI is used for all gameobject inspectors. no point recreating it.
if (!m_UIConstructed)
{
m_UIConstructed = true;
s_childList = new ChildList();
s_compList = new ComponentList();
s_controls = new GameObjectControls();
ConstructUI();
}
}
public override void SetActive()
{
base.SetActive();
ActiveInstance = this;
}
public override void SetInactive()
{
base.SetInactive();
ActiveInstance = null;
}
internal void ChangeInspectorTarget(GameObject newTarget)
{
if (!newTarget)
return;
this.Target = this.TargetGO = newTarget;
}
// Update
public override void Update()
{
base.Update();
if (m_pendingDestroy || !this.IsActive)
return;
RefreshTopInfo();
s_childList.RefreshChildObjectList();
s_compList.RefreshComponentList();
s_controls.RefreshControls();
if (GameObjectControls.s_sliderChangedWanted)
GameObjectControls.UpdateSliderControl();
}
private static GameObject s_content;
public override GameObject Content
{
get => s_content;
set => s_content = value;
}
private static string m_lastName;
public static InputField m_nameInput;
private static string m_lastPath;
public static InputField m_pathInput;
private static RectTransform m_pathInputRect;
private static GameObject m_pathGroupObj;
private static Text m_hiddenPathText;
private static RectTransform m_hiddenPathRect;
private static Toggle m_enabledToggle;
private static Text m_enabledText;
private static bool? m_lastEnabledState;
private static Dropdown m_layerDropdown;
private static int m_lastLayer = -1;
private static Text m_sceneText;
private static string m_lastScene;
internal void RefreshTopInfo()
{
var target = TargetGO;
string name = target.name;
if (m_lastName != name)
{
m_lastName = name;
m_nameInput.text = m_lastName;
}
if (target.transform.parent)
{
if (!m_pathGroupObj.activeSelf)
m_pathGroupObj.SetActive(true);
var path = target.transform.GetTransformPath(true);
if (m_lastPath != path)
{
m_lastPath = path;
m_pathInput.text = path;
m_hiddenPathText.text = path;
LayoutRebuilder.ForceRebuildLayoutImmediate(m_pathInputRect);
LayoutRebuilder.ForceRebuildLayoutImmediate(m_hiddenPathRect);
}
}
else if (m_pathGroupObj.activeSelf)
m_pathGroupObj.SetActive(false);
if (m_lastEnabledState != target.activeSelf)
{
m_lastEnabledState = target.activeSelf;
m_enabledToggle.isOn = target.activeSelf;
m_enabledText.text = target.activeSelf ? "Enabled" : "Disabled";
m_enabledText.color = target.activeSelf ? Color.green : Color.red;
}
if (m_lastLayer != target.layer)
{
m_lastLayer = target.layer;
m_layerDropdown.value = target.layer;
}
if (string.IsNullOrEmpty(m_lastScene) || m_lastScene != target.scene.name)
{
m_lastScene = target.scene.name;
if (!string.IsNullOrEmpty(target.scene.name))
m_sceneText.text = m_lastScene;
else
m_sceneText.text = "None (Asset/Resource)";
}
}
// UI Callbacks
private static void OnApplyNameClicked()
{
if (ActiveInstance == null)
return;
ActiveInstance.TargetGO.name = m_nameInput.text;
}
private static void OnEnableToggled(bool enabled)
{
if (ActiveInstance == null)
return;
ActiveInstance.TargetGO.SetActive(enabled);
}
private static void OnLayerSelected(int layer)
{
if (ActiveInstance == null)
return;
ActiveInstance.TargetGO.layer = layer;
}
internal static void OnBackButtonClicked()
{
if (ActiveInstance == null)
return;
ActiveInstance.ChangeInspectorTarget(ActiveInstance.TargetGO.transform.parent.gameObject);
}
#region UI CONSTRUCTION
internal void ConstructUI()
{
var parent = InspectorManager.m_inspectorContent;
s_content = UIFactory.CreateScrollView(parent, "GameObjectInspector_Content", out GameObject scrollContent, out _,
new Color(0.1f, 0.1f, 0.1f));
UIFactory.SetLayoutGroup<VerticalLayoutGroup>(scrollContent.transform.parent.gameObject, true, true, true, true);
UIFactory.SetLayoutGroup<VerticalLayoutGroup>(scrollContent, true, true, true, true, 5);
var contentFitter = scrollContent.GetComponent<ContentSizeFitter>();
contentFitter.verticalFit = ContentSizeFitter.FitMode.Unconstrained;
ConstructTopArea(scrollContent);
s_controls.ConstructControls(scrollContent);
var midGroupObj = ConstructMidGroup(scrollContent);
s_childList.ConstructChildList(midGroupObj);
s_compList.ConstructCompList(midGroupObj);
LayoutRebuilder.ForceRebuildLayoutImmediate(s_content.GetComponent<RectTransform>());
Canvas.ForceUpdateCanvases();
}
private void ConstructTopArea(GameObject scrollContent)
{
// path row
m_pathGroupObj = UIFactory.CreateHorizontalGroup(scrollContent, "TopArea", false, false, true, true, 5, default, new Color(0.1f, 0.1f, 0.1f));
var pathRect = m_pathGroupObj.GetComponent<RectTransform>();
pathRect.sizeDelta = new Vector2(pathRect.sizeDelta.x, 20);
UIFactory.SetLayoutElement(m_pathGroupObj, minHeight: 20, flexibleHeight: 75);
// Back button
var backButton = UIFactory.CreateButton(m_pathGroupObj, "BackButton", "◄", OnBackButtonClicked, new Color(0.15f, 0.15f, 0.15f));
UIFactory.SetLayoutElement(backButton.gameObject, minWidth: 55, flexibleWidth: 0, minHeight: 25, flexibleHeight: 0);
m_hiddenPathText = UIFactory.CreateLabel(m_pathGroupObj, "HiddenPathText", "", TextAnchor.MiddleLeft);
m_hiddenPathText.color = Color.clear;
m_hiddenPathText.fontSize = 14;
m_hiddenPathText.raycastTarget = false;
var hiddenFitter = m_hiddenPathText.gameObject.AddComponent<ContentSizeFitter>();
hiddenFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
UIFactory.SetLayoutElement(m_hiddenPathText.gameObject, minHeight: 25, flexibleHeight: 125, minWidth: 250, flexibleWidth: 9000);
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(m_hiddenPathText.gameObject, true, true, true, true);
// Path input
var pathInputObj = UIFactory.CreateInputField(m_hiddenPathText.gameObject, "PathInputField", "...");
UIFactory.SetLayoutElement(pathInputObj, minHeight: 25, flexibleHeight: 75, preferredWidth: 400, flexibleWidth: 9999);
var pathInputRect = pathInputObj.GetComponent<RectTransform>();
pathInputRect.sizeDelta = new Vector2(pathInputRect.sizeDelta.x, 25);
m_pathInput = pathInputObj.GetComponent<InputField>();
m_pathInput.text = ActiveInstance.TargetGO.transform.GetTransformPath();
m_pathInput.readOnly = true;
m_pathInput.lineType = InputField.LineType.MultiLineNewline;
m_pathInput.textComponent.color = new Color(0.75f, 0.75f, 0.75f);
var textRect = m_pathInput.textComponent.GetComponent<RectTransform>();
textRect.offsetMin = new Vector2(3, 3);
textRect.offsetMax = new Vector2(3, 3);
m_pathInputRect = m_pathInput.GetComponent<RectTransform>();
m_hiddenPathRect = m_hiddenPathText.GetComponent<RectTransform>();
// name and enabled row
var nameRowObj = UIFactory.CreateHorizontalGroup(scrollContent, "NameGroup", false, false, true, true, 5, default, new Color(0.1f, 0.1f, 0.1f));
UIFactory.SetLayoutElement(nameRowObj, minHeight: 25, flexibleHeight: 0);
var nameRect = nameRowObj.GetComponent<RectTransform>();
nameRect.sizeDelta = new Vector2(nameRect.sizeDelta.x, 25);
var nameLabel = UIFactory.CreateLabel(nameRowObj, "NameLabel", "Name:", TextAnchor.MiddleCenter, Color.grey, true, 14);
UIFactory.SetLayoutElement(nameLabel.gameObject, minHeight: 25, flexibleHeight: 0, minWidth: 55, flexibleWidth: 0);
var nameInputObj = UIFactory.CreateInputField(nameRowObj, "NameInput", "...");
var nameInputRect = nameInputObj.GetComponent<RectTransform>();
nameInputRect.sizeDelta = new Vector2(nameInputRect.sizeDelta.x, 25);
m_nameInput = nameInputObj.GetComponent<InputField>();
m_nameInput.text = ActiveInstance.TargetGO.name;
var applyNameBtn = UIFactory.CreateButton(nameRowObj, "ApplyNameButton", "Apply", OnApplyNameClicked);
UIFactory.SetLayoutElement(applyNameBtn.gameObject, minWidth: 65, minHeight: 25, flexibleHeight: 0);
var applyNameRect = applyNameBtn.GetComponent<RectTransform>();
applyNameRect.sizeDelta = new Vector2(applyNameRect.sizeDelta.x, 25);
var activeLabel = UIFactory.CreateLabel(nameRowObj, "ActiveLabel", "Active:", TextAnchor.MiddleCenter, Color.grey, true, 14);
UIFactory.SetLayoutElement(activeLabel.gameObject, minWidth: 55, minHeight: 25);
var enabledToggleObj = UIFactory.CreateToggle(nameRowObj, "EnabledToggle", out m_enabledToggle, out m_enabledText);
UIFactory.SetLayoutElement(enabledToggleObj, minHeight: 25, minWidth: 100, flexibleWidth: 0);
m_enabledText.text = "Enabled";
m_enabledText.color = Color.green;
m_enabledToggle.onValueChanged.AddListener(OnEnableToggled);
// layer and scene row
var sceneLayerRow = UIFactory.CreateHorizontalGroup(scrollContent, "SceneLayerRow", false, true, true, true, 5, default, new Color(0.1f, 0.1f, 0.1f));
// layer
var layerLabel = UIFactory.CreateLabel(sceneLayerRow, "LayerLabel", "Layer:", TextAnchor.MiddleCenter, Color.grey, true, 14);
UIFactory.SetLayoutElement(layerLabel.gameObject, minWidth: 55, flexibleWidth: 0);
var layerDropdownObj = UIFactory.CreateDropdown(sceneLayerRow, out m_layerDropdown, "<notset>", 14, OnLayerSelected);
m_layerDropdown.options.Clear();
for (int i = 0; i < 32; i++)
{
var layer = RuntimeProvider.Instance.LayerToName(i);
m_layerDropdown.options.Add(new Dropdown.OptionData { text = $"{i}: {layer}" });
}
UIFactory.SetLayoutElement(layerDropdownObj, minWidth: 120, flexibleWidth: 2000, minHeight: 25);
// scene
var sceneLabel = UIFactory.CreateLabel(sceneLayerRow, "SceneLabel", "Scene:", TextAnchor.MiddleCenter, Color.grey, true, 14);
UIFactory.SetLayoutElement(sceneLabel.gameObject, minWidth: 55, flexibleWidth: 0);
m_sceneText = UIFactory.CreateLabel(sceneLayerRow, "SceneText", "<notset>", TextAnchor.MiddleLeft);
UIFactory.SetLayoutElement(m_sceneText.gameObject, minWidth: 120, flexibleWidth: 2000);
}
private GameObject ConstructMidGroup(GameObject parent)
{
var midGroupObj = UIFactory.CreateHorizontalGroup(parent, "MidGroup", true, true, true, true, 5, default, new Color(1, 1, 1, 0));
UIFactory.SetLayoutElement(midGroupObj, minHeight: 300, flexibleHeight: 3000);
return midGroupObj;
}
#endregion
}
}

View File

@ -1,378 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.Core.Unity;
using UnityExplorer.Core.Inspectors;
using UnityExplorer.Core.Runtime;
namespace UnityExplorer.UI.Main.Home.Inspectors
{
public class GameObjectInspectorUI : InspectorBaseUI
{
private static GameObject s_content;
public override GameObject Content
{
get => s_content;
set => s_content = value;
}
private static string m_lastName;
public static InputField m_nameInput;
private static string m_lastPath;
public static InputField m_pathInput;
private static RectTransform m_pathInputRect;
private static GameObject m_pathGroupObj;
private static Text m_hiddenPathText;
private static RectTransform m_hiddenPathRect;
private static Toggle m_enabledToggle;
private static Text m_enabledText;
private static bool? m_lastEnabledState;
private static Dropdown m_layerDropdown;
private static int m_lastLayer = -1;
private static Text m_sceneText;
private static string m_lastScene;
internal void RefreshTopInfo()
{
var target = GameObjectInspector.ActiveInstance.TargetGO;
string name = target.name;
if (m_lastName != name)
{
m_lastName = name;
m_nameInput.text = m_lastName;
}
if (target.transform.parent)
{
if (!m_pathGroupObj.activeSelf)
m_pathGroupObj.SetActive(true);
var path = target.transform.GetTransformPath(true);
if (m_lastPath != path)
{
m_lastPath = path;
m_pathInput.text = path;
m_hiddenPathText.text = path;
LayoutRebuilder.ForceRebuildLayoutImmediate(m_pathInputRect);
LayoutRebuilder.ForceRebuildLayoutImmediate(m_hiddenPathRect);
}
}
else if (m_pathGroupObj.activeSelf)
m_pathGroupObj.SetActive(false);
if (m_lastEnabledState != target.activeSelf)
{
m_lastEnabledState = target.activeSelf;
m_enabledToggle.isOn = target.activeSelf;
m_enabledText.text = target.activeSelf ? "Enabled" : "Disabled";
m_enabledText.color = target.activeSelf ? Color.green : Color.red;
}
if (m_lastLayer != target.layer)
{
m_lastLayer = target.layer;
m_layerDropdown.value = target.layer;
}
if (string.IsNullOrEmpty(m_lastScene) || m_lastScene != target.scene.name)
{
m_lastScene = target.scene.name;
if (!string.IsNullOrEmpty(target.scene.name))
m_sceneText.text = m_lastScene;
else
m_sceneText.text = "None (Asset/Resource)";
}
}
// UI Callbacks
private static void OnApplyNameClicked()
{
if (GameObjectInspector.ActiveInstance == null)
return;
GameObjectInspector.ActiveInstance.TargetGO.name = m_nameInput.text;
}
private static void OnEnableToggled(bool enabled)
{
if (GameObjectInspector.ActiveInstance == null)
return;
GameObjectInspector.ActiveInstance.TargetGO.SetActive(enabled);
}
private static void OnLayerSelected(int layer)
{
if (GameObjectInspector.ActiveInstance == null)
return;
GameObjectInspector.ActiveInstance.TargetGO.layer = layer;
}
internal static void OnBackButtonClicked()
{
if (GameObjectInspector.ActiveInstance == null)
return;
GameObjectInspector.ActiveInstance.ChangeInspectorTarget(
GameObjectInspector.ActiveInstance.TargetGO.transform.parent.gameObject);
}
#region UI CONSTRUCTION
internal void ConstructUI()
{
var parent = InspectorManager.UI.m_inspectorContent;
s_content = UIFactory.CreateScrollView(parent, out GameObject scrollContent, out _, new Color(0.1f, 0.1f, 0.1f));
var parentLayout = scrollContent.transform.parent.gameObject.AddComponent<VerticalLayoutGroup>();
parentLayout.childForceExpandWidth = true;
parentLayout.childControlWidth = true;
parentLayout.childForceExpandHeight = true;
parentLayout.childControlHeight = true;
var scrollGroup = scrollContent.GetComponent<VerticalLayoutGroup>();
scrollGroup.childForceExpandHeight = true;
scrollGroup.childControlHeight = true;
scrollGroup.childForceExpandWidth = true;
scrollGroup.childControlWidth = true;
scrollGroup.spacing = 5;
var contentFitter = scrollContent.GetComponent<ContentSizeFitter>();
contentFitter.verticalFit = ContentSizeFitter.FitMode.Unconstrained;
ConstructTopArea(scrollContent);
GameObjectInspector.s_controls.ConstructControls(scrollContent);
var midGroupObj = ConstructMidGroup(scrollContent);
GameObjectInspector.s_childList.ConstructChildList(midGroupObj);
GameObjectInspector.s_compList.ConstructCompList(midGroupObj);
LayoutRebuilder.ForceRebuildLayoutImmediate(s_content.GetComponent<RectTransform>());
Canvas.ForceUpdateCanvases();
}
private void ConstructTopArea(GameObject scrollContent)
{
// path row
m_pathGroupObj = UIFactory.CreateHorizontalGroup(scrollContent, new Color(0.1f, 0.1f, 0.1f));
var pathGroup = m_pathGroupObj.GetComponent<HorizontalLayoutGroup>();
pathGroup.childForceExpandHeight = false;
pathGroup.childForceExpandWidth = false;
pathGroup.childControlHeight = false;
pathGroup.childControlWidth = true;
pathGroup.spacing = 5;
var pathRect = m_pathGroupObj.GetComponent<RectTransform>();
pathRect.sizeDelta = new Vector2(pathRect.sizeDelta.x, 20);
var pathLayout = m_pathGroupObj.AddComponent<LayoutElement>();
pathLayout.minHeight = 20;
pathLayout.flexibleHeight = 75;
var backButtonObj = UIFactory.CreateButton(m_pathGroupObj);
var backButton = backButtonObj.GetComponent<Button>();
backButton.onClick.AddListener(OnBackButtonClicked);
var backColors = backButton.colors;
backColors.normalColor = new Color(0.15f, 0.15f, 0.15f);
backButton.colors = backColors;
var backText = backButtonObj.GetComponentInChildren<Text>();
backText.text = "◄";
var backLayout = backButtonObj.AddComponent<LayoutElement>();
backLayout.minWidth = 55;
backLayout.flexibleWidth = 0;
backLayout.minHeight = 25;
backLayout.flexibleHeight = 0;
var pathHiddenTextObj = UIFactory.CreateLabel(m_pathGroupObj, TextAnchor.MiddleLeft);
m_hiddenPathText = pathHiddenTextObj.GetComponent<Text>();
m_hiddenPathText.color = Color.clear;
m_hiddenPathText.fontSize = 14;
//m_hiddenPathText.lineSpacing = 1.5f;
m_hiddenPathText.raycastTarget = false;
var hiddenFitter = pathHiddenTextObj.AddComponent<ContentSizeFitter>();
hiddenFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
var hiddenLayout = pathHiddenTextObj.AddComponent<LayoutElement>();
hiddenLayout.minHeight = 25;
hiddenLayout.flexibleHeight = 125;
hiddenLayout.minWidth = 250;
hiddenLayout.flexibleWidth = 9000;
var hiddenGroup = pathHiddenTextObj.AddComponent<HorizontalLayoutGroup>();
hiddenGroup.childForceExpandWidth = true;
hiddenGroup.childControlWidth = true;
hiddenGroup.childForceExpandHeight = true;
hiddenGroup.childControlHeight = true;
var pathInputObj = UIFactory.CreateInputField(pathHiddenTextObj);
var pathInputRect = pathInputObj.GetComponent<RectTransform>();
pathInputRect.sizeDelta = new Vector2(pathInputRect.sizeDelta.x, 25);
m_pathInput = pathInputObj.GetComponent<InputField>();
m_pathInput.text = GameObjectInspector.ActiveInstance.TargetGO.transform.GetTransformPath();
m_pathInput.readOnly = true;
m_pathInput.lineType = InputField.LineType.MultiLineNewline;
var pathInputLayout = pathInputObj.AddComponent<LayoutElement>();
pathInputLayout.minHeight = 25;
pathInputLayout.flexibleHeight = 75;
pathInputLayout.preferredWidth = 400;
pathInputLayout.flexibleWidth = 9999;
var textRect = m_pathInput.textComponent.GetComponent<RectTransform>();
textRect.offsetMin = new Vector2(3, 3);
textRect.offsetMax = new Vector2(3, 3);
m_pathInput.textComponent.color = new Color(0.75f, 0.75f, 0.75f);
//m_pathInput.textComponent.lineSpacing = 1.5f;
m_pathInputRect = m_pathInput.GetComponent<RectTransform>();
m_hiddenPathRect = m_hiddenPathText.GetComponent<RectTransform>();
// name row
var nameRowObj = UIFactory.CreateHorizontalGroup(scrollContent, new Color(0.1f, 0.1f, 0.1f));
var nameGroup = nameRowObj.GetComponent<HorizontalLayoutGroup>();
nameGroup.childForceExpandHeight = false;
nameGroup.childForceExpandWidth = false;
nameGroup.childControlHeight = true;
nameGroup.childControlWidth = true;
nameGroup.spacing = 5;
var nameRect = nameRowObj.GetComponent<RectTransform>();
nameRect.sizeDelta = new Vector2(nameRect.sizeDelta.x, 25);
var nameLayout = nameRowObj.AddComponent<LayoutElement>();
nameLayout.minHeight = 25;
nameLayout.flexibleHeight = 0;
var nameTextObj = UIFactory.CreateLabel(nameRowObj, TextAnchor.MiddleCenter);
var nameTextText = nameTextObj.GetComponent<Text>();
nameTextText.text = "Name:";
nameTextText.fontSize = 14;
nameTextText.color = Color.grey;
var nameTextLayout = nameTextObj.AddComponent<LayoutElement>();
nameTextLayout.minHeight = 25;
nameTextLayout.flexibleHeight = 0;
nameTextLayout.minWidth = 55;
nameTextLayout.flexibleWidth = 0;
var nameInputObj = UIFactory.CreateInputField(nameRowObj);
var nameInputRect = nameInputObj.GetComponent<RectTransform>();
nameInputRect.sizeDelta = new Vector2(nameInputRect.sizeDelta.x, 25);
m_nameInput = nameInputObj.GetComponent<InputField>();
m_nameInput.text = GameObjectInspector.ActiveInstance.TargetGO.name;
var applyNameBtnObj = UIFactory.CreateButton(nameRowObj);
var applyNameBtn = applyNameBtnObj.GetComponent<Button>();
applyNameBtn.onClick.AddListener(OnApplyNameClicked);
var applyNameText = applyNameBtnObj.GetComponentInChildren<Text>();
applyNameText.text = "Apply";
applyNameText.fontSize = 14;
var applyNameLayout = applyNameBtnObj.AddComponent<LayoutElement>();
applyNameLayout.minWidth = 65;
applyNameLayout.minHeight = 25;
applyNameLayout.flexibleHeight = 0;
var applyNameRect = applyNameBtnObj.GetComponent<RectTransform>();
applyNameRect.sizeDelta = new Vector2(applyNameRect.sizeDelta.x, 25);
var activeLabel = UIFactory.CreateLabel(nameRowObj, TextAnchor.MiddleCenter);
var activeLabelLayout = activeLabel.AddComponent<LayoutElement>();
activeLabelLayout.minWidth = 55;
activeLabelLayout.minHeight = 25;
var activeText = activeLabel.GetComponent<Text>();
activeText.text = "Active:";
activeText.color = Color.grey;
activeText.fontSize = 14;
var enabledToggleObj = UIFactory.CreateToggle(nameRowObj, out m_enabledToggle, out m_enabledText);
var toggleLayout = enabledToggleObj.AddComponent<LayoutElement>();
toggleLayout.minHeight = 25;
toggleLayout.minWidth = 100;
toggleLayout.flexibleWidth = 0;
m_enabledText.text = "Enabled";
m_enabledText.color = Color.green;
m_enabledToggle.onValueChanged.AddListener(OnEnableToggled);
// layer and scene row
var sceneLayerRow = UIFactory.CreateHorizontalGroup(scrollContent, new Color(0.1f, 0.1f, 0.1f));
var sceneLayerGroup = sceneLayerRow.GetComponent<HorizontalLayoutGroup>();
sceneLayerGroup.childForceExpandWidth = false;
sceneLayerGroup.childControlWidth = true;
sceneLayerGroup.spacing = 5;
var layerLabel = UIFactory.CreateLabel(sceneLayerRow, TextAnchor.MiddleCenter);
var layerText = layerLabel.GetComponent<Text>();
layerText.text = "Layer:";
layerText.fontSize = 14;
layerText.color = Color.grey;
var layerTextLayout = layerLabel.AddComponent<LayoutElement>();
layerTextLayout.minWidth = 55;
layerTextLayout.flexibleWidth = 0;
var layerDropdownObj = UIFactory.CreateDropdown(sceneLayerRow, out m_layerDropdown);
m_layerDropdown.options.Clear();
for (int i = 0; i < 32; i++)
{
var layer = RuntimeProvider.Instance.LayerToName(i);
m_layerDropdown.options.Add(new Dropdown.OptionData { text = $"{i}: {layer}" });
}
//var itemText = layerDropdownObj.transform.Find("Label").GetComponent<Text>();
//itemText.resizeTextForBestFit = true;
var layerDropdownLayout = layerDropdownObj.AddComponent<LayoutElement>();
layerDropdownLayout.minWidth = 120;
layerDropdownLayout.flexibleWidth = 2000;
layerDropdownLayout.minHeight = 25;
m_layerDropdown.onValueChanged.AddListener(OnLayerSelected);
var scenelabelObj = UIFactory.CreateLabel(sceneLayerRow, TextAnchor.MiddleCenter);
var sceneLabel = scenelabelObj.GetComponent<Text>();
sceneLabel.text = "Scene:";
sceneLabel.color = Color.grey;
sceneLabel.fontSize = 14;
var sceneLabelLayout = scenelabelObj.AddComponent<LayoutElement>();
sceneLabelLayout.minWidth = 55;
sceneLabelLayout.flexibleWidth = 0;
var objectSceneText = UIFactory.CreateLabel(sceneLayerRow, TextAnchor.MiddleLeft);
m_sceneText = objectSceneText.GetComponent<Text>();
m_sceneText.fontSize = 14;
m_sceneText.horizontalOverflow = HorizontalWrapMode.Overflow;
var sceneTextLayout = objectSceneText.AddComponent<LayoutElement>();
sceneTextLayout.minWidth = 120;
sceneTextLayout.flexibleWidth = 2000;
}
private GameObject ConstructMidGroup(GameObject parent)
{
var midGroupObj = UIFactory.CreateHorizontalGroup(parent, new Color(1, 1, 1, 0));
var midGroup = midGroupObj.GetComponent<HorizontalLayoutGroup>();
midGroup.spacing = 5;
midGroup.childForceExpandWidth = true;
midGroup.childControlWidth = true;
midGroup.childForceExpandHeight = true;
midGroup.childControlHeight = true;
var midLayout = midGroupObj.AddComponent<LayoutElement>();
midLayout.minHeight = 300;
midLayout.flexibleHeight = 5000;
return midGroupObj;
}
#endregion
}
}

View File

@ -2,21 +2,16 @@
using UnityEngine; using UnityEngine;
using UnityEngine.UI; using UnityEngine.UI;
using UnityExplorer.Core.Unity; using UnityExplorer.Core.Unity;
using UnityExplorer.UI;
using UnityExplorer.UI.Main.Home.Inspectors;
namespace UnityExplorer.Core.Inspectors namespace UnityExplorer.UI.Main.Home.Inspectors
{ {
public abstract class InspectorBase public abstract class InspectorBase
{ {
public object Target; public object Target;
public bool IsActive { get; private set; }
public InspectorBaseUI BaseUI;
public abstract string TabLabel { get; } public abstract string TabLabel { get; }
public bool IsActive { get; private set; }
internal bool m_pendingDestroy; internal bool m_pendingDestroy;
public InspectorBase(object target) public InspectorBase(object target)
@ -29,23 +24,19 @@ namespace UnityExplorer.Core.Inspectors
return; return;
} }
CreateUIModule(); AddInspectorTab(this);
BaseUI.AddInspectorTab(this);
} }
public abstract void CreateUIModule();
public virtual void SetActive() public virtual void SetActive()
{ {
this.IsActive = true; this.IsActive = true;
BaseUI.Content?.SetActive(true); Content?.SetActive(true);
} }
public virtual void SetInactive() public virtual void SetInactive()
{ {
this.IsActive = false; this.IsActive = false;
BaseUI.Content?.SetActive(false); Content?.SetActive(false);
} }
public virtual void Update() public virtual void Update()
@ -56,19 +47,17 @@ namespace UnityExplorer.Core.Inspectors
return; return;
} }
BaseUI.tabText.text = TabLabel; m_tabText.text = TabLabel;
} }
public virtual void Destroy() public virtual void Destroy()
{ {
m_pendingDestroy = true; m_pendingDestroy = true;
GameObject tabGroup = BaseUI.tabButton?.transform.parent.gameObject; GameObject tabGroup = m_tabButton?.transform.parent.gameObject;
if (tabGroup) if (tabGroup)
{
GameObject.Destroy(tabGroup); GameObject.Destroy(tabGroup);
}
int thisIndex = -1; int thisIndex = -1;
if (InspectorManager.Instance.m_currentInspectors.Contains(this)) if (InspectorManager.Instance.m_currentInspectors.Contains(this))
@ -88,5 +77,44 @@ namespace UnityExplorer.Core.Inspectors
} }
} }
} }
#region UI
public abstract GameObject Content { get; set; }
public Button m_tabButton;
public Text m_tabText;
public void AddInspectorTab(InspectorBase parent)
{
var tabContent = InspectorManager.m_tabBarContent;
var tabGroupObj = UIFactory.CreateHorizontalGroup(tabContent, "TabObject", true, true, true, true);
UIFactory.SetLayoutElement(tabGroupObj, minWidth: 185, flexibleWidth: 0);
tabGroupObj.AddComponent<Mask>();
m_tabButton = UIFactory.CreateButton(tabGroupObj,
"TabButton",
"<notset>",
() => { InspectorManager.Instance.SetInspectorTab(parent); });
UIFactory.SetLayoutElement(m_tabButton.gameObject, minWidth: 165, flexibleWidth: 0);
m_tabText = m_tabButton.GetComponentInChildren<Text>();
m_tabText.horizontalOverflow = HorizontalWrapMode.Overflow;
m_tabText.alignment = TextAnchor.MiddleLeft;
var closeBtn = UIFactory.CreateButton(tabGroupObj,
"CloseButton",
"X",
parent.Destroy,
new Color(0.2f, 0.2f, 0.2f, 1));
UIFactory.SetLayoutElement(closeBtn.gameObject, minWidth: 20, flexibleWidth: 0);
var closeBtnText = closeBtn.GetComponentInChildren<Text>();
closeBtnText.color = new Color(1, 0, 0, 1);
}
#endregion
} }
} }

View File

@ -1,61 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.Core.Inspectors;
namespace UnityExplorer.UI.Main.Home.Inspectors
{
public abstract class InspectorBaseUI
{
public abstract GameObject Content { get; set; }
public Button tabButton;
public Text tabText;
public void AddInspectorTab(InspectorBase parent)
{
var tabContent = InspectorManager.UI.m_tabBarContent;
var tabGroupObj = UIFactory.CreateHorizontalGroup(tabContent);
var tabGroup = tabGroupObj.GetComponent<HorizontalLayoutGroup>();
tabGroup.childForceExpandWidth = true;
tabGroup.childControlWidth = true;
var tabLayout = tabGroupObj.AddComponent<LayoutElement>();
tabLayout.minWidth = 185;
tabLayout.flexibleWidth = 0;
tabGroupObj.AddComponent<Mask>();
var targetButtonObj = UIFactory.CreateButton(tabGroupObj);
targetButtonObj.AddComponent<Mask>();
var targetButtonLayout = targetButtonObj.AddComponent<LayoutElement>();
targetButtonLayout.minWidth = 165;
targetButtonLayout.flexibleWidth = 0;
tabText = targetButtonObj.GetComponentInChildren<Text>();
tabText.horizontalOverflow = HorizontalWrapMode.Overflow;
tabText.alignment = TextAnchor.MiddleLeft;
tabButton = targetButtonObj.GetComponent<Button>();
tabButton.onClick.AddListener(() => { InspectorManager.Instance.SetInspectorTab(parent); });
var closeBtnObj = UIFactory.CreateButton(tabGroupObj);
var closeBtnLayout = closeBtnObj.AddComponent<LayoutElement>();
closeBtnLayout.minWidth = 20;
closeBtnLayout.flexibleWidth = 0;
var closeBtnText = closeBtnObj.GetComponentInChildren<Text>();
closeBtnText.text = "X";
closeBtnText.color = new Color(1, 0, 0, 1);
var closeBtn = closeBtnObj.GetComponent<Button>();
closeBtn.onClick.AddListener(parent.Destroy);
var closeColors = closeBtn.colors;
closeColors.normalColor = new Color(0.2f, 0.2f, 0.2f, 1);
closeBtn.colors = closeColors;
}
}
}

View File

@ -1,69 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
namespace UnityExplorer.UI.Main.Home.Inspectors
{
public class MouseInspectorUI
{
internal Text s_objNameLabel;
internal Text s_objPathLabel;
internal Text s_mousePosLabel;
internal GameObject s_UIContent;
public MouseInspectorUI()
{
ConstructUI();
}
#region UI Construction
internal void ConstructUI()
{
s_UIContent = UIFactory.CreatePanel(UIManager.CanvasRoot, "MouseInspect", out GameObject content);
s_UIContent.AddComponent<Mask>();
var baseRect = s_UIContent.GetComponent<RectTransform>();
var half = new Vector2(0.5f, 0.5f);
baseRect.anchorMin = half;
baseRect.anchorMax = half;
baseRect.pivot = half;
baseRect.sizeDelta = new Vector2(700, 150);
var group = content.GetComponent<VerticalLayoutGroup>();
group.childForceExpandHeight = true;
// Title text
var titleObj = UIFactory.CreateLabel(content, TextAnchor.MiddleCenter);
var titleText = titleObj.GetComponent<Text>();
titleText.text = "<b>Mouse Inspector</b> (press <b>ESC</b> to cancel)";
var mousePosObj = UIFactory.CreateLabel(content, TextAnchor.MiddleCenter);
s_mousePosLabel = mousePosObj.GetComponent<Text>();
s_mousePosLabel.text = "Mouse Position:";
var hitLabelObj = UIFactory.CreateLabel(content, TextAnchor.MiddleLeft);
s_objNameLabel = hitLabelObj.GetComponent<Text>();
s_objNameLabel.text = "No hits...";
s_objNameLabel.horizontalOverflow = HorizontalWrapMode.Overflow;
var pathLabelObj = UIFactory.CreateLabel(content, TextAnchor.MiddleLeft);
s_objPathLabel = pathLabelObj.GetComponent<Text>();
s_objPathLabel.fontStyle = FontStyle.Italic;
s_objPathLabel.horizontalOverflow = HorizontalWrapMode.Wrap;
var pathLayout = pathLabelObj.AddComponent<LayoutElement>();
pathLayout.minHeight = 75;
pathLayout.flexibleHeight = 0;
s_UIContent.SetActive(false);
}
#endregion
}
}

View File

@ -0,0 +1,262 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.Core;
using UnityExplorer.Core.Config;
using UnityExplorer.Core.Runtime;
namespace UnityExplorer.UI.Main.Home.Inspectors.Reflection
{
public enum MemberScopes
{
All,
Instance,
Static
}
public class InstanceInspector : ReflectionInspector
{
public override string TabLabel => $" <color=cyan>[R]</color> {base.TabLabel}";
internal MemberScopes m_scopeFilter;
internal Button m_lastActiveScopeButton;
public InstanceInspector(object target) : base(target) { }
internal void OnScopeFilterClicked(MemberScopes type, Button button)
{
if (m_lastActiveScopeButton)
{
var lastColors = m_lastActiveScopeButton.colors;
lastColors.normalColor = new Color(0.2f, 0.2f, 0.2f);
m_lastActiveScopeButton.colors = lastColors;
}
m_scopeFilter = type;
m_lastActiveScopeButton = button;
var colors = m_lastActiveScopeButton.colors;
colors.normalColor = new Color(0.2f, 0.6f, 0.2f);
m_lastActiveScopeButton.colors = colors;
FilterMembers(null, true);
m_sliderScroller.m_slider.value = 1f;
}
public void ConstructUnityInstanceHelpers()
{
if (!typeof(UnityEngine.Object).IsAssignableFrom(m_targetType))
return;
var rowObj = UIFactory.CreateHorizontalGroup(Content, "InstanceHelperRow", true, true, true, true, 5, new Vector4(2,2,2,2),
new Color(0.1f, 0.1f, 0.1f));
UIFactory.SetLayoutElement(rowObj, minHeight: 25, flexibleWidth: 5000);
if (typeof(Component).IsAssignableFrom(m_targetType))
ConstructCompHelper(rowObj);
ConstructUnityObjHelper(rowObj);
if (m_targetType == typeof(Texture2D))
ConstructTextureHelper();
}
internal void ConstructCompHelper(GameObject rowObj)
{
var gameObjectLabel = UIFactory.CreateLabel(rowObj, "GameObjectLabel", "GameObject:", TextAnchor.MiddleLeft);
UIFactory.SetLayoutElement(gameObjectLabel.gameObject, minWidth: 90, minHeight: 25, flexibleWidth: 0);
var comp = Target.Cast(typeof(Component)) as Component;
var btn = UIFactory.CreateButton(rowObj,
"GameObjectButton",
comp.name,
() => { InspectorManager.Instance.Inspect(comp.gameObject); },
new Color(0.2f, 0.5f, 0.2f));
UIFactory.SetLayoutElement(btn.gameObject, minHeight: 25, minWidth: 200, flexibleWidth: 0);
}
internal void ConstructUnityObjHelper(GameObject rowObj)
{
var label = UIFactory.CreateLabel(rowObj, "NameLabel", "Name:", TextAnchor.MiddleLeft);
UIFactory.SetLayoutElement(label.gameObject, minWidth: 60, minHeight: 25, flexibleWidth: 0);
var uObj = Target.Cast(typeof(UnityEngine.Object)) as UnityEngine.Object;
var inputObj = UIFactory.CreateInputField(rowObj, "NameInput", "...", 14, 3, 1);
UIFactory.SetLayoutElement(inputObj, minHeight: 25, flexibleWidth: 2000);
var inputField = inputObj.GetComponent<InputField>();
inputField.readOnly = true;
inputField.text = uObj.name;
}
internal bool showingTextureHelper;
internal bool constructedTextureViewer;
internal GameObject m_textureViewerObj;
internal void ConstructTextureHelper()
{
var rowObj = UIFactory.CreateHorizontalGroup(Content, "TextureHelper", true, false, true, true, 5, new Vector4(3,3,3,3),
new Color(0.1f, 0.1f, 0.1f));
UIFactory.SetLayoutElement(rowObj, minHeight: 25, flexibleHeight: 0);
var showBtn = UIFactory.CreateButton(rowObj, "ShowButton", "Show", null, new Color(0.2f, 0.6f, 0.2f));
UIFactory.SetLayoutElement(showBtn.gameObject, minWidth: 50, flexibleWidth: 0);
UIFactory.CreateLabel(rowObj, "TextureViewerLabel", "Texture Viewer", TextAnchor.MiddleLeft);
var textureViewerObj = UIFactory.CreateScrollView(Content, "TextureViewerContent", out GameObject scrollContent, out _, new Color(0.1f, 0.1f, 0.1f));
UIFactory.SetLayoutGroup<VerticalLayoutGroup>(textureViewerObj, false, false, true, true);
UIFactory.SetLayoutElement(textureViewerObj, minHeight: 100, flexibleHeight: 9999, flexibleWidth: 9999);
textureViewerObj.SetActive(false);
m_textureViewerObj = textureViewerObj;
var showText = showBtn.GetComponentInChildren<Text>();
showBtn.onClick.AddListener(() =>
{
showingTextureHelper = !showingTextureHelper;
if (showingTextureHelper)
{
if (!constructedTextureViewer)
ConstructTextureViewerArea(scrollContent);
showText.text = "Hide";
ToggleTextureViewer(true);
}
else
{
showText.text = "Show";
ToggleTextureViewer(false);
}
});
}
internal void ConstructTextureViewerArea(GameObject parent)
{
constructedTextureViewer = true;
var tex = Target.Cast(typeof(Texture2D)) as Texture2D;
if (!tex)
{
ExplorerCore.LogWarning("Could not cast the target instance to Texture2D! Maybe its null or destroyed?");
return;
}
// Save helper
var saveRowObj = UIFactory.CreateHorizontalGroup(parent, "SaveRow", true, true, true, true, 2, new Vector4(2,2,2,2),
new Color(0.1f, 0.1f, 0.1f));
var saveBtn = UIFactory.CreateButton(saveRowObj, "SaveButton", "Save .PNG", null, new Color(0.2f, 0.2f, 0.2f));
UIFactory.SetLayoutElement(saveBtn.gameObject, minHeight: 25, minWidth: 100, flexibleWidth: 0);
var inputObj = UIFactory.CreateInputField(saveRowObj, "SaveInput", "...");
UIFactory.SetLayoutElement(inputObj, minHeight: 25, minWidth: 100, flexibleWidth: 9999);
var inputField = inputObj.GetComponent<InputField>();
var name = tex.name;
if (string.IsNullOrEmpty(name))
name = "untitled";
inputField.text = Path.Combine(ConfigManager.Default_Output_Path.Value, $"{name}.png");
saveBtn.onClick.AddListener(() =>
{
if (tex && !string.IsNullOrEmpty(inputField.text))
{
var path = inputField.text;
if (!path.EndsWith(".png", StringComparison.InvariantCultureIgnoreCase))
{
ExplorerCore.LogWarning("Desired save path must end with '.png'!");
return;
}
var dir = Path.GetDirectoryName(path);
if (!Directory.Exists(dir))
Directory.CreateDirectory(dir);
if (File.Exists(path))
File.Delete(path);
if (!TextureUtilProvider.IsReadable(tex))
tex = TextureUtilProvider.ForceReadTexture(tex);
byte[] data = TextureUtilProvider.Instance.EncodeToPNG(tex);
File.WriteAllBytes(path, data);
}
});
// Actual texture viewer
var imageObj = UIFactory.CreateUIObject("TextureViewerImage", parent);
var image = imageObj.AddComponent<Image>();
var sprite = TextureUtilProvider.Instance.CreateSprite(tex);
image.sprite = sprite;
var fitter = imageObj.AddComponent<ContentSizeFitter>();
fitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
var imageLayout = imageObj.AddComponent<LayoutElement>();
imageLayout.preferredHeight = sprite.rect.height;
imageLayout.preferredWidth = sprite.rect.width;
}
internal void ToggleTextureViewer(bool enabled)
{
m_textureViewerObj.SetActive(enabled);
m_filterAreaObj.SetActive(!enabled);
m_memberListObj.SetActive(!enabled);
m_updateRowObj.SetActive(!enabled);
}
public void ConstructInstanceFilters(GameObject parent)
{
var memberFilterRowObj = UIFactory.CreateHorizontalGroup(parent, "InstanceFilterRow", false, false, true, true, 5, default,
new Color(1, 1, 1, 0));
UIFactory.SetLayoutElement(memberFilterRowObj, minHeight: 25, flexibleHeight: 0, flexibleWidth: 5000);
var memLabel = UIFactory.CreateLabel(memberFilterRowObj, "MemberLabel", "Filter scope:", TextAnchor.MiddleLeft);
UIFactory.SetLayoutElement(memLabel.gameObject, minWidth: 100, minHeight: 25, flexibleWidth: 0);
AddFilterButton(memberFilterRowObj, MemberScopes.All, true);
AddFilterButton(memberFilterRowObj, MemberScopes.Instance);
AddFilterButton(memberFilterRowObj, MemberScopes.Static);
}
private void AddFilterButton(GameObject parent, MemberScopes type, bool setEnabled = false)
{
var btn = UIFactory.CreateButton(parent,
"ScopeFilterButton_" + type,
type.ToString(),
null,
new Color(0.2f, 0.2f, 0.2f));
UIFactory.SetLayoutElement(btn.gameObject, minHeight: 25, minWidth: 70);
btn.onClick.AddListener(() => { OnScopeFilterClicked(type, btn); });
var colors = btn.colors;
colors.highlightedColor = new Color(0.3f, 0.7f, 0.3f);
if (setEnabled)
{
colors.normalColor = new Color(0.2f, 0.6f, 0.2f);
m_scopeFilter = type;
m_lastActiveScopeButton = btn;
}
btn.colors = colors;
}
}
}

View File

@ -1,328 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.Core.Inspectors;
using UnityExplorer.Core.Inspectors.Reflection;
using UnityExplorer.Core.Runtime;
namespace UnityExplorer.UI.Main.Home.Inspectors
{
public class InstanceInspectorUI
{
public InstanceInspectorUI(InstanceInspector parent)
{
Parent = parent;
}
internal InstanceInspector Parent;
public void ConstructInstanceHelpers()
{
if (!typeof(Component).IsAssignableFrom(Parent.m_targetType) && !typeof(UnityEngine.Object).IsAssignableFrom(Parent.m_targetType))
return;
var rowObj = UIFactory.CreateHorizontalGroup(Parent.ReflectionUI.Content, new Color(0.1f, 0.1f, 0.1f));
var rowGroup = rowObj.GetComponent<HorizontalLayoutGroup>();
rowGroup.childForceExpandWidth = true;
rowGroup.childControlWidth = true;
rowGroup.spacing = 5;
rowGroup.padding.top = 2;
rowGroup.padding.bottom = 2;
rowGroup.padding.right = 2;
rowGroup.padding.left = 2;
var rowLayout = rowObj.AddComponent<LayoutElement>();
rowLayout.minHeight = 25;
rowLayout.flexibleWidth = 5000;
if (typeof(Component).IsAssignableFrom(Parent.m_targetType))
{
ConstructCompHelper(rowObj);
}
ConstructUObjHelper(rowObj);
if (Parent.m_targetType == typeof(Texture2D))
ConstructTextureHelper();
}
internal void ConstructCompHelper(GameObject rowObj)
{
var labelObj = UIFactory.CreateLabel(rowObj, TextAnchor.MiddleLeft);
var labelLayout = labelObj.AddComponent<LayoutElement>();
labelLayout.minWidth = 90;
labelLayout.minHeight = 25;
labelLayout.flexibleWidth = 0;
var labelText = labelObj.GetComponent<Text>();
labelText.text = "GameObject:";
#if MONO
var comp = Parent.Target as Component;
#else
var comp = (Parent.Target as Il2CppSystem.Object).TryCast<Component>();
#endif
var goBtnObj = UIFactory.CreateButton(rowObj, new Color(0.2f, 0.5f, 0.2f));
var goBtnLayout = goBtnObj.AddComponent<LayoutElement>();
goBtnLayout.minHeight = 25;
goBtnLayout.minWidth = 200;
goBtnLayout.flexibleWidth = 0;
var text = goBtnObj.GetComponentInChildren<Text>();
text.text = comp.name;
var btn = goBtnObj.GetComponent<Button>();
btn.onClick.AddListener(() => { InspectorManager.Instance.Inspect(comp.gameObject); });
}
internal void ConstructUObjHelper(GameObject rowObj)
{
var labelObj = UIFactory.CreateLabel(rowObj, TextAnchor.MiddleLeft);
var labelLayout = labelObj.AddComponent<LayoutElement>();
labelLayout.minWidth = 60;
labelLayout.minHeight = 25;
labelLayout.flexibleWidth = 0;
var labelText = labelObj.GetComponent<Text>();
labelText.text = "Name:";
#if MONO
var uObj = Parent.Target as UnityEngine.Object;
#else
var uObj = (Parent.Target as Il2CppSystem.Object).TryCast<UnityEngine.Object>();
#endif
var inputObj = UIFactory.CreateInputField(rowObj, 14, 3, 1);
var inputLayout = inputObj.AddComponent<LayoutElement>();
inputLayout.minHeight = 25;
inputLayout.flexibleWidth = 2000;
var inputField = inputObj.GetComponent<InputField>();
inputField.readOnly = true;
inputField.text = uObj.name;
}
internal bool showingTextureHelper;
internal bool constructedTextureViewer;
internal GameObject m_textureViewerObj;
internal void ConstructTextureHelper()
{
var rowObj = UIFactory.CreateHorizontalGroup(Parent.ReflectionUI.Content, new Color(0.1f, 0.1f, 0.1f));
var rowLayout = rowObj.AddComponent<LayoutElement>();
rowLayout.minHeight = 25;
rowLayout.flexibleHeight = 0;
var rowGroup = rowObj.GetComponent<HorizontalLayoutGroup>();
rowGroup.childForceExpandHeight = true;
rowGroup.childForceExpandWidth = false;
rowGroup.padding.top = 3;
rowGroup.padding.left = 3;
rowGroup.padding.bottom = 3;
rowGroup.padding.right = 3;
rowGroup.spacing = 5;
var showBtnObj = UIFactory.CreateButton(rowObj, new Color(0.2f, 0.6f, 0.2f));
var showBtnLayout = showBtnObj.AddComponent<LayoutElement>();
showBtnLayout.minWidth = 50;
showBtnLayout.flexibleWidth = 0;
var showText = showBtnObj.GetComponentInChildren<Text>();
showText.text = "Show";
var showBtn = showBtnObj.GetComponent<Button>();
var labelObj = UIFactory.CreateLabel(rowObj, TextAnchor.MiddleLeft);
var labelText = labelObj.GetComponent<Text>();
labelText.text = "Texture Viewer";
var textureViewerObj = UIFactory.CreateScrollView(Parent.ReflectionUI.Content, out GameObject scrollContent, out _, new Color(0.1f, 0.1f, 0.1f));
var viewerGroup = scrollContent.GetComponent<VerticalLayoutGroup>();
viewerGroup.childForceExpandHeight = false;
viewerGroup.childForceExpandWidth = false;
viewerGroup.childControlHeight = true;
viewerGroup.childControlWidth = true;
var mainLayout = textureViewerObj.GetComponent<LayoutElement>();
mainLayout.flexibleHeight = 9999;
mainLayout.flexibleWidth = 9999;
mainLayout.minHeight = 100;
textureViewerObj.SetActive(false);
m_textureViewerObj = textureViewerObj;
showBtn.onClick.AddListener(() =>
{
showingTextureHelper = !showingTextureHelper;
if (showingTextureHelper)
{
if (!constructedTextureViewer)
ConstructTextureViewerArea(scrollContent);
showText.text = "Hide";
ToggleTextureViewer(true);
}
else
{
showText.text = "Show";
ToggleTextureViewer(false);
}
});
}
internal void ConstructTextureViewerArea(GameObject parent)
{
constructedTextureViewer = true;
var tex = Parent.Target as Texture2D;
#if CPP
if (!tex)
tex = (Parent.Target as Il2CppSystem.Object).TryCast<Texture2D>();
#endif
if (!tex)
{
ExplorerCore.LogWarning("Could not cast the target instance to Texture2D! Maybe its null or destroyed?");
return;
}
// Save helper
var saveRowObj = UIFactory.CreateHorizontalGroup(parent, new Color(0.1f, 0.1f, 0.1f));
var saveRow = saveRowObj.GetComponent<HorizontalLayoutGroup>();
saveRow.childForceExpandHeight = true;
saveRow.childForceExpandWidth = true;
saveRow.padding = new RectOffset() { left = 2, bottom = 2, right = 2, top = 2 };
saveRow.spacing = 2;
var btnObj = UIFactory.CreateButton(saveRowObj, new Color(0.2f, 0.2f, 0.2f));
var btnLayout = btnObj.AddComponent<LayoutElement>();
btnLayout.minHeight = 25;
btnLayout.minWidth = 100;
btnLayout.flexibleWidth = 0;
var saveBtn = btnObj.GetComponent<Button>();
var saveBtnText = btnObj.GetComponentInChildren<Text>();
saveBtnText.text = "Save .PNG";
var inputObj = UIFactory.CreateInputField(saveRowObj);
var inputLayout = inputObj.AddComponent<LayoutElement>();
inputLayout.minHeight = 25;
inputLayout.minWidth = 100;
inputLayout.flexibleWidth = 9999;
var inputField = inputObj.GetComponent<InputField>();
var name = tex.name;
if (string.IsNullOrEmpty(name))
name = "untitled";
var savePath = $@"{Core.Config.ExplorerConfig.Instance.Default_Output_Path}\{name}.png";
inputField.text = savePath;
saveBtn.onClick.AddListener(() =>
{
if (tex && !string.IsNullOrEmpty(inputField.text))
{
var path = inputField.text;
if (!path.EndsWith(".png", StringComparison.InvariantCultureIgnoreCase))
{
ExplorerCore.LogWarning("Desired save path must end with '.png'!");
return;
}
var dir = Path.GetDirectoryName(path);
if (!Directory.Exists(dir))
Directory.CreateDirectory(dir);
if (File.Exists(path))
File.Delete(path);
if (TextureUtilProvider.IsReadable(tex))
tex = TextureUtilProvider.ForceReadTexture(tex);
byte[] data = TextureUtilProvider.Instance.EncodeToPNG(tex);
File.WriteAllBytes(path, data);
}
});
// Actual texture viewer
var imageObj = UIFactory.CreateUIObject("TextureViewerImage", parent);
var image = imageObj.AddComponent<Image>();
var sprite = TextureUtilProvider.Instance.CreateSprite(tex);
image.sprite = sprite;
var fitter = imageObj.AddComponent<ContentSizeFitter>();
fitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
//fitter.horizontalFit = ContentSizeFitter.FitMode.PreferredSize;
var imageLayout = imageObj.AddComponent<LayoutElement>();
imageLayout.preferredHeight = sprite.rect.height;
imageLayout.preferredWidth = sprite.rect.width;
}
internal void ToggleTextureViewer(bool enabled)
{
m_textureViewerObj.SetActive(enabled);
Parent.ReflectionUI.m_filterAreaObj.SetActive(!enabled);
Parent.ReflectionUI.m_memberListObj.SetActive(!enabled);
Parent.ReflectionUI.m_updateRowObj.SetActive(!enabled);
}
public void ConstructInstanceFilters(GameObject parent)
{
var memberFilterRowObj = UIFactory.CreateHorizontalGroup(parent, new Color(1, 1, 1, 0));
var memFilterGroup = memberFilterRowObj.GetComponent<HorizontalLayoutGroup>();
memFilterGroup.childForceExpandHeight = false;
memFilterGroup.childForceExpandWidth = false;
memFilterGroup.childControlWidth = true;
memFilterGroup.childControlHeight = true;
memFilterGroup.spacing = 5;
var memFilterLayout = memberFilterRowObj.AddComponent<LayoutElement>();
memFilterLayout.minHeight = 25;
memFilterLayout.flexibleHeight = 0;
memFilterLayout.flexibleWidth = 5000;
var memLabelObj = UIFactory.CreateLabel(memberFilterRowObj, TextAnchor.MiddleLeft);
var memLabelLayout = memLabelObj.AddComponent<LayoutElement>();
memLabelLayout.minWidth = 100;
memLabelLayout.minHeight = 25;
memLabelLayout.flexibleWidth = 0;
var memLabelText = memLabelObj.GetComponent<Text>();
memLabelText.text = "Filter scope:";
memLabelText.color = Color.grey;
AddFilterButton(memberFilterRowObj, MemberScopes.All, true);
AddFilterButton(memberFilterRowObj, MemberScopes.Instance);
AddFilterButton(memberFilterRowObj, MemberScopes.Static);
}
private void AddFilterButton(GameObject parent, MemberScopes type, bool setEnabled = false)
{
var btnObj = UIFactory.CreateButton(parent, new Color(0.2f, 0.2f, 0.2f));
var btnLayout = btnObj.AddComponent<LayoutElement>();
btnLayout.minHeight = 25;
btnLayout.minWidth = 70;
var text = btnObj.GetComponentInChildren<Text>();
text.text = type.ToString();
var btn = btnObj.GetComponent<Button>();
btn.onClick.AddListener(() => { Parent.OnScopeFilterClicked(type, btn); });
var colors = btn.colors;
colors.highlightedColor = new Color(0.3f, 0.7f, 0.3f);
if (setEnabled)
{
colors.normalColor = new Color(0.2f, 0.6f, 0.2f);
Parent.m_scopeFilter = type;
Parent.m_lastActiveScopeButton = btn;
}
btn.colors = colors;
}
}
}

View File

@ -1,20 +1,16 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text;
using UnityExplorer.Core.Unity;
using UnityEngine;
using UnityExplorer.Core.Inspectors.Reflection;
using UnityExplorer.UI.Reusable;
using System.Reflection; using System.Reflection;
using UnityExplorer.UI; using System.Text;
using UnityEngine;
using UnityEngine.UI; using UnityEngine.UI;
using UnityExplorer.Core.Config;
using UnityExplorer.Core; using UnityExplorer.Core;
using UnityExplorer.Core.Config;
using UnityExplorer.UI.CacheObject;
using UnityExplorer.UI.Utility; using UnityExplorer.UI.Utility;
using UnityExplorer.UI.Main.Home.Inspectors;
namespace UnityExplorer.Core.Inspectors namespace UnityExplorer.UI.Main.Home.Inspectors.Reflection
{ {
public class ReflectionInspector : InspectorBase public class ReflectionInspector : InspectorBase
{ {
@ -24,16 +20,16 @@ namespace UnityExplorer.Core.Inspectors
static ReflectionInspector() static ReflectionInspector()
{ {
PanelDragger.OnFinishResize += OnContainerResized; PanelDragger.OnFinishResize += (RectTransform _) => OnContainerResized();
SceneExplorer.OnToggleShow += OnContainerResized; SceneExplorer.OnToggleShow += OnContainerResized;
} }
private static void OnContainerResized() private static void OnContainerResized(bool _ = false)
{ {
if (ActiveInstance == null) if (ActiveInstance == null)
return; return;
ActiveInstance.ReflectionUI.m_widthUpdateWanted = true; ActiveInstance.m_widthUpdateWanted = true;
} }
// Blacklists // Blacklists
@ -64,8 +60,6 @@ namespace UnityExplorer.Core.Inspectors
internal CacheObjectBase ParentMember { get; set; } internal CacheObjectBase ParentMember { get; set; }
internal ReflectionInspectorUI ReflectionUI;
internal readonly Type m_targetType; internal readonly Type m_targetType;
internal readonly string m_targetTypeShortName; internal readonly string m_targetTypeShortName;
@ -74,7 +68,7 @@ namespace UnityExplorer.Core.Inspectors
// filtered members based on current filters // filtered members based on current filters
internal readonly List<CacheMember> m_membersFiltered = new List<CacheMember>(); internal readonly List<CacheMember> m_membersFiltered = new List<CacheMember>();
// actual shortlist of displayed members // actual shortlist of displayed members
internal readonly CacheMember[] m_displayedMembers = new CacheMember[ExplorerConfig.Instance.Default_Page_Limit]; internal readonly CacheMember[] m_displayedMembers = new CacheMember[ConfigManager.Default_Page_Limit.Value];
internal bool m_autoUpdate; internal bool m_autoUpdate;
@ -87,18 +81,13 @@ namespace UnityExplorer.Core.Inspectors
m_targetTypeShortName = SignatureHighlighter.ParseFullSyntax(m_targetType, false); m_targetTypeShortName = SignatureHighlighter.ParseFullSyntax(m_targetType, false);
ReflectionUI.ConstructUI(); ConstructUI();
CacheMembers(m_targetType); CacheMembers(m_targetType);
FilterMembers(); FilterMembers();
} }
public override void CreateUIModule()
{
BaseUI = ReflectionUI = new ReflectionInspectorUI(this);
}
public override void SetActive() public override void SetActive()
{ {
base.SetActive(); base.SetActive();
@ -115,8 +104,8 @@ namespace UnityExplorer.Core.Inspectors
{ {
base.Destroy(); base.Destroy();
if (this.BaseUI.Content) if (this.Content)
GameObject.Destroy(this.BaseUI.Content); GameObject.Destroy(this.Content);
} }
internal void OnPageTurned() internal void OnPageTurned()
@ -188,11 +177,11 @@ namespace UnityExplorer.Core.Inspectors
cachedSigs.Add(sig); cachedSigs.Add(sig);
if (mi != null) if (mi != null)
list.Add(new CacheMethod(mi, target, ReflectionUI.m_scrollContent)); list.Add(new CacheMethod(mi, target, m_scrollContent));
else if (pi != null) else if (pi != null)
list.Add(new CacheProperty(pi, target, ReflectionUI.m_scrollContent)); list.Add(new CacheProperty(pi, target, m_scrollContent));
else else
list.Add(new CacheField(fi, target, ReflectionUI.m_scrollContent)); list.Add(new CacheField(fi, target, m_scrollContent));
list.Last().ParentInspector = this; list.Last().ParentInspector = this;
} }
@ -233,37 +222,37 @@ namespace UnityExplorer.Core.Inspectors
} }
} }
if (ReflectionUI.m_widthUpdateWanted) if (m_widthUpdateWanted)
{ {
if (!ReflectionUI.m_widthUpdateWaiting) if (!m_widthUpdateWaiting)
ReflectionUI.m_widthUpdateWaiting = true; m_widthUpdateWaiting = true;
else else
{ {
UpdateWidths(); UpdateWidths();
ReflectionUI.m_widthUpdateWaiting = false; m_widthUpdateWaiting = false;
ReflectionUI.m_widthUpdateWanted = false; m_widthUpdateWanted = false;
} }
} }
} }
internal void OnMemberFilterClicked(MemberTypes type, Button button) internal void OnMemberFilterClicked(MemberTypes type, Button button)
{ {
if (ReflectionUI.m_lastActiveMemButton) if (m_lastActiveMemButton)
{ {
var lastColors = ReflectionUI.m_lastActiveMemButton.colors; var lastColors = m_lastActiveMemButton.colors;
lastColors.normalColor = new Color(0.2f, 0.2f, 0.2f); lastColors.normalColor = new Color(0.2f, 0.2f, 0.2f);
ReflectionUI.m_lastActiveMemButton.colors = lastColors; m_lastActiveMemButton.colors = lastColors;
} }
ReflectionUI.m_memberFilter = type; m_memberFilter = type;
ReflectionUI.m_lastActiveMemButton = button; m_lastActiveMemButton = button;
var colors = ReflectionUI.m_lastActiveMemButton.colors; var colors = m_lastActiveMemButton.colors;
colors.normalColor = new Color(0.2f, 0.6f, 0.2f); colors.normalColor = new Color(0.2f, 0.6f, 0.2f);
ReflectionUI.m_lastActiveMemButton.colors = colors; m_lastActiveMemButton.colors = colors;
FilterMembers(null, true); FilterMembers(null, true);
ReflectionUI.m_sliderScroller.m_slider.value = 1f; m_sliderScroller.m_slider.value = 1f;
} }
public void FilterMembers(string nameFilter = null, bool force = false) public void FilterMembers(string nameFilter = null, bool force = false)
@ -271,12 +260,12 @@ namespace UnityExplorer.Core.Inspectors
int lastCount = m_membersFiltered.Count; int lastCount = m_membersFiltered.Count;
m_membersFiltered.Clear(); m_membersFiltered.Clear();
nameFilter = nameFilter?.ToLower() ?? ReflectionUI.m_nameFilterText.text.ToLower(); nameFilter = nameFilter?.ToLower() ?? m_nameFilterText.text.ToLower();
foreach (var mem in m_allMembers) foreach (var mem in m_allMembers)
{ {
// membertype filter // membertype filter
if (ReflectionUI.m_memberFilter != MemberTypes.All && mem.MemInfo.MemberType != ReflectionUI.m_memberFilter) if (m_memberFilter != MemberTypes.All && mem.MemInfo.MemberType != m_memberFilter)
continue; continue;
if (this is InstanceInspector ii && ii.m_scopeFilter != MemberScopes.All) if (this is InstanceInspector ii && ii.m_scopeFilter != MemberScopes.All)
@ -301,7 +290,7 @@ namespace UnityExplorer.Core.Inspectors
public void RefreshDisplay() public void RefreshDisplay()
{ {
var members = m_membersFiltered; var members = m_membersFiltered;
ReflectionUI.m_pageHandler.ListCount = members.Count; m_pageHandler.ListCount = members.Count;
// disable current members // disable current members
for (int i = 0; i < m_displayedMembers.Length; i++) for (int i = 0; i < m_displayedMembers.Length; i++)
@ -316,17 +305,17 @@ namespace UnityExplorer.Core.Inspectors
if (members.Count < 1) if (members.Count < 1)
return; return;
foreach (var itemIndex in ReflectionUI.m_pageHandler) foreach (var itemIndex in m_pageHandler)
{ {
if (itemIndex >= members.Count) if (itemIndex >= members.Count)
break; break;
CacheMember member = members[itemIndex]; CacheMember member = members[itemIndex];
m_displayedMembers[itemIndex - ReflectionUI.m_pageHandler.StartIndex] = member; m_displayedMembers[itemIndex - m_pageHandler.StartIndex] = member;
member.Enable(); member.Enable();
} }
ReflectionUI.m_widthUpdateWanted = true; m_widthUpdateWanted = true;
} }
internal void UpdateWidths() internal void UpdateWidths()
@ -338,13 +327,13 @@ namespace UnityExplorer.Core.Inspectors
if (cache == null) if (cache == null)
break; break;
var width = cache.GetMemberLabelWidth(ReflectionUI.m_scrollContentRect); var width = cache.GetMemberLabelWidth(m_scrollContentRect);
if (width > labelWidth) if (width > labelWidth)
labelWidth = width; labelWidth = width;
} }
float valueWidth = ReflectionUI.m_scrollContentRect.rect.width - labelWidth - 20; float valueWidth = m_scrollContentRect.rect.width - labelWidth - 20;
foreach (var cache in m_displayedMembers) foreach (var cache in m_displayedMembers)
{ {
@ -356,5 +345,180 @@ namespace UnityExplorer.Core.Inspectors
#endregion // end instance #endregion // end instance
#region UI
private GameObject m_content;
public override GameObject Content
{
get => m_content;
set => m_content = value;
}
internal Text m_nameFilterText;
internal MemberTypes m_memberFilter;
internal Button m_lastActiveMemButton;
internal PageHandler m_pageHandler;
internal SliderScrollbar m_sliderScroller;
internal GameObject m_scrollContent;
internal RectTransform m_scrollContentRect;
internal bool m_widthUpdateWanted;
internal bool m_widthUpdateWaiting;
internal GameObject m_filterAreaObj;
internal GameObject m_updateRowObj;
internal GameObject m_memberListObj;
internal void ConstructUI()
{
var parent = InspectorManager.m_inspectorContent;
this.Content = UIFactory.CreateVerticalGroup(parent, "ReflectionInspector", true, false, true, true, 5, new Vector4(4,4,4,4),
new Color(0.15f, 0.15f, 0.15f));
ConstructTopArea();
ConstructMemberList();
}
internal void ConstructTopArea()
{
var nameRowObj = UIFactory.CreateHorizontalGroup(Content, "NameRowObj", true, true, true, true, 2, default, new Color(1, 1, 1, 0));
UIFactory.SetLayoutElement(nameRowObj, minHeight: 25, flexibleHeight: 0, minWidth: 200, flexibleWidth: 5000);
var typeLabelText = UIFactory.CreateLabel(nameRowObj, "TypeLabel", "Type:", TextAnchor.MiddleLeft);
typeLabelText.horizontalOverflow = HorizontalWrapMode.Overflow;
UIFactory.SetLayoutElement(typeLabelText.gameObject, minWidth: 40, flexibleWidth: 0, minHeight: 25);
var typeDisplay = UIFactory.CreateLabel(nameRowObj, "TypeDisplayText", SignatureHighlighter.ParseFullSyntax(m_targetType, true),
TextAnchor.MiddleLeft);
UIFactory.SetLayoutElement(typeDisplay.gameObject, minHeight: 25, flexibleWidth: 5000);
// instance helper tools
if (this is InstanceInspector instanceInspector)
{
instanceInspector.ConstructUnityInstanceHelpers();
}
ConstructFilterArea();
ConstructUpdateRow();
}
internal void ConstructFilterArea()
{
// Filters
m_filterAreaObj = UIFactory.CreateVerticalGroup(Content, "FilterGroup", true, true, true, true, 4, new Vector4(4,4,4,4),
new Color(0.1f, 0.1f, 0.1f));
UIFactory.SetLayoutElement(m_filterAreaObj, minHeight: 60);
// name filter
var nameFilterRowObj = UIFactory.CreateHorizontalGroup(m_filterAreaObj, "NameFilterRow", false, false, true, true, 5, default,
new Color(1, 1, 1, 0));
UIFactory.SetLayoutElement(nameFilterRowObj, minHeight: 25, flexibleHeight: 0, flexibleWidth: 5000);
var nameLabel = UIFactory.CreateLabel(nameFilterRowObj, "NameLabel", "Filter names:", TextAnchor.MiddleLeft, Color.grey);
UIFactory.SetLayoutElement(nameLabel.gameObject, minWidth: 100, minHeight: 25, flexibleWidth: 0);
var nameInputObj = UIFactory.CreateInputField(nameFilterRowObj, "NameInput", "...", 14, (int)TextAnchor.MiddleLeft, (int)HorizontalWrapMode.Overflow);
UIFactory.SetLayoutElement(nameInputObj, flexibleWidth: 5000, minWidth: 100, minHeight: 25);
var nameInput = nameInputObj.GetComponent<InputField>();
nameInput.onValueChanged.AddListener((string val) => { FilterMembers(val); });
m_nameFilterText = nameInput.textComponent;
// membertype filter
var memberFilterRowObj = UIFactory.CreateHorizontalGroup(m_filterAreaObj, "MemberFilter", false, false, true, true, 5, default,
new Color(1, 1, 1, 0));
UIFactory.SetLayoutElement(memberFilterRowObj, minHeight: 25, flexibleHeight: 0, flexibleWidth: 5000);
var memLabel = UIFactory.CreateLabel(memberFilterRowObj, "MemberFilterLabel", "Filter members:", TextAnchor.MiddleLeft, Color.grey);
UIFactory.SetLayoutElement(memLabel.gameObject, minWidth: 100, minHeight: 25, flexibleWidth: 0);
AddFilterButton(memberFilterRowObj, MemberTypes.All);
AddFilterButton(memberFilterRowObj, MemberTypes.Method);
AddFilterButton(memberFilterRowObj, MemberTypes.Property, true);
AddFilterButton(memberFilterRowObj, MemberTypes.Field);
// Instance filters
if (this is InstanceInspector instanceInspector)
{
instanceInspector.ConstructInstanceFilters(m_filterAreaObj);
}
}
private void AddFilterButton(GameObject parent, MemberTypes type, bool setEnabled = false)
{
var btn = UIFactory.CreateButton(parent,
"FilterButton_" + type,
type.ToString(),
null,
new Color(0.2f, 0.2f, 0.2f));
UIFactory.SetLayoutElement(btn.gameObject, minHeight: 25, minWidth: 70);
btn.onClick.AddListener(() => { OnMemberFilterClicked(type, btn); });
var colors = btn.colors;
colors.highlightedColor = new Color(0.3f, 0.7f, 0.3f);
if (setEnabled)
{
colors.normalColor = new Color(0.2f, 0.6f, 0.2f);
m_memberFilter = type;
m_lastActiveMemButton = btn;
}
btn.colors = colors;
}
internal void ConstructUpdateRow()
{
m_updateRowObj = UIFactory.CreateHorizontalGroup(Content, "UpdateRow", false, true, true, true, 10, default, new Color(1, 1, 1, 0));
UIFactory.SetLayoutElement(m_updateRowObj, minHeight: 25);
// update button
var updateBtn = UIFactory.CreateButton(m_updateRowObj, "UpdateButton", "Update Values", null, new Color(0.2f, 0.2f, 0.2f));
UIFactory.SetLayoutElement(updateBtn.gameObject, minWidth: 110, flexibleWidth: 0);
updateBtn.onClick.AddListener(() =>
{
bool orig = m_autoUpdate;
m_autoUpdate = true;
Update();
if (!orig)
m_autoUpdate = orig;
});
// auto update
var autoUpdateObj = UIFactory.CreateToggle(m_updateRowObj, "UpdateToggle", out Toggle autoUpdateToggle, out Text autoUpdateText);
var autoUpdateLayout = autoUpdateObj.AddComponent<LayoutElement>();
autoUpdateLayout.minWidth = 150;
autoUpdateLayout.minHeight = 25;
autoUpdateText.text = "Auto-update?";
autoUpdateToggle.isOn = false;
autoUpdateToggle.onValueChanged.AddListener((bool val) => { m_autoUpdate = val; });
}
internal void ConstructMemberList()
{
m_memberListObj = UIFactory.CreateScrollView(Content, "MemberList", out m_scrollContent, out m_sliderScroller, new Color(0.05f, 0.05f, 0.05f));
m_scrollContentRect = m_scrollContent.GetComponent<RectTransform>();
UIFactory.SetLayoutGroup<VerticalLayoutGroup>(m_scrollContent, forceHeight: true, spacing: 3, padLeft: 0, padRight: 0);
m_pageHandler = new PageHandler(m_sliderScroller);
m_pageHandler.ConstructUI(Content);
m_pageHandler.OnPageChanged += OnPageTurned;
}
} }
}
#endregion
}

View File

@ -1,288 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.Core.Inspectors;
using UnityExplorer.Core.Inspectors.Reflection;
using UnityExplorer.UI.Reusable;
using UnityExplorer.UI.Utility;
namespace UnityExplorer.UI.Main.Home.Inspectors
{
public class ReflectionInspectorUI : InspectorBaseUI
{
public ReflectionInspectorUI(ReflectionInspector parent)
{
this.Parent = parent;
}
public ReflectionInspector Parent;
// UI members
private GameObject m_content;
public override GameObject Content
{
get => m_content;
set => m_content = value;
}
internal Text m_nameFilterText;
internal MemberTypes m_memberFilter;
internal Button m_lastActiveMemButton;
internal PageHandler m_pageHandler;
internal SliderScrollbar m_sliderScroller;
internal GameObject m_scrollContent;
internal RectTransform m_scrollContentRect;
internal bool m_widthUpdateWanted;
internal bool m_widthUpdateWaiting;
internal GameObject m_filterAreaObj;
internal GameObject m_updateRowObj;
internal GameObject m_memberListObj;
internal void ConstructUI()
{
var parent = InspectorManager.UI.m_inspectorContent;
this.Content = UIFactory.CreateVerticalGroup(parent, new Color(0.15f, 0.15f, 0.15f));
var mainGroup = Content.GetComponent<VerticalLayoutGroup>();
mainGroup.childForceExpandHeight = false;
mainGroup.childForceExpandWidth = true;
mainGroup.childControlHeight = true;
mainGroup.childControlWidth = true;
mainGroup.spacing = 5;
mainGroup.padding.top = 4;
mainGroup.padding.left = 4;
mainGroup.padding.right = 4;
mainGroup.padding.bottom = 4;
ConstructTopArea();
ConstructMemberList();
}
internal void ConstructTopArea()
{
var nameRowObj = UIFactory.CreateHorizontalGroup(Content, new Color(1, 1, 1, 0));
var nameRow = nameRowObj.GetComponent<HorizontalLayoutGroup>();
nameRow.childForceExpandWidth = true;
nameRow.childForceExpandHeight = true;
nameRow.childControlHeight = true;
nameRow.childControlWidth = true;
nameRow.padding.top = 2;
var nameRowLayout = nameRowObj.AddComponent<LayoutElement>();
nameRowLayout.minHeight = 25;
nameRowLayout.flexibleHeight = 0;
nameRowLayout.minWidth = 200;
nameRowLayout.flexibleWidth = 5000;
var typeLabel = UIFactory.CreateLabel(nameRowObj, TextAnchor.MiddleLeft);
var typeLabelText = typeLabel.GetComponent<Text>();
typeLabelText.text = "Type:";
typeLabelText.horizontalOverflow = HorizontalWrapMode.Overflow;
var typeLabelTextLayout = typeLabel.AddComponent<LayoutElement>();
typeLabelTextLayout.minWidth = 40;
typeLabelTextLayout.flexibleWidth = 0;
typeLabelTextLayout.minHeight = 25;
var typeDisplayObj = UIFactory.CreateLabel(nameRowObj, TextAnchor.MiddleLeft);
var typeDisplayText = typeDisplayObj.GetComponent<Text>();
typeDisplayText.text = SignatureHighlighter.ParseFullSyntax(Parent.m_targetType, true);
var typeDisplayLayout = typeDisplayObj.AddComponent<LayoutElement>();
typeDisplayLayout.minHeight = 25;
typeDisplayLayout.flexibleWidth = 5000;
// instance helper tools
if (Parent is InstanceInspector instanceInspector)
{
instanceInspector.CreateInstanceUIModule();
instanceInspector.InstanceUI.ConstructInstanceHelpers();
}
ConstructFilterArea();
ConstructUpdateRow();
}
internal void ConstructFilterArea()
{
// Filters
var filterAreaObj = UIFactory.CreateVerticalGroup(Content, new Color(0.1f, 0.1f, 0.1f));
var filterLayout = filterAreaObj.AddComponent<LayoutElement>();
filterLayout.minHeight = 60;
var filterGroup = filterAreaObj.GetComponent<VerticalLayoutGroup>();
filterGroup.childForceExpandWidth = true;
filterGroup.childForceExpandHeight = true;
filterGroup.childControlWidth = true;
filterGroup.childControlHeight = true;
filterGroup.spacing = 4;
filterGroup.padding.left = 4;
filterGroup.padding.right = 4;
filterGroup.padding.top = 4;
filterGroup.padding.bottom = 4;
m_filterAreaObj = filterAreaObj;
// name filter
var nameFilterRowObj = UIFactory.CreateHorizontalGroup(filterAreaObj, new Color(1, 1, 1, 0));
var nameFilterGroup = nameFilterRowObj.GetComponent<HorizontalLayoutGroup>();
nameFilterGroup.childForceExpandHeight = false;
nameFilterGroup.childForceExpandWidth = false;
nameFilterGroup.childControlWidth = true;
nameFilterGroup.childControlHeight = true;
nameFilterGroup.spacing = 5;
var nameFilterLayout = nameFilterRowObj.AddComponent<LayoutElement>();
nameFilterLayout.minHeight = 25;
nameFilterLayout.flexibleHeight = 0;
nameFilterLayout.flexibleWidth = 5000;
var nameLabelObj = UIFactory.CreateLabel(nameFilterRowObj, TextAnchor.MiddleLeft);
var nameLabelLayout = nameLabelObj.AddComponent<LayoutElement>();
nameLabelLayout.minWidth = 100;
nameLabelLayout.minHeight = 25;
nameLabelLayout.flexibleWidth = 0;
var nameLabelText = nameLabelObj.GetComponent<Text>();
nameLabelText.text = "Filter names:";
nameLabelText.color = Color.grey;
var nameInputObj = UIFactory.CreateInputField(nameFilterRowObj, 14, (int)TextAnchor.MiddleLeft, (int)HorizontalWrapMode.Overflow);
var nameInputLayout = nameInputObj.AddComponent<LayoutElement>();
nameInputLayout.flexibleWidth = 5000;
nameInputLayout.minWidth = 100;
nameInputLayout.minHeight = 25;
var nameInput = nameInputObj.GetComponent<InputField>();
nameInput.onValueChanged.AddListener((string val) => { Parent.FilterMembers(val); });
m_nameFilterText = nameInput.textComponent;
// membertype filter
var memberFilterRowObj = UIFactory.CreateHorizontalGroup(filterAreaObj, new Color(1, 1, 1, 0));
var memFilterGroup = memberFilterRowObj.GetComponent<HorizontalLayoutGroup>();
memFilterGroup.childForceExpandHeight = false;
memFilterGroup.childForceExpandWidth = false;
memFilterGroup.childControlWidth = true;
memFilterGroup.childControlHeight = true;
memFilterGroup.spacing = 5;
var memFilterLayout = memberFilterRowObj.AddComponent<LayoutElement>();
memFilterLayout.minHeight = 25;
memFilterLayout.flexibleHeight = 0;
memFilterLayout.flexibleWidth = 5000;
var memLabelObj = UIFactory.CreateLabel(memberFilterRowObj, TextAnchor.MiddleLeft);
var memLabelLayout = memLabelObj.AddComponent<LayoutElement>();
memLabelLayout.minWidth = 100;
memLabelLayout.minHeight = 25;
memLabelLayout.flexibleWidth = 0;
var memLabelText = memLabelObj.GetComponent<Text>();
memLabelText.text = "Filter members:";
memLabelText.color = Color.grey;
AddFilterButton(memberFilterRowObj, MemberTypes.All);
AddFilterButton(memberFilterRowObj, MemberTypes.Method);
AddFilterButton(memberFilterRowObj, MemberTypes.Property, true);
AddFilterButton(memberFilterRowObj, MemberTypes.Field);
// Instance filters
if (Parent is InstanceInspector instanceInspector)
{
instanceInspector.InstanceUI.ConstructInstanceFilters(filterAreaObj);
}
}
private void AddFilterButton(GameObject parent, MemberTypes type, bool setEnabled = false)
{
var btnObj = UIFactory.CreateButton(parent, new Color(0.2f, 0.2f, 0.2f));
var btnLayout = btnObj.AddComponent<LayoutElement>();
btnLayout.minHeight = 25;
btnLayout.minWidth = 70;
var text = btnObj.GetComponentInChildren<Text>();
text.text = type.ToString();
var btn = btnObj.GetComponent<Button>();
btn.onClick.AddListener(() => { Parent.OnMemberFilterClicked(type, btn); });
var colors = btn.colors;
colors.highlightedColor = new Color(0.3f, 0.7f, 0.3f);
if (setEnabled)
{
colors.normalColor = new Color(0.2f, 0.6f, 0.2f);
m_memberFilter = type;
m_lastActiveMemButton = btn;
}
btn.colors = colors;
}
internal void ConstructUpdateRow()
{
var optionsRowObj = UIFactory.CreateHorizontalGroup(Content, new Color(1, 1, 1, 0));
var optionsLayout = optionsRowObj.AddComponent<LayoutElement>();
optionsLayout.minHeight = 25;
var optionsGroup = optionsRowObj.GetComponent<HorizontalLayoutGroup>();
optionsGroup.childForceExpandHeight = true;
optionsGroup.childForceExpandWidth = false;
optionsGroup.childAlignment = TextAnchor.MiddleLeft;
optionsGroup.spacing = 10;
m_updateRowObj = optionsRowObj;
// update button
var updateButtonObj = UIFactory.CreateButton(optionsRowObj, new Color(0.2f, 0.2f, 0.2f));
var updateBtnLayout = updateButtonObj.AddComponent<LayoutElement>();
updateBtnLayout.minWidth = 110;
updateBtnLayout.flexibleWidth = 0;
var updateText = updateButtonObj.GetComponentInChildren<Text>();
updateText.text = "Update Values";
var updateBtn = updateButtonObj.GetComponent<Button>();
updateBtn.onClick.AddListener(() =>
{
bool orig = Parent.m_autoUpdate;
Parent.m_autoUpdate = true;
Parent.Update();
if (!orig) Parent.m_autoUpdate = orig;
});
// auto update
var autoUpdateObj = UIFactory.CreateToggle(optionsRowObj, out Toggle autoUpdateToggle, out Text autoUpdateText);
var autoUpdateLayout = autoUpdateObj.AddComponent<LayoutElement>();
autoUpdateLayout.minWidth = 150;
autoUpdateLayout.minHeight = 25;
autoUpdateText.text = "Auto-update?";
autoUpdateToggle.isOn = false;
autoUpdateToggle.onValueChanged.AddListener((bool val) => { Parent.m_autoUpdate = val; });
}
internal void ConstructMemberList()
{
var scrollobj = UIFactory.CreateScrollView(Content, out m_scrollContent, out m_sliderScroller, new Color(0.05f, 0.05f, 0.05f));
m_memberListObj = scrollobj;
m_scrollContentRect = m_scrollContent.GetComponent<RectTransform>();
var scrollGroup = m_scrollContent.GetComponent<VerticalLayoutGroup>();
scrollGroup.spacing = 3;
scrollGroup.padding.left = 0;
scrollGroup.padding.right = 0;
scrollGroup.childForceExpandHeight = true;
m_pageHandler = new PageHandler(m_sliderScroller);
m_pageHandler.ConstructUI(Content);
m_pageHandler.OnPageChanged += Parent.OnPageTurned;
}
}
}

View File

@ -1,6 +1,9 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace UnityExplorer.Core.Inspectors.Reflection namespace UnityExplorer.UI.Main.Home.Inspectors.Reflection
{ {
public class StaticInspector : ReflectionInspector public class StaticInspector : ReflectionInspector
{ {

View File

@ -0,0 +1,512 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UnityExplorer.UI;
using UnityExplorer.UI.Main;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using UnityExplorer.Core.Runtime;
using UnityExplorer.UI.Main.Home;
using UnityExplorer.Core.Config;
using UnityExplorer.UI.Utility;
using UnityExplorer.UI.Main.Search;
namespace UnityExplorer.UI.Main.Home
{
public class SceneExplorer
{
public static SceneExplorer Instance;
internal static Action<bool> OnToggleShow;
public SceneExplorer()
{
Instance = this;
ConstructScenePane();
}
internal bool Hiding;
private const float UPDATE_INTERVAL = 1f;
private float m_timeOfLastSceneUpdate;
// private int m_currentSceneHandle = -1;
public static Scene DontDestroyScene => DontDestroyObject.scene;
internal Scene m_currentScene;
internal Scene[] m_currentScenes = new Scene[0];
internal GameObject[] m_allObjects = new GameObject[0];
internal GameObject m_selectedSceneObject;
internal int m_lastCount;
private Dropdown m_sceneDropdown;
private Text m_sceneDropdownText;
private Text m_scenePathText;
private GameObject m_mainInspectBtn;
private GameObject m_backButtonObj;
public PageHandler m_pageHandler;
private GameObject m_pageContent;
private readonly List<Text> m_shortListTexts = new List<Text>();
private readonly List<Toggle> m_shortListToggles = new List<Toggle>();
internal readonly List<GameObject> m_shortList = new List<GameObject>();
private Text m_hideText;
private GameObject m_titleObj;
private GameObject m_sceneDropdownObj;
private GameObject m_scenePathGroupObj;
private GameObject m_scrollObj;
private LayoutElement m_leftLayout;
internal static GameObject DontDestroyObject
{
get
{
if (!s_dontDestroyObject)
{
s_dontDestroyObject = new GameObject("DontDestroyMe");
GameObject.DontDestroyOnLoad(s_dontDestroyObject);
}
return s_dontDestroyObject;
}
}
internal static GameObject s_dontDestroyObject;
public void Init()
{
RefreshSceneSelector();
if (!ConfigManager.Last_SceneExplorer_State.Value)
ToggleShow();
}
public void Update()
{
if (Hiding || Time.realtimeSinceStartup - m_timeOfLastSceneUpdate < UPDATE_INTERVAL)
return;
RefreshSceneSelector();
if (!m_selectedSceneObject)
{
if (m_currentScene != default)
{
var rootObjects = RuntimeProvider.Instance.GetRootGameObjects(m_currentScene);
SetSceneObjectList(rootObjects);
}
}
else
{
RefreshSelectedSceneObject();
}
}
private void RefreshSceneSelector()
{
var newNames = new List<string>();
var newScenes = new List<Scene>();
if (m_currentScenes == null)
m_currentScenes = new Scene[0];
bool anyChange = SceneManager.sceneCount != m_currentScenes.Length - 1;
for (int i = 0; i < SceneManager.sceneCount; i++)
{
Scene scene = SceneManager.GetSceneAt(i);
if (scene == default)
continue;
int handle = RuntimeProvider.Instance.GetSceneHandle(scene);
if (!anyChange && !m_currentScenes.Any(it => handle == RuntimeProvider.Instance.GetSceneHandle(it)))
anyChange = true;
newScenes.Add(scene);
newNames.Add(scene.name);
}
if (anyChange)
{
newNames.Add("DontDestroyOnLoad");
newScenes.Add(DontDestroyScene);
m_currentScenes = newScenes.ToArray();
OnActiveScenesChanged(newNames);
SetTargetScene(newScenes[0]);
SearchPage.Instance.OnSceneChange();
}
}
public void SetTargetScene(int index)
=> SetTargetScene(m_currentScenes[index]);
public void SetTargetScene(Scene scene)
{
if (scene == default)
return;
m_currentScene = scene;
var rootObjs = RuntimeProvider.Instance.GetRootGameObjects(scene);
SetSceneObjectList(rootObjs);
m_selectedSceneObject = null;
OnSceneSelected();
}
public void SetSceneObjectParent()
{
if (!m_selectedSceneObject || !m_selectedSceneObject.transform.parent?.gameObject)
{
m_selectedSceneObject = null;
SetTargetScene(m_currentScene);
}
else
{
SetTargetObject(m_selectedSceneObject.transform.parent.gameObject);
}
}
public void SetTargetObject(GameObject obj)
{
if (!obj)
return;
OnGameObjectSelected(obj);
m_selectedSceneObject = obj;
RefreshSelectedSceneObject();
}
private void RefreshSelectedSceneObject()
{
GameObject[] list = new GameObject[m_selectedSceneObject.transform.childCount];
for (int i = 0; i < m_selectedSceneObject.transform.childCount; i++)
{
list[i] = m_selectedSceneObject.transform.GetChild(i).gameObject;
}
SetSceneObjectList(list);
}
private void SetSceneObjectList(GameObject[] objects)
{
m_allObjects = objects;
RefreshSceneObjectList();
}
internal void RefreshSceneObjectList()
{
m_timeOfLastSceneUpdate = Time.realtimeSinceStartup;
RefreshSceneObjectList(m_allObjects, out int newCount);
m_lastCount = newCount;
}
internal static void InspectSelectedGameObject()
{
InspectorManager.Instance.Inspect(Instance.m_selectedSceneObject);
}
internal static void InvokeOnToggleShow()
{
OnToggleShow?.Invoke(!Instance.Hiding);
}
public void ToggleShow()
{
if (!Hiding)
{
Hiding = true;
m_hideText.text = "►";
m_titleObj.SetActive(false);
m_sceneDropdownObj.SetActive(false);
m_scenePathGroupObj.SetActive(false);
m_scrollObj.SetActive(false);
m_pageHandler.Hide();
m_leftLayout.minWidth = 15;
}
else
{
Hiding = false;
m_hideText.text = "Hide Scene Explorer";
m_titleObj.SetActive(true);
m_sceneDropdownObj.SetActive(true);
m_scenePathGroupObj.SetActive(true);
m_scrollObj.SetActive(true);
m_leftLayout.minWidth = 350;
Update();
}
InvokeOnToggleShow();
}
public void OnActiveScenesChanged(List<string> newNames)
{
m_sceneDropdown.options.Clear();
foreach (string scene in newNames)
{
m_sceneDropdown.options.Add(new Dropdown.OptionData { text = scene });
}
m_sceneDropdown.OnCancel(null);
m_sceneDropdownText.text = newNames[0];
}
private void SceneListObjectClicked(int index)
{
if (index >= m_shortList.Count || !m_shortList[index])
{
return;
}
var obj = m_shortList[index];
if (obj.transform.childCount > 0)
SetTargetObject(obj);
else
InspectorManager.Instance.Inspect(obj);
}
internal void RefreshSceneObjectList(GameObject[] allObjects, out int newCount)
{
var objects = allObjects;
m_pageHandler.ListCount = objects.Length;
//int startIndex = m_sceneListPageHandler.StartIndex;
newCount = 0;
foreach (var itemIndex in m_pageHandler)
{
newCount++;
// normalized index starting from 0
var i = itemIndex - m_pageHandler.StartIndex;
if (itemIndex >= objects.Length)
{
if (i > SceneExplorer.Instance.m_lastCount || i >= m_shortListTexts.Count)
break;
GameObject label = m_shortListTexts[i].transform.parent.parent.gameObject;
if (label.activeSelf)
label.SetActive(false);
}
else
{
GameObject obj = objects[itemIndex];
if (!obj)
continue;
if (i >= m_shortList.Count)
{
m_shortList.Add(obj);
AddObjectListButton();
}
else
{
m_shortList[i] = obj;
}
var text = m_shortListTexts[i];
var name = obj.name;
if (obj.transform.childCount > 0)
name = $"<color=grey>[{obj.transform.childCount}]</color> {name}";
text.text = name;
text.color = obj.activeSelf ? Color.green : Color.red;
var tog = m_shortListToggles[i];
tog.isOn = obj.activeSelf;
var label = text.transform.parent.parent.gameObject;
if (!label.activeSelf)
{
label.SetActive(true);
}
}
}
}
private void OnSceneListPageTurn()
{
RefreshSceneObjectList();
}
private void OnToggleClicked(int index, bool val)
{
if (index >= m_shortList.Count || !m_shortList[index])
return;
var obj = m_shortList[index];
obj.SetActive(val);
}
internal void OnGameObjectSelected(GameObject obj)
{
m_scenePathText.text = obj.name;
if (!m_backButtonObj.activeSelf)
{
m_backButtonObj.SetActive(true);
m_mainInspectBtn.SetActive(true);
}
}
internal void OnSceneSelected()
{
if (m_backButtonObj.activeSelf)
{
m_backButtonObj.SetActive(false);
m_mainInspectBtn.SetActive(false);
}
m_scenePathText.text = "Scene root:";
//m_scenePathText.ForceMeshUpdate();
}
#region UI CONSTRUCTION
public void ConstructScenePane()
{
GameObject leftPane = UIFactory.CreateVerticalGroup(HomePage.Instance.Content, "SceneGroup", true, false, true, true, 0, default,
new Color(72f / 255f, 72f / 255f, 72f / 255f));
m_leftLayout = leftPane.AddComponent<LayoutElement>();
m_leftLayout.minWidth = 350;
m_leftLayout.flexibleWidth = 0;
UIFactory.SetLayoutGroup<VerticalLayoutGroup>(leftPane, true, true, true, true, spacing: 4, padTop: 8, 4, 4, 4);
m_titleObj = UIFactory.CreateLabel(leftPane, "SceneExplorerTitle", "Scene Explorer", TextAnchor.UpperLeft, default, true, 20).gameObject;
UIFactory.SetLayoutElement(m_titleObj, minHeight: 30, flexibleHeight: 0);
m_sceneDropdownObj = UIFactory.CreateDropdown(leftPane, out m_sceneDropdown, "<notset>", 14, null);
UIFactory.SetLayoutElement(m_sceneDropdownObj, minHeight: 40, minWidth: 320, flexibleWidth: 0, flexibleHeight: 0);
m_sceneDropdownText = m_sceneDropdown.transform.Find("Label").GetComponent<Text>();
m_sceneDropdown.onValueChanged.AddListener((int val) => { SetTargetScene(val); });
m_scenePathGroupObj = UIFactory.CreateHorizontalGroup(leftPane, "ScenePathGroup", true, true, true, true, 5, default, new Color(1, 1, 1, 0f));
UIFactory.SetLayoutElement(m_scenePathGroupObj, minHeight: 20, minWidth: 335);
var backBtnObj = UIFactory.CreateButton(m_scenePathGroupObj,
"BackButton",
"◄",
() => { SetSceneObjectParent(); },
new Color(0.12f, 0.12f, 0.12f));
m_backButtonObj = backBtnObj.gameObject;
UIFactory.SetLayoutElement(m_backButtonObj, minWidth: 40, flexibleWidth: 0);
GameObject scenePathLabel = UIFactory.CreateHorizontalGroup(m_scenePathGroupObj, "ScenePathLabel", false, false, false, false);
Image image = scenePathLabel.GetComponent<Image>();
image.color = Color.white;
scenePathLabel.AddComponent<Mask>().showMaskGraphic = false;
UIFactory.SetLayoutElement(scenePathLabel, minWidth: 210, minHeight: 20, flexibleWidth: 120);
m_scenePathText = UIFactory.CreateLabel(scenePathLabel, "ScenePathLabelText", "Scene root:", TextAnchor.MiddleLeft, default, true, 15);
m_scenePathText.horizontalOverflow = HorizontalWrapMode.Overflow;
UIFactory.SetLayoutElement(m_scenePathText.gameObject, minWidth: 210, flexibleWidth: 120, minHeight: 20);
var mainInspectButton = UIFactory.CreateButton(m_scenePathGroupObj,
"MainInspectButton",
"Inspect",
() => { InspectSelectedGameObject(); },
new Color(0.12f, 0.12f, 0.12f));
m_mainInspectBtn = mainInspectButton.gameObject;
UIFactory.SetLayoutElement(m_mainInspectBtn, minWidth: 65);
m_scrollObj = UIFactory.CreateScrollView(leftPane, "SceneExplorerScrollView",
out m_pageContent, out SliderScrollbar scroller, new Color(0.1f, 0.1f, 0.1f));
m_pageHandler = new PageHandler(scroller);
m_pageHandler.ConstructUI(leftPane);
m_pageHandler.OnPageChanged += OnSceneListPageTurn;
// hide button
var hideButton = UIFactory.CreateButton(leftPane, "HideButton", "Hide Scene Explorer", ToggleShow, new Color(0.15f, 0.15f, 0.15f));
hideButton.GetComponentInChildren<Text>().fontSize = 13;
m_hideText = hideButton.GetComponentInChildren<Text>();
UIFactory.SetLayoutElement(hideButton.gameObject, minWidth: 20, minHeight: 20);
}
private void AddObjectListButton()
{
int thisIndex = m_shortListTexts.Count();
GameObject btnGroupObj = UIFactory.CreateHorizontalGroup(m_pageContent, "SceneObjectButton", true, false, true, true,
0, default, new Color(0.1f, 0.1f, 0.1f));
UIFactory.SetLayoutElement(btnGroupObj, flexibleWidth: 320, minHeight: 25);
btnGroupObj.AddComponent<Mask>();
var toggleObj = UIFactory.CreateToggle(btnGroupObj, "ObjectToggleButton", out Toggle toggle, out Text toggleText, new Color(0.1f, 0.1f, 0.1f));
var toggleLayout = toggleObj.AddComponent<LayoutElement>();
toggleLayout.minHeight = 25;
toggleLayout.minWidth = 25;
toggleText.text = "";
toggle.isOn = false;
m_shortListToggles.Add(toggle);
toggle.onValueChanged.AddListener((bool val) => { OnToggleClicked(thisIndex, val); });
ColorBlock mainColors = new ColorBlock();
mainColors.normalColor = new Color(0.1f, 0.1f, 0.1f);
mainColors.highlightedColor = new Color(0.2f, 0.2f, 0.2f);
mainColors.pressedColor = new Color(0.05f, 0.05f, 0.05f);
var mainButton = UIFactory.CreateButton(btnGroupObj,
"MainButton",
"",
() => { SceneListObjectClicked(thisIndex); },
mainColors);
UIFactory.SetLayoutElement(mainButton.gameObject, minHeight: 25, minWidth: 230);
Text mainText = mainButton.GetComponentInChildren<Text>();
mainText.alignment = TextAnchor.MiddleLeft;
mainText.horizontalOverflow = HorizontalWrapMode.Overflow;
m_shortListTexts.Add(mainText);
ColorBlock inspectColors = new ColorBlock();
inspectColors.normalColor = new Color(0.15f, 0.15f, 0.15f);
inspectColors.highlightedColor = new Color(0.2f, 0.2f, 0.2f);
inspectColors.pressedColor = new Color(0.1f, 0.1f, 0.1f);
var inspectButton = UIFactory.CreateButton(btnGroupObj,
"InspectButton",
"Inspect",
() => { InspectorManager.Instance.Inspect(m_shortList[thisIndex]); },
inspectColors);
UIFactory.SetLayoutElement(inspectButton.gameObject, minWidth: 60, minHeight: 25);
}
#endregion
}
}

View File

@ -1,386 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.Core.Inspectors;
using UnityExplorer.UI.Main;
using UnityExplorer.UI.Reusable;
namespace UnityExplorer.UI.Main.Home
{
public class SceneExplorerUI
{
internal static bool Hiding;
private Dropdown m_sceneDropdown;
private Text m_sceneDropdownText;
private Text m_scenePathText;
private GameObject m_mainInspectBtn;
private GameObject m_backButtonObj;
public PageHandler m_pageHandler;
private GameObject m_pageContent;
private readonly List<Text> m_shortListTexts = new List<Text>();
private readonly List<Toggle> m_shortListToggles = new List<Toggle>();
internal readonly List<GameObject> m_shortList = new List<GameObject>();
public void OnActiveScenesChanged(List<string> newNames)
{
m_sceneDropdown.options.Clear();
foreach (string scene in newNames)
{
m_sceneDropdown.options.Add(new Dropdown.OptionData { text = scene });
}
m_sceneDropdown.OnCancel(null);
m_sceneDropdownText.text = newNames[0];
}
private void SceneListObjectClicked(int index)
{
if (index >= m_shortList.Count || !m_shortList[index])
{
return;
}
var obj = m_shortList[index];
if (obj.transform.childCount > 0)
SceneExplorer.Instance.SetTargetObject(obj);
else
InspectorManager.Instance.Inspect(obj);
}
internal void RefreshSceneObjectList(GameObject[] allObjects, out int newCount)
{
var objects = allObjects;
m_pageHandler.ListCount = objects.Length;
//int startIndex = m_sceneListPageHandler.StartIndex;
newCount = 0;
foreach (var itemIndex in m_pageHandler)
{
newCount++;
// normalized index starting from 0
var i = itemIndex - m_pageHandler.StartIndex;
if (itemIndex >= objects.Length)
{
if (i > SceneExplorer.Instance.m_lastCount || i >= m_shortListTexts.Count)
break;
GameObject label = m_shortListTexts[i].transform.parent.parent.gameObject;
if (label.activeSelf)
label.SetActive(false);
}
else
{
GameObject obj = objects[itemIndex];
if (!obj)
continue;
if (i >= m_shortList.Count)
{
m_shortList.Add(obj);
AddObjectListButton();
}
else
{
m_shortList[i] = obj;
}
var text = m_shortListTexts[i];
var name = obj.name;
if (obj.transform.childCount > 0)
name = $"<color=grey>[{obj.transform.childCount}]</color> {name}";
text.text = name;
text.color = obj.activeSelf ? Color.green : Color.red;
var tog = m_shortListToggles[i];
tog.isOn = obj.activeSelf;
var label = text.transform.parent.parent.gameObject;
if (!label.activeSelf)
{
label.SetActive(true);
}
}
}
}
private void OnSceneListPageTurn()
{
SceneExplorer.Instance.RefreshSceneObjectList();
}
private void OnToggleClicked(int index, bool val)
{
if (index >= m_shortList.Count || !m_shortList[index])
return;
var obj = m_shortList[index];
obj.SetActive(val);
}
internal void OnGameObjectSelected(GameObject obj)
{
m_scenePathText.text = obj.name;
//m_scenePathText.ForceMeshUpdate();
if (!m_backButtonObj.activeSelf)
{
m_backButtonObj.SetActive(true);
m_mainInspectBtn.SetActive(true);
}
}
internal void OnSceneSelected()
{
if (m_backButtonObj.activeSelf)
{
m_backButtonObj.SetActive(false);
m_mainInspectBtn.SetActive(false);
}
m_scenePathText.text = "Scene root:";
//m_scenePathText.ForceMeshUpdate();
}
#region UI CONSTRUCTION
public void ConstructScenePane()
{
GameObject leftPane = UIFactory.CreateVerticalGroup(HomePage.Instance.Content, new Color(72f / 255f, 72f / 255f, 72f / 255f));
LayoutElement leftLayout = leftPane.AddComponent<LayoutElement>();
leftLayout.minWidth = 350;
leftLayout.flexibleWidth = 0;
VerticalLayoutGroup leftGroup = leftPane.GetComponent<VerticalLayoutGroup>();
leftGroup.padding.left = 4;
leftGroup.padding.right = 4;
leftGroup.padding.top = 8;
leftGroup.padding.bottom = 4;
leftGroup.spacing = 4;
leftGroup.childControlWidth = true;
leftGroup.childControlHeight = true;
leftGroup.childForceExpandWidth = true;
leftGroup.childForceExpandHeight = true;
GameObject titleObj = UIFactory.CreateLabel(leftPane, TextAnchor.UpperLeft);
Text titleLabel = titleObj.GetComponent<Text>();
titleLabel.text = "Scene Explorer";
titleLabel.fontSize = 20;
LayoutElement titleLayout = titleObj.AddComponent<LayoutElement>();
titleLayout.minHeight = 30;
titleLayout.flexibleHeight = 0;
GameObject sceneDropdownObj = UIFactory.CreateDropdown(leftPane, out m_sceneDropdown);
LayoutElement dropdownLayout = sceneDropdownObj.AddComponent<LayoutElement>();
dropdownLayout.minHeight = 40;
dropdownLayout.flexibleHeight = 0;
dropdownLayout.minWidth = 320;
dropdownLayout.flexibleWidth = 2;
m_sceneDropdownText = m_sceneDropdown.transform.Find("Label").GetComponent<Text>();
m_sceneDropdown.onValueChanged.AddListener((int val) => { SetSceneFromDropdown(val); });
void SetSceneFromDropdown(int val)
{
//string scene = m_sceneDropdown.options[val].text;
SceneExplorer.Instance.SetTargetScene(val);
}
GameObject scenePathGroupObj = UIFactory.CreateHorizontalGroup(leftPane, new Color(1, 1, 1, 0f));
HorizontalLayoutGroup scenePathGroup = scenePathGroupObj.GetComponent<HorizontalLayoutGroup>();
scenePathGroup.childControlHeight = true;
scenePathGroup.childControlWidth = true;
scenePathGroup.childForceExpandHeight = true;
scenePathGroup.childForceExpandWidth = true;
scenePathGroup.spacing = 5;
LayoutElement scenePathLayout = scenePathGroupObj.AddComponent<LayoutElement>();
scenePathLayout.minHeight = 20;
scenePathLayout.minWidth = 335;
scenePathLayout.flexibleWidth = 0;
m_backButtonObj = UIFactory.CreateButton(scenePathGroupObj);
Text backButtonText = m_backButtonObj.GetComponentInChildren<Text>();
backButtonText.text = "◄";
LayoutElement backButtonLayout = m_backButtonObj.AddComponent<LayoutElement>();
backButtonLayout.minWidth = 40;
backButtonLayout.flexibleWidth = 0;
Button backButton = m_backButtonObj.GetComponent<Button>();
var colors = backButton.colors;
colors.normalColor = new Color(0.12f, 0.12f, 0.12f);
backButton.colors = colors;
backButton.onClick.AddListener(() => { SceneExplorer.Instance.SetSceneObjectParent(); });
GameObject scenePathLabel = UIFactory.CreateHorizontalGroup(scenePathGroupObj);
Image image = scenePathLabel.GetComponent<Image>();
image.color = Color.white;
LayoutElement scenePathLabelLayout = scenePathLabel.AddComponent<LayoutElement>();
scenePathLabelLayout.minWidth = 210;
scenePathLabelLayout.minHeight = 20;
scenePathLabelLayout.flexibleHeight = 0;
scenePathLabelLayout.flexibleWidth = 120;
scenePathLabel.AddComponent<Mask>().showMaskGraphic = false;
GameObject scenePathLabelText = UIFactory.CreateLabel(scenePathLabel, TextAnchor.MiddleLeft);
m_scenePathText = scenePathLabelText.GetComponent<Text>();
m_scenePathText.text = "Scene root:";
m_scenePathText.fontSize = 15;
m_scenePathText.horizontalOverflow = HorizontalWrapMode.Overflow;
LayoutElement textLayout = scenePathLabelText.gameObject.AddComponent<LayoutElement>();
textLayout.minWidth = 210;
textLayout.flexibleWidth = 120;
textLayout.minHeight = 20;
textLayout.flexibleHeight = 0;
m_mainInspectBtn = UIFactory.CreateButton(scenePathGroupObj);
Text inspectButtonText = m_mainInspectBtn.GetComponentInChildren<Text>();
inspectButtonText.text = "Inspect";
LayoutElement inspectButtonLayout = m_mainInspectBtn.AddComponent<LayoutElement>();
inspectButtonLayout.minWidth = 65;
inspectButtonLayout.flexibleWidth = 0;
Button inspectButton = m_mainInspectBtn.GetComponent<Button>();
colors = inspectButton.colors;
colors.normalColor = new Color(0.12f, 0.12f, 0.12f);
inspectButton.colors = colors;
inspectButton.onClick.AddListener(() => { SceneExplorer.InspectSelectedGameObject(); });
GameObject scrollObj = UIFactory.CreateScrollView(leftPane, out m_pageContent, out SliderScrollbar scroller, new Color(0.1f, 0.1f, 0.1f));
m_pageHandler = new PageHandler(scroller);
m_pageHandler.ConstructUI(leftPane);
m_pageHandler.OnPageChanged += OnSceneListPageTurn;
// hide button
var hideButtonObj = UIFactory.CreateButton(leftPane);
var hideBtn = hideButtonObj.GetComponent<Button>();
var hideColors = hideBtn.colors;
hideColors.normalColor = new Color(0.15f, 0.15f, 0.15f);
hideBtn.colors = hideColors;
var hideText = hideButtonObj.GetComponentInChildren<Text>();
hideText.text = "Hide Scene Explorer";
hideText.fontSize = 13;
var hideLayout = hideButtonObj.AddComponent<LayoutElement>();
hideLayout.minWidth = 20;
hideLayout.minHeight = 20;
hideBtn.onClick.AddListener(OnHide);
void OnHide()
{
if (!Hiding)
{
Hiding = true;
hideText.text = "►";
titleObj.SetActive(false);
sceneDropdownObj.SetActive(false);
scenePathGroupObj.SetActive(false);
scrollObj.SetActive(false);
m_pageHandler.Hide();
leftLayout.minWidth = 15;
}
else
{
Hiding = false;
hideText.text = "Hide Scene Explorer";
titleObj.SetActive(true);
sceneDropdownObj.SetActive(true);
scenePathGroupObj.SetActive(true);
scrollObj.SetActive(true);
leftLayout.minWidth = 350;
SceneExplorer.Instance.Update();
}
SceneExplorer.InvokeOnToggleShow();
}
}
private void AddObjectListButton()
{
int thisIndex = m_shortListTexts.Count();
GameObject btnGroupObj = UIFactory.CreateHorizontalGroup(m_pageContent, new Color(0.1f, 0.1f, 0.1f));
HorizontalLayoutGroup btnGroup = btnGroupObj.GetComponent<HorizontalLayoutGroup>();
btnGroup.childForceExpandWidth = true;
btnGroup.childControlWidth = true;
btnGroup.childForceExpandHeight = false;
btnGroup.childControlHeight = true;
LayoutElement btnLayout = btnGroupObj.AddComponent<LayoutElement>();
btnLayout.flexibleWidth = 320;
btnLayout.minHeight = 25;
btnLayout.flexibleHeight = 0;
btnGroupObj.AddComponent<Mask>();
var toggleObj = UIFactory.CreateToggle(btnGroupObj, out Toggle toggle, out Text toggleText, new Color(0.1f, 0.1f, 0.1f));
var toggleLayout = toggleObj.AddComponent<LayoutElement>();
toggleLayout.minHeight = 25;
toggleLayout.minWidth = 25;
toggleText.text = "";
toggle.isOn = false;
m_shortListToggles.Add(toggle);
toggle.onValueChanged.AddListener((bool val) => { OnToggleClicked(thisIndex, val); });
GameObject mainButtonObj = UIFactory.CreateButton(btnGroupObj);
LayoutElement mainBtnLayout = mainButtonObj.AddComponent<LayoutElement>();
mainBtnLayout.minHeight = 25;
mainBtnLayout.flexibleHeight = 0;
mainBtnLayout.minWidth = 230;
mainBtnLayout.flexibleWidth = 0;
Button mainBtn = mainButtonObj.GetComponent<Button>();
ColorBlock mainColors = mainBtn.colors;
mainColors.normalColor = new Color(0.1f, 0.1f, 0.1f);
mainColors.highlightedColor = new Color(0.2f, 0.2f, 0.2f, 1);
mainBtn.colors = mainColors;
mainBtn.onClick.AddListener(() => { SceneListObjectClicked(thisIndex); });
Text mainText = mainButtonObj.GetComponentInChildren<Text>();
mainText.alignment = TextAnchor.MiddleLeft;
mainText.horizontalOverflow = HorizontalWrapMode.Overflow;
m_shortListTexts.Add(mainText);
GameObject inspectBtnObj = UIFactory.CreateButton(btnGroupObj);
LayoutElement inspectBtnLayout = inspectBtnObj.AddComponent<LayoutElement>();
inspectBtnLayout.minWidth = 60;
inspectBtnLayout.flexibleWidth = 0;
inspectBtnLayout.minHeight = 25;
inspectBtnLayout.flexibleHeight = 0;
Text inspectText = inspectBtnObj.GetComponentInChildren<Text>();
inspectText.text = "Inspect";
inspectText.color = Color.white;
Button inspectBtn = inspectBtnObj.GetComponent<Button>();
ColorBlock inspectColors = inspectBtn.colors;
inspectColors.normalColor = new Color(0.15f, 0.15f, 0.15f);
mainColors.highlightedColor = new Color(0.2f, 0.2f, 0.2f, 0.5f);
inspectBtn.colors = inspectColors;
inspectBtn.onClick.AddListener(() => { InspectorManager.Instance.Inspect(m_shortList[thisIndex]); });
}
#endregion
}
}

View File

@ -6,7 +6,10 @@ using UnityEngine.UI;
using UnityExplorer.Core.Config; using UnityExplorer.Core.Config;
using UnityExplorer.Core.Unity; using UnityExplorer.Core.Unity;
using UnityExplorer.UI.Main; using UnityExplorer.UI.Main;
using UnityExplorer.UI.Main.Home;
using UnityExplorer.UI.Main.Search;
using UnityExplorer.UI.Main.CSConsole; using UnityExplorer.UI.Main.CSConsole;
using UnityExplorer.UI.Main.Options;
namespace UnityExplorer.UI.Main namespace UnityExplorer.UI.Main
{ {
@ -22,13 +25,21 @@ namespace UnityExplorer.UI.Main
public readonly List<BaseMenuPage> Pages = new List<BaseMenuPage>(); public readonly List<BaseMenuPage> Pages = new List<BaseMenuPage>();
private BaseMenuPage m_activePage; private BaseMenuPage m_activePage;
public static Action<int> OnActiveTabChanged;
// Navbar buttons // Navbar buttons
private Button m_lastNavButtonPressed; private Button m_lastNavButtonPressed;
private readonly Color m_navButtonNormal = new Color(0.3f, 0.3f, 0.3f, 1); private readonly Color m_navButtonNormal = new Color(0.3f, 0.3f, 0.3f, 1);
private readonly Color m_navButtonHighlight = new Color(0.3f, 0.6f, 0.3f); private readonly Color m_navButtonHighlight = new Color(0.3f, 0.6f, 0.3f);
private readonly Color m_navButtonSelected = new Color(0.2f, 0.5f, 0.2f, 1); private readonly Color m_navButtonSelected = new Color(0.2f, 0.5f, 0.2f, 1);
public MainMenu() internal Vector3 initPos;
internal bool pageLayoutInit;
internal int layoutInitIndex;
private int origDesiredPage = -1;
public static void Create()
{ {
if (Instance != null) if (Instance != null)
{ {
@ -36,8 +47,12 @@ namespace UnityExplorer.UI.Main
return; return;
} }
Instance = this; Instance = new MainMenu();
Instance.Init();
}
private void Init()
{
Pages.Add(new HomePage()); Pages.Add(new HomePage());
Pages.Add(new SearchPage()); Pages.Add(new SearchPage());
Pages.Add(new CSharpConsole()); Pages.Add(new CSharpConsole());
@ -48,7 +63,7 @@ namespace UnityExplorer.UI.Main
for (int i = 0; i < Pages.Count; i++) for (int i = 0; i < Pages.Count; i++)
{ {
var page = Pages[i]; var page = Pages[i];
if (!page.Init()) if (!page.Init())
{ {
// page init failed. // page init failed.
@ -57,7 +72,7 @@ namespace UnityExplorer.UI.Main
if (page.RefNavbarButton) if (page.RefNavbarButton)
page.RefNavbarButton.interactable = false; page.RefNavbarButton.interactable = false;
if (page.Content) if (page.Content)
GameObject.Destroy(page.Content); GameObject.Destroy(page.Content);
} }
@ -68,14 +83,13 @@ namespace UnityExplorer.UI.Main
MainPanel.transform.position = new Vector3(9999, 9999); MainPanel.transform.position = new Vector3(9999, 9999);
} }
internal Vector3 initPos;
internal bool pageLayoutInit;
internal int layoutInitIndex;
public void Update() public void Update()
{ {
if (!pageLayoutInit) if (!pageLayoutInit)
{ {
if (origDesiredPage == -1)
origDesiredPage = ConfigManager.Last_Active_Tab?.Value ?? 0;
if (layoutInitIndex < Pages.Count) if (layoutInitIndex < Pages.Count)
{ {
SetPage(Pages[layoutInitIndex]); SetPage(Pages[layoutInitIndex]);
@ -85,7 +99,7 @@ namespace UnityExplorer.UI.Main
{ {
pageLayoutInit = true; pageLayoutInit = true;
MainPanel.transform.position = initPos; MainPanel.transform.position = initPos;
SetPage(Pages[0]); SetPage(Pages[origDesiredPage]);
} }
return; return;
} }
@ -98,19 +112,6 @@ namespace UnityExplorer.UI.Main
if (page == null || m_activePage == page) if (page == null || m_activePage == page)
return; return;
// WIP, was going to hide current page if you press current page's button,
// but the main panel does not resize so its just a big empty gap there.
// Could be good if I resize that gap, not bothering for now.
// Would need a fix in PanelDragger as well.
//if (m_activePage == page)
//{
// SetButtonInactiveColors(page.RefNavbarButton);
// m_activePage.Content.SetActive(false);
// m_activePage = null;
// return;
//}
m_activePage?.Content?.SetActive(false); m_activePage?.Content?.SetActive(false);
// unique case for console page, at the moment this will just go here // unique case for console page, at the moment this will just go here
@ -128,6 +129,8 @@ namespace UnityExplorer.UI.Main
SetButtonInactiveColors(m_lastNavButtonPressed); SetButtonInactiveColors(m_lastNavButtonPressed);
m_lastNavButtonPressed = button; m_lastNavButtonPressed = button;
OnActiveTabChanged?.Invoke(Pages.IndexOf(m_activePage));
} }
internal void SetButtonActiveColors(Button button) internal void SetButtonActiveColors(Button button)
@ -148,64 +151,29 @@ namespace UnityExplorer.UI.Main
private void ConstructMenu() private void ConstructMenu()
{ {
MainPanel = UIFactory.CreatePanel(UIManager.CanvasRoot, "MainMenu", out GameObject content); MainPanel = UIFactory.CreatePanel("MainMenu", out GameObject content, ConfigManager.Last_Window_Anchors.Value);
RectTransform panelRect = MainPanel.GetComponent<RectTransform>();
var anchors = ExplorerConfig.Instance.GetWindowAnchorsVector();
SetPanelAnchors(panelRect, anchors);
if (panelRect.rect.width < 400 || panelRect.rect.height < 400)
{
anchors = ExplorerConfig.DefaultWindowAnchors();
SetPanelAnchors(panelRect, anchors);
}
MainPanel.AddComponent<Mask>();
ConstructTitleBar(content); ConstructTitleBar(content);
ConstructNavbar(content); ConstructNavbar(content);
ConstructMainViewport(content); PageViewport = UIFactory.CreateHorizontalGroup(content, "MainViewPort", true, true, true, true);
new DebugConsole(content); new DebugConsole(content);
} }
private void SetPanelAnchors(RectTransform panelRect, Vector4 anchors)
{
panelRect.anchorMin = new Vector2(anchors.x, anchors.y);
panelRect.anchorMax = new Vector2(anchors.z, anchors.w);
}
private void ConstructTitleBar(GameObject content) private void ConstructTitleBar(GameObject content)
{ {
// Core title bar holder // Core title bar holder
GameObject titleBar = UIFactory.CreateHorizontalGroup(content); GameObject titleBar = UIFactory.CreateHorizontalGroup(content, "MainTitleBar", true, true, true, true, 0, new Vector4(3,3,15,3));
UIFactory.SetLayoutElement(titleBar, minWidth: 25, flexibleHeight: 0);
HorizontalLayoutGroup titleGroup = titleBar.GetComponent<HorizontalLayoutGroup>(); // Main title label
titleGroup.childControlHeight = true;
titleGroup.childControlWidth = true;
titleGroup.childForceExpandHeight = true;
titleGroup.childForceExpandWidth = true;
titleGroup.padding.left = 15;
titleGroup.padding.right = 3;
titleGroup.padding.top = 3;
titleGroup.padding.bottom = 3;
LayoutElement titleLayout = titleBar.AddComponent<LayoutElement>(); var text = UIFactory.CreateLabel(titleBar, "TitleLabel", $"<b>UnityExplorer</b> <i>v{ExplorerCore.VERSION}</i>", TextAnchor.MiddleLeft,
titleLayout.minHeight = 25; default, true, 15);
titleLayout.flexibleHeight = 0; UIFactory.SetLayoutElement(text.gameObject, flexibleWidth: 5000);
// Explorer label
GameObject textObj = UIFactory.CreateLabel(titleBar, TextAnchor.MiddleLeft);
Text text = textObj.GetComponent<Text>();
text.text = $"<b>UnityExplorer</b> <i>v{ExplorerCore.VERSION}</i>";
text.fontSize = 15;
LayoutElement textLayout = textObj.AddComponent<LayoutElement>();
textLayout.flexibleWidth = 5000;
// Add PanelDragger using the label object // Add PanelDragger using the label object
@ -213,84 +181,53 @@ namespace UnityExplorer.UI.Main
// Hide button // Hide button
GameObject hideBtnObj = UIFactory.CreateButton(titleBar); ColorBlock colorBlock = new ColorBlock();
Button hideBtn = hideBtnObj.GetComponent<Button>();
hideBtn.onClick.AddListener(() => { UIManager.ShowMenu = false; });
ColorBlock colorBlock = hideBtn.colors;
colorBlock.normalColor = new Color(65f / 255f, 23f / 255f, 23f / 255f); colorBlock.normalColor = new Color(65f / 255f, 23f / 255f, 23f / 255f);
colorBlock.pressedColor = new Color(35f / 255f, 10f / 255f, 10f / 255f); colorBlock.pressedColor = new Color(35f / 255f, 10f / 255f, 10f / 255f);
colorBlock.highlightedColor = new Color(156f / 255f, 0f, 0f); colorBlock.highlightedColor = new Color(156f / 255f, 0f, 0f);
hideBtn.colors = colorBlock;
LayoutElement btnLayout = hideBtnObj.AddComponent<LayoutElement>(); var hideButton = UIFactory.CreateButton(titleBar,
btnLayout.minWidth = 90; "HideButton",
btnLayout.flexibleWidth = 2; $"Hide ({ConfigManager.Main_Menu_Toggle.Value})",
() => { UIManager.ShowMenu = false; },
colorBlock);
Text hideText = hideBtnObj.GetComponentInChildren<Text>(); UIFactory.SetLayoutElement(hideButton.gameObject, minWidth: 90, flexibleWidth: 0);
Text hideText = hideButton.GetComponentInChildren<Text>();
hideText.color = Color.white; hideText.color = Color.white;
hideText.resizeTextForBestFit = true; hideText.resizeTextForBestFit = true;
hideText.resizeTextMinSize = 8; hideText.resizeTextMinSize = 8;
hideText.resizeTextMaxSize = 14; hideText.resizeTextMaxSize = 14;
hideText.text = $"Hide ({ExplorerConfig.Instance.Main_Menu_Toggle})";
ExplorerConfig.OnConfigChanged += ModConfig_OnConfigChanged; ConfigManager.Main_Menu_Toggle.OnValueChanged += (KeyCode val) =>
void ModConfig_OnConfigChanged()
{ {
hideText.text = $"Hide ({ExplorerConfig.Instance.Main_Menu_Toggle})"; hideText.text = $"Hide ({val})";
} };
} }
private void ConstructNavbar(GameObject content) private void ConstructNavbar(GameObject content)
{ {
GameObject navbarObj = UIFactory.CreateHorizontalGroup(content); GameObject navbarObj = UIFactory.CreateHorizontalGroup(content, "MainNavBar", true, true, true, true, 5);
UIFactory.SetLayoutElement(navbarObj, minHeight: 25, flexibleHeight: 0);
HorizontalLayoutGroup navGroup = navbarObj.GetComponent<HorizontalLayoutGroup>(); ColorBlock colorBlock = new ColorBlock();
navGroup.spacing = 5; colorBlock.normalColor = m_navButtonNormal;
navGroup.childControlHeight = true; colorBlock.highlightedColor = m_navButtonHighlight;
navGroup.childControlWidth = true; colorBlock.pressedColor = m_navButtonSelected;
navGroup.childForceExpandHeight = true;
navGroup.childForceExpandWidth = true;
LayoutElement navLayout = navbarObj.AddComponent<LayoutElement>(); foreach (var page in Pages)
navLayout.minHeight = 25;
navLayout.flexibleHeight = 0;
foreach (BaseMenuPage page in Pages)
{ {
GameObject btnObj = UIFactory.CreateButton(navbarObj); Button btn = UIFactory.CreateButton(navbarObj,
Button btn = btnObj.GetComponent<Button>(); $"Button_{page.Name}",
page.Name,
() => { SetPage(page); },
colorBlock);
page.RefNavbarButton = btn; page.RefNavbarButton = btn;
btn.onClick.AddListener(() => { SetPage(page); });
Text text = btnObj.GetComponentInChildren<Text>();
text.text = page.Name;
// Set button colors
ColorBlock colorBlock = btn.colors;
colorBlock.normalColor = m_navButtonNormal;
//try { colorBlock.selectedColor = colorBlock.normalColor; } catch { }
colorBlock.highlightedColor = m_navButtonHighlight;
colorBlock.pressedColor = m_navButtonSelected;
btn.colors = colorBlock;
} }
} }
private void ConstructMainViewport(GameObject content)
{
GameObject mainObj = UIFactory.CreateHorizontalGroup(content);
HorizontalLayoutGroup mainGroup = mainObj.GetComponent<HorizontalLayoutGroup>();
mainGroup.childControlHeight = true;
mainGroup.childControlWidth = true;
mainGroup.childForceExpandHeight = true;
mainGroup.childForceExpandWidth = true;
PageViewport = mainObj;
}
#endregion #endregion
} }
} }

View File

@ -4,19 +4,16 @@ using System.Linq;
using UnityEngine; using UnityEngine;
using UnityEngine.UI; using UnityEngine.UI;
using UnityExplorer.Core.Config; using UnityExplorer.Core.Config;
using UnityExplorer.UI.Reusable; using UnityExplorer.UI.CacheObject;
using UnityExplorer.UI.Utility;
namespace UnityExplorer.UI.Main namespace UnityExplorer.UI.Main.Options
{ {
public class OptionsPage : BaseMenuPage public class OptionsPage : BaseMenuPage
{ {
public override string Name => "Options"; public override string Name => "Options";
private InputField m_keycodeInput; internal static readonly List<CacheConfigEntry> _cachedConfigEntries = new List<CacheConfigEntry>();
private Toggle m_unlockMouseToggle;
private InputField m_pageLimitInput;
private InputField m_defaultOutputInput;
private Toggle m_hideOnStartupToggle;
public override bool Init() public override bool Init()
{ {
@ -27,231 +24,49 @@ namespace UnityExplorer.UI.Main
public override void Update() public override void Update()
{ {
} // Not needed
internal void OnApply()
{
if (!string.IsNullOrEmpty(m_keycodeInput.text) && Enum.Parse(typeof(KeyCode), m_keycodeInput.text) is KeyCode keyCode)
ExplorerConfig.Instance.Main_Menu_Toggle = keyCode;
ExplorerConfig.Instance.Force_Unlock_Mouse = m_unlockMouseToggle.isOn;
if (!string.IsNullOrEmpty(m_pageLimitInput.text) && int.TryParse(m_pageLimitInput.text, out int lim))
ExplorerConfig.Instance.Default_Page_Limit = lim;
ExplorerConfig.Instance.Default_Output_Path = m_defaultOutputInput.text;
ExplorerConfig.Instance.Hide_On_Startup = m_hideOnStartupToggle.isOn;
ExplorerConfig.SaveSettings();
ExplorerConfig.InvokeConfigChanged();
} }
#region UI CONSTRUCTION #region UI CONSTRUCTION
internal GameObject m_contentObj;
internal void ConstructUI() internal void ConstructUI()
{ {
GameObject parent = MainMenu.Instance.PageViewport; GameObject parent = MainMenu.Instance.PageViewport;
Content = UIFactory.CreateVerticalGroup(parent, new Color(0.15f, 0.15f, 0.15f)); Content = UIFactory.CreateVerticalGroup(parent, "OptionsPage", true, true, true, true, 5, new Vector4(4,4,4,4),
var mainGroup = Content.GetComponent<VerticalLayoutGroup>(); new Color(0.15f, 0.15f, 0.15f));
mainGroup.padding.left = 4; UIFactory.SetLayoutElement(Content, minHeight: 340, flexibleHeight: 9999);
mainGroup.padding.right = 4;
mainGroup.padding.top = 4;
mainGroup.padding.bottom = 4;
mainGroup.spacing = 5;
mainGroup.childForceExpandHeight = false;
mainGroup.childForceExpandWidth = true;
mainGroup.childControlHeight = true;
mainGroup.childControlWidth = true;
// ~~~~~ Title ~~~~~ // ~~~~~ Title ~~~~~
GameObject titleObj = UIFactory.CreateLabel(Content, TextAnchor.UpperLeft); var titleLabel = UIFactory.CreateLabel(Content, "Title", "Options", TextAnchor.UpperLeft, default, true, 25);
Text titleLabel = titleObj.GetComponent<Text>(); UIFactory.SetLayoutElement(titleLabel.gameObject, minHeight: 30, flexibleHeight: 0);
titleLabel.text = "Options";
titleLabel.fontSize = 20; // Save button
LayoutElement titleLayout = titleObj.AddComponent<LayoutElement>();
titleLayout.minHeight = 30; var btn = UIFactory.CreateButton(Content,
titleLayout.flexibleHeight = 0; "SaveButton",
"Save Config File",
() => { ConfigManager.Handler.SaveConfig(); },
new Color(0.25f, 0.6f, 0.25f));
UIFactory.SetLayoutElement(btn.gameObject, flexibleWidth: 9999, minHeight: 30, flexibleHeight: 0);
// ~~~~~ Actual options ~~~~~ // ~~~~~ Actual options ~~~~~
var optionsGroupObj = UIFactory.CreateVerticalGroup(Content, new Color(0.1f, 0.1f, 0.1f)); UIFactory.CreateScrollView(Content, "ConfigList", out m_contentObj, out _, new Color(0.05f, 0.05f, 0.05f));
var optionsGroup = optionsGroupObj.GetComponent<VerticalLayoutGroup>(); UIFactory.SetLayoutGroup<VerticalLayoutGroup>(m_contentObj, forceHeight: true, spacing: 3, padLeft: 3, padRight: 3);
optionsGroup.childForceExpandHeight = false;
optionsGroup.childForceExpandWidth = true;
optionsGroup.childControlWidth = true;
optionsGroup.childControlHeight = true;
optionsGroup.spacing = 5;
optionsGroup.padding.top = 5;
optionsGroup.padding.left = 5;
optionsGroup.padding.right = 5;
optionsGroup.padding.bottom = 5;
ConstructKeycodeOpt(optionsGroupObj); _cachedConfigEntries.AddRange(ConfigManager.ConfigElements.Values
ConstructMouseUnlockOpt(optionsGroupObj); .Where(it => !it.IsInternal)
ConstructPageLimitOpt(optionsGroupObj); .Select(it => new CacheConfigEntry(it, m_contentObj)));
ConstructOutputPathOpt(optionsGroupObj);
ConstructHideOnStartupOpt(optionsGroupObj);
var applyBtnObj = UIFactory.CreateButton(Content, new Color(0.2f, 0.2f, 0.2f)); foreach (var entry in _cachedConfigEntries)
var applyText = applyBtnObj.GetComponentInChildren<Text>(); entry.Enable();
applyText.text = "Apply and Save";
var applyLayout = applyBtnObj.AddComponent<LayoutElement>();
applyLayout.minHeight = 30;
applyLayout.flexibleWidth = 1000;
var applyBtn = applyBtnObj.GetComponent<Button>();
var applyColors = applyBtn.colors;
applyColors.normalColor = new Color(0.3f, 0.7f, 0.3f);
applyBtn.colors = applyColors;
applyBtn.onClick.AddListener(OnApply);
} }
private void ConstructHideOnStartupOpt(GameObject optionsGroupObj)
{
var rowObj = UIFactory.CreateHorizontalGroup(optionsGroupObj, new Color(1, 1, 1, 0));
var rowGroup = rowObj.GetComponent<HorizontalLayoutGroup>();
rowGroup.childControlWidth = true;
rowGroup.childForceExpandWidth = false;
rowGroup.childControlHeight = true;
rowGroup.childForceExpandHeight = true;
var groupLayout = rowObj.AddComponent<LayoutElement>();
groupLayout.minHeight = 25;
groupLayout.flexibleHeight = 0;
groupLayout.minWidth = 200;
groupLayout.flexibleWidth = 1000;
var labelObj = UIFactory.CreateLabel(rowObj, TextAnchor.MiddleLeft); #endregion
var labelText = labelObj.GetComponent<Text>();
labelText.text = "Hide UI on startup:";
var labelLayout = labelObj.AddComponent<LayoutElement>();
labelLayout.minWidth = 150;
labelLayout.minHeight = 25;
UIFactory.CreateToggle(rowObj, out m_hideOnStartupToggle, out Text toggleText);
m_hideOnStartupToggle.isOn = ExplorerConfig.Instance.Hide_On_Startup;
toggleText.text = "";
}
internal void ConstructKeycodeOpt(GameObject parent)
{
var rowObj = UIFactory.CreateHorizontalGroup(parent, new Color(1, 1, 1, 0));
var rowGroup = rowObj.GetComponent<HorizontalLayoutGroup>();
rowGroup.childControlWidth = true;
rowGroup.childForceExpandWidth = false;
rowGroup.childControlHeight = true;
rowGroup.childForceExpandHeight = true;
var groupLayout = rowObj.AddComponent<LayoutElement>();
groupLayout.minHeight = 25;
groupLayout.flexibleHeight = 0;
groupLayout.minWidth = 200;
groupLayout.flexibleWidth = 1000;
var labelObj = UIFactory.CreateLabel(rowObj, TextAnchor.MiddleLeft);
var labelText = labelObj.GetComponent<Text>();
labelText.text = "Main Menu Toggle:";
var labelLayout = labelObj.AddComponent<LayoutElement>();
labelLayout.minWidth = 150;
labelLayout.minHeight = 25;
var keycodeInputObj = UIFactory.CreateInputField(rowObj);
m_keycodeInput = keycodeInputObj.GetComponent<InputField>();
m_keycodeInput.text = ExplorerConfig.Instance.Main_Menu_Toggle.ToString();
m_keycodeInput.placeholder.gameObject.GetComponent<Text>().text = "KeyCode, eg. F7";
}
internal void ConstructMouseUnlockOpt(GameObject parent)
{
var rowObj = UIFactory.CreateHorizontalGroup(parent, new Color(1, 1, 1, 0));
var rowGroup = rowObj.GetComponent<HorizontalLayoutGroup>();
rowGroup.childControlWidth = true;
rowGroup.childForceExpandWidth = false;
rowGroup.childControlHeight = true;
rowGroup.childForceExpandHeight = true;
var groupLayout = rowObj.AddComponent<LayoutElement>();
groupLayout.minHeight = 25;
groupLayout.flexibleHeight = 0;
groupLayout.minWidth = 200;
groupLayout.flexibleWidth = 1000;
var labelObj = UIFactory.CreateLabel(rowObj, TextAnchor.MiddleLeft);
var labelText = labelObj.GetComponent<Text>();
labelText.text = "Force Unlock Mouse:";
var labelLayout = labelObj.AddComponent<LayoutElement>();
labelLayout.minWidth = 150;
labelLayout.minHeight = 25;
UIFactory.CreateToggle(rowObj, out m_unlockMouseToggle, out Text toggleText);
m_unlockMouseToggle.isOn = ExplorerConfig.Instance.Force_Unlock_Mouse;
toggleText.text = "";
}
internal void ConstructPageLimitOpt(GameObject parent)
{
//public int Default_Page_Limit = 20;
var rowObj = UIFactory.CreateHorizontalGroup(parent, new Color(1, 1, 1, 0));
var rowGroup = rowObj.GetComponent<HorizontalLayoutGroup>();
rowGroup.childControlWidth = true;
rowGroup.childForceExpandWidth = false;
rowGroup.childControlHeight = true;
rowGroup.childForceExpandHeight = true;
var groupLayout = rowObj.AddComponent<LayoutElement>();
groupLayout.minHeight = 25;
groupLayout.flexibleHeight = 0;
groupLayout.minWidth = 200;
groupLayout.flexibleWidth = 1000;
var labelObj = UIFactory.CreateLabel(rowObj, TextAnchor.MiddleLeft);
var labelText = labelObj.GetComponent<Text>();
labelText.text = "Default Page Limit:";
var labelLayout = labelObj.AddComponent<LayoutElement>();
labelLayout.minWidth = 150;
labelLayout.minHeight = 25;
var inputObj = UIFactory.CreateInputField(rowObj);
m_pageLimitInput = inputObj.GetComponent<InputField>();
m_pageLimitInput.text = ExplorerConfig.Instance.Default_Page_Limit.ToString();
m_pageLimitInput.placeholder.gameObject.GetComponent<Text>().text = "Integer, eg. 20";
}
internal void ConstructOutputPathOpt(GameObject parent)
{
//public string Default_Output_Path = ExplorerCore.EXPLORER_FOLDER;
var rowObj = UIFactory.CreateHorizontalGroup(parent, new Color(1, 1, 1, 0));
var rowGroup = rowObj.GetComponent<HorizontalLayoutGroup>();
rowGroup.childControlWidth = true;
rowGroup.childForceExpandWidth = false;
rowGroup.childControlHeight = true;
rowGroup.childForceExpandHeight = true;
var groupLayout = rowObj.AddComponent<LayoutElement>();
groupLayout.minHeight = 25;
groupLayout.flexibleHeight = 0;
groupLayout.minWidth = 200;
groupLayout.flexibleWidth = 1000;
var labelObj = UIFactory.CreateLabel(rowObj, TextAnchor.MiddleLeft);
var labelText = labelObj.GetComponent<Text>();
labelText.text = "Default Output Path:";
var labelLayout = labelObj.AddComponent<LayoutElement>();
labelLayout.minWidth = 150;
labelLayout.minHeight = 25;
var inputObj = UIFactory.CreateInputField(rowObj);
m_defaultOutputInput = inputObj.GetComponent<InputField>();
m_defaultOutputInput.text = ExplorerConfig.Instance.Default_Output_Path.ToString();
m_defaultOutputInput.placeholder.gameObject.GetComponent<Text>().text = @"Directory, eg. Mods\UnityExplorer";
}
#endregion
} }
} }

View File

@ -4,9 +4,10 @@ using UnityEngine;
using UnityEngine.UI; using UnityEngine.UI;
using UnityExplorer.Core.Input; using UnityExplorer.Core.Input;
using System.IO; using System.IO;
using UnityExplorer.Core.Inspectors; using System.Diagnostics;
using UnityExplorer.UI.Main.Home;
namespace UnityExplorer.UI namespace UnityExplorer.UI.Main
{ {
// Handles dragging and resizing for the main explorer window. // Handles dragging and resizing for the main explorer window.
@ -16,7 +17,7 @@ namespace UnityExplorer.UI
public RectTransform Panel { get; set; } public RectTransform Panel { get; set; }
public static event Action OnFinishResize; public static event Action<RectTransform> OnFinishResize;
public PanelDragger(RectTransform dragArea, RectTransform panelToDrag) public PanelDragger(RectTransform dragArea, RectTransform panelToDrag)
{ {
@ -39,7 +40,7 @@ namespace UnityExplorer.UI
Vector3 dragPos = DragableArea.InverseTransformPoint(rawMousePos); Vector3 dragPos = DragableArea.InverseTransformPoint(rawMousePos);
bool inDragPos = DragableArea.rect.Contains(dragPos); bool inDragPos = DragableArea.rect.Contains(dragPos);
if (WasHoveringResize && s_resizeCursorImage) if (WasHoveringResize && s_resizeCursorObj)
{ {
UpdateHoverImagePos(); UpdateHoverImagePos();
} }
@ -141,16 +142,16 @@ namespace UnityExplorer.UI
private bool WasHoveringResize { get; set; } private bool WasHoveringResize { get; set; }
private ResizeTypes m_lastResizeHoverType; private ResizeTypes m_lastResizeHoverType;
public static GameObject s_resizeCursorImage; public static GameObject s_resizeCursorObj;
private Rect m_resizeRect; private Rect m_resizeRect;
private readonly Dictionary<ResizeTypes, Rect> m_resizeMask = new Dictionary<ResizeTypes, Rect> private readonly Dictionary<ResizeTypes, Rect> m_resizeMask = new Dictionary<ResizeTypes, Rect>
{ {
{ ResizeTypes.Top, Rect.zero }, { ResizeTypes.Top, default },
{ ResizeTypes.Left, Rect.zero }, { ResizeTypes.Left, default },
{ ResizeTypes.Right, Rect.zero }, { ResizeTypes.Right, default },
{ ResizeTypes.Bottom, Rect.zero }, { ResizeTypes.Bottom, default },
}; };
[Flags] [Flags]
@ -167,15 +168,14 @@ namespace UnityExplorer.UI
BottomRight = Bottom | Right, BottomRight = Bottom | Right,
} }
private const int HALF_THICKESS = RESIZE_THICKNESS / 2;
private void UpdateResizeCache() private void UpdateResizeCache()
{ {
int halfThick = RESIZE_THICKNESS / 2; m_resizeRect = new Rect(Panel.rect.x - HALF_THICKESS,
int dblThick = RESIZE_THICKNESS * 2; Panel.rect.y - HALF_THICKESS,
Panel.rect.width + RESIZE_THICKNESS,
m_resizeRect = new Rect(Panel.rect.x - halfThick, Panel.rect.height + RESIZE_THICKNESS);
Panel.rect.y - halfThick,
Panel.rect.width + dblThick,
Panel.rect.height + dblThick);
// calculate the four cross sections to use as flags // calculate the four cross sections to use as flags
@ -196,20 +196,25 @@ namespace UnityExplorer.UI
private ResizeTypes GetResizeType(Vector2 mousePos) private ResizeTypes GetResizeType(Vector2 mousePos)
{ {
// Calculate which part of the resize area we're in, if any. // Calculate which part of the resize area we're in, if any.
// More readable method commented out below.
ResizeTypes mask = 0; 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)) //if (m_resizeMask[ResizeTypes.Top].Contains(mousePos))
mask |= ResizeTypes.Top; // mask |= ResizeTypes.Top;
else if (m_resizeMask[ResizeTypes.Bottom].Contains(mousePos)) //else if (m_resizeMask[ResizeTypes.Bottom].Contains(mousePos))
mask |= ResizeTypes.Bottom; // mask |= ResizeTypes.Bottom;
if (m_resizeMask[ResizeTypes.Left].Contains(mousePos)) //if (m_resizeMask[ResizeTypes.Left].Contains(mousePos))
mask |= ResizeTypes.Left; // mask |= ResizeTypes.Left;
else if (m_resizeMask[ResizeTypes.Right].Contains(mousePos)) //else if (m_resizeMask[ResizeTypes.Right].Contains(mousePos))
mask |= ResizeTypes.Right; // mask |= ResizeTypes.Right;
return mask; return (ResizeTypes)mask;
} }
public void OnHoverResize(ResizeTypes resizeType) public void OnHoverResize(ResizeTypes resizeType)
@ -222,7 +227,7 @@ namespace UnityExplorer.UI
WasHoveringResize = true; WasHoveringResize = true;
m_lastResizeHoverType = resizeType; m_lastResizeHoverType = resizeType;
s_resizeCursorImage.SetActive(true); s_resizeCursorObj.SetActive(true);
// set the rotation for the resize icon // set the rotation for the resize icon
float iconRotation = 0f; float iconRotation = 0f;
@ -239,9 +244,9 @@ namespace UnityExplorer.UI
iconRotation = 135f; break; iconRotation = 135f; break;
} }
Quaternion rot = s_resizeCursorImage.transform.rotation; Quaternion rot = s_resizeCursorObj.transform.rotation;
rot.eulerAngles = new Vector3(0, 0, iconRotation); rot.eulerAngles = new Vector3(0, 0, iconRotation);
s_resizeCursorImage.transform.rotation = rot; s_resizeCursorObj.transform.rotation = rot;
UpdateHoverImagePos(); UpdateHoverImagePos();
} }
@ -250,13 +255,13 @@ namespace UnityExplorer.UI
private void UpdateHoverImagePos() private void UpdateHoverImagePos()
{ {
RectTransform t = UIManager.CanvasRoot.GetComponent<RectTransform>(); RectTransform t = UIManager.CanvasRoot.GetComponent<RectTransform>();
s_resizeCursorImage.transform.localPosition = t.InverseTransformPoint(InputManager.MousePosition); s_resizeCursorObj.transform.localPosition = t.InverseTransformPoint(InputManager.MousePosition);
} }
public void OnHoverResizeEnd() public void OnHoverResizeEnd()
{ {
WasHoveringResize = false; WasHoveringResize = false;
s_resizeCursorImage.SetActive(false); s_resizeCursorObj.SetActive(false);
} }
public void OnBeginResize(ResizeTypes resizeType) public void OnBeginResize(ResizeTypes resizeType)
@ -310,34 +315,29 @@ namespace UnityExplorer.UI
} }
} }
public void OnEndResize() public void OnEndResize(bool showing = false)
{ {
WasResizing = false; WasResizing = false;
UpdateResizeCache(); UpdateResizeCache();
OnFinishResize?.Invoke(); OnFinishResize?.Invoke(Panel);
} }
internal static void LoadCursorImage() internal static void CreateCursorUI()
{ {
try try
{ {
var sprite = UIManager.ResizeCursor; var text = UIFactory.CreateLabel(UIManager.CanvasRoot.gameObject, "ResizeCursor", "↔", TextAnchor.MiddleCenter, Color.white, true, 35);
s_resizeCursorObj = text.gameObject;
s_resizeCursorImage = new GameObject("ResizeCursorImage"); RectTransform rect = s_resizeCursorObj.GetComponent<RectTransform>();
s_resizeCursorImage.transform.SetParent(UIManager.CanvasRoot.transform); rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, 64);
rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 64);
Image image = s_resizeCursorImage.AddComponent<Image>(); s_resizeCursorObj.SetActive(false);
image.sprite = sprite;
image.material = Graphic.defaultGraphicMaterial;
RectTransform rect = image.transform.GetComponent<RectTransform>();
rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, 32);
rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 32);
s_resizeCursorImage.SetActive(false);
} }
catch (Exception e) catch (Exception e)
{ {
ExplorerCore.LogWarning("Exception loading cursor image!\r\n" + e.ToString()); ExplorerCore.LogWarning("Exception creating Resize Cursor UI!\r\n" + e.ToString());
} }
} }

View File

@ -4,15 +4,14 @@ using System.Linq;
using UnityEngine; using UnityEngine;
using UnityEngine.SceneManagement; using UnityEngine.SceneManagement;
using UnityEngine.UI; using UnityEngine.UI;
using UnityExplorer.Core.Inspectors;
using UnityExplorer.UI.Reusable;
using System.Reflection; using System.Reflection;
using UnityExplorer.Core.Runtime; using UnityExplorer.Core.Runtime;
using UnityExplorer.Core; using UnityExplorer.Core;
using UnityExplorer.Search;
using UnityExplorer.UI.Utility; using UnityExplorer.UI.Utility;
using UnityExplorer.Core.Search;
using UnityExplorer.UI.Main.Home;
namespace UnityExplorer.UI.Main namespace UnityExplorer.UI.Main.Search
{ {
public class SearchPage : BaseMenuPage public class SearchPage : BaseMenuPage
{ {
@ -207,7 +206,7 @@ namespace UnityExplorer.UI.Main
}); });
} }
m_sceneDropdown.transform.Find("Label").GetComponent<Text>().text = "Any"; m_sceneDropdown.itemText.text = "Any";
m_sceneFilter = SceneFilter.Any; m_sceneFilter = SceneFilter.Any;
} }
@ -254,7 +253,7 @@ namespace UnityExplorer.UI.Main
return; return;
if (m_selectedContextButton) if (m_selectedContextButton)
UIFactory.SetDefaultColorTransitionValues(m_selectedContextButton); UIFactory.SetDefaultSelectableColors(m_selectedContextButton);
var button = m_contextButtons[context]; var button = m_contextButtons[context];
@ -268,8 +267,8 @@ namespace UnityExplorer.UI.Main
m_context = context; m_context = context;
// if extra filters are valid // if extra filters are valid
if (context == SearchContext.Component if (context == SearchContext.Component
|| context == SearchContext.GameObject || context == SearchContext.GameObject
|| context == SearchContext.Custom) || context == SearchContext.Custom)
{ {
m_extraFilterRow?.SetActive(true); m_extraFilterRow?.SetActive(true);
@ -280,23 +279,13 @@ namespace UnityExplorer.UI.Main
} }
} }
#region UI CONSTRUCTION #region UI CONSTRUCTION
internal void ConstructUI() internal void ConstructUI()
{ {
GameObject parent = MainMenu.Instance.PageViewport; GameObject parent = MainMenu.Instance.PageViewport;
Content = UIFactory.CreateVerticalGroup(parent); Content = UIFactory.CreateVerticalGroup(parent, "SearchPage", true, true, true, true, 5, new Vector4(4,4,4,4));
var mainGroup = Content.GetComponent<VerticalLayoutGroup>();
mainGroup.padding.left = 4;
mainGroup.padding.right = 4;
mainGroup.padding.top = 4;
mainGroup.padding.bottom = 4;
mainGroup.spacing = 5;
mainGroup.childForceExpandHeight = true;
mainGroup.childForceExpandWidth = true;
mainGroup.childControlHeight = true;
mainGroup.childControlWidth = true;
ConstructTopArea(); ConstructTopArea();
@ -305,312 +294,172 @@ namespace UnityExplorer.UI.Main
internal void ConstructTopArea() internal void ConstructTopArea()
{ {
var topAreaObj = UIFactory.CreateVerticalGroup(Content, new Color(0.15f, 0.15f, 0.15f)); var topAreaObj = UIFactory.CreateVerticalGroup(Content, "TitleArea", true, false, true, true, 5, new Vector4(5,5,5,5),
var topGroup = topAreaObj.GetComponent<VerticalLayoutGroup>(); new Color(0.15f, 0.15f, 0.15f));
topGroup.childForceExpandHeight = false;
topGroup.childControlHeight = true;
topGroup.childForceExpandWidth = true;
topGroup.childControlWidth = true;
topGroup.padding.top = 5;
topGroup.padding.left = 5;
topGroup.padding.right = 5;
topGroup.padding.bottom = 5;
topGroup.spacing = 5;
GameObject titleObj = UIFactory.CreateLabel(topAreaObj, TextAnchor.UpperLeft); var titleLabel = UIFactory.CreateLabel(topAreaObj, "SearchTitle", "Search", TextAnchor.UpperLeft, Color.white, true, 25);
Text titleLabel = titleObj.GetComponent<Text>(); UIFactory.SetLayoutElement(titleLabel.gameObject, minHeight: 30, flexibleHeight: 0);
titleLabel.text = "Search";
titleLabel.fontSize = 20;
LayoutElement titleLayout = titleObj.AddComponent<LayoutElement>();
titleLayout.minHeight = 30;
titleLayout.flexibleHeight = 0;
// top area options // top area options
var optionsGroupObj = UIFactory.CreateVerticalGroup(topAreaObj, new Color(0.1f, 0.1f, 0.1f)); var optionsGroupObj = UIFactory.CreateVerticalGroup(topAreaObj, "OptionsArea", true, false, true, true, 10, new Vector4(4,4,4,4),
var optionsGroup = optionsGroupObj.GetComponent<VerticalLayoutGroup>(); new Color(0.1f, 0.1f, 0.1f));
optionsGroup.childForceExpandHeight = false; UIFactory.SetLayoutElement(optionsGroupObj, minWidth: 500, minHeight: 70, flexibleHeight: 100);
optionsGroup.childControlHeight = true;
optionsGroup.childForceExpandWidth = true;
optionsGroup.childControlWidth = true;
optionsGroup.spacing = 10;
optionsGroup.padding.top = 4;
optionsGroup.padding.right = 4;
optionsGroup.padding.left = 4;
optionsGroup.padding.bottom = 4;
var optionsLayout = optionsGroupObj.AddComponent<LayoutElement>();
optionsLayout.minWidth = 500;
optionsLayout.minHeight = 70;
optionsLayout.flexibleHeight = 100;
// search context row // search context row
var contextRowObj = UIFactory.CreateHorizontalGroup(optionsGroupObj, new Color(1, 1, 1, 0)); var contextRowObj = UIFactory.CreateHorizontalGroup(optionsGroupObj, "ContextFilters", false, false, true, true, 3, default,
var contextGroup = contextRowObj.GetComponent<HorizontalLayoutGroup>(); new Color(1, 1, 1, 0));
contextGroup.childForceExpandWidth = false; UIFactory.SetLayoutElement(contextRowObj, minHeight: 25);
contextGroup.childControlWidth = true;
contextGroup.childForceExpandHeight = false;
contextGroup.childControlHeight = true;
contextGroup.spacing = 3;
var contextLayout = contextRowObj.AddComponent<LayoutElement>();
contextLayout.minHeight = 25;
var contextLabelObj = UIFactory.CreateLabel(contextRowObj, TextAnchor.MiddleLeft); var contextLabelObj = UIFactory.CreateLabel(contextRowObj, "ContextLabel", "Searching for:", TextAnchor.MiddleLeft);
var contextText = contextLabelObj.GetComponent<Text>(); UIFactory.SetLayoutElement(contextLabelObj.gameObject, minWidth: 125, minHeight: 25);
contextText.text = "Searching for:";
var contextLabelLayout = contextLabelObj.AddComponent<LayoutElement>();
contextLabelLayout.minWidth = 125;
contextLabelLayout.minHeight = 25;
// context buttons // context buttons
AddContextButton(contextRowObj, "UnityEngine.Object", SearchContext.UnityObject, 140); AddContextButton(contextRowObj, "UnityEngine.Object", SearchContext.UnityObject, 140);
AddContextButton(contextRowObj, "GameObject", SearchContext.GameObject); AddContextButton(contextRowObj, "GameObject", SearchContext.GameObject);
AddContextButton(contextRowObj, "Component", SearchContext.Component); AddContextButton(contextRowObj, "Component", SearchContext.Component);
AddContextButton(contextRowObj, "Custom...", SearchContext.Custom); AddContextButton(contextRowObj, "Custom...", SearchContext.Custom);
// custom type input // custom type input
var customTypeObj = UIFactory.CreateInputField(contextRowObj); var customTypeObj = UIFactory.CreateInputField(contextRowObj, "CustomTypeInput", "eg. UnityEngine.Texture2D, etc...");
var customTypeLayout = customTypeObj.AddComponent<LayoutElement>(); UIFactory.SetLayoutElement(customTypeObj, minWidth: 250, flexibleWidth: 2000, minHeight: 25, flexibleHeight: 0);
customTypeLayout.minWidth = 250;
customTypeLayout.flexibleWidth = 2000;
customTypeLayout.minHeight = 25;
customTypeLayout.flexibleHeight = 0;
m_customTypeInput = customTypeObj.GetComponent<InputField>(); m_customTypeInput = customTypeObj.GetComponent<InputField>();
m_customTypeInput.placeholder.gameObject.GetComponent<Text>().text = "eg. UnityEngine.Texture2D, etc...";
// static class and singleton buttons // static class and singleton buttons
var secondRow = UIFactory.CreateHorizontalGroup(optionsGroupObj, new Color(1, 1, 1, 0)); var secondRow = UIFactory.CreateHorizontalGroup(optionsGroupObj, "SecondRow", false, false, true, true, 3, default, new Color(1, 1, 1, 0));
var secondGroup = secondRow.GetComponent<HorizontalLayoutGroup>(); UIFactory.SetLayoutElement(secondRow, minHeight: 25);
secondGroup.childForceExpandWidth = false;
secondGroup.childForceExpandHeight = false;
secondGroup.spacing = 3;
var secondLayout = secondRow.AddComponent<LayoutElement>();
secondLayout.minHeight = 25;
var spacer = UIFactory.CreateUIObject("spacer", secondRow); var spacer = UIFactory.CreateUIObject("spacer", secondRow);
var spaceLayout = spacer.AddComponent<LayoutElement>(); UIFactory.SetLayoutElement(spacer, minWidth: 25, minHeight: 25);
spaceLayout.minWidth = 125;
spaceLayout.minHeight = 25;
AddContextButton(secondRow, "Static Class", SearchContext.StaticClass); AddContextButton(secondRow, "Static Class", SearchContext.StaticClass);
AddContextButton(secondRow, "Singleton", SearchContext.Singleton); AddContextButton(secondRow, "Singleton", SearchContext.Singleton);
// search input // search input
var nameRowObj = UIFactory.CreateHorizontalGroup(optionsGroupObj, new Color(1, 1, 1, 0)); var nameRowObj = UIFactory.CreateHorizontalGroup(optionsGroupObj, "SearchInput", true, false, true, true, 0, default, new Color(1, 1, 1, 0));
var nameRowGroup = nameRowObj.GetComponent<HorizontalLayoutGroup>(); UIFactory.SetLayoutElement(nameRowObj, minHeight: 25, flexibleHeight: 0, flexibleWidth: 5000);
nameRowGroup.childForceExpandWidth = true;
nameRowGroup.childControlWidth = true;
nameRowGroup.childForceExpandHeight = false;
nameRowGroup.childControlHeight = true;
var nameRowLayout = nameRowObj.AddComponent<LayoutElement>();
nameRowLayout.minHeight = 25;
nameRowLayout.flexibleHeight = 0;
nameRowLayout.flexibleWidth = 5000;
var nameLabelObj = UIFactory.CreateLabel(nameRowObj, TextAnchor.MiddleLeft); var nameLabel = UIFactory.CreateLabel(nameRowObj, "NameLabel", "Name contains:", TextAnchor.MiddleLeft);
var nameLabelText = nameLabelObj.GetComponent<Text>(); UIFactory.SetLayoutElement(nameLabel.gameObject, minWidth: 125, minHeight: 25);
nameLabelText.text = "Name contains:";
var nameLabelLayout = nameLabelObj.AddComponent<LayoutElement>();
nameLabelLayout.minWidth = 125;
nameLabelLayout.minHeight = 25;
var nameInputObj = UIFactory.CreateInputField(nameRowObj); var nameInputObj = UIFactory.CreateInputField(nameRowObj, "NameInputField", "...");
m_nameInput = nameInputObj.GetComponent<InputField>(); m_nameInput = nameInputObj.GetComponent<InputField>();
//m_nameInput.placeholder.gameObject.GetComponent<TextMeshProUGUI>().text = ""; UIFactory.SetLayoutElement(nameInputObj, minWidth: 150, flexibleWidth: 5000, minHeight: 25);
var nameInputLayout = nameInputObj.AddComponent<LayoutElement>();
nameInputLayout.minWidth = 150;
nameInputLayout.flexibleWidth = 5000;
nameInputLayout.minHeight = 25;
// extra filter row // extra filter row
m_extraFilterRow = UIFactory.CreateHorizontalGroup(optionsGroupObj, new Color(1, 1, 1, 0)); m_extraFilterRow = UIFactory.CreateHorizontalGroup(optionsGroupObj, "ExtraFilterRow", false, true, true, true, 0, default, new Color(1, 1, 1, 0));
m_extraFilterRow.SetActive(false); m_extraFilterRow.SetActive(false);
var extraGroup = m_extraFilterRow.GetComponent<HorizontalLayoutGroup>(); UIFactory.SetLayoutElement(m_extraFilterRow, minHeight: 25, minWidth: 125, flexibleHeight: 0, flexibleWidth: 150);
extraGroup.childForceExpandHeight = true;
extraGroup.childControlHeight = true;
extraGroup.childForceExpandWidth = false;
extraGroup.childControlWidth = true;
var filterRowLayout = m_extraFilterRow.AddComponent<LayoutElement>();
filterRowLayout.minHeight = 25;
filterRowLayout.flexibleHeight = 0;
filterRowLayout.minWidth = 125;
filterRowLayout.flexibleWidth = 150;
// scene filter // scene filter
var sceneLabelObj = UIFactory.CreateLabel(m_extraFilterRow, TextAnchor.MiddleLeft); var sceneLabelObj = UIFactory.CreateLabel(m_extraFilterRow, "SceneFilterLabel", "Scene filter:", TextAnchor.MiddleLeft);
var sceneLabel = sceneLabelObj.GetComponent<Text>(); UIFactory.SetLayoutElement(sceneLabelObj.gameObject, minWidth: 125, minHeight: 25);
sceneLabel.text = "Scene Filter:";
var sceneLayout = sceneLabelObj.AddComponent<LayoutElement>();
sceneLayout.minWidth = 125;
sceneLayout.minHeight = 25;
var sceneDropObj = UIFactory.CreateDropdown(m_extraFilterRow, out m_sceneDropdown); var sceneDropObj = UIFactory.CreateDropdown(m_extraFilterRow,
m_sceneDropdown.itemText.text = "Any"; out m_sceneDropdown,
m_sceneDropdown.itemText.fontSize = 12; "Any",
var sceneDropLayout = sceneDropObj.AddComponent<LayoutElement>(); 12,
sceneDropLayout.minWidth = 220; (int value) => { m_sceneFilter = (SceneFilter)value; }
sceneDropLayout.minHeight = 25; );
m_sceneDropdown.onValueChanged.AddListener(OnSceneDropdownChanged); UIFactory.SetLayoutElement(sceneDropObj, minWidth: 220, minHeight: 25);
void OnSceneDropdownChanged(int value)
{
if (value < 4)
m_sceneFilter = (SceneFilter)value;
else
m_sceneFilter = SceneFilter.Explicit;
}
// invisible space // invisible space
var invis = UIFactory.CreateUIObject("spacer", m_extraFilterRow); var invis = UIFactory.CreateUIObject("spacer", m_extraFilterRow);
var invisLayout = invis.AddComponent<LayoutElement>(); UIFactory.SetLayoutElement(invis, minWidth: 25, flexibleWidth: 0);
invisLayout.minWidth = 25;
invisLayout.flexibleWidth = 0;
// children filter // children filter
var childLabelObj = UIFactory.CreateLabel(m_extraFilterRow, TextAnchor.MiddleLeft); var childLabelObj = UIFactory.CreateLabel(m_extraFilterRow, "ChildFilterLabel", "Child filter:", TextAnchor.MiddleLeft);
var childLabel = childLabelObj.GetComponent<Text>(); UIFactory.SetLayoutElement(childLabelObj.gameObject, minWidth: 100, minHeight: 25);
childLabel.text = "Child Filter:";
var childLayout = childLabelObj.AddComponent<LayoutElement>();
childLayout.minWidth = 100;
childLayout.minHeight = 25;
var childDropObj = UIFactory.CreateDropdown(m_extraFilterRow, out Dropdown childDrop); var childDropObj = UIFactory.CreateDropdown(m_extraFilterRow,
childDrop.itemText.text = "Any"; out Dropdown childDrop,
childDrop.itemText.fontSize = 12; "Any",
var childDropLayout = childDropObj.AddComponent<LayoutElement>(); 12,
childDropLayout.minWidth = 180; (int value) => { m_childFilter = (ChildFilter)value; },
childDropLayout.minHeight = 25; new[] { "Any", "Root Objects Only", "Children Only" });
childDrop.options.Add(new Dropdown.OptionData { text = "Any" }); UIFactory.SetLayoutElement(childDropObj, minWidth: 180, minHeight: 25);
childDrop.options.Add(new Dropdown.OptionData { text = "Root Objects Only" });
childDrop.options.Add(new Dropdown.OptionData { text = "Children Only" });
childDrop.onValueChanged.AddListener(OnChildDropdownChanged);
void OnChildDropdownChanged(int value)
{
m_childFilter = (ChildFilter)value;
}
// search button // search button
var searchBtnObj = UIFactory.CreateButton(topAreaObj); var searchBtnObj = UIFactory.CreateButton(topAreaObj, "SearchButton", "Search", OnSearchClicked);
var searchText = searchBtnObj.GetComponentInChildren<Text>(); UIFactory.SetLayoutElement(searchBtnObj.gameObject, minHeight: 30, flexibleHeight: 0);
searchText.text = "Search";
LayoutElement searchBtnLayout = searchBtnObj.AddComponent<LayoutElement>();
searchBtnLayout.minHeight = 30;
searchBtnLayout.flexibleHeight = 0;
var searchBtn = searchBtnObj.GetComponent<Button>();
searchBtn.onClick.AddListener(OnSearchClicked);
} }
internal void AddContextButton(GameObject parent, string label, SearchContext context, float width = 110) internal void AddContextButton(GameObject parent, string label, SearchContext context, float width = 110)
{ {
var btnObj = UIFactory.CreateButton(parent); var btn = UIFactory.CreateButton(parent, $"Context_{context}", label, () => { OnContextButtonClicked(context); });
UIFactory.SetLayoutElement(btn.gameObject, minHeight: 25, minWidth: (int)width);
var btn = btnObj.GetComponent<Button>();
m_contextButtons.Add(context, btn); m_contextButtons.Add(context, btn);
btn.onClick.AddListener(() => { OnContextButtonClicked(context); });
var btnLayout = btnObj.AddComponent<LayoutElement>();
btnLayout.minHeight = 25;
btnLayout.minWidth = width;
var btnText = btnObj.GetComponentInChildren<Text>();
btnText.text = label;
// if first button // if first button
if (!m_selectedContextButton) if (!m_selectedContextButton)
{
OnContextButtonClicked(context); OnContextButtonClicked(context);
}
} }
internal void ConstructResultsArea() internal void ConstructResultsArea()
{ {
// Result group holder (NOT actual result list content) // Result group holder (NOT actual result list content)
var resultGroupObj = UIFactory.CreateVerticalGroup(Content, new Color(1,1,1,0)); var resultGroupObj = UIFactory.CreateVerticalGroup(Content, "SearchResults", true, false, true, true, 5, new Vector4(5,5,5,5),
var resultGroup = resultGroupObj.GetComponent<VerticalLayoutGroup>(); new Color(1, 1, 1, 0));
resultGroup.childForceExpandHeight = false;
resultGroup.childForceExpandWidth = true;
resultGroup.childControlHeight = true;
resultGroup.childControlWidth = true;
resultGroup.spacing = 5;
resultGroup.padding.top = 5;
resultGroup.padding.right = 5;
resultGroup.padding.left = 5;
resultGroup.padding.bottom = 5;
var resultCountObj = UIFactory.CreateLabel(resultGroupObj, TextAnchor.MiddleCenter); m_resultCountText = UIFactory.CreateLabel(resultGroupObj, "ResultsLabel", "No results...", TextAnchor.MiddleCenter);
m_resultCountText = resultCountObj.GetComponent<Text>();
m_resultCountText.text = "No results...";
GameObject scrollObj = UIFactory.CreateScrollView(resultGroupObj, GameObject scrollObj = UIFactory.CreateScrollView(resultGroupObj,
out m_resultListContent, "ResultsScrollView",
out SliderScrollbar scroller, out m_resultListContent,
out SliderScrollbar scroller,
new Color(0.07f, 0.07f, 0.07f, 1)); new Color(0.07f, 0.07f, 0.07f, 1));
m_resultListPageHandler = new PageHandler(scroller); m_resultListPageHandler = new PageHandler(scroller);
m_resultListPageHandler.ConstructUI(resultGroupObj); m_resultListPageHandler.ConstructUI(resultGroupObj);
m_resultListPageHandler.OnPageChanged += OnResultPageTurn; m_resultListPageHandler.OnPageChanged += OnResultPageTurn;
// actual result list content UIFactory.SetLayoutGroup<VerticalLayoutGroup>(m_resultListContent, forceHeight: false, childControlHeight: true, spacing: 2);
var contentGroup = m_resultListContent.GetComponent<VerticalLayoutGroup>();
contentGroup.spacing = 2;
contentGroup.childForceExpandHeight = false;
contentGroup.childControlHeight = true;
} }
internal void AddResultButton() internal void AddResultButton()
{ {
int thisIndex = m_resultListTexts.Count(); int thisIndex = m_resultListTexts.Count();
GameObject btnGroupObj = UIFactory.CreateHorizontalGroup(m_resultListContent, new Color(0.1f, 0.1f, 0.1f)); GameObject btnGroupObj = UIFactory.CreateHorizontalGroup(m_resultListContent, "ResultButtonGroup",
HorizontalLayoutGroup btnGroup = btnGroupObj.GetComponent<HorizontalLayoutGroup>(); true, false, true, true, 0, new Vector4(1,1,1,1), new Color(0.1f, 0.1f, 0.1f));
btnGroup.childForceExpandWidth = true; UIFactory.SetLayoutElement(btnGroupObj, flexibleWidth: 320, minHeight: 25, flexibleHeight: 0);
btnGroup.childControlWidth = true;
btnGroup.childForceExpandHeight = false;
btnGroup.childControlHeight = true;
btnGroup.padding.top = 1;
btnGroup.padding.left = 1;
btnGroup.padding.right = 1;
btnGroup.padding.bottom = 1;
LayoutElement btnLayout = btnGroupObj.AddComponent<LayoutElement>();
btnLayout.flexibleWidth = 320;
btnLayout.minHeight = 25;
btnLayout.flexibleHeight = 0;
btnGroupObj.AddComponent<Mask>(); btnGroupObj.AddComponent<Mask>();
GameObject mainButtonObj = UIFactory.CreateButton(btnGroupObj); var mainColors = new ColorBlock
LayoutElement mainBtnLayout = mainButtonObj.AddComponent<LayoutElement>(); {
mainBtnLayout.minHeight = 25; normalColor = new Color(0.1f, 0.1f, 0.1f),
mainBtnLayout.flexibleHeight = 0; highlightedColor = new Color(0.2f, 0.2f, 0.2f, 1),
mainBtnLayout.minWidth = 230; pressedColor = new Color(0.05f, 0.05f, 0.05f)
mainBtnLayout.flexibleWidth = 0; };
Button mainBtn = mainButtonObj.GetComponent<Button>();
ColorBlock mainColors = mainBtn.colors;
mainColors.normalColor = new Color(0.1f, 0.1f, 0.1f);
mainColors.highlightedColor = new Color(0.2f, 0.2f, 0.2f, 1);
mainBtn.colors = mainColors;
mainBtn.onClick.AddListener(() => { OnResultClicked(thisIndex); }); var mainButton = UIFactory.CreateButton(btnGroupObj,
"ResultButton",
"<not set>",
() => { OnResultClicked(thisIndex); },
mainColors);
Text mainText = mainButtonObj.GetComponentInChildren<Text>(); UIFactory.SetLayoutElement(mainButton.gameObject, minHeight: 25, flexibleHeight: 0, minWidth: 320, flexibleWidth: 0);
mainText.alignment = TextAnchor.MiddleLeft;
mainText.horizontalOverflow = HorizontalWrapMode.Overflow; Text text = mainButton.GetComponentInChildren<Text>();
m_resultListTexts.Add(mainText); text.alignment = TextAnchor.MiddleLeft;
text.horizontalOverflow = HorizontalWrapMode.Overflow;
m_resultListTexts.Add(text);
} }
#endregion #endregion
} }
} }

View File

@ -1,131 +1,237 @@
using System; using System;
//using TMPro;
using UnityEngine; using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI; using UnityEngine.UI;
using UnityExplorer.Core.Unity; using UnityExplorer.Core.Config;
using UnityExplorer.UI.Reusable; using UnityExplorer.Core.Runtime;
using UnityExplorer.UI.Utility;
namespace UnityExplorer.UI namespace UnityExplorer.UI
{ {
public static class UIFactory public static class UIFactory
{ {
internal static Vector2 thickSize = new Vector2(160f, 30f); internal static Vector2 _largeElementSize = new Vector2(160f, 30f);
internal static Vector2 thinSize = new Vector2(160f, 20f); internal static Vector2 _smallElementSize = new Vector2(160f, 20f);
internal static Color defaultTextColor = new Color(0.95f, 0.95f, 0.95f, 1f); internal static Color _defaultTextColor = Color.white;
internal static Font s_defaultFont; internal static Font _defaultFont;
public static GameObject CreateUIObject(string name, GameObject parent, Vector2 size = default) public static void Init()
{ {
GameObject obj = new GameObject(name); _defaultFont = Resources.GetBuiltinResource<Font>("Arial.ttf");
}
RectTransform rect = obj.AddComponent<RectTransform>(); public static GameObject CreateUIObject(string name, GameObject parent = null, Vector2 size = default)
if (size != default) {
if (!parent)
{ {
rect.sizeDelta = size; ExplorerCore.LogWarning("Cannot create UI object as the parent is null or destroyed! (" + name + ")");
return null;
} }
SetParentAndAlign(obj, parent); var obj = new GameObject(name)
{
layer = 5,
hideFlags = HideFlags.HideAndDontSave
};
obj.transform.SetParent(parent.transform, false);
RectTransform rect = obj.AddComponent<RectTransform>();
rect.sizeDelta = size == default
? _smallElementSize
: size;
return obj; return obj;
} }
private static void SetParentAndAlign(GameObject child, GameObject parent) internal static void SetDefaultTextValues(Text text)
{ {
if (parent == null) text.color = _defaultTextColor;
{ text.font = _defaultFont;
return; text.fontSize = 14;
}
child.transform.SetParent(parent.transform, false);
SetLayerRecursively(child);
} }
public static void SetLayerRecursively(GameObject go) internal static void SetDefaultSelectableColors(Selectable selectable)
{
go.layer = 5;
Transform transform = go.transform;
for (int i = 0; i < transform.childCount; i++)
{
SetLayerRecursively(transform.GetChild(i).gameObject);
}
}
private static void SetDefaultTextValues(Text lbl)
{
lbl.color = defaultTextColor;
if (!s_defaultFont)
s_defaultFont = Resources.GetBuiltinResource<Font>("Arial.ttf");
if (s_defaultFont)
lbl.font = s_defaultFont;
}
public static void SetDefaultColorTransitionValues(Selectable selectable)
{ {
ColorBlock colors = selectable.colors; ColorBlock colors = selectable.colors;
colors.normalColor = new Color(0.35f, 0.35f, 0.35f); SetColorBlockValues(ref colors, new Color(0.2f, 0.2f, 0.2f), new Color(0.3f, 0.3f, 0.3f), new Color(0.15f, 0.15f, 0.15f));
colors.highlightedColor = new Color(0.45f, 0.45f, 0.45f);
colors.pressedColor = new Color(0.25f, 0.25f, 0.25f);
//colors.disabledColor = new Color(0.6f, 0.6f, 0.6f);
// fix to make all buttons become de-selected after being clicked.
// this is because i'm not setting any ColorBlock.selectedColor, because it is commonly stripped.
if (selectable is Button button)
{
button.onClick.AddListener(Deselect);
void Deselect()
{
button.OnDeselect(null);
}
}
selectable.colors = colors; selectable.colors = colors;
// Deselect all Buttons after they are clicked.
if (selectable is Button button)
button.onClick.AddListener(() => { button.OnDeselect(null); });
} }
public static GameObject CreatePanel(GameObject parent, string name, out GameObject content) public static void SetColorBlockValues(ref this ColorBlock colorBlock, Color? normal = null, Color? highlighted = null,
Color? pressed = null)
{ {
GameObject panelObj = CreateUIObject($"Panel_{name}", parent, thickSize); if (normal != null)
colorBlock.normalColor = (Color)normal;
RectTransform rect = panelObj.GetComponent<RectTransform>(); if (highlighted != null)
colorBlock.highlightedColor = (Color)highlighted;
if (pressed != null)
colorBlock.pressedColor = (Color)pressed;
}
/// <summary>
/// Get and/or Add a LayoutElement component to the GameObject, and set any of the values on it.
/// </summary>
public static LayoutElement SetLayoutElement(GameObject gameObject, int? minWidth = null, int? minHeight = null,
int? flexibleWidth = null, int? flexibleHeight = null, int? preferredWidth = null, int? preferredHeight = null,
bool? ignoreLayout = null)
{
var layout = gameObject.GetComponent<LayoutElement>();
if (!layout)
layout = gameObject.AddComponent<LayoutElement>();
if (minWidth != null)
layout.minWidth = (int)minWidth;
if (minHeight != null)
layout.minHeight = (int)minHeight;
if (flexibleWidth != null)
layout.flexibleWidth = (int)flexibleWidth;
if (flexibleHeight != null)
layout.flexibleHeight = (int)flexibleHeight;
if (preferredWidth != null)
layout.preferredWidth = (int)preferredWidth;
if (preferredHeight != null)
layout.preferredHeight = (int)preferredHeight;
if (ignoreLayout != null)
layout.ignoreLayout = (bool)ignoreLayout;
return layout;
}
/// <summary>
/// Get and/or Add a HorizontalOrVerticalLayoutGroup (must pick one) to the GameObject, and set the values on it.
/// </summary>
public static T SetLayoutGroup<T>(GameObject gameObject, bool? forceWidth = null, bool? forceHeight = null,
bool? childControlWidth = null, bool? childControlHeight = null, int? spacing = null, int? padTop = null,
int? padBottom = null, int? padLeft = null, int? padRight = null, TextAnchor? childAlignment = null) where T : HorizontalOrVerticalLayoutGroup
{
var group = gameObject.GetComponent<T>();
if (!group)
group = gameObject.AddComponent<T>();
return SetLayoutGroup(group, forceWidth, forceHeight, childControlWidth, childControlHeight, spacing, padTop, padBottom, padLeft, padRight);
}
/// <summary>
/// Set the values on a HorizontalOrVerticalLayoutGroup.
/// </summary>
public static T SetLayoutGroup<T>(T group, bool? forceWidth = null, bool? forceHeight = null,
bool? childControlWidth = null, bool? childControlHeight = null, int? spacing = null, int? padTop = null,
int? padBottom = null, int? padLeft = null, int? padRight = null, TextAnchor? childAlignment = null) where T : HorizontalOrVerticalLayoutGroup
{
if (forceWidth != null)
group.childForceExpandWidth = (bool)forceWidth;
if (forceHeight != null)
group.childForceExpandHeight = (bool)forceHeight;
if (childControlWidth != null)
group.SetChildControlWidth((bool)childControlWidth);
if (childControlHeight != null)
group.SetChildControlHeight((bool)childControlHeight);
if (spacing != null)
group.spacing = (int)spacing;
if (padTop != null)
group.padding.top = (int)padTop;
if (padBottom != null)
group.padding.bottom = (int)padBottom;
if (padLeft != null)
group.padding.left = (int)padLeft;
if (padRight != null)
group.padding.right = (int)padRight;
if (childAlignment != null)
group.childAlignment = (TextAnchor)childAlignment;
return group;
}
/// <summary>
/// Create a Panel on the UI Canvas.
/// </summary>
public static GameObject CreatePanel(string name, out GameObject contentHolder, string anchors = null)
{
var panelObj = CreateUIObject(name, UIManager.CanvasRoot);
var rect = panelObj.GetComponent<RectTransform>();
rect.anchorMin = Vector2.zero; rect.anchorMin = Vector2.zero;
rect.anchorMax = Vector2.one; rect.anchorMax = Vector2.one;
rect.anchoredPosition = Vector2.zero; rect.anchoredPosition = Vector2.zero;
rect.sizeDelta = Vector2.zero; rect.sizeDelta = Vector2.zero;
var img = panelObj.AddComponent<Image>(); if (anchors != null)
img.color = Color.white; rect.SetAnchorsFromString(anchors);
VerticalLayoutGroup group = panelObj.AddComponent<VerticalLayoutGroup>(); var maskImg = panelObj.AddComponent<Image>();
group.childControlHeight = true; maskImg.color = Color.white;
group.childControlWidth = true; panelObj.AddComponent<Mask>().showMaskGraphic = false;
group.childForceExpandHeight = true;
group.childForceExpandWidth = true;
content = new GameObject("Content"); SetLayoutGroup<VerticalLayoutGroup>(panelObj, true, true, true, true);
content.transform.parent = panelObj.transform;
Image image2 = content.AddComponent<Image>(); contentHolder = CreateUIObject("Content", panelObj);
image2.type = Image.Type.Filled;
image2.color = new Color(0.1f, 0.1f, 0.1f);
VerticalLayoutGroup group2 = content.AddComponent<VerticalLayoutGroup>(); Image bgImage = contentHolder.AddComponent<Image>();
group2.padding.left = 3; bgImage.type = Image.Type.Filled;
group2.padding.right = 3; bgImage.color = new Color(0.1f, 0.1f, 0.1f);
group2.padding.bottom = 3;
group2.padding.top = 3; SetLayoutGroup<VerticalLayoutGroup>(contentHolder, true, true, true, true, 3, 3, 3, 3, 3);
group2.spacing = 3;
group2.childControlHeight = true;
group2.childControlWidth = true;
group2.childForceExpandHeight = false;
group2.childForceExpandWidth = true;
return panelObj; return panelObj;
} }
public static GameObject CreateGridGroup(GameObject parent, Vector2 cellSize, Vector2 spacing, Color color = default) /// <summary>
/// Create a VerticalLayoutGroup object.
/// </summary>
public static GameObject CreateVerticalGroup(GameObject parent, string name, bool forceWidth, bool forceHeight,
bool childControlWidth, bool childControlHeight, int spacing = 0, Vector4 padding = default, Color bgColor = default,
TextAnchor? childAlignment = null)
{ {
GameObject groupObj = CreateUIObject("GridLayout", parent); GameObject groupObj = CreateUIObject(name, parent);
SetLayoutGroup<VerticalLayoutGroup>(groupObj, forceWidth, forceHeight, childControlWidth, childControlHeight,
spacing, (int)padding.x, (int)padding.y, (int)padding.z, (int)padding.w, childAlignment);
Image image = groupObj.AddComponent<Image>();
image.color = bgColor == default
? new Color(0.17f, 0.17f, 0.17f)
: bgColor;
return groupObj;
}
/// <summary>
/// Create a HorizontalLayoutGroup object.
/// </summary>
public static GameObject CreateHorizontalGroup(GameObject parent, string name, bool forceExpandWidth, bool forceExpandHeight,
bool childControlWidth, bool childControlHeight, int spacing = 0, Vector4 padding = default, Color bgColor = default,
TextAnchor? childAlignment = null)
{
GameObject groupObj = CreateUIObject(name, parent);
SetLayoutGroup<HorizontalLayoutGroup>(groupObj, forceExpandWidth, forceExpandHeight, childControlWidth, childControlHeight,
spacing, (int)padding.x, (int)padding.y, (int)padding.z, (int)padding.w, childAlignment);
Image image = groupObj.AddComponent<Image>();
image.color = bgColor == default
? new Color(0.17f, 0.17f, 0.17f)
: bgColor;
return groupObj;
}
/// <summary>
/// Create a GridLayoutGroup object.
/// </summary>
public static GameObject CreateGridGroup(GameObject parent, string name, Vector2 cellSize, Vector2 spacing, Color bgColor = default)
{
var groupObj = CreateUIObject(name, parent);
GridLayoutGroup gridGroup = groupObj.AddComponent<GridLayoutGroup>(); GridLayoutGroup gridGroup = groupObj.AddComponent<GridLayoutGroup>();
gridGroup.childAlignment = TextAnchor.UpperLeft; gridGroup.childAlignment = TextAnchor.UpperLeft;
@ -133,120 +239,131 @@ namespace UnityExplorer.UI
gridGroup.spacing = spacing; gridGroup.spacing = spacing;
Image image = groupObj.AddComponent<Image>(); Image image = groupObj.AddComponent<Image>();
if (color != default)
{ image.color = bgColor == default
image.color = color; ? new Color(0.17f, 0.17f, 0.17f)
} : bgColor;
else
{
image.color = new Color(44f / 255f, 44f / 255f, 44f / 255f);
}
return groupObj; return groupObj;
} }
public static GameObject CreateVerticalGroup(GameObject parent, Color color = default) /// <summary>
/// Create a Label object.
/// </summary>
public static Text CreateLabel(GameObject parent, string name, string text, TextAnchor alignment,
Color color = default, bool supportRichText = true, int fontSize = 14)
{ {
GameObject groupObj = CreateUIObject("VerticalLayout", parent); var obj = CreateUIObject(name, parent);
var textComp = obj.AddComponent<Text>();
VerticalLayoutGroup horiGroup = groupObj.AddComponent<VerticalLayoutGroup>(); SetDefaultTextValues(textComp);
horiGroup.childAlignment = TextAnchor.UpperLeft;
horiGroup.childControlWidth = true;
horiGroup.childControlHeight = true;
Image image = groupObj.AddComponent<Image>(); textComp.text = text;
if (color != default) textComp.color = color == default ? _defaultTextColor : color;
{ textComp.supportRichText = supportRichText;
image.color = color; textComp.alignment = alignment;
} textComp.fontSize = fontSize;
return textComp;
}
public static Button CreateButton(GameObject parent, string name, string text, Action onClick = null, Color? normalColor = null)
{
var colors = new ColorBlock();
if (normalColor != null)
colors.normalColor = (Color)normalColor;
else else
{ colors.normalColor = new Color(0.25f, 0.25f, 0.25f);
image.color = new Color(44f / 255f, 44f / 255f, 44f / 255f);
}
return groupObj; colors.pressedColor = new Color(0.15f, 0.15f, 0.15f);
colors.highlightedColor = new Color(0.4f, 0.4f, 0.4f);
return CreateButton(parent, name, text, onClick, colors);
} }
public static GameObject CreateHorizontalGroup(GameObject parent, Color color = default) public static Button CreateButton(GameObject parent, string name, string text, Action onClick, ColorBlock colors)
{ {
GameObject groupObj = CreateUIObject("HorizontalLayout", parent); GameObject buttonObj = CreateUIObject(name, parent, _smallElementSize);
HorizontalLayoutGroup horiGroup = groupObj.AddComponent<HorizontalLayoutGroup>(); var textObj = CreateUIObject("Text", buttonObj);
horiGroup.childAlignment = TextAnchor.UpperLeft;
horiGroup.childControlWidth = true;
horiGroup.childControlHeight = true;
Image image = groupObj.AddComponent<Image>();
if (color != default)
image.color = color;
else
image.color = new Color(44f / 255f, 44f / 255f, 44f / 255f);
return groupObj;
}
//public static GameObject CreateTMPLabel(GameObject parent, TextAlignmentOptions alignment)
//{
// GameObject labelObj = CreateUIObject("Label", parent, thinSize);
// TextMeshProUGUI text = labelObj.AddComponent<TextMeshProUGUI>();
// text.alignment = alignment;
// text.richText = true;
// return labelObj;
//}
public static GameObject CreateLabel(GameObject parent, TextAnchor alignment)
{
GameObject labelObj = CreateUIObject("Label", parent, thinSize);
Text text = labelObj.AddComponent<Text>();
SetDefaultTextValues(text);
text.alignment = alignment;
text.supportRichText = true;
return labelObj;
}
public static GameObject CreateButton(GameObject parent, Color normalColor = default)
{
GameObject buttonObj = CreateUIObject("Button", parent, thinSize);
GameObject textObj = new GameObject("Text");
textObj.AddComponent<RectTransform>();
SetParentAndAlign(textObj, buttonObj);
Image image = buttonObj.AddComponent<Image>(); Image image = buttonObj.AddComponent<Image>();
image.type = Image.Type.Sliced; image.type = Image.Type.Sliced;
image.color = new Color(1, 1, 1, 0.75f); image.color = new Color(1, 1, 1, 0.75f);
SetDefaultColorTransitionValues(buttonObj.AddComponent<Button>()); var button = buttonObj.AddComponent<Button>();
SetDefaultSelectableColors(button);
if (normalColor != default) colors.colorMultiplier = 1;
{ button.colors = colors;
var btn = buttonObj.GetComponent<Button>();
var colors = btn.colors;
colors.normalColor = normalColor;
btn.colors = colors;
}
Text text = textObj.AddComponent<Text>(); Text textComp = textObj.AddComponent<Text>();
text.text = "Button"; textComp.text = text;
SetDefaultTextValues(text); SetDefaultTextValues(textComp);
text.alignment = TextAnchor.MiddleCenter; textComp.alignment = TextAnchor.MiddleCenter;
RectTransform rect = textObj.GetComponent<RectTransform>(); RectTransform rect = textObj.GetComponent<RectTransform>();
rect.anchorMin = Vector2.zero; rect.anchorMin = Vector2.zero;
rect.anchorMax = Vector2.one; rect.anchorMax = Vector2.one;
rect.sizeDelta = Vector2.zero; rect.sizeDelta = Vector2.zero;
return buttonObj; if (onClick != null)
button.onClick.AddListener(onClick);
return button;
} }
public static GameObject CreateSlider(GameObject parent) ///// <summary>
///// Create a Button and specify only the Normal color.
///// </summary>
//public static Button CreateButton(GameObject parent, string name, string text, Action onClick = null, Color? normalColor = null)
//{
// var colors = new ColorBlock
// {
// normalColor = normalColor ?? new Color(0.25f, 0.25f, 0.25f),
// highlightedColor = new Color(0.3f, 0.3f, 0.3f),
// pressedColor = new Color(0.15f, 0.15f, 0.15f)
// };
// return CreateButton(parent, name, text, onClick, colors);
//}
///// <summary>
///// Create a Button and specify the entire ColorBlock for the transition values.
///// </summary>
//public static Button CreateButton(GameObject parent, string name, string text, Action onClick, ColorBlock? colors)
//{
// var buttonObj = CreateUIObject(name, parent);
// Image bgImage = buttonObj.AddComponent<Image>();
// bgImage.type = Image.Type.Sliced;
// bgImage.color = new Color(1, 1, 1, 0.75f);
// Button button = buttonObj.AddComponent<Button>();
// SetDefaultSelectableColors(button);
// if (onClick != null)
// button.onClick.AddListener(onClick);
// if (colors != null)
// button.colors = (ColorBlock)colors;
// var textObj = CreateLabel(buttonObj, "Text", text, TextAnchor.MiddleCenter);
// RectTransform rect = textObj.GetComponent<RectTransform>();
// rect.anchorMin = Vector2.zero;
// rect.anchorMax = Vector2.one;
// rect.sizeDelta = Vector2.zero;
// return button;
//}
/// <summary>
/// Create a Slider control.
/// </summary>
public static GameObject CreateSlider(GameObject parent, string name, out Slider slider)
{ {
GameObject sliderObj = CreateUIObject("Slider", parent, thinSize); GameObject sliderObj = CreateUIObject(name, parent, _smallElementSize);
GameObject bgObj = CreateUIObject("Background", sliderObj); GameObject bgObj = CreateUIObject("Background", sliderObj);
GameObject fillAreaObj = CreateUIObject("Fill Area", sliderObj); GameObject fillAreaObj = CreateUIObject("Fill Area", sliderObj);
@ -285,19 +402,23 @@ namespace UnityExplorer.UI
handleObj.GetComponent<RectTransform>().sizeDelta = new Vector2(20f, 0f); handleObj.GetComponent<RectTransform>().sizeDelta = new Vector2(20f, 0f);
Slider slider = sliderObj.AddComponent<Slider>(); slider = sliderObj.AddComponent<Slider>();
slider.fillRect = fillObj.GetComponent<RectTransform>(); slider.fillRect = fillObj.GetComponent<RectTransform>();
slider.handleRect = handleObj.GetComponent<RectTransform>(); slider.handleRect = handleObj.GetComponent<RectTransform>();
slider.targetGraphic = handleImage; slider.targetGraphic = handleImage;
slider.direction = Slider.Direction.LeftToRight; slider.direction = Slider.Direction.LeftToRight;
SetDefaultColorTransitionValues(slider);
SetDefaultSelectableColors(slider);
return sliderObj; return sliderObj;
} }
public static GameObject CreateScrollbar(GameObject parent) /// <summary>
/// Create a Scrollbar control.
/// </summary>
public static GameObject CreateScrollbar(GameObject parent, string name, out Scrollbar scrollbar)
{ {
GameObject scrollObj = CreateUIObject("Scrollbar", parent, thinSize); GameObject scrollObj = CreateUIObject(name, parent, _smallElementSize);
GameObject slideAreaObj = CreateUIObject("Sliding Area", scrollObj); GameObject slideAreaObj = CreateUIObject("Sliding Area", scrollObj);
GameObject handleObj = CreateUIObject("Handle", slideAreaObj); GameObject handleObj = CreateUIObject("Handle", slideAreaObj);
@ -318,17 +439,21 @@ namespace UnityExplorer.UI
RectTransform handleRect = handleObj.GetComponent<RectTransform>(); RectTransform handleRect = handleObj.GetComponent<RectTransform>();
handleRect.sizeDelta = new Vector2(20f, 20f); handleRect.sizeDelta = new Vector2(20f, 20f);
Scrollbar scrollbar = scrollObj.AddComponent<Scrollbar>(); scrollbar = scrollObj.AddComponent<Scrollbar>();
scrollbar.handleRect = handleRect; scrollbar.handleRect = handleRect;
scrollbar.targetGraphic = handleImage; scrollbar.targetGraphic = handleImage;
SetDefaultColorTransitionValues(scrollbar);
SetDefaultSelectableColors(scrollbar);
return scrollObj; return scrollObj;
} }
public static GameObject CreateToggle(GameObject parent, out Toggle toggle, out Text text, Color bgColor = default) /// <summary>
/// Create a Toggle control.
/// </summary>
public static GameObject CreateToggle(GameObject parent, string name, out Toggle toggle, out Text text, Color bgColor = default)
{ {
GameObject toggleObj = CreateUIObject("Toggle", parent, thinSize); GameObject toggleObj = CreateUIObject(name, parent, _smallElementSize);
GameObject bgObj = CreateUIObject("Background", toggleObj); GameObject bgObj = CreateUIObject("Background", toggleObj);
GameObject checkObj = CreateUIObject("Checkmark", bgObj); GameObject checkObj = CreateUIObject("Checkmark", bgObj);
@ -345,8 +470,8 @@ namespace UnityExplorer.UI
} }
Image bgImage = bgObj.AddComponent<Image>(); Image bgImage = bgObj.AddComponent<Image>();
bgImage.color = bgColor == default bgImage.color = bgColor == default
? new Color(0.2f, 0.2f, 0.2f, 1.0f) ? new Color(0.2f, 0.2f, 0.2f, 1.0f)
: bgColor; : bgColor;
Image checkImage = checkObj.AddComponent<Image>(); Image checkImage = checkObj.AddComponent<Image>();
@ -358,7 +483,7 @@ namespace UnityExplorer.UI
toggle.graphic = checkImage; toggle.graphic = checkImage;
toggle.targetGraphic = bgImage; toggle.targetGraphic = bgImage;
SetDefaultColorTransitionValues(toggle); SetDefaultSelectableColors(toggle);
RectTransform bgRect = bgObj.GetComponent<RectTransform>(); RectTransform bgRect = bgObj.GetComponent<RectTransform>();
bgRect.anchorMin = new Vector2(0f, 1f); bgRect.anchorMin = new Vector2(0f, 1f);
@ -380,14 +505,18 @@ namespace UnityExplorer.UI
return toggleObj; return toggleObj;
} }
public static GameObject CreateSrollInputField(GameObject parent, out InputFieldScroller inputScroll, int fontSize = 14, Color color = default) /// <summary>
/// Create a Scrollable Input Field control (custom InputFieldScroller).
/// </summary>
public static GameObject CreateSrollInputField(GameObject parent, string name, string placeHolderText,
out InputFieldScroller inputScroll, int fontSize = 14, Color color = default)
{ {
if (color == default) if (color == default)
color = new Color(0.15f, 0.15f, 0.15f); color = new Color(0.15f, 0.15f, 0.15f);
var mainObj = CreateScrollView(parent, out GameObject scrollContent, out SliderScrollbar scroller, color); var mainObj = CreateScrollView(parent, "InputFieldScrollView", out GameObject scrollContent, out SliderScrollbar scroller, color);
var inputObj = CreateInputField(scrollContent, fontSize, 0); var inputObj = CreateInputField(scrollContent, name, placeHolderText ?? "...", fontSize, 0);
var inputField = inputObj.GetComponent<InputField>(); var inputField = inputObj.GetComponent<InputField>();
inputField.lineType = InputField.LineType.MultiLineNewline; inputField.lineType = InputField.LineType.MultiLineNewline;
@ -398,9 +527,12 @@ namespace UnityExplorer.UI
return mainObj; return mainObj;
} }
public static GameObject CreateInputField(GameObject parent, int fontSize = 14, int alignment = 3, int wrap = 0) /// <summary>
/// Create a standard InputField control.
/// </summary>
public static GameObject CreateInputField(GameObject parent, string name, string placeHolderText, int fontSize = 14, int alignment = 3, int wrap = 0)
{ {
GameObject mainObj = CreateUIObject("InputField", parent); GameObject mainObj = CreateUIObject(name, parent);
Image mainImage = mainObj.AddComponent<Image>(); Image mainImage = mainObj.AddComponent<Image>();
mainImage.type = Image.Type.Sliced; mainImage.type = Image.Type.Sliced;
@ -417,16 +549,12 @@ namespace UnityExplorer.UI
ColorBlock mainColors = mainInput.colors; ColorBlock mainColors = mainInput.colors;
mainColors.normalColor = new Color(1, 1, 1, 1); mainColors.normalColor = new Color(1, 1, 1, 1);
mainColors.highlightedColor = new Color(245f / 255f, 245f / 255f, 245f / 255f, 1.0f); mainColors.highlightedColor = new Color(0.95f, 0.95f, 0.95f, 1.0f);
mainColors.pressedColor = new Color(200f / 255f, 200f / 255f, 200f / 255f, 1.0f); mainColors.pressedColor = new Color(0.78f, 0.78f, 0.78f, 1.0f);
mainColors.highlightedColor = new Color(245f / 255f, 245f / 255f, 245f / 255f, 1.0f); mainColors.highlightedColor = new Color(0.95f, 0.95f, 0.95f, 1.0f);
mainInput.colors = mainColors; mainInput.colors = mainColors;
VerticalLayoutGroup mainGroup = mainObj.AddComponent<VerticalLayoutGroup>(); SetLayoutGroup<VerticalLayoutGroup>(mainObj, true, true, true, true);
mainGroup.childControlHeight = true;
mainGroup.childControlWidth = true;
mainGroup.childForceExpandWidth = true;
mainGroup.childForceExpandHeight = true;
GameObject textArea = CreateUIObject("TextArea", mainObj); GameObject textArea = CreateUIObject("TextArea", mainObj);
textArea.AddComponent<RectMask2D>(); textArea.AddComponent<RectMask2D>();
@ -442,7 +570,7 @@ namespace UnityExplorer.UI
GameObject placeHolderObj = CreateUIObject("Placeholder", textArea); GameObject placeHolderObj = CreateUIObject("Placeholder", textArea);
Text placeholderText = placeHolderObj.AddComponent<Text>(); Text placeholderText = placeHolderObj.AddComponent<Text>();
SetDefaultTextValues(placeholderText); SetDefaultTextValues(placeholderText);
placeholderText.text = "..."; placeholderText.text = placeHolderText ?? "...";
placeholderText.color = new Color(0.5f, 0.5f, 0.5f, 1.0f); placeholderText.color = new Color(0.5f, 0.5f, 0.5f, 1.0f);
placeholderText.horizontalOverflow = (HorizontalWrapMode)wrap; placeholderText.horizontalOverflow = (HorizontalWrapMode)wrap;
placeholderText.alignment = (TextAnchor)alignment; placeholderText.alignment = (TextAnchor)alignment;
@ -454,9 +582,7 @@ namespace UnityExplorer.UI
placeHolderRect.offsetMin = Vector2.zero; placeHolderRect.offsetMin = Vector2.zero;
placeHolderRect.offsetMax = Vector2.zero; placeHolderRect.offsetMax = Vector2.zero;
LayoutElement placeholderLayout = placeHolderObj.AddComponent<LayoutElement>(); SetLayoutElement(placeHolderObj, minWidth: 500, flexibleWidth: 5000);
placeholderLayout.minWidth = 500;
placeholderLayout.flexibleWidth = 5000;
mainInput.placeholder = placeholderText; mainInput.placeholder = placeholderText;
@ -475,18 +601,20 @@ namespace UnityExplorer.UI
inputTextRect.offsetMin = Vector2.zero; inputTextRect.offsetMin = Vector2.zero;
inputTextRect.offsetMax = Vector2.zero; inputTextRect.offsetMax = Vector2.zero;
LayoutElement inputTextLayout = inputTextObj.AddComponent<LayoutElement>(); SetLayoutElement(inputTextObj, minWidth: 500, flexibleWidth: 5000);
inputTextLayout.minWidth = 500;
inputTextLayout.flexibleWidth = 5000;
mainInput.textComponent = inputText; mainInput.textComponent = inputText;
return mainObj; return mainObj;
} }
public static GameObject CreateDropdown(GameObject parent, out Dropdown dropdown) /// <summary>
/// Create a DropDown control.
/// </summary>
public static GameObject CreateDropdown(GameObject parent, out Dropdown dropdown, string defaultItemText, int itemFontSize,
Action<int> onValueChanged, string[] defaultOptions = null)
{ {
GameObject dropdownObj = CreateUIObject("Dropdown", parent, thickSize); GameObject dropdownObj = CreateUIObject("Dropdown", parent, _largeElementSize);
GameObject labelObj = CreateUIObject("Label", dropdownObj); GameObject labelObj = CreateUIObject("Label", dropdownObj);
GameObject arrowObj = CreateUIObject("Arrow", dropdownObj); GameObject arrowObj = CreateUIObject("Arrow", dropdownObj);
@ -498,9 +626,7 @@ namespace UnityExplorer.UI
GameObject itemCheckObj = CreateUIObject("Item Checkmark", itemObj); GameObject itemCheckObj = CreateUIObject("Item Checkmark", itemObj);
GameObject itemLabelObj = CreateUIObject("Item Label", itemObj); GameObject itemLabelObj = CreateUIObject("Item Label", itemObj);
GameObject scrollbarObj = CreateScrollbar(templateObj); GameObject scrollbarObj = CreateScrollbar(templateObj, "DropdownScroll", out Scrollbar scrollbar);
scrollbarObj.name = "Scrollbar";
Scrollbar scrollbar = scrollbarObj.GetComponent<Scrollbar>();
scrollbar.SetDirection(Scrollbar.Direction.BottomToTop, true); scrollbar.SetDirection(Scrollbar.Direction.BottomToTop, true);
RectTransform scrollRectTransform = scrollbarObj.GetComponent<RectTransform>(); RectTransform scrollRectTransform = scrollbarObj.GetComponent<RectTransform>();
@ -512,6 +638,8 @@ namespace UnityExplorer.UI
Text itemLabelText = itemLabelObj.AddComponent<Text>(); Text itemLabelText = itemLabelObj.AddComponent<Text>();
SetDefaultTextValues(itemLabelText); SetDefaultTextValues(itemLabelText);
itemLabelText.alignment = TextAnchor.MiddleLeft; itemLabelText.alignment = TextAnchor.MiddleLeft;
itemLabelText.text = defaultItemText;
itemLabelText.fontSize = itemFontSize;
var arrowText = arrowObj.AddComponent<Text>(); var arrowText = arrowObj.AddComponent<Text>();
SetDefaultTextValues(arrowText); SetDefaultTextValues(arrowText);
@ -566,7 +694,7 @@ namespace UnityExplorer.UI
dropdown.template = templateObj.GetComponent<RectTransform>(); dropdown.template = templateObj.GetComponent<RectTransform>();
dropdown.captionText = labelText; dropdown.captionText = labelText;
dropdown.itemText = itemLabelText; dropdown.itemText = itemLabelText;
itemLabelText.text = "DEFAULT"; //itemLabelText.text = "DEFAULT";
dropdown.RefreshShownValue(); dropdown.RefreshShownValue();
@ -613,18 +741,27 @@ namespace UnityExplorer.UI
itemLabelRect.offsetMax = new Vector2(-10f, -2f); itemLabelRect.offsetMax = new Vector2(-10f, -2f);
templateObj.SetActive(false); templateObj.SetActive(false);
if (onValueChanged != null)
dropdown.onValueChanged.AddListener(onValueChanged);
if (defaultOptions != null)
{
foreach (var option in defaultOptions)
dropdown.options.Add(new Dropdown.OptionData(option));
}
return dropdownObj; return dropdownObj;
} }
public static GameObject CreateScrollView(GameObject parent, out GameObject content, out SliderScrollbar scroller, Color color = default) /// <summary>
/// Create a ScrollView element.
/// </summary>
public static GameObject CreateScrollView(GameObject parent, string name, out GameObject content, out SliderScrollbar scroller,
Color color = default)
{ {
GameObject mainObj = CreateUIObject("DynamicScrollView", parent); GameObject mainObj = CreateUIObject("DynamicScrollView", parent);
var mainLayout = mainObj.AddComponent<LayoutElement>(); SetLayoutElement(mainObj, minWidth: 100, minHeight: 30, flexibleWidth: 5000, flexibleHeight: 5000);
mainLayout.minWidth = 100;
mainLayout.minHeight = 30;
mainLayout.flexibleWidth = 5000;
mainLayout.flexibleHeight = 5000;
Image mainImage = mainObj.AddComponent<Image>(); Image mainImage = mainObj.AddComponent<Image>();
mainImage.type = Image.Type.Filled; mainImage.type = Image.Type.Filled;
@ -637,7 +774,7 @@ namespace UnityExplorer.UI
viewportRect.anchorMax = Vector2.one; viewportRect.anchorMax = Vector2.one;
viewportRect.pivot = new Vector2(0.0f, 1.0f); viewportRect.pivot = new Vector2(0.0f, 1.0f);
viewportRect.sizeDelta = new Vector2(-15.0f, 0.0f); viewportRect.sizeDelta = new Vector2(-15.0f, 0.0f);
viewportRect.offsetMax = new Vector2(-20.0f, 0.0f); viewportRect.offsetMax = new Vector2(-20.0f, 0.0f);
viewportObj.AddComponent<Image>().color = Color.white; viewportObj.AddComponent<Image>().color = Color.white;
viewportObj.AddComponent<Mask>().showMaskGraphic = false; viewportObj.AddComponent<Mask>().showMaskGraphic = false;
@ -653,22 +790,13 @@ namespace UnityExplorer.UI
contentFitter.horizontalFit = ContentSizeFitter.FitMode.Unconstrained; contentFitter.horizontalFit = ContentSizeFitter.FitMode.Unconstrained;
contentFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize; contentFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
var contentGroup = content.AddComponent<VerticalLayoutGroup>(); SetLayoutGroup<VerticalLayoutGroup>(content, true, true, true, true, 5, 5, 5, 5, 5);
contentGroup.childForceExpandHeight = true;
contentGroup.childControlHeight = true;
contentGroup.childForceExpandWidth = true;
contentGroup.childControlWidth = true;
contentGroup.padding.left = 5;
contentGroup.padding.right = 5;
contentGroup.padding.top = 5;
contentGroup.padding.bottom = 5;
contentGroup.spacing = 5;
GameObject scrollBarObj = CreateUIObject("DynamicScrollbar", mainObj); GameObject scrollBarObj = CreateUIObject("DynamicScrollbar", mainObj);
var scrollbarLayout = scrollBarObj.AddComponent<VerticalLayoutGroup>(); var scrollbarLayout = scrollBarObj.AddComponent<VerticalLayoutGroup>();
scrollbarLayout.childForceExpandHeight = true; scrollbarLayout.childForceExpandHeight = true;
scrollbarLayout.childControlHeight = true; scrollbarLayout.SetChildControlHeight(true);
RectTransform scrollBarRect = scrollBarObj.GetComponent<RectTransform>(); RectTransform scrollBarRect = scrollBarObj.GetComponent<RectTransform>();
scrollBarRect.anchorMin = new Vector2(1.0f, 0.0f); scrollBarRect.anchorMin = new Vector2(1.0f, 0.0f);
@ -676,8 +804,7 @@ namespace UnityExplorer.UI
scrollBarRect.sizeDelta = new Vector2(15.0f, 0.0f); scrollBarRect.sizeDelta = new Vector2(15.0f, 0.0f);
scrollBarRect.offsetMin = new Vector2(-15.0f, 0.0f); scrollBarRect.offsetMin = new Vector2(-15.0f, 0.0f);
GameObject hiddenBar = CreateScrollbar(scrollBarObj); GameObject hiddenBar = CreateScrollbar(scrollBarObj, "HiddenScrollviewScroller", out Scrollbar hiddenScroll);
var hiddenScroll = hiddenBar.GetComponent<Scrollbar>();
hiddenScroll.SetDirection(Scrollbar.Direction.BottomToTop, true); hiddenScroll.SetDirection(Scrollbar.Direction.BottomToTop, true);
for (int i = 0; i < hiddenBar.transform.childCount; i++) for (int i = 0; i < hiddenBar.transform.childCount; i++)
@ -705,8 +832,6 @@ namespace UnityExplorer.UI
// Create a custom DynamicScrollbar module // Create a custom DynamicScrollbar module
scroller = new SliderScrollbar(hiddenScroll, scrollSlider); scroller = new SliderScrollbar(hiddenScroll, scrollSlider);
//scrollRect.sliderScrollbar = scroller;
return mainObj; return mainObj;
} }
} }

View File

@ -1,14 +1,16 @@
using UnityEngine; using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.EventSystems; using UnityEngine.EventSystems;
using UnityEngine.UI; using UnityEngine.UI;
using UnityExplorer.Core.Inspectors;
using UnityExplorer.UI.Main;
using System.IO;
using System.Reflection;
using UnityExplorer.UI.Reusable;
using UnityExplorer.Core.Input;
using System;
using UnityExplorer.Core.Config; using UnityExplorer.Core.Config;
using UnityExplorer.Core.Input;
using UnityExplorer.Core.Runtime;
using UnityExplorer.UI.Main;
using UnityExplorer.UI.Main.Home;
using UnityExplorer.UI.Utility; using UnityExplorer.UI.Utility;
namespace UnityExplorer.UI namespace UnityExplorer.UI
@ -19,154 +21,95 @@ namespace UnityExplorer.UI
public static EventSystem EventSys { get; private set; } public static EventSystem EventSys { get; private set; }
internal static Font ConsoleFont { get; private set; } internal static Font ConsoleFont { get; private set; }
internal static Sprite ResizeCursor { get; private set; }
internal static Shader BackupShader { get; private set; } internal static Shader BackupShader { get; private set; }
public static bool ShowMenu public static bool ShowMenu
{ {
get => s_showMenu; get => s_showMenu;
set => SetShowMenu(value); set
}
public static bool s_showMenu;
private static bool s_doneUIInit;
private static float s_timeSinceStartup;
internal static void CheckUIInit()
{
if (s_doneUIInit)
return;
s_timeSinceStartup += Time.deltaTime;
if (s_timeSinceStartup > 0.1f)
{ {
s_doneUIInit = true; if (s_showMenu == value || !CanvasRoot)
try return;
{
Init();
ExplorerCore.Log("Initialized UnityExplorer UI.");
if (ExplorerConfig.Instance.Hide_On_Startup) s_showMenu = value;
ShowMenu = false; CanvasRoot.SetActive(value);
CursorUnlocker.UpdateCursorControl();
// InspectorManager.Instance.Inspect(Tests.TestClass.Instance);
}
catch (Exception e)
{
ExplorerCore.LogWarning($"Exception setting up UI: {e}");
}
} }
} }
public static bool s_showMenu = true;
public static void Init() internal static void Init()
{ {
LoadBundle();
// Create core UI Canvas and Event System handler
CreateRootCanvas(); CreateRootCanvas();
// Create submodules LoadBundle();
new MainMenu();
InspectUnderMouse.UI.ConstructUI();
PanelDragger.LoadCursorImage();
// Force refresh of anchors UIFactory.Init();
MainMenu.Create();
InspectUnderMouse.ConstructUI();
PanelDragger.CreateCursorUI();
// Force refresh of anchors etc
Canvas.ForceUpdateCanvases(); Canvas.ForceUpdateCanvases();
if (!ConfigManager.Hide_On_Startup.Value)
ShowMenu = true;
ExplorerCore.Log("UI initialized.");
} }
private static void SetShowMenu(bool show) internal static void Update()
{ {
if (s_showMenu == show) if (!CanvasRoot)
return; return;
s_showMenu = show; if (InspectUnderMouse.Inspecting)
if (CanvasRoot)
{ {
CanvasRoot.SetActive(show); InspectUnderMouse.UpdateInspect();
return;
if (show)
CursorUnlocker.SetEventSystem();
else
CursorUnlocker.ReleaseEventSystem();
} }
CursorUnlocker.UpdateCursorControl(); if (InputManager.GetKeyDown(ConfigManager.Main_Menu_Toggle.Value))
}
//public static void OnSceneChange()
//{
// SceneExplorer.Instance?.OnSceneChange();
// SearchPage.Instance?.OnSceneChange();
//}
public static void Update()
{
if (InputManager.GetKeyDown(ExplorerConfig.Instance.Main_Menu_Toggle))
ShowMenu = !ShowMenu; ShowMenu = !ShowMenu;
if (!ShowMenu || !s_doneUIInit || !CanvasRoot) if (!ShowMenu)
return; return;
MainMenu.Instance?.Update(); MainMenu.Instance.Update();
if (EventSys) if (EventSystem.current != EventSys)
{ CursorUnlocker.SetEventSystem();
if (EventSystem.current != EventSys)
CursorUnlocker.SetEventSystem();
#if CPP
// Some IL2CPP games behave weird with multiple UI Input Systems, some fixes for them.
var evt = InputManager.InputPointerEvent;
if (evt != null)
{
if (!evt.eligibleForClick && evt.selectedObject)
evt.eligibleForClick = true;
}
#endif
}
if (PanelDragger.Instance != null) RuntimeProvider.Instance.CheckInputPointerEvent();
PanelDragger.Instance.Update();
for (int i = 0; i < SliderScrollbar.Instances.Count; i++) PanelDragger.Instance.Update();
{
var slider = SliderScrollbar.Instances[i];
if (slider.CheckDestroyed()) SliderScrollbar.UpdateInstances();
i--; InputFieldScroller.UpdateInstances();
else
slider.Update();
}
for (int i = 0; i < InputFieldScroller.Instances.Count; i++)
{
var input = InputFieldScroller.Instances[i];
if (input.CheckDestroyed())
i--;
else
input.Update();
}
} }
private static AssetBundle LoadExplorerUi(string id) private static void CreateRootCanvas()
{ {
return AssetBundle.LoadFromMemory(ReadFully(typeof(ExplorerCore).Assembly.GetManifestResourceStream($"UnityExplorer.Resources.explorerui.{id}.bundle"))); CanvasRoot = new GameObject("ExplorerCanvas");
} UnityEngine.Object.DontDestroyOnLoad(CanvasRoot);
CanvasRoot.hideFlags |= HideFlags.HideAndDontSave;
CanvasRoot.layer = 5;
CanvasRoot.transform.position = new Vector3(0f, 0f, 1f);
private static byte[] ReadFully(this Stream input) EventSys = CanvasRoot.AddComponent<EventSystem>();
{ InputManager.AddUIModule();
using (var ms = new MemoryStream())
{
byte[] buffer = new byte[81920];
int read;
while ((read = input.Read(buffer, 0, buffer.Length)) != 0)
ms.Write(buffer, 0, read);
return ms.ToArray(); Canvas canvas = CanvasRoot.AddComponent<Canvas>();
} canvas.renderMode = RenderMode.ScreenSpaceCamera;
canvas.referencePixelsPerUnit = 100;
canvas.sortingOrder = 999;
CanvasScaler scaler = CanvasRoot.AddComponent<CanvasScaler>();
scaler.referenceResolution = new Vector2(1920, 1080);
scaler.screenMatchMode = CanvasScaler.ScreenMatchMode.Expand;
CanvasRoot.AddComponent<GraphicRaycaster>();
} }
private static void LoadBundle() private static void LoadBundle()
@ -176,24 +119,19 @@ namespace UnityExplorer.UI
try try
{ {
bundle = LoadExplorerUi("modern"); bundle = LoadExplorerUi("modern");
if (bundle == null)
bundle = LoadExplorerUi("legacy");
} }
catch catch
{ {
ExplorerCore.Log("Failed to load modern ExplorerUI Bundle, falling back to legacy"); // ignored
try
{
bundle = LoadExplorerUi("legacy");
}
catch
{
// ignored
}
} }
if (bundle == null) if (bundle == null)
{ {
ExplorerCore.LogWarning("Could not load the ExplorerUI Bundle!"); ExplorerCore.LogWarning("Could not load the ExplorerUI Bundle!");
ConsoleFont = Resources.GetBuiltinResource<Font>("Arial.ttf");
return; return;
} }
@ -206,38 +144,30 @@ namespace UnityExplorer.UI
Graphic.defaultGraphicMaterial.shader = BackupShader; Graphic.defaultGraphicMaterial.shader = BackupShader;
} }
ResizeCursor = bundle.LoadAsset<Sprite>("cursor");
ConsoleFont = bundle.LoadAsset<Font>("CONSOLA"); ConsoleFont = bundle.LoadAsset<Font>("CONSOLA");
ExplorerCore.Log("Loaded UI bundle"); ExplorerCore.Log("Loaded UI AssetBundle");
} }
private static GameObject CreateRootCanvas() private static AssetBundle LoadExplorerUi(string id)
{ {
GameObject rootObj = new GameObject("ExplorerCanvas"); var data = ReadFully(typeof(ExplorerCore)
UnityEngine.Object.DontDestroyOnLoad(rootObj); .Assembly
rootObj.layer = 5; .GetManifestResourceStream($"UnityExplorer.Resources.explorerui.{id}.bundle"));
CanvasRoot = rootObj; return AssetBundle.LoadFromMemory(data);
CanvasRoot.transform.position = new Vector3(0f, 0f, 1f); }
EventSys = rootObj.AddComponent<EventSystem>(); private static byte[] ReadFully(Stream input)
InputManager.AddUIModule(); {
using (var ms = new MemoryStream())
Canvas canvas = rootObj.AddComponent<Canvas>(); {
canvas.renderMode = RenderMode.ScreenSpaceCamera; byte[] buffer = new byte[81920];
canvas.referencePixelsPerUnit = 100; int read;
canvas.sortingOrder = 999; while ((read = input.Read(buffer, 0, buffer.Length)) != 0)
//canvas.pixelPerfect = false; ms.Write(buffer, 0, read);
return ms.ToArray();
CanvasScaler scaler = rootObj.AddComponent<CanvasScaler>(); }
scaler.referenceResolution = new Vector2(1920, 1080);
scaler.screenMatchMode = CanvasScaler.ScreenMatchMode.Expand;
rootObj.AddComponent<GraphicRaycaster>();
return rootObj;
} }
} }
} }

View File

@ -9,7 +9,7 @@ using UnityEngine.EventSystems;
using UnityEngine.Events; using UnityEngine.Events;
using UnityExplorer.Core.Unity; using UnityExplorer.Core.Unity;
namespace UnityExplorer.UI.Reusable namespace UnityExplorer.UI.Utility
{ {
// To fix an issue with Input Fields and allow them to go inside a ScrollRect nicely. // To fix an issue with Input Fields and allow them to go inside a ScrollRect nicely.
@ -17,6 +17,22 @@ namespace UnityExplorer.UI.Reusable
{ {
public static readonly List<InputFieldScroller> Instances = new List<InputFieldScroller>(); public static readonly List<InputFieldScroller> Instances = new List<InputFieldScroller>();
public static void UpdateInstances()
{
if (!Instances.Any())
return;
for (int i = 0; i < Instances.Count; i++)
{
var input = Instances[i];
if (input.CheckDestroyed())
i--;
else
input.Update();
}
}
internal SliderScrollbar sliderScroller; internal SliderScrollbar sliderScroller;
internal InputField inputField; internal InputField inputField;

View File

@ -6,7 +6,7 @@ using UnityEngine;
using UnityEngine.UI; using UnityEngine.UI;
using UnityExplorer.Core.Unity; using UnityExplorer.Core.Unity;
namespace UnityExplorer.UI.Reusable namespace UnityExplorer.UI.Utility
{ {
public enum Turn public enum Turn
{ {
@ -14,14 +14,11 @@ namespace UnityExplorer.UI.Reusable
Right Right
} }
// TODO:
// - Input for setting page directly
public class PageHandler : IEnumerator public class PageHandler : IEnumerator
{ {
public PageHandler(SliderScrollbar scroll) public PageHandler(SliderScrollbar scroll)
{ {
ItemsPerPage = ExplorerConfig.Instance?.Default_Page_Limit ?? 20; ItemsPerPage = ConfigManager.Default_Page_Limit?.Value ?? 20;
m_scrollbar = scroll; m_scrollbar = scroll;
} }
@ -168,55 +165,32 @@ namespace UnityExplorer.UI.Reusable
public void ConstructUI(GameObject parent) public void ConstructUI(GameObject parent)
{ {
m_pageUIHolder = UIFactory.CreateHorizontalGroup(parent); m_pageUIHolder = UIFactory.CreateHorizontalGroup(parent, "PageHandlerButtons", false, true, true, true);
Image image = m_pageUIHolder.GetComponent<Image>(); Image image = m_pageUIHolder.GetComponent<Image>();
image.color = new Color(0.2f, 0.2f, 0.2f, 0.5f); image.color = new Color(0.2f, 0.2f, 0.2f, 0.5f);
HorizontalLayoutGroup mainGroup = m_pageUIHolder.GetComponent<HorizontalLayoutGroup>(); UIFactory.SetLayoutElement(m_pageUIHolder, minHeight: 25, minWidth: 100, flexibleWidth: 5000);
mainGroup.childForceExpandHeight = true;
mainGroup.childForceExpandWidth = false;
mainGroup.childControlWidth = true;
mainGroup.childControlHeight = true;
LayoutElement mainLayout = m_pageUIHolder.AddComponent<LayoutElement>(); var leftBtnObj = UIFactory.CreateButton(m_pageUIHolder,
mainLayout.minHeight = 25; "BackBtn",
mainLayout.flexibleHeight = 0; "◄",
mainLayout.minWidth = 100; () => { TurnPage(Turn.Left); },
mainLayout.flexibleWidth = 5000; new Color(0.15f, 0.15f, 0.15f));
GameObject leftBtnObj = UIFactory.CreateButton(m_pageUIHolder, new Color(0.15f, 0.15f, 0.15f)); UIFactory.SetLayoutElement(leftBtnObj.gameObject, flexibleWidth: 1500, minWidth: 25, minHeight: 25);
Button leftBtn = leftBtnObj.GetComponent<Button>();
leftBtn.onClick.AddListener(() => { TurnPage(Turn.Left); }); m_currentPageLabel = UIFactory.CreateLabel(m_pageUIHolder, "PageLabel", "Page 1 / TODO", TextAnchor.MiddleCenter);
Text leftBtnText = leftBtnObj.GetComponentInChildren<Text>(); UIFactory.SetLayoutElement(m_currentPageLabel.gameObject, minWidth: 100, flexibleWidth: 40);
leftBtnText.text = "◄";
LayoutElement leftBtnLayout = leftBtnObj.AddComponent<LayoutElement>();
leftBtnLayout.flexibleHeight = 0f;
leftBtnLayout.flexibleWidth = 1500f;
leftBtnLayout.minWidth = 25f;
leftBtnLayout.minHeight = 25f;
GameObject labelObj = UIFactory.CreateLabel(m_pageUIHolder, TextAnchor.MiddleCenter); Button rightBtn = UIFactory.CreateButton(m_pageUIHolder,
m_currentPageLabel = labelObj.GetComponent<Text>(); "RightBtn",
m_currentPageLabel.text = "Page 1 / TODO"; "►",
LayoutElement textLayout = labelObj.AddComponent<LayoutElement>(); () => { TurnPage(Turn.Right); },
textLayout.minWidth = 100f; new Color(0.15f, 0.15f, 0.15f));
textLayout.flexibleWidth = 40f;
GameObject rightBtnObj = UIFactory.CreateButton(m_pageUIHolder, new Color(0.15f, 0.15f, 0.15f)); UIFactory.SetLayoutElement(rightBtn.gameObject, flexibleWidth: 1500, minWidth: 25, minHeight: 25);
Button rightBtn = rightBtnObj.GetComponent<Button>();
rightBtn.onClick.AddListener(() => { TurnPage(Turn.Right); });
Text rightBtnText = rightBtnObj.GetComponentInChildren<Text>();
rightBtnText.text = "►";
LayoutElement rightBtnLayout = rightBtnObj.AddComponent<LayoutElement>();
rightBtnLayout.flexibleHeight = 0;
rightBtnLayout.flexibleWidth = 1500f;
rightBtnLayout.minWidth = 25f;
rightBtnLayout.minHeight = 25;
ListCount = 0; ListCount = 0;
} }

View File

@ -130,7 +130,7 @@ namespace UnityExplorer.UI.Utility
var args = "<"; var args = "<";
for (int i = 0; i < gArgs.Length; i++) for (int i = 0; i < gArgs.Length; i++)
{ {
if (i > 0) if (i > 0)
args += ", "; args += ", ";
var arg = gArgs[i]; var arg = gArgs[i];

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Reflection; using System.Reflection;
using UnityEngine; using UnityEngine;
using UnityEngine.Events; using UnityEngine.Events;
@ -9,13 +10,29 @@ using UnityExplorer.Core;
using UnityExplorer.Core.Unity; using UnityExplorer.Core.Unity;
using UnityExplorer.UI; using UnityExplorer.UI;
namespace UnityExplorer.UI.Reusable namespace UnityExplorer.UI.Utility
{ {
// Basically just to fix an issue with Scrollbars, instead we use a Slider as the scrollbar. // Basically just to fix an issue with Scrollbars, instead we use a Slider as the scrollbar.
public class SliderScrollbar public class SliderScrollbar
{ {
internal static readonly List<SliderScrollbar> Instances = new List<SliderScrollbar>(); internal static readonly List<SliderScrollbar> Instances = new List<SliderScrollbar>();
public static void UpdateInstances()
{
if (!Instances.Any())
return;
for (int i = 0; i < Instances.Count; i++)
{
var slider = Instances[i];
if (slider.CheckDestroyed())
i--;
else
slider.Update();
}
}
public bool IsActive { get; private set; } public bool IsActive { get; private set; }
internal readonly Scrollbar m_scrollbar; internal readonly Scrollbar m_scrollbar;
@ -93,7 +110,7 @@ namespace UnityExplorer.UI.Reusable
public static GameObject CreateSliderScrollbar(GameObject parent, out Slider slider) public static GameObject CreateSliderScrollbar(GameObject parent, out Slider slider)
{ {
GameObject sliderObj = UIFactory.CreateUIObject("Slider", parent, UIFactory.thinSize); GameObject sliderObj = UIFactory.CreateUIObject("SliderScrollbar", parent, UIFactory._smallElementSize);
GameObject bgObj = UIFactory.CreateUIObject("Background", sliderObj); GameObject bgObj = UIFactory.CreateUIObject("Background", sliderObj);
GameObject fillAreaObj = UIFactory.CreateUIObject("Fill Area", sliderObj); GameObject fillAreaObj = UIFactory.CreateUIObject("Fill Area", sliderObj);
@ -149,7 +166,7 @@ namespace UnityExplorer.UI.Reusable
slider.handleRect = handleObj.GetComponent<RectTransform>(); slider.handleRect = handleObj.GetComponent<RectTransform>();
slider.targetGraphic = handleImage; slider.targetGraphic = handleImage;
slider.direction = Slider.Direction.BottomToTop; slider.direction = Slider.Direction.BottomToTop;
UIFactory.SetDefaultColorTransitionValues(slider); UIFactory.SetDefaultSelectableColors(slider);
return sliderObj; return sliderObj;
} }

View File

@ -1,332 +1,324 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Release_ML_Cpp</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{B21DBDE3-5D6F-4726-93AB-CC3CC68BAE7D}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
<TargetFrameworkProfile />
<OutputPath>..\Release\UnityExplorer.MelonLoader.Il2Cpp\</OutputPath>
<DefineConstants>
</DefineConstants>
<IsCpp>false</IsCpp>
<IsBepInEx>false</IsBepInEx>
<IsMelonLoader>false</IsMelonLoader>
<IsStandalone>false</IsStandalone>
<DebugSymbols>false</DebugSymbols>
<DebugType>none</DebugType>
<Optimize>false</Optimize>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>x64</PlatformTarget>
<Prefer32Bit>false</Prefer32Bit>
<RootNamespace>UnityExplorer</RootNamespace>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<!-- CONFIGURATIONS -->
<!-- ML IL2CPP -->
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release_ML_Cpp|AnyCPU' ">
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<OutputPath>..\Release\UnityExplorer.MelonLoader.Il2Cpp\</OutputPath>
<DefineConstants>CPP,ML</DefineConstants>
<AssemblyName>UnityExplorer.ML.IL2CPP</AssemblyName>
<IsCpp>true</IsCpp>
<IsMelonLoader>true</IsMelonLoader>
</PropertyGroup>
<!-- ML MONO -->
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release_ML_Mono|AnyCPU' ">
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<OutputPath>..\Release\UnityExplorer.MelonLoader.Mono\</OutputPath>
<DefineConstants>MONO,ML</DefineConstants>
<AssemblyName>UnityExplorer.ML.Mono</AssemblyName>
<Prefer32Bit>false</Prefer32Bit>
<IsCpp>false</IsCpp>
<IsMelonLoader>true</IsMelonLoader>
</PropertyGroup>
<!-- BEPINEX IL2CPP -->
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release_BIE_Cpp|AnyCPU' ">
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<OutputPath>..\Release\UnityExplorer.BepInEx.Il2Cpp\</OutputPath>
<DefineConstants>CPP,BIE,BIE6</DefineConstants>
<AssemblyName>UnityExplorer.BIE.IL2CPP</AssemblyName>
<IsCpp>true</IsCpp>
<IsBepInEx>true</IsBepInEx>
</PropertyGroup>
<!-- BEPINEX 6 MONO -->
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release_BIE6_Mono|AnyCPU' ">
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<OutputPath>..\Release\UnityExplorer.BepInEx6.Mono\</OutputPath>
<DefineConstants>MONO,BIE,BIE6</DefineConstants>
<AssemblyName>UnityExplorer.BIE6.Mono</AssemblyName>
<IsCpp>false</IsCpp>
<IsBepInEx>true</IsBepInEx>
</PropertyGroup>
<!-- BEPINEX 5 MONO -->
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release_BIE5_Mono|AnyCPU'">
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<OutputPath>..\Release\UnityExplorer.BepInEx5.Mono\</OutputPath>
<DefineConstants>MONO,BIE,BIE5</DefineConstants>
<AssemblyName>UnityExplorer.BIE5.Mono</AssemblyName>
<IsCpp>false</IsCpp>
<IsBepInEx>true</IsBepInEx>
</PropertyGroup>
<!-- STANDALONE IL2CPP -->
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release_STANDALONE_Mono|AnyCPU'">
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<OutputPath>..\Release\UnityExplorer.Standalone.Mono\</OutputPath>
<DefineConstants>MONO,STANDALONE</DefineConstants>
<AssemblyName>UnityExplorer.STANDALONE.Mono</AssemblyName>
<IsCpp>false</IsCpp>
<IsStandalone>true</IsStandalone>
</PropertyGroup>
<!-- STANDALONE MONO -->
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release_STANDALONE_Cpp|AnyCPU'">
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<OutputPath>..\Release\UnityExplorer.Standalone.Il2Cpp\</OutputPath>
<DefineConstants>CPP,STANDALONE</DefineConstants>
<AssemblyName>UnityExplorer.STANDALONE.IL2CPP</AssemblyName>
<IsCpp>true</IsCpp>
<IsStandalone>true</IsStandalone>
</PropertyGroup>
<!-- Global refs, Mono and Il2Cpp -->
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="mcs">
<HintPath>..\lib\mcs.dll</HintPath>
<Private>False</Private>
</Reference>
</ItemGroup>
<!-- MelonLoader refs -->
<ItemGroup Condition="'$(IsMelonLoader)'=='true'">
<Reference Include="MelonLoader">
<HintPath>..\lib\MelonLoader.dll</HintPath>
<Private>False</Private>
</Reference>
</ItemGroup>
<!-- BepInEx refs -->
<ItemGroup Condition="'$(IsBepInEx)'=='true'">
<Reference Include="0Harmony">
<HintPath>..\lib\0Harmony.dll</HintPath>
<Private>False</Private>
</Reference>
</ItemGroup>
<!-- BepInEx 5 Mono refs -->
<ItemGroup Condition="'$(IsBepInEx)|$(IsCpp)|$(Configuration)'=='true|false|Release_BIE5_Mono'">
<Reference Include="BepInEx">
<HintPath>..\lib\BepInEx.dll</HintPath>
<Private>False</Private>
</Reference>
</ItemGroup>
<!-- BepInEx 6 Mono refs -->
<ItemGroup Condition="'$(IsBepInEx)|$(IsCpp)|$(Configuration)'=='true|false|Release_BIE6_Mono'">
<Reference Include="BepInEx">
<HintPath>..\lib\BepInEx.Core.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="BepInEx.Unity">
<HintPath>..\lib\BepInEx.Unity.dll</HintPath>
<Private>False</Private>
</Reference>
</ItemGroup>
<!-- BepInEx Il2Cpp refs -->
<ItemGroup Condition="'$(IsBepInEx)|$(IsCpp)'=='true|true'">
<Reference Include="BepInEx">
<HintPath>..\lib\BepInEx.Core.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="BepInEx.IL2CPP">
<HintPath>..\lib\BepInEx.IL2CPP.dll</HintPath>
<Private>False</Private>
</Reference>
</ItemGroup>
<!-- Standalone refs -->
<ItemGroup Condition="'$(IsStandalone)'=='true'">
<Reference Include="0Harmony">
<HintPath>..\lib\0Harmony.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="INIFileParser, Version=2.5.2.0, Culture=neutral, PublicKeyToken=79af7b307b65cf3c, processorArchitecture=MSIL">
<HintPath>packages\ini-parser.2.5.2\lib\net20\INIFileParser.dll</HintPath>
<Private>False</Private>
</Reference>
</ItemGroup>
<!-- Mono refs -->
<ItemGroup Condition="'$(IsCpp)'=='false'">
<Reference Include="UnityEngine">
<HintPath>..\lib\UnityEngine.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="UnityEngine.UI">
<HintPath>..\lib\UnityEngine.UI.dll</HintPath>
<Private>False</Private>
</Reference>
</ItemGroup>
<!-- Il2Cpp refs -->
<ItemGroup Condition="'$(IsCpp)'=='true'">
<Reference Include="UnhollowerBaseLib">
<HintPath>..\lib\UnhollowerBaseLib.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="Il2Cppmscorlib">
<HintPath>..\lib\unhollowed\Il2Cppmscorlib.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="Il2CppSystem.Core">
<HintPath>..\lib\unhollowed\Il2CppSystem.Core.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="UnityEngine">
<HintPath>..\lib\unhollowed\UnityEngine.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="UnityEngine.CoreModule">
<HintPath>..\lib\unhollowed\UnityEngine.CoreModule.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="UnityEngine.PhysicsModule">
<HintPath>..\lib\unhollowed\UnityEngine.PhysicsModule.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="UnityEngine.TextRenderingModule">
<HintPath>..\lib\unhollowed\UnityEngine.TextRenderingModule.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="UnityEngine.UI">
<HintPath>..\lib\unhollowed\UnityEngine.UI.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="UnityEngine.UIModule">
<HintPath>..\lib\unhollowed\UnityEngine.UIModule.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="UnityEngine.IMGUIModule">
<HintPath>..\lib\unhollowed\UnityEngine.IMGUIModule.dll</HintPath>
<Private>False</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Core\Config\ConfigElement.cs" />
<Compile Include="Core\Config\ConfigManager.cs" />
<Compile Include="Core\Config\IConfigElement.cs" />
<Compile Include="Core\Config\ConfigHandler.cs" />
<Compile Include="Core\CSharp\DummyBehaviour.cs" />
<Compile Include="Core\CSharp\ScriptEvaluator.cs" />
<Compile Include="Core\CSharp\ScriptInteraction.cs" />
<Compile Include="Core\CSharp\Suggestion.cs" />
<Compile Include="Core\Input\CursorUnlocker.cs" />
<Compile Include="Core\Input\IHandleInput.cs" />
<Compile Include="Core\Input\InputManager.cs" />
<Compile Include="Core\Input\InputSystem.cs" />
<Compile Include="Core\Input\LegacyInput.cs" />
<Compile Include="Core\Input\NoInput.cs" />
<Compile Include="Core\ReflectionUtility.cs" />
<Compile Include="Core\Runtime\Il2Cpp\AssetBundle.cs" />
<Compile Include="Core\Runtime\Il2Cpp\ICallManager.cs" />
<Compile Include="Core\Runtime\Il2Cpp\Il2CppCoroutine.cs" />
<Compile Include="Core\Runtime\Il2Cpp\Il2CppProvider.cs" />
<Compile Include="Core\Runtime\Il2Cpp\Il2CppReflection.cs" />
<Compile Include="Core\Runtime\Il2Cpp\Il2CppTextureUtil.cs" />
<Compile Include="Core\Runtime\Mono\MonoProvider.cs" />
<Compile Include="Core\Runtime\Mono\MonoReflection.cs" />
<Compile Include="Core\Runtime\Mono\MonoTextureUtil.cs" />
<Compile Include="Core\Runtime\ReflectionProvider.cs" />
<Compile Include="Core\Runtime\RuntimeProvider.cs" />
<Compile Include="Core\Runtime\TextureUtilProvider.cs" />
<Compile Include="Core\Search\ChildFilter.cs" />
<Compile Include="Core\Search\SceneFilter.cs" />
<Compile Include="Core\Search\SearchContext.cs" />
<Compile Include="Core\Search\SearchProvider.cs" />
<Compile Include="Core\Unity\UnityHelpers.cs" />
<Compile Include="Loader\BIE\BepInExConfigHandler.cs" />
<Compile Include="Loader\BIE\ExplorerBepInPlugin.cs" />
<Compile Include="Loader\ML\MelonLoaderConfigHandler.cs" />
<Compile Include="Loader\STANDALONE\ExplorerStandalone.cs" />
<Compile Include="ExplorerCore.cs" />
<Compile Include="Loader\ML\ExplorerMelonMod.cs" />
<Compile Include="Loader\IExplorerLoader.cs" />
<Compile Include="Loader\STANDALONE\StandaloneConfigHandler.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="UI\CacheObject\CacheConfigEntry.cs" />
<Compile Include="UI\CacheObject\CacheEnumerated.cs" />
<Compile Include="UI\CacheObject\CacheField.cs" />
<Compile Include="UI\CacheObject\CacheMember.cs" />
<Compile Include="UI\CacheObject\CacheMethod.cs" />
<Compile Include="UI\CacheObject\CacheObjectBase.cs" />
<Compile Include="UI\CacheObject\CachePaired.cs" />
<Compile Include="UI\CacheObject\CacheProperty.cs" />
<Compile Include="UI\InteractiveValues\InteractiveBool.cs" />
<Compile Include="UI\InteractiveValues\InteractiveDictionary.cs" />
<Compile Include="UI\InteractiveValues\InteractiveEnum.cs" />
<Compile Include="UI\InteractiveValues\InteractiveEnumerable.cs" />
<Compile Include="UI\InteractiveValues\InteractiveFlags.cs" />
<Compile Include="UI\InteractiveValues\InteractiveNumber.cs" />
<Compile Include="UI\InteractiveValues\InteractiveString.cs" />
<Compile Include="UI\InteractiveValues\InteractiveUnityStruct.cs" />
<Compile Include="UI\InteractiveValues\InteractiveValue.cs" />
<Compile Include="UI\Main\BaseMenuPage.cs" />
<Compile Include="UI\Main\CSConsole\AutoCompleter.cs" />
<Compile Include="UI\Main\CSConsole\CSharpConsole.cs" />
<Compile Include="UI\Main\CSConsole\CSLexerHighlighter.cs" />
<Compile Include="UI\Main\CSConsole\Lexer\CommentMatch.cs" />
<Compile Include="UI\Main\CSConsole\Lexer\KeywordMatch.cs" />
<Compile Include="UI\Main\CSConsole\Lexer\Matcher.cs" />
<Compile Include="UI\Main\CSConsole\Lexer\NumberMatch.cs" />
<Compile Include="UI\Main\CSConsole\Lexer\StringMatch.cs" />
<Compile Include="UI\Main\CSConsole\Lexer\SymbolMatch.cs" />
<Compile Include="UI\Main\DebugConsole.cs" />
<Compile Include="UI\Main\Home\HomePage.cs" />
<Compile Include="UI\Main\Home\InspectorManager.cs" />
<Compile Include="UI\Main\Home\Inspectors\GameObjects\ChildList.cs" />
<Compile Include="UI\Main\Home\Inspectors\GameObjects\ComponentList.cs" />
<Compile Include="UI\Main\Home\Inspectors\GameObjects\GameObjectControls.cs" />
<Compile Include="UI\Main\Home\Inspectors\GameObjects\GameObjectInspector.cs" />
<Compile Include="UI\Main\Home\Inspectors\InspectorBase.cs" />
<Compile Include="UI\Main\Home\Inspectors\Reflection\InstanceInspector.cs" />
<Compile Include="UI\Main\Home\Inspectors\Reflection\ReflectionInspector.cs" />
<Compile Include="UI\Main\Home\Inspectors\Reflection\StaticInspector.cs" />
<Compile Include="UI\Main\Home\InspectUnderMouse.cs" />
<Compile Include="UI\Main\Home\SceneExplorer.cs" />
<Compile Include="UI\Main\MainMenu.cs" />
<Compile Include="UI\Main\Options\OptionsPage.cs" />
<Compile Include="UI\Main\PanelDragger.cs" />
<Compile Include="UI\Main\Search\SearchPage.cs" />
<Compile Include="UI\UIFactory.cs" />
<Compile Include="UI\UIManager.cs" />
<Compile Include="UI\Utility\InputFieldScroller.cs" />
<Compile Include="UI\Utility\PageHandler.cs" />
<Compile Include="UI\Utility\SignatureHighlighter.cs" />
<Compile Include="UI\Utility\SliderScrollbar.cs" />
<EmbeddedResource Include="Resources\*" />
</ItemGroup>
<ItemGroup>
<None Include="ILRepack.targets" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="packages\ILRepack.Lib.MSBuild.Task.2.0.18.1\build\ILRepack.Lib.MSBuild.Task.targets" Condition="Exists('packages\ILRepack.Lib.MSBuild.Task.2.0.18.1\build\ILRepack.Lib.MSBuild.Task.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup> <PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Release_ML_Cpp</Configuration> <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{B21DBDE3-5D6F-4726-93AB-CC3CC68BAE7D}</ProjectGuid>
<OutputType>Library</OutputType>
<!--<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>-->
<AppDesignerFolder>Properties</AppDesignerFolder>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
<TargetFrameworkProfile />
<OutputPath>..\Release\UnityExplorer.MelonLoader.Il2Cpp\</OutputPath>
<DefineConstants>
</DefineConstants>
<IsCpp>false</IsCpp>
<IsMelonLoader>false</IsMelonLoader>
<DebugSymbols>false</DebugSymbols>
<DebugType>none</DebugType>
<Optimize>false</Optimize>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>x64</PlatformTarget>
<Prefer32Bit>false</Prefer32Bit>
<RootNamespace>UnityExplorer</RootNamespace>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release_ML_Cpp|AnyCPU' "> <Error Condition="!Exists('packages\ILRepack.Lib.MSBuild.Task.2.0.18.1\build\ILRepack.Lib.MSBuild.Task.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\ILRepack.Lib.MSBuild.Task.2.0.18.1\build\ILRepack.Lib.MSBuild.Task.targets'))" />
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion> </Target>
<OutputPath>..\Release\UnityExplorer.MelonLoader.Il2Cpp\</OutputPath>
<DefineConstants>CPP,ML</DefineConstants>
<AssemblyName>UnityExplorer.ML.IL2CPP</AssemblyName>
<IsCpp>true</IsCpp>
<IsMelonLoader>true</IsMelonLoader>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release_ML_Mono|AnyCPU' ">
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<OutputPath>..\Release\UnityExplorer.MelonLoader.Mono\</OutputPath>
<DefineConstants>MONO,ML</DefineConstants>
<AssemblyName>UnityExplorer.ML.Mono</AssemblyName>
<Prefer32Bit>false</Prefer32Bit>
<IsCpp>false</IsCpp>
<IsMelonLoader>true</IsMelonLoader>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release_BIE_Cpp|AnyCPU' ">
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<OutputPath>..\Release\UnityExplorer.BepInEx.Il2Cpp\</OutputPath>
<DefineConstants>CPP,BIE,BIE6</DefineConstants>
<AssemblyName>UnityExplorer.BIE.IL2CPP</AssemblyName>
<IsCpp>true</IsCpp>
<IsMelonLoader>false</IsMelonLoader>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release_BIE6_Mono|AnyCPU' ">
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<OutputPath>..\Release\UnityExplorer.BepInEx6.Mono\</OutputPath>
<DefineConstants>MONO,BIE,BIE6</DefineConstants>
<AssemblyName>UnityExplorer.BIE6.Mono</AssemblyName>
<IsCpp>false</IsCpp>
<IsMelonLoader>false</IsMelonLoader>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release_BIE5_Mono|AnyCPU'">
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<OutputPath>..\Release\UnityExplorer.BepInEx5.Mono\</OutputPath>
<DefineConstants>MONO,BIE,BIE5</DefineConstants>
<AssemblyName>UnityExplorer.BIE5.Mono</AssemblyName>
<IsCpp>false</IsCpp>
<IsMelonLoader>false</IsMelonLoader>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release_STANDALONE_Mono|AnyCPU'">
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<OutputPath>..\Release\UnityExplorer.Standalone.Mono\</OutputPath>
<DefineConstants>MONO,STANDALONE</DefineConstants>
<AssemblyName>UnityExplorer.STANDALONE.Mono</AssemblyName>
<IsCpp>false</IsCpp>
<IsMelonLoader>false</IsMelonLoader>
<IsStandalone>true</IsStandalone>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release_STANDALONE_Cpp|AnyCPU'">
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<OutputPath>..\Release\UnityExplorer.Standalone.Il2Cpp\</OutputPath>
<DefineConstants>CPP,STANDALONE</DefineConstants>
<AssemblyName>UnityExplorer.STANDALONE.IL2CPP</AssemblyName>
<IsCpp>true</IsCpp>
<IsMelonLoader>false</IsMelonLoader>
<IsStandalone>true</IsStandalone>
</PropertyGroup>
<ItemGroup>
<Reference Include="INIFileParser, Version=2.5.2.0, Culture=neutral, PublicKeyToken=79af7b307b65cf3c, processorArchitecture=MSIL">
<HintPath>packages\ini-parser.2.5.2\lib\net20\INIFileParser.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<!-- MCS ref -->
<Reference Include="mcs">
<HintPath>..\lib\mcs.dll</HintPath>
<Private>False</Private>
</Reference>
</ItemGroup>
<!-- Universal Mono UnityEngine.dll ref (v5.3) -->
<ItemGroup Condition="'$(IsCpp)'=='false'">
<Reference Include="UnityEngine">
<HintPath>..\lib\UnityEngine.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="UnityEngine.UI">
<HintPath>..\lib\UnityEngine.UI.dll</HintPath>
<Private>False</Private>
</Reference>
</ItemGroup>
<!-- MelonLoader Mono refs -->
<ItemGroup Condition="'$(IsMelonLoader)|$(IsCpp)'=='true|false'">
<Reference Include="MelonLoader">
<HintPath>..\lib\MelonLoader.dll</HintPath>
<Private>False</Private>
</Reference>
</ItemGroup>
<!-- BepInEx 5 Mono refs -->
<ItemGroup Condition="'$(IsMelonLoader)|$(IsCpp)|$(Configuration)'=='false|false|Release_BIE5_Mono'">
<Reference Include="BepInEx">
<HintPath>..\lib\BepInEx.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="0Harmony">
<HintPath>..\lib\0Harmony.dll</HintPath>
<Private>False</Private>
</Reference>
</ItemGroup>
<!-- BepInEx 6 Mono refs -->
<ItemGroup Condition="'$(IsMelonLoader)|$(IsCpp)|$(Configuration)'=='false|false|Release_BIE6_Mono'">
<Reference Include="BepInEx">
<HintPath>..\lib\BepInEx.Core.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="BepInEx.Unity">
<HintPath>..\lib\BepInEx.Unity.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="0Harmony">
<HintPath>..\lib\0Harmony.dll</HintPath>
<Private>False</Private>
</Reference>
</ItemGroup>
<!-- Standalone refs -->
<ItemGroup Condition="'$(IsStandalone)'=='true'">
<Reference Include="0Harmony">
<HintPath>..\lib\0Harmony.dll</HintPath>
<Private>False</Private>
</Reference>
</ItemGroup>
<!-- MelonLoader Il2Cpp refs -->
<ItemGroup Condition="'$(IsMelonLoader)|$(IsCpp)'=='true|true'">
<Reference Include="MelonLoader">
<HintPath>..\lib\MelonLoader.dll</HintPath>
<Private>False</Private>
</Reference>
</ItemGroup>
<!-- BepInEx Il2Cpp refs -->
<ItemGroup Condition="'$(IsMelonLoader)|$(IsCpp)'=='false|true'">
<Reference Include="BepInEx">
<HintPath>..\lib\BepInEx.Core.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="0Harmony">
<HintPath>..\lib\0Harmony.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="BepInEx.IL2CPP">
<HintPath>..\lib\BepInEx.IL2CPP.dll</HintPath>
<Private>False</Private>
</Reference>
</ItemGroup>
<!-- Unhollowed Il2Cpp refs -->
<ItemGroup Condition="'$(IsCpp)'=='true'">
<Reference Include="UnhollowerBaseLib">
<HintPath>..\lib\UnhollowerBaseLib.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="Il2Cppmscorlib">
<HintPath>..\lib\unhollowed\Il2Cppmscorlib.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="Il2CppSystem.Core">
<HintPath>..\lib\unhollowed\Il2CppSystem.Core.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="UnityEngine">
<HintPath>..\lib\unhollowed\UnityEngine.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="UnityEngine.CoreModule">
<HintPath>..\lib\unhollowed\UnityEngine.CoreModule.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="UnityEngine.PhysicsModule">
<HintPath>..\lib\unhollowed\UnityEngine.PhysicsModule.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="UnityEngine.TextRenderingModule">
<HintPath>..\lib\unhollowed\UnityEngine.TextRenderingModule.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="UnityEngine.UI">
<HintPath>..\lib\unhollowed\UnityEngine.UI.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="UnityEngine.UIModule">
<HintPath>..\lib\unhollowed\UnityEngine.UIModule.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="UnityEngine.IMGUIModule">
<HintPath>..\lib\unhollowed\UnityEngine.IMGUIModule.dll</HintPath>
<Private>False</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Core\CSharp\DummyBehaviour.cs" />
<Compile Include="Core\Runtime\Il2Cpp\Il2CppCoroutine.cs" />
<Compile Include="Loader\ExplorerBepIn6Plugin.cs" />
<Compile Include="Loader\ExplorerStandalone.cs" />
<Compile Include="Core\Runtime\Il2Cpp\Il2CppReflection.cs" />
<Compile Include="Core\Runtime\Il2Cpp\Il2CppTextureUtil.cs" />
<Compile Include="Core\Runtime\Mono\MonoReflection.cs" />
<Compile Include="Core\Runtime\Mono\MonoTextureUtil.cs" />
<Compile Include="Core\Runtime\ReflectionProvider.cs" />
<Compile Include="Core\Runtime\TextureUtilProvider.cs" />
<Compile Include="Core\Inspectors\InspectUnderMouse.cs" />
<Compile Include="Core\Inspectors\Reflection\CacheObject\CacheEnumerated.cs" />
<Compile Include="Core\Inspectors\Reflection\CacheObject\CacheField.cs" />
<Compile Include="Core\Inspectors\Reflection\CacheObject\CachePaired.cs" />
<Compile Include="Core\Inspectors\Reflection\CacheObject\CacheMember.cs" />
<Compile Include="Core\Inspectors\Reflection\CacheObject\CacheMethod.cs" />
<Compile Include="Core\Inspectors\Reflection\CacheObject\CacheProperty.cs" />
<Compile Include="Core\Inspectors\Reflection\CacheObject\CacheObjectBase.cs" />
<Compile Include="Core\Config\ExplorerConfig.cs" />
<Compile Include="ExplorerCore.cs" />
<Compile Include="Loader\ExplorerBepIn5Plugin.cs" />
<Compile Include="Loader\ExplorerMelonMod.cs" />
<Compile Include="Core\ReflectionUtility.cs" />
<Compile Include="Core\Unity\UnityHelper.cs" />
<Compile Include="UI\Main\Home\Inspectors\GameObjects\ChildList.cs" />
<Compile Include="UI\Main\Home\Inspectors\GameObjects\ComponentList.cs" />
<Compile Include="UI\Main\Home\Inspectors\GameObjects\GameObjectControls.cs" />
<Compile Include="Core\Inspectors\Reflection\InteractiveValue\InteractiveBool.cs" />
<Compile Include="Core\Inspectors\Reflection\InteractiveValue\InteractiveDictionary.cs" />
<Compile Include="Core\Inspectors\Reflection\InteractiveValue\InteractiveEnum.cs" />
<Compile Include="Core\Inspectors\Reflection\InteractiveValue\InteractiveEnumerable.cs" />
<Compile Include="Core\Inspectors\Reflection\InteractiveValue\InteractiveFlags.cs" />
<Compile Include="Core\Inspectors\Reflection\InteractiveValue\InteractiveNumber.cs" />
<Compile Include="Core\Inspectors\Reflection\InteractiveValue\InteractiveString.cs" />
<Compile Include="Core\Inspectors\Reflection\InteractiveValue\InteractiveUnityStruct.cs" />
<Compile Include="Loader\IExplorerLoader.cs" />
<Compile Include="Core\Runtime\Il2Cpp\Il2CppProvider.cs" />
<Compile Include="Core\Runtime\RuntimeProvider.cs" />
<Compile Include="Core\Runtime\Mono\MonoProvider.cs" />
<Compile Include="Core\Search\ChildFilter.cs" />
<Compile Include="Core\Search\SceneFilter.cs" />
<Compile Include="Core\Search\SearchContext.cs" />
<Compile Include="Core\Search\SearchProvider.cs" />
<Compile Include="UI\Main\Home\InspectorManagerUI.cs" />
<Compile Include="UI\Main\Home\Inspectors\GameObjects\GameObjectInspectorUI.cs" />
<Compile Include="UI\Main\Home\Inspectors\InspectorBaseUI.cs" />
<Compile Include="UI\Main\Home\Inspectors\Reflection\InstanceInspectorUI.cs" />
<Compile Include="UI\Main\Home\Inspectors\MouseInspectorUI.cs" />
<Compile Include="UI\Main\Home\Inspectors\Reflection\ReflectionInspectorUI.cs" />
<Compile Include="UI\Main\Home\SceneExplorerUI.cs" />
<Compile Include="UI\Utility\CursorUnlocker.cs" />
<Compile Include="Core\Input\IHandleInput.cs" />
<Compile Include="Core\Tests\Tests.cs" />
<Compile Include="Core\Input\InputManager.cs" />
<Compile Include="Core\Input\InputSystem.cs" />
<Compile Include="Core\Input\LegacyInput.cs" />
<Compile Include="Core\Input\NoInput.cs" />
<Compile Include="UI\Main\DebugConsole.cs" />
<Compile Include="Core\InspectorManager.cs" />
<Compile Include="Core\Inspectors\Reflection\ReflectionInspector.cs" />
<Compile Include="UI\Main\MainMenu.cs" />
<Compile Include="UI\Main\CSConsole\CSharpConsole.cs" />
<Compile Include="UI\Main\CSConsole\AutoCompleter.cs" />
<Compile Include="UI\Main\CSConsole\Lexer\CommentMatch.cs" />
<Compile Include="UI\Main\CSConsole\CSLexerHighlighter.cs" />
<Compile Include="UI\Main\CSConsole\Lexer\KeywordMatch.cs" />
<Compile Include="UI\Main\CSConsole\Lexer\StringMatch.cs" />
<Compile Include="UI\Main\CSConsole\Lexer\Matcher.cs" />
<Compile Include="UI\Main\CSConsole\Lexer\NumberMatch.cs" />
<Compile Include="UI\Main\CSConsole\Lexer\SymbolMatch.cs" />
<Compile Include="Core\CSharp\Suggestion.cs" />
<Compile Include="Core\CSharp\ScriptEvaluator.cs" />
<Compile Include="Core\CSharp\ScriptInteraction.cs" />
<Compile Include="UI\Main\Home\HomePage.cs" />
<Compile Include="Core\Inspectors\GameObjects\GameObjectInspector.cs" />
<Compile Include="Core\Inspectors\InspectorBase.cs" />
<Compile Include="Core\Inspectors\Reflection\InstanceInspector.cs" />
<Compile Include="Core\Inspectors\Reflection\StaticInspector.cs" />
<Compile Include="UI\Main\BaseMenuPage.cs" />
<Compile Include="UI\Main\Options\OptionsPage.cs" />
<Compile Include="Core\SceneExplorer.cs" />
<Compile Include="UI\Main\Search\SearchPage.cs" />
<Compile Include="UI\Main\PanelDragger.cs" />
<Compile Include="Core\Inspectors\Reflection\InteractiveValue\InteractiveValue.cs" />
<Compile Include="UI\Reusable\InputFieldScroller.cs" />
<Compile Include="UI\Reusable\SliderScrollbar.cs" />
<Compile Include="UI\Reusable\PageHandler.cs" />
<Compile Include="UI\Utility\SignatureHighlighter.cs" />
<Compile Include="UI\UIManager.cs" />
<Compile Include="Core\Runtime\Il2Cpp\AssetBundle.cs" />
<Compile Include="Core\Unity\ColorHelper.cs" />
<Compile Include="Core\Runtime\Il2Cpp\ICallManager.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="UI\UIFactory.cs" />
<EmbeddedResource Include="Resources\*" />
</ItemGroup>
<ItemGroup>
<None Include="ILRepack.targets" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="packages\ILRepack.Lib.MSBuild.Task.2.0.18.1\build\ILRepack.Lib.MSBuild.Task.targets" Condition="Exists('packages\ILRepack.Lib.MSBuild.Task.2.0.18.1\build\ILRepack.Lib.MSBuild.Task.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('packages\ILRepack.Lib.MSBuild.Task.2.0.18.1\build\ILRepack.Lib.MSBuild.Task.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\ILRepack.Lib.MSBuild.Task.2.0.18.1\build\ILRepack.Lib.MSBuild.Task.targets'))" />
</Target>
</Project> </Project>