mirror of
https://github.com/sinai-dev/UnityExplorer.git
synced 2025-06-28 10:52:44 +08:00
Lots of fixes, everything basically done except Reflection Inspector
This commit is contained in:
144
src/UI/Modules/ConsolePage.cs
Normal file
144
src/UI/Modules/ConsolePage.cs
Normal file
@ -0,0 +1,144 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using UnityExplorer.Console;
|
||||
|
||||
namespace UnityExplorer.UI.Modules
|
||||
{
|
||||
public class ConsolePage : MainMenu.Page
|
||||
{
|
||||
public override string Name => "C# Console";
|
||||
|
||||
public static ConsolePage Instance { get; private set; }
|
||||
|
||||
public CodeEditor m_codeEditor;
|
||||
public ScriptEvaluator m_evaluator;
|
||||
|
||||
public static bool EnableAutocompletes { get; set; } = true;
|
||||
public static bool EnableAutoIndent { get; set; } = true;
|
||||
|
||||
public static List<Suggestion> AutoCompletes = new List<Suggestion>();
|
||||
public static List<string> UsingDirectives;
|
||||
|
||||
public static readonly string[] DefaultUsing = new string[]
|
||||
{
|
||||
"System",
|
||||
"System.Linq",
|
||||
"System.Collections",
|
||||
"System.Collections.Generic",
|
||||
"System.Reflection",
|
||||
"UnityEngine",
|
||||
#if CPP
|
||||
"UnhollowerBaseLib",
|
||||
"UnhollowerRuntimeLib",
|
||||
#endif
|
||||
};
|
||||
|
||||
public override void Init()
|
||||
{
|
||||
Instance = this;
|
||||
|
||||
try
|
||||
{
|
||||
m_codeEditor = new CodeEditor();
|
||||
|
||||
AutoCompleter.Init();
|
||||
|
||||
ResetConsole();
|
||||
|
||||
// Make sure compiler is supported on this platform
|
||||
m_evaluator.Compile("");
|
||||
|
||||
foreach (string use in DefaultUsing)
|
||||
{
|
||||
AddUsing(use);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// TODO remove page button from menu?
|
||||
ExplorerCore.LogWarning($"Error setting up console!\r\nMessage: {e.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
m_codeEditor?.Update();
|
||||
|
||||
AutoCompleter.Update();
|
||||
}
|
||||
|
||||
public void AddUsing(string asm)
|
||||
{
|
||||
if (!UsingDirectives.Contains(asm))
|
||||
{
|
||||
Evaluate($"using {asm};", true);
|
||||
UsingDirectives.Add(asm);
|
||||
}
|
||||
}
|
||||
|
||||
public void Evaluate(string code, bool suppressWarning = false)
|
||||
{
|
||||
m_evaluator.Compile(code, out Mono.CSharp.CompiledMethod compiled);
|
||||
|
||||
if (compiled == null)
|
||||
{
|
||||
if (!suppressWarning)
|
||||
ExplorerCore.LogWarning("Unable to compile the code!");
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
object ret = VoidType.Value;
|
||||
compiled.Invoke(ref ret);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (!suppressWarning)
|
||||
ExplorerCore.LogWarning($"Exception executing code: {e.GetType()}, {e.Message}\r\n{e.StackTrace}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ResetConsole()
|
||||
{
|
||||
if (m_evaluator != null)
|
||||
{
|
||||
m_evaluator.Dispose();
|
||||
}
|
||||
|
||||
m_evaluator = new ScriptEvaluator(new StringWriter(new StringBuilder())) { InteractiveBaseClass = typeof(ScriptInteraction) };
|
||||
|
||||
UsingDirectives = new List<string>();
|
||||
}
|
||||
|
||||
internal void OnInputChanged()
|
||||
{
|
||||
if (!EnableAutocompletes)
|
||||
return;
|
||||
|
||||
AutoCompleter.CheckAutocomplete();
|
||||
AutoCompleter.SetSuggestions(AutoCompletes.ToArray());
|
||||
}
|
||||
|
||||
public void UseAutocomplete(string suggestion)
|
||||
{
|
||||
int cursorIndex = m_codeEditor.InputField.caretPosition;
|
||||
string input = m_codeEditor.InputField.text;
|
||||
input = input.Insert(cursorIndex, suggestion);
|
||||
m_codeEditor.InputField.text = input;
|
||||
m_codeEditor.InputField.caretPosition += suggestion.Length;
|
||||
|
||||
AutoCompleter.ClearAutocompletes();
|
||||
}
|
||||
|
||||
private class VoidType
|
||||
{
|
||||
public static readonly VoidType Value = new VoidType();
|
||||
private VoidType() { }
|
||||
}
|
||||
}
|
||||
}
|
274
src/UI/Modules/DebugConsole.cs
Normal file
274
src/UI/Modules/DebugConsole.cs
Normal file
@ -0,0 +1,274 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityExplorer.Unstrip;
|
||||
//using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityExplorer.Config;
|
||||
using UnityExplorer.UI.Shared;
|
||||
|
||||
namespace UnityExplorer.UI.Modules
|
||||
{
|
||||
public class DebugConsole
|
||||
{
|
||||
public static DebugConsole Instance { get; private set; }
|
||||
|
||||
public static bool LogUnity { get; set; } = ModConfig.Instance.Log_Unity_Debug;
|
||||
|
||||
public static readonly List<string> AllMessages = new List<string>();
|
||||
public static readonly List<Text> MessageHolders = new List<Text>();
|
||||
|
||||
internal static readonly List<string> s_preInitMessages = new List<string>();
|
||||
|
||||
private InputField m_textInput;
|
||||
|
||||
public DebugConsole(GameObject parent)
|
||||
{
|
||||
Instance = this;
|
||||
|
||||
//AllMessages = new List<string>();
|
||||
//MessageHolders = new List<Text>();
|
||||
|
||||
ConstructUI(parent);
|
||||
|
||||
string preAppend = "";
|
||||
for (int i = s_preInitMessages.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var msg = s_preInitMessages[i];
|
||||
if (preAppend != "")
|
||||
preAppend += "\r\n";
|
||||
preAppend += msg;
|
||||
}
|
||||
m_textInput.text = preAppend;
|
||||
}
|
||||
|
||||
public static void Log(string message)
|
||||
{
|
||||
Log(message, null);
|
||||
}
|
||||
|
||||
public static void Log(string message, Color color)
|
||||
{
|
||||
Log(message, color.ToHex());
|
||||
}
|
||||
|
||||
public static void Log(string message, string hexColor)
|
||||
{
|
||||
message = $"{AllMessages.Count}: {message}";
|
||||
|
||||
AllMessages.Add(message);
|
||||
|
||||
if (hexColor != null)
|
||||
message = $"<color=#{hexColor}>{message}</color>";
|
||||
|
||||
if (Instance?.m_textInput)
|
||||
Instance.m_textInput.text = $"{message}\n{Instance.m_textInput.text}";
|
||||
else
|
||||
s_preInitMessages.Add(message);
|
||||
}
|
||||
|
||||
public void ConstructUI(GameObject parent)
|
||||
{
|
||||
var mainObj = UIFactory.CreateVerticalGroup(parent, 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>();
|
||||
mainImage.maskable = true;
|
||||
|
||||
var mask = mainObj.AddComponent<Mask>();
|
||||
mask.showMaskGraphic = true;
|
||||
|
||||
var mainLayout = mainObj.AddComponent<LayoutElement>();
|
||||
mainLayout.minHeight = 190;
|
||||
mainLayout.flexibleHeight = 0;
|
||||
|
||||
#region LOG AREA
|
||||
var logAreaObj = UIFactory.CreateHorizontalGroup(mainObj);
|
||||
var logAreaGroup = logAreaObj.GetComponent<HorizontalLayoutGroup>();
|
||||
logAreaGroup.childControlHeight = true;
|
||||
logAreaGroup.childControlWidth = true;
|
||||
logAreaGroup.childForceExpandHeight = true;
|
||||
logAreaGroup.childForceExpandWidth = true;
|
||||
|
||||
var logAreaLayout = logAreaObj.AddComponent<LayoutElement>();
|
||||
logAreaLayout.preferredHeight = 190;
|
||||
logAreaLayout.flexibleHeight = 0;
|
||||
|
||||
//var inputObj = UIFactory.CreateInputField(logAreaObj, 14, 0, 1);
|
||||
|
||||
//var mainInputGroup = inputObj.GetComponent<VerticalLayoutGroup>();
|
||||
//mainInputGroup.padding.left = 8;
|
||||
//mainInputGroup.padding.right = 8;
|
||||
//mainInputGroup.padding.top = 5;
|
||||
//mainInputGroup.padding.bottom = 5;
|
||||
|
||||
//var inputLayout = inputObj.AddComponent<LayoutElement>();
|
||||
//inputLayout.preferredWidth = 500;
|
||||
//inputLayout.flexibleWidth = 9999;
|
||||
|
||||
//var inputImage = inputObj.GetComponent<Image>();
|
||||
//inputImage.color = new Color(0.05f, 0.05f, 0.05f, 1.0f);
|
||||
|
||||
//var scroll = UIFactory.CreateScrollbar(logAreaObj);
|
||||
|
||||
//var scrollLayout = scroll.AddComponent<LayoutElement>();
|
||||
//scrollLayout.preferredWidth = 25;
|
||||
//scrollLayout.flexibleWidth = 0;
|
||||
|
||||
//var scroller = scroll.GetComponent<Scrollbar>();
|
||||
//scroller.direction = Scrollbar.Direction.TopToBottom;
|
||||
//var scrollColors = scroller.colors;
|
||||
//scrollColors.normalColor = new Color(0.5f, 0.5f, 0.5f, 1.0f);
|
||||
//scroller.colors = scrollColors;
|
||||
|
||||
//var tmpInput = inputObj.GetComponent<InputField>();
|
||||
//tmpInput.readOnly = true;
|
||||
|
||||
//if (UIManager.ConsoleFont)
|
||||
//{
|
||||
// tmpInput.textComponent.font = UIManager.ConsoleFont;
|
||||
//}
|
||||
|
||||
//tmpInput.readOnly = true;
|
||||
|
||||
var inputScrollerObj = UIFactory.CreateSrollInputField(logAreaObj, out InputFieldScroller inputScroll, 14, new Color(0.05f, 0.05f, 0.05f));
|
||||
|
||||
inputScroll.inputField.textComponent.font = UIManager.ConsoleFont;
|
||||
inputScroll.inputField.readOnly = true;
|
||||
|
||||
m_textInput = inputScroll.inputField;
|
||||
|
||||
#endregion
|
||||
|
||||
#region BOTTOM BAR
|
||||
|
||||
var bottomBarObj = UIFactory.CreateHorizontalGroup(mainObj);
|
||||
LayoutElement topBarLayout = bottomBarObj.AddComponent<LayoutElement>();
|
||||
topBarLayout.minHeight = 40;
|
||||
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
|
||||
|
||||
var bottomLabel = UIFactory.CreateLabel(bottomBarObj, TextAnchor.MiddleLeft);
|
||||
var topBarLabelLayout = bottomLabel.AddComponent<LayoutElement>();
|
||||
topBarLabelLayout.minWidth = 100;
|
||||
topBarLabelLayout.flexibleWidth = 0;
|
||||
var topBarText = bottomLabel.GetComponent<Text>();
|
||||
topBarText.fontStyle = FontStyle.Bold;
|
||||
topBarText.text = "Debug Console";
|
||||
topBarText.fontSize = 14;
|
||||
|
||||
// Hide button
|
||||
|
||||
var hideButtonObj = UIFactory.CreateButton(bottomBarObj);
|
||||
|
||||
var hideBtnText = hideButtonObj.GetComponentInChildren<Text>();
|
||||
hideBtnText.text = "Hide";
|
||||
|
||||
var hideButton = hideButtonObj.GetComponent<Button>();
|
||||
#if CPP
|
||||
hideButton.onClick.AddListener(new Action(HideCallback));
|
||||
#else
|
||||
hideButton.onClick.AddListener(HideCallback);
|
||||
#endif
|
||||
void HideCallback()
|
||||
{
|
||||
if (logAreaObj.activeSelf)
|
||||
{
|
||||
logAreaObj.SetActive(false);
|
||||
hideBtnText.text = "Show";
|
||||
mainLayout.minHeight = 40;
|
||||
}
|
||||
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
|
||||
|
||||
var clearButtonObj = UIFactory.CreateButton(bottomBarObj);
|
||||
|
||||
var clearBtnText = clearButtonObj.GetComponentInChildren<Text>();
|
||||
clearBtnText.text = "Clear";
|
||||
|
||||
var clearButton = clearButtonObj.GetComponent<Button>();
|
||||
#if CPP
|
||||
clearButton.onClick.AddListener(new Action(ClearCallback));
|
||||
#else
|
||||
clearButton.onClick.AddListener(ClearCallback);
|
||||
#endif
|
||||
|
||||
void ClearCallback()
|
||||
{
|
||||
m_textInput.text = "";
|
||||
AllMessages.Clear();
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
var unityToggleObj = UIFactory.CreateToggle(bottomBarObj, out Toggle unityToggle, out Text unityToggleText);
|
||||
#if CPP
|
||||
unityToggle.onValueChanged.AddListener(new Action<bool>(ToggleLogUnity));
|
||||
#else
|
||||
unityToggle.onValueChanged.AddListener(ToggleLogUnity);
|
||||
#endif
|
||||
unityToggle.isOn = LogUnity;
|
||||
unityToggleText.text = "Print Unity Debug?";
|
||||
unityToggleText.alignment = TextAnchor.MiddleLeft;
|
||||
|
||||
void ToggleLogUnity(bool val)
|
||||
{
|
||||
LogUnity = val;
|
||||
ModConfig.Instance.Log_Unity_Debug = val;
|
||||
ModConfig.SaveSettings();
|
||||
}
|
||||
|
||||
var unityToggleLayout = unityToggleObj.AddComponent<LayoutElement>();
|
||||
unityToggleLayout.minWidth = 200;
|
||||
unityToggleLayout.flexibleWidth = 0;
|
||||
|
||||
var unityToggleRect = unityToggleObj.transform.Find("Background").GetComponent<RectTransform>();
|
||||
var pos = unityToggleRect.localPosition;
|
||||
pos.y = -8;
|
||||
unityToggleRect.localPosition = pos;
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
52
src/UI/Modules/HomePage.cs
Normal file
52
src/UI/Modules/HomePage.cs
Normal file
@ -0,0 +1,52 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityExplorer.Inspectors;
|
||||
|
||||
namespace UnityExplorer.UI.Modules
|
||||
{
|
||||
public class HomePage : MainMenu.Page
|
||||
{
|
||||
public override string Name => "Home";
|
||||
|
||||
public static HomePage Instance { get; internal set; }
|
||||
|
||||
public override void Init()
|
||||
{
|
||||
Instance = this;
|
||||
|
||||
ConstructMenu();
|
||||
|
||||
new SceneExplorer();
|
||||
|
||||
new InspectorManager();
|
||||
|
||||
SceneExplorer.Instance.Init();
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
SceneExplorer.Instance.Update();
|
||||
InspectorManager.Instance.Update();
|
||||
}
|
||||
|
||||
private void ConstructMenu()
|
||||
{
|
||||
GameObject parent = MainMenu.Instance.PageViewport;
|
||||
|
||||
Content = UIFactory.CreateHorizontalGroup(parent);
|
||||
var mainGroup = Content.GetComponent<HorizontalLayoutGroup>();
|
||||
mainGroup.padding.left = 3;
|
||||
mainGroup.padding.right = 3;
|
||||
mainGroup.padding.top = 3;
|
||||
mainGroup.padding.bottom = 3;
|
||||
mainGroup.spacing = 5;
|
||||
mainGroup.childForceExpandHeight = true;
|
||||
mainGroup.childForceExpandWidth = true;
|
||||
mainGroup.childControlHeight = true;
|
||||
mainGroup.childControlWidth = true;
|
||||
}
|
||||
}
|
||||
}
|
241
src/UI/Modules/OptionsPage.cs
Normal file
241
src/UI/Modules/OptionsPage.cs
Normal file
@ -0,0 +1,241 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
//using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityExplorer.Config;
|
||||
using UnityExplorer.UI.Shared;
|
||||
using UnityExplorer.Unstrip;
|
||||
|
||||
namespace UnityExplorer.UI.Modules
|
||||
{
|
||||
public class OptionsPage : MainMenu.Page
|
||||
{
|
||||
public override string Name => "Options";
|
||||
|
||||
private InputField m_keycodeInput;
|
||||
private Toggle m_unlockMouseToggle;
|
||||
private InputField m_pageLimitInput;
|
||||
private InputField m_defaultOutputInput;
|
||||
|
||||
public override void Init()
|
||||
{
|
||||
ConstructUI();
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
ModConfig.Instance.Main_Menu_Toggle = keyCode;
|
||||
}
|
||||
|
||||
ModConfig.Instance.Force_Unlock_Mouse = m_unlockMouseToggle.isOn;
|
||||
|
||||
if (!string.IsNullOrEmpty(m_pageLimitInput.text) && int.TryParse(m_pageLimitInput.text, out int lim))
|
||||
{
|
||||
ModConfig.Instance.Default_Page_Limit = lim;
|
||||
}
|
||||
|
||||
ModConfig.Instance.Default_Output_Path = m_defaultOutputInput.text;
|
||||
|
||||
// todo default output path
|
||||
|
||||
ModConfig.SaveSettings();
|
||||
ModConfig.InvokeConfigChanged();
|
||||
}
|
||||
|
||||
#region UI CONSTRUCTION
|
||||
|
||||
internal void ConstructUI()
|
||||
{
|
||||
GameObject parent = MainMenu.Instance.PageViewport;
|
||||
|
||||
Content = UIFactory.CreateVerticalGroup(parent, new Color(0.15f, 0.15f, 0.15f));
|
||||
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 = false;
|
||||
mainGroup.childForceExpandWidth = true;
|
||||
mainGroup.childControlHeight = true;
|
||||
mainGroup.childControlWidth = true;
|
||||
|
||||
// ~~~~~ Title ~~~~~
|
||||
|
||||
GameObject titleObj = UIFactory.CreateLabel(Content, TextAnchor.UpperLeft);
|
||||
Text titleLabel = titleObj.GetComponent<Text>();
|
||||
titleLabel.text = "Options";
|
||||
titleLabel.fontSize = 20;
|
||||
LayoutElement titleLayout = titleObj.AddComponent<LayoutElement>();
|
||||
titleLayout.minHeight = 30;
|
||||
titleLayout.flexibleHeight = 0;
|
||||
|
||||
// ~~~~~ Actual options ~~~~~
|
||||
|
||||
var optionsGroupObj = UIFactory.CreateVerticalGroup(Content, new Color(0.1f, 0.1f, 0.1f));
|
||||
var optionsGroup = optionsGroupObj.GetComponent<VerticalLayoutGroup>();
|
||||
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);
|
||||
ConstructMouseUnlockOpt(optionsGroupObj);
|
||||
ConstructPageLimitOpt(optionsGroupObj);
|
||||
ConstructOutputPathOpt(optionsGroupObj);
|
||||
|
||||
var applyBtnObj = UIFactory.CreateButton(Content, new Color(0.2f, 0.2f, 0.2f));
|
||||
var applyText = applyBtnObj.GetComponentInChildren<Text>();
|
||||
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;
|
||||
#if MONO
|
||||
applyBtn.onClick.AddListener(OnApply);
|
||||
#else
|
||||
applyBtn.onClick.AddListener(new Action(OnApply));
|
||||
#endif
|
||||
}
|
||||
|
||||
internal void ConstructKeycodeOpt(GameObject parent)
|
||||
{
|
||||
//public KeyCode Main_Menu_Toggle = KeyCode.F7;
|
||||
|
||||
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 = ModConfig.Instance.Main_Menu_Toggle.ToString();
|
||||
|
||||
m_keycodeInput.placeholder.gameObject.GetComponent<Text>().text = "KeyCode, eg. F7";
|
||||
}
|
||||
|
||||
internal void ConstructMouseUnlockOpt(GameObject parent)
|
||||
{
|
||||
//public bool Force_Unlock_Mouse = true;
|
||||
|
||||
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 = ModConfig.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 = ModConfig.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 = ModConfig.Instance.Default_Output_Path.ToString();
|
||||
|
||||
m_defaultOutputInput.placeholder.gameObject.GetComponent<Text>().text = @"Directory, eg. Mods\UnityExplorer";
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
736
src/UI/Modules/SearchPage.cs
Normal file
736
src/UI/Modules/SearchPage.cs
Normal file
@ -0,0 +1,736 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
//using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEngine.UI;
|
||||
using UnityExplorer.Helpers;
|
||||
using UnityExplorer.Inspectors;
|
||||
using UnityExplorer.UI.Shared;
|
||||
using UnityExplorer.Unstrip;
|
||||
#if CPP
|
||||
using UnhollowerRuntimeLib;
|
||||
#endif
|
||||
|
||||
namespace UnityExplorer.UI.Modules
|
||||
{
|
||||
internal enum SearchContext
|
||||
{
|
||||
UnityObject,
|
||||
GameObject,
|
||||
Component,
|
||||
Custom,
|
||||
Instance,
|
||||
StaticClass
|
||||
}
|
||||
|
||||
internal enum SceneFilter
|
||||
{
|
||||
Any,
|
||||
Asset,
|
||||
DontDestroyOnLoad,
|
||||
Explicit,
|
||||
}
|
||||
|
||||
internal enum ChildFilter
|
||||
{
|
||||
Any,
|
||||
RootObject,
|
||||
HasParent
|
||||
}
|
||||
|
||||
public class SearchPage : MainMenu.Page
|
||||
{
|
||||
public override string Name => "Search";
|
||||
|
||||
public static SearchPage Instance;
|
||||
|
||||
// ui elements
|
||||
|
||||
private Text m_resultCountText;
|
||||
|
||||
internal SearchContext m_context;
|
||||
private InputField m_customTypeInput;
|
||||
|
||||
private InputField m_nameInput;
|
||||
|
||||
private Button m_selectedContextButton;
|
||||
private readonly Dictionary<SearchContext, Button> m_contextButtons = new Dictionary<SearchContext, Button>();
|
||||
|
||||
private Dropdown m_sceneDropdown;
|
||||
private int m_lastSceneCount = -1;
|
||||
private SceneFilter m_sceneFilter;
|
||||
|
||||
private ChildFilter m_childFilter;
|
||||
|
||||
private GameObject m_extraFilterRow;
|
||||
|
||||
// Results
|
||||
|
||||
internal object[] m_results;
|
||||
internal readonly List<object> m_resultShortList = new List<object>();
|
||||
|
||||
private int m_lastCount;
|
||||
public PageHandler m_resultListPageHandler;
|
||||
private GameObject m_resultListContent;
|
||||
private readonly List<Text> m_resultListTexts = new List<Text>();
|
||||
|
||||
public SearchPage()
|
||||
{
|
||||
Instance = this;
|
||||
}
|
||||
|
||||
public override void Init()
|
||||
{
|
||||
ConstructUI();
|
||||
}
|
||||
|
||||
public void OnSceneChange()
|
||||
{
|
||||
m_results = new object[0];
|
||||
RefreshResultList();
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
if (HaveScenesChanged())
|
||||
{
|
||||
RefreshSceneDropdown();
|
||||
}
|
||||
|
||||
if (m_customTypeInput.isFocused && m_context != SearchContext.Custom)
|
||||
{
|
||||
OnContextButtonClicked(SearchContext.Custom);
|
||||
}
|
||||
}
|
||||
|
||||
// Updating result list content
|
||||
|
||||
private void RefreshResultList()
|
||||
{
|
||||
m_resultListPageHandler.ListCount = m_results.Length;
|
||||
|
||||
int newCount = 0;
|
||||
|
||||
foreach (var itemIndex in m_resultListPageHandler)
|
||||
{
|
||||
newCount++;
|
||||
|
||||
// normalized index starting from 0
|
||||
var i = itemIndex - m_resultListPageHandler.StartIndex;
|
||||
|
||||
if (itemIndex >= m_results.Length)
|
||||
{
|
||||
if (i > m_lastCount || i >= m_resultListTexts.Count)
|
||||
break;
|
||||
|
||||
GameObject label = m_resultListTexts[i].transform.parent.parent.gameObject;
|
||||
if (label.activeSelf)
|
||||
label.SetActive(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
var obj = m_results[itemIndex];
|
||||
|
||||
var uObj = obj as UnityEngine.Object;
|
||||
|
||||
if (obj == null || (uObj != null && !uObj))
|
||||
continue;
|
||||
|
||||
if (i >= m_resultShortList.Count)
|
||||
{
|
||||
m_resultShortList.Add(obj);
|
||||
AddResultButton();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_resultShortList[i] = obj;
|
||||
}
|
||||
|
||||
var text = m_resultListTexts[i];
|
||||
|
||||
var name = $"<color={SyntaxColors.Class_Instance}>{ReflectionHelpers.GetActualType(obj).Name}</color>";
|
||||
|
||||
if (m_context != SearchContext.Instance && m_context != SearchContext.StaticClass)
|
||||
{
|
||||
if (uObj && !string.IsNullOrEmpty(uObj.name))
|
||||
name += $": {uObj.name}";
|
||||
else
|
||||
name += ": <i><color=grey>untitled</color></i>";
|
||||
}
|
||||
|
||||
text.text = name;
|
||||
|
||||
var label = text.transform.parent.parent.gameObject;
|
||||
if (!label.activeSelf)
|
||||
label.SetActive(true);
|
||||
}
|
||||
}
|
||||
|
||||
m_lastCount = newCount;
|
||||
}
|
||||
|
||||
// scene dropdown update
|
||||
|
||||
internal bool HaveScenesChanged()
|
||||
{
|
||||
if (m_lastSceneCount != SceneManager.sceneCount)
|
||||
return true;
|
||||
|
||||
for (int i = 0; i < SceneManager.sceneCount; i++)
|
||||
{
|
||||
int dropdownIndex = i + 3;
|
||||
if (dropdownIndex >= m_sceneDropdown.options.Count
|
||||
|| m_sceneDropdown.options[dropdownIndex].text != SceneManager.GetSceneAt(i).name)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
internal void RefreshSceneDropdown()
|
||||
{
|
||||
m_sceneDropdown.OnCancel(null);
|
||||
|
||||
m_sceneDropdown.options.Clear();
|
||||
|
||||
m_sceneDropdown.options.Add(new Dropdown.OptionData
|
||||
{
|
||||
text = "Any"
|
||||
});
|
||||
|
||||
m_sceneDropdown.options.Add(new Dropdown.OptionData
|
||||
{
|
||||
text = "None (Asset / Resource)"
|
||||
});
|
||||
m_sceneDropdown.options.Add(new Dropdown.OptionData
|
||||
{
|
||||
text = "DontDestroyOnLoad"
|
||||
});
|
||||
|
||||
m_lastSceneCount = 0;
|
||||
for (int i = 0; i < SceneManager.sceneCount; i++)
|
||||
{
|
||||
m_lastSceneCount++;
|
||||
|
||||
var scene = SceneManager.GetSceneAt(i).name;
|
||||
m_sceneDropdown.options.Add(new Dropdown.OptionData
|
||||
{
|
||||
text = scene
|
||||
});
|
||||
}
|
||||
|
||||
m_sceneDropdown.transform.Find("Label").GetComponent<Text>().text = "Any";
|
||||
}
|
||||
|
||||
// ~~~~~ UI Callbacks ~~~~~
|
||||
|
||||
internal void OnUnitySearchClicked()
|
||||
{
|
||||
m_resultListPageHandler.CurrentPage = 0;
|
||||
|
||||
Type searchType = null;
|
||||
switch (m_context)
|
||||
{
|
||||
case SearchContext.GameObject:
|
||||
searchType = typeof(GameObject); break;
|
||||
|
||||
case SearchContext.Component:
|
||||
searchType = typeof(Component); break;
|
||||
|
||||
case SearchContext.Custom:
|
||||
if (string.IsNullOrEmpty(m_customTypeInput.text))
|
||||
{
|
||||
ExplorerCore.LogWarning("Custom Type input must not be empty!");
|
||||
return;
|
||||
}
|
||||
if (ReflectionHelpers.GetTypeByName(m_customTypeInput.text) is Type customType)
|
||||
if (typeof(UnityEngine.Object).IsAssignableFrom(customType))
|
||||
searchType = customType;
|
||||
else
|
||||
ExplorerCore.LogWarning($"Custom type '{customType.FullName}' is not assignable from UnityEngine.Object!");
|
||||
else
|
||||
ExplorerCore.LogWarning($"Could not find a type by the name '{m_customTypeInput.text}'!");
|
||||
break;
|
||||
|
||||
default:
|
||||
searchType = typeof(UnityEngine.Object); break;
|
||||
}
|
||||
|
||||
if (searchType == null)
|
||||
return;
|
||||
#if MONO
|
||||
var allObjects = ResourcesUnstrip.FindObjectsOfTypeAll(searchType);
|
||||
#else
|
||||
var allObjects = ResourcesUnstrip.FindObjectsOfTypeAll(Il2CppType.From(searchType));
|
||||
#endif
|
||||
var results = new List<object>();
|
||||
|
||||
// perform filter comparers
|
||||
|
||||
string nameFilter = null;
|
||||
if (!string.IsNullOrEmpty(m_nameInput.text))
|
||||
nameFilter = m_nameInput.text.ToLower();
|
||||
|
||||
bool canGetGameObject = (m_sceneFilter != SceneFilter.Any || m_childFilter != ChildFilter.Any)
|
||||
&& (m_context == SearchContext.GameObject || typeof(Component).IsAssignableFrom(searchType));
|
||||
|
||||
string sceneFilter = null;
|
||||
if (!canGetGameObject)
|
||||
{
|
||||
if (m_context != SearchContext.UnityObject && (m_sceneFilter != SceneFilter.Any || m_childFilter != ChildFilter.Any))
|
||||
ExplorerCore.LogWarning($"Type '{searchType}' cannot have Scene or Child filters applied to it");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_sceneFilter == SceneFilter.DontDestroyOnLoad)
|
||||
sceneFilter = "DontDestroyOnLoad";
|
||||
else if (m_sceneFilter == SceneFilter.Explicit)
|
||||
sceneFilter = m_sceneDropdown.options[m_sceneDropdown.value].text;
|
||||
}
|
||||
|
||||
foreach (var obj in allObjects)
|
||||
{
|
||||
// name check
|
||||
if (!string.IsNullOrEmpty(nameFilter) && !obj.name.ToLower().Contains(nameFilter))
|
||||
continue;
|
||||
|
||||
if (canGetGameObject)
|
||||
{
|
||||
#if MONO
|
||||
var go = m_context == SearchContext.GameObject
|
||||
? obj as GameObject
|
||||
: (obj as Component).gameObject;
|
||||
#else
|
||||
var go = m_context == SearchContext.GameObject
|
||||
? obj.TryCast<GameObject>()
|
||||
: obj.TryCast<Component>().gameObject;
|
||||
#endif
|
||||
|
||||
if (!go)
|
||||
continue;
|
||||
|
||||
// scene check
|
||||
if (m_sceneFilter != SceneFilter.Any)
|
||||
{
|
||||
switch (m_context)
|
||||
{
|
||||
case SearchContext.GameObject:
|
||||
if (go.scene.name != sceneFilter)
|
||||
continue;
|
||||
break;
|
||||
case SearchContext.Custom:
|
||||
case SearchContext.Component:
|
||||
if (go.scene.name != sceneFilter)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// root object check (no parent)
|
||||
if (m_childFilter == ChildFilter.HasParent && !go.transform.parent)
|
||||
continue;
|
||||
else if (m_childFilter == ChildFilter.RootObject && go.transform.parent)
|
||||
continue;
|
||||
}
|
||||
|
||||
results.Add(obj);
|
||||
}
|
||||
|
||||
m_results = results.ToArray();
|
||||
|
||||
if (m_results.Length > 0)
|
||||
m_resultCountText.text = $"{m_results.Length} Results";
|
||||
else
|
||||
m_resultCountText.text = "No results...";
|
||||
|
||||
RefreshResultList();
|
||||
}
|
||||
|
||||
private void OnResultPageTurn()
|
||||
{
|
||||
RefreshResultList();
|
||||
}
|
||||
|
||||
internal void OnResultClicked(int index)
|
||||
{
|
||||
if (m_context == SearchContext.StaticClass)
|
||||
InspectorManager.Instance.Inspect((Type)m_resultShortList[index]);
|
||||
else
|
||||
InspectorManager.Instance.Inspect(m_resultShortList[index]);
|
||||
}
|
||||
|
||||
internal void OnContextButtonClicked(SearchContext context)
|
||||
{
|
||||
if (m_selectedContextButton && m_context == context)
|
||||
return;
|
||||
|
||||
if (m_selectedContextButton)
|
||||
UIFactory.SetDefaultColorTransitionValues(m_selectedContextButton);
|
||||
|
||||
var button = m_contextButtons[context];
|
||||
|
||||
m_selectedContextButton = button;
|
||||
|
||||
var colors = m_selectedContextButton.colors;
|
||||
colors.normalColor = new Color(0.35f, 0.7f, 0.35f);
|
||||
colors.highlightedColor = colors.normalColor;
|
||||
m_selectedContextButton.colors = colors;
|
||||
|
||||
m_context = context;
|
||||
|
||||
// if extra filters are valid
|
||||
if (context == SearchContext.Component
|
||||
|| context == SearchContext.GameObject
|
||||
|| context == SearchContext.Custom)
|
||||
{
|
||||
m_extraFilterRow?.SetActive(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_extraFilterRow?.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
#region UI CONSTRUCTION
|
||||
|
||||
internal void ConstructUI()
|
||||
{
|
||||
GameObject parent = MainMenu.Instance.PageViewport;
|
||||
|
||||
Content = UIFactory.CreateVerticalGroup(parent);
|
||||
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();
|
||||
|
||||
ConstructResultsArea();
|
||||
}
|
||||
|
||||
internal void ConstructTopArea()
|
||||
{
|
||||
var topAreaObj = UIFactory.CreateVerticalGroup(Content, new Color(0.15f, 0.15f, 0.15f));
|
||||
var topGroup = topAreaObj.GetComponent<VerticalLayoutGroup>();
|
||||
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);
|
||||
Text titleLabel = titleObj.GetComponent<Text>();
|
||||
titleLabel.text = "Search";
|
||||
titleLabel.fontSize = 20;
|
||||
LayoutElement titleLayout = titleObj.AddComponent<LayoutElement>();
|
||||
titleLayout.minHeight = 30;
|
||||
titleLayout.flexibleHeight = 0;
|
||||
|
||||
// top area options
|
||||
|
||||
var optionsGroupObj = UIFactory.CreateVerticalGroup(topAreaObj, new Color(0.1f, 0.1f, 0.1f));
|
||||
var optionsGroup = optionsGroupObj.GetComponent<VerticalLayoutGroup>();
|
||||
optionsGroup.childForceExpandHeight = false;
|
||||
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
|
||||
|
||||
var contextRowObj = UIFactory.CreateHorizontalGroup(optionsGroupObj, new Color(1, 1, 1, 0));
|
||||
var contextGroup = contextRowObj.GetComponent<HorizontalLayoutGroup>();
|
||||
contextGroup.childForceExpandWidth = false;
|
||||
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 contextText = contextLabelObj.GetComponent<Text>();
|
||||
contextText.text = "Searching for:";
|
||||
var contextLabelLayout = contextLabelObj.AddComponent<LayoutElement>();
|
||||
contextLabelLayout.minWidth = 125;
|
||||
contextLabelLayout.minHeight = 25;
|
||||
|
||||
// context buttons
|
||||
|
||||
AddContextButton(contextRowObj, "UnityEngine.Object", SearchContext.UnityObject, 140);
|
||||
AddContextButton(contextRowObj, "GameObject", SearchContext.GameObject);
|
||||
AddContextButton(contextRowObj, "Component", SearchContext.Component);
|
||||
AddContextButton(contextRowObj, "Custom...", SearchContext.Custom);
|
||||
|
||||
// custom type input
|
||||
|
||||
var customTypeObj = UIFactory.CreateInputField(contextRowObj);
|
||||
var customTypeLayout = customTypeObj.AddComponent<LayoutElement>();
|
||||
customTypeLayout.minWidth = 250;
|
||||
customTypeLayout.flexibleWidth = 2000;
|
||||
customTypeLayout.minHeight = 25;
|
||||
customTypeLayout.flexibleHeight = 0;
|
||||
m_customTypeInput = customTypeObj.GetComponent<InputField>();
|
||||
m_customTypeInput.placeholder.gameObject.GetComponent<Text>().text = "eg. UnityEngine.Texture2D, etc...";
|
||||
//m_customTypeInput.onFocusSelectAll = true;
|
||||
//#if MONO
|
||||
// m_customTypeInput.onSelect.AddListener((string val) => { OnContextButtonClicked(SearchContext.Custom); });
|
||||
//#else
|
||||
// m_customTypeInput.onSelect.AddListener(new Action<string>((string val) => { OnContextButtonClicked(SearchContext.Custom); }));
|
||||
//#endif
|
||||
|
||||
// search input
|
||||
|
||||
var nameRowObj = UIFactory.CreateHorizontalGroup(optionsGroupObj, new Color(1, 1, 1, 0));
|
||||
var nameRowGroup = nameRowObj.GetComponent<HorizontalLayoutGroup>();
|
||||
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 nameLabelText = nameLabelObj.GetComponent<Text>();
|
||||
nameLabelText.text = "Name contains:";
|
||||
var nameLabelLayout = nameLabelObj.AddComponent<LayoutElement>();
|
||||
nameLabelLayout.minWidth = 125;
|
||||
nameLabelLayout.minHeight = 25;
|
||||
|
||||
var nameInputObj = UIFactory.CreateInputField(nameRowObj);
|
||||
m_nameInput = nameInputObj.GetComponent<InputField>();
|
||||
//m_nameInput.placeholder.gameObject.GetComponent<TextMeshProUGUI>().text = "";
|
||||
var nameInputLayout = nameInputObj.AddComponent<LayoutElement>();
|
||||
nameInputLayout.minWidth = 150;
|
||||
nameInputLayout.flexibleWidth = 5000;
|
||||
nameInputLayout.minHeight = 25;
|
||||
|
||||
// extra filter row
|
||||
|
||||
m_extraFilterRow = UIFactory.CreateHorizontalGroup(optionsGroupObj, new Color(1, 1, 1, 0));
|
||||
m_extraFilterRow.SetActive(false);
|
||||
var extraGroup = m_extraFilterRow.GetComponent<HorizontalLayoutGroup>();
|
||||
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
|
||||
|
||||
var sceneLabelObj = UIFactory.CreateLabel(m_extraFilterRow, TextAnchor.MiddleLeft);
|
||||
var sceneLabel = sceneLabelObj.GetComponent<Text>();
|
||||
sceneLabel.text = "Scene Filter:";
|
||||
var sceneLayout = sceneLabelObj.AddComponent<LayoutElement>();
|
||||
sceneLayout.minWidth = 125;
|
||||
sceneLayout.minHeight = 25;
|
||||
|
||||
var sceneDropObj = UIFactory.CreateDropdown(m_extraFilterRow, out m_sceneDropdown);
|
||||
m_sceneDropdown.itemText.text = "Any";
|
||||
m_sceneDropdown.itemText.fontSize = 12;
|
||||
var sceneDropLayout = sceneDropObj.AddComponent<LayoutElement>();
|
||||
sceneDropLayout.minWidth = 220;
|
||||
sceneDropLayout.minHeight = 25;
|
||||
|
||||
#if MONO
|
||||
m_sceneDropdown.onValueChanged.AddListener(OnSceneDropdownChanged);
|
||||
#else
|
||||
m_sceneDropdown.onValueChanged.AddListener(new Action<int>(OnSceneDropdownChanged));
|
||||
#endif
|
||||
void OnSceneDropdownChanged(int value)
|
||||
{
|
||||
if (value < 4)
|
||||
m_sceneFilter = (SceneFilter)value;
|
||||
else
|
||||
m_sceneFilter = SceneFilter.Explicit;
|
||||
}
|
||||
|
||||
// invisible space
|
||||
|
||||
var invis = UIFactory.CreateUIObject("spacer", m_extraFilterRow);
|
||||
var invisLayout = invis.AddComponent<LayoutElement>();
|
||||
invisLayout.minWidth = 25;
|
||||
invisLayout.flexibleWidth = 0;
|
||||
|
||||
// children filter
|
||||
|
||||
var childLabelObj = UIFactory.CreateLabel(m_extraFilterRow, TextAnchor.MiddleLeft);
|
||||
var childLabel = childLabelObj.GetComponent<Text>();
|
||||
childLabel.text = "Child Filter:";
|
||||
var childLayout = childLabelObj.AddComponent<LayoutElement>();
|
||||
childLayout.minWidth = 100;
|
||||
childLayout.minHeight = 25;
|
||||
|
||||
var childDropObj = UIFactory.CreateDropdown(m_extraFilterRow, out Dropdown childDrop);
|
||||
childDrop.itemText.text = "Any";
|
||||
childDrop.itemText.fontSize = 12;
|
||||
var childDropLayout = childDropObj.AddComponent<LayoutElement>();
|
||||
childDropLayout.minWidth = 180;
|
||||
childDropLayout.minHeight = 25;
|
||||
|
||||
childDrop.options.Add(new Dropdown.OptionData { text = "Any" });
|
||||
childDrop.options.Add(new Dropdown.OptionData { text = "Root Objects Only" });
|
||||
childDrop.options.Add(new Dropdown.OptionData { text = "Children Only" });
|
||||
|
||||
#if MONO
|
||||
childDrop.onValueChanged.AddListener(OnChildDropdownChanged);
|
||||
#else
|
||||
childDrop.onValueChanged.AddListener(new Action<int>(OnChildDropdownChanged));
|
||||
#endif
|
||||
void OnChildDropdownChanged(int value)
|
||||
{
|
||||
m_childFilter = (ChildFilter)value;
|
||||
}
|
||||
|
||||
// search button
|
||||
|
||||
var searchBtnObj = UIFactory.CreateButton(topAreaObj);
|
||||
var searchText = searchBtnObj.GetComponentInChildren<Text>();
|
||||
searchText.text = "Search";
|
||||
LayoutElement searchBtnLayout = searchBtnObj.AddComponent<LayoutElement>();
|
||||
searchBtnLayout.minHeight = 30;
|
||||
searchBtnLayout.flexibleHeight = 0;
|
||||
var searchBtn = searchBtnObj.GetComponent<Button>();
|
||||
#if MONO
|
||||
searchBtn.onClick.AddListener(OnUnitySearchClicked);
|
||||
#else
|
||||
searchBtn.onClick.AddListener(new Action(OnUnitySearchClicked));
|
||||
#endif
|
||||
}
|
||||
|
||||
internal void AddContextButton(GameObject parent, string label, SearchContext context, float width = 110)
|
||||
{
|
||||
var btnObj = UIFactory.CreateButton(parent);
|
||||
|
||||
var btn = btnObj.GetComponent<Button>();
|
||||
|
||||
m_contextButtons.Add(context, btn);
|
||||
|
||||
#if MONO
|
||||
btn.onClick.AddListener(() => { OnContextButtonClicked(context); });
|
||||
#else
|
||||
btn.onClick.AddListener(new Action(() => { OnContextButtonClicked(context); }));
|
||||
#endif
|
||||
|
||||
var btnLayout = btnObj.AddComponent<LayoutElement>();
|
||||
btnLayout.minHeight = 25;
|
||||
btnLayout.minWidth = width;
|
||||
|
||||
var btnText = btnObj.GetComponentInChildren<Text>();
|
||||
btnText.text = label;
|
||||
|
||||
// if first button
|
||||
if (!m_selectedContextButton)
|
||||
{
|
||||
OnContextButtonClicked(context);
|
||||
}
|
||||
}
|
||||
|
||||
internal void ConstructResultsArea()
|
||||
{
|
||||
// Result group holder (NOT actual result list content)
|
||||
|
||||
var resultGroupObj = UIFactory.CreateVerticalGroup(Content, new Color(1,1,1,0));
|
||||
var resultGroup = resultGroupObj.GetComponent<VerticalLayoutGroup>();
|
||||
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 = resultCountObj.GetComponent<Text>();
|
||||
m_resultCountText.text = "No results...";
|
||||
|
||||
GameObject scrollObj = UIFactory.CreateScrollView(resultGroupObj,
|
||||
out m_resultListContent,
|
||||
out SliderScrollbar scroller,
|
||||
new Color(0.07f, 0.07f, 0.07f, 1));
|
||||
|
||||
m_resultListPageHandler = new PageHandler(scroller);
|
||||
m_resultListPageHandler.ConstructUI(resultGroupObj);
|
||||
m_resultListPageHandler.OnPageChanged += OnResultPageTurn;
|
||||
|
||||
// actual result list content
|
||||
var contentGroup = m_resultListContent.GetComponent<VerticalLayoutGroup>();
|
||||
contentGroup.spacing = 2;
|
||||
contentGroup.childForceExpandHeight = false;
|
||||
contentGroup.childControlHeight = true;
|
||||
}
|
||||
|
||||
internal void AddResultButton()
|
||||
{
|
||||
int thisIndex = m_resultListTexts.Count();
|
||||
|
||||
GameObject btnGroupObj = UIFactory.CreateHorizontalGroup(m_resultListContent, 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;
|
||||
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>();
|
||||
|
||||
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;
|
||||
#if CPP
|
||||
mainBtn.onClick.AddListener(new Action(() => { OnResultClicked(thisIndex); }));
|
||||
#else
|
||||
mainBtn.onClick.AddListener(() => { OnResultClicked(thisIndex); });
|
||||
#endif
|
||||
|
||||
Text mainText = mainButtonObj.GetComponentInChildren<Text>();
|
||||
mainText.alignment = TextAnchor.MiddleLeft;
|
||||
mainText.horizontalOverflow = HorizontalWrapMode.Overflow;
|
||||
m_resultListTexts.Add(mainText);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user