mirror of
https://github.com/sinai-dev/UnityExplorer.git
synced 2024-12-23 01:59:40 +08:00
finished C# Console and Debug Console, starting work on Scene Explorer
This commit is contained in:
parent
2256828384
commit
fd950e2aef
Binary file not shown.
@ -12,7 +12,7 @@
|
||||
<Deterministic>true</Deterministic>
|
||||
<TargetFrameworkProfile />
|
||||
<OutputPath>..\Release\Explorer.MelonLoader.Il2Cpp\</OutputPath>
|
||||
<DefineConstants>CPP,ML</DefineConstants>
|
||||
<DefineConstants></DefineConstants>
|
||||
<IsCpp>true</IsCpp>
|
||||
<IsMelonLoader>true</IsMelonLoader>
|
||||
<DebugSymbols>false</DebugSymbols>
|
||||
@ -25,18 +25,22 @@
|
||||
<RootNamespace>Explorer</RootNamespace>
|
||||
<AssemblyName>ExplorerBeta</AssemblyName>
|
||||
<!-- Set this to the MelonLoader Il2Cpp Game folder, without the ending '\' character. -->
|
||||
<MLCppGameFolder>D:\Steam\steamapps\common\Hellpoint</MLCppGameFolder>
|
||||
<MLCppGameFolder>D:\Steam\steamapps\common\VRChat</MLCppGameFolder>
|
||||
<!-- Set this to the MelonLoader Mono Game folder, without the ending '\' character. -->
|
||||
<MLMonoGameFolder>D:\Steam\steamapps\common\Outward</MLMonoGameFolder>
|
||||
<!-- Set this to the Mono Managed folder, without the ending '\' character. -->
|
||||
<MLMonoManagedFolder>D:\Steam\steamapps\common\Outward\Outward_Data\Managed</MLMonoManagedFolder>
|
||||
<!-- Set this to the BepInEx Il2Cpp Game folder, without the ending '\' character. -->
|
||||
<BIECppGameFolder>D:\Steam\steamapps\common\Outward_Il2Cpp</BIECppGameFolder>
|
||||
<!-- Set this to the BepInEx Mono Game folder, without the ending '\' character. -->
|
||||
<BIEMonoGameFolder>D:\Steam\steamapps\common\Outward</BIEMonoGameFolder>
|
||||
<!-- Set this to the BepInEx Managed folder, without the ending '\' character. -->
|
||||
<BIEMonoManagedFolder>D:\Steam\steamapps\common\Outward\Outward_Data\Managed</BIEMonoManagedFolder>
|
||||
<NuGetPackageImportStamp>
|
||||
</NuGetPackageImportStamp>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release_ML_Cpp|AnyCPU' ">
|
||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||
<!-- <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion> -->
|
||||
<OutputPath>..\Release\Explorer.MelonLoader.Il2Cpp\</OutputPath>
|
||||
<DefineConstants>CPP,ML</DefineConstants>
|
||||
<IsCpp>true</IsCpp>
|
||||
@ -44,7 +48,7 @@
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release_ML_Mono|AnyCPU' ">
|
||||
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
|
||||
<!-- <TargetFrameworkVersion>v3.5</TargetFrameworkVersion> -->
|
||||
<OutputPath>..\Release\Explorer.MelonLoader.Mono\</OutputPath>
|
||||
<DefineConstants>MONO,ML</DefineConstants>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
@ -53,7 +57,7 @@
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release_BIE_Cpp|AnyCPU' ">
|
||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||
<!-- <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion> -->
|
||||
<OutputPath>..\Release\Explorer.BepInEx.Il2Cpp\</OutputPath>
|
||||
<DefineConstants>CPP,BIE</DefineConstants>
|
||||
<IsCpp>true</IsCpp>
|
||||
@ -61,7 +65,7 @@
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release_BIE_Mono|AnyCPU' ">
|
||||
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
|
||||
<!-- <TargetFrameworkVersion>v3.5</TargetFrameworkVersion> -->
|
||||
<OutputPath>..\Release\Explorer.BepInEx.Mono\</OutputPath>
|
||||
<DefineConstants>MONO,BIE</DefineConstants>
|
||||
<IsCpp>false</IsCpp>
|
||||
@ -81,24 +85,71 @@
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<!-- Universal Mono UnityEngine.dll ref (v5.3) -->
|
||||
|
||||
<!-- 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>
|
||||
<Reference Include="Unity.TextMeshPro">
|
||||
<HintPath>..\lib\Unity.TextMeshPro.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<!-- MelonLoader Mono ref -->
|
||||
</ItemGroup>-->
|
||||
|
||||
<!-- MelonLoader Mono refs -->
|
||||
<ItemGroup Condition="'$(IsMelonLoader)|$(IsCpp)'=='true|false'">
|
||||
<Reference Include="MelonLoader.ModHandler">
|
||||
<HintPath>$(MLMonoGameFolder)\MelonLoader\MelonLoader.ModHandler.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="Unity.TextMeshPro">
|
||||
<HintPath>$(MLMonoManagedFolder)\Unity.TextMeshPro.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine">
|
||||
<HintPath>$(MLMonoManagedFolder)\UnityEngine.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.CoreModule">
|
||||
<HintPath>$(MLMonoManagedFolder)\UnityEngine.CoreModule.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.PhysicsModule">
|
||||
<HintPath>$(MLMonoManagedFolder)\UnityEngine.PhysicsModule.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TextCoreModule">
|
||||
<HintPath>$(MLMonoManagedFolder)\UnityEngine.TextCoreModule.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TextRenderingModule">
|
||||
<HintPath>$(MLMonoManagedFolder)\UnityEngine.TextRenderingModule.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UI">
|
||||
<HintPath>$(MLMonoManagedFolder)\UnityEngine.UI.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UIModule">
|
||||
<HintPath>$(MLMonoManagedFolder)\UnityEngine.UIModule.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.IMGUIModule">
|
||||
<HintPath>$(MLMonoManagedFolder)\UnityEngine.IMGUIModule.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ImageConversionModule">
|
||||
<HintPath>$(MLMonoManagedFolder)\UnityEngine.ImageConversionModule.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
<!-- BepInEx Mono refs -->
|
||||
<ItemGroup Condition="'$(IsMelonLoader)|$(IsCpp)'=='false|false'">
|
||||
<Reference Include="BepInEx">
|
||||
@ -109,7 +160,48 @@
|
||||
<HintPath>$(BIEMonoGameFolder)\BepInEx\core\0Harmony.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="Unity.TextMeshPro">
|
||||
<HintPath>$(BIEMonoManagedFolder)\Unity.TextMeshPro.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine">
|
||||
<HintPath>$(BIEMonoManagedFolder)\UnityEngine.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.CoreModule">
|
||||
<HintPath>$(BIEMonoManagedFolder)\UnityEngine.CoreModule.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.PhysicsModule">
|
||||
<HintPath>$(BIEMonoManagedFolder)\UnityEngine.PhysicsModule.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TextCoreModule">
|
||||
<HintPath>$(BIEMonoManagedFolder)\UnityEngine.TextCoreModule.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TextRenderingModule">
|
||||
<HintPath>$(BIEMonoManagedFolder)\UnityEngine.TextRenderingModule.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UI">
|
||||
<HintPath>$(BIEMonoManagedFolder)\UnityEngine.UI.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UIModule">
|
||||
<HintPath>$(BIEMonoManagedFolder)\UnityEngine.UIModule.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.IMGUIModule">
|
||||
<HintPath>$(BIEMonoManagedFolder)\UnityEngine.IMGUIModule.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ImageConversionModule">
|
||||
<HintPath>$(BIEMonoManagedFolder)\UnityEngine.ImageConversionModule.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
<!-- MelonLoader Il2Cpp refs -->
|
||||
<ItemGroup Condition="'$(IsMelonLoader)|$(IsCpp)'=='true|true'">
|
||||
<Reference Include="MelonLoader.ModHandler">
|
||||
@ -165,6 +257,7 @@
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
<!-- BepInEx Il2Cpp refs -->
|
||||
<ItemGroup Condition="'$(IsMelonLoader)|$(IsCpp)'=='false|true'">
|
||||
<Reference Include="BepInEx">
|
||||
@ -247,7 +340,7 @@
|
||||
<Compile Include="Helpers\UnityHelpers.cs" />
|
||||
<Compile Include="UI\ForceUnlockCursor.cs" />
|
||||
<Compile Include="Input\IAbstractInput.cs" />
|
||||
<Compile Include="Tests\TestClass.cs" />
|
||||
<Compile Include="CacheObject\Tests\TestClass.cs" />
|
||||
<Compile Include="Input\InputManager.cs" />
|
||||
<Compile Include="Input\InputSystem.cs" />
|
||||
<Compile Include="Input\LegacyInput.cs" />
|
||||
@ -256,6 +349,7 @@
|
||||
<Compile Include="UI\Main\MainMenu.cs" />
|
||||
<Compile Include="UI\Main\Pages\BaseMenuPage.cs" />
|
||||
<Compile Include="UI\Main\Pages\ConsolePage.cs" />
|
||||
<Compile Include="UI\Main\Pages\Console\AutoCompleter.cs" />
|
||||
<Compile Include="UI\Main\Pages\Console\Editor\CodeEditor.cs" />
|
||||
<Compile Include="UI\Main\Pages\Console\Editor\CSharpLexer.cs" />
|
||||
<Compile Include="UI\Main\Pages\Console\Editor\Lexer\CommentMatch.cs" />
|
||||
|
@ -5,6 +5,7 @@ using ExplorerBeta.Config;
|
||||
using ExplorerBeta.Input;
|
||||
using ExplorerBeta.UI;
|
||||
using ExplorerBeta.UI.Main;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ExplorerBeta
|
||||
@ -56,6 +57,12 @@ namespace ExplorerBeta
|
||||
InputManager.Init();
|
||||
ForceUnlockCursor.Init();
|
||||
|
||||
#if CPP
|
||||
Application.add_logMessageReceived(new Action<string, string, LogType>(LogCallback));
|
||||
#else
|
||||
Application.logMessageReceived += LogCallback;
|
||||
#endif
|
||||
|
||||
ShowMenu = true;
|
||||
|
||||
Log($"{NAME} initialized.");
|
||||
@ -89,7 +96,7 @@ namespace ExplorerBeta
|
||||
{
|
||||
m_timeSinceStartup += Time.deltaTime;
|
||||
|
||||
if (m_timeSinceStartup > 1f)
|
||||
if (m_timeSinceStartup > 0.1f)
|
||||
{
|
||||
UIManager.Init();
|
||||
|
||||
@ -115,9 +122,36 @@ namespace ExplorerBeta
|
||||
UIManager.OnSceneChange();
|
||||
}
|
||||
|
||||
public static void Log(object message)
|
||||
private void LogCallback(string message, string stackTrace, LogType type)
|
||||
{
|
||||
if (!DebugConsole.LogUnity)
|
||||
return;
|
||||
|
||||
message = $"[UNITY] {message}";
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case LogType.Assert:
|
||||
case LogType.Log:
|
||||
Log(message);
|
||||
break;
|
||||
case LogType.Warning:
|
||||
LogWarning(message);
|
||||
break;
|
||||
case LogType.Exception:
|
||||
case LogType.Error:
|
||||
LogError(message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public static void Log(object message, bool unity = false)
|
||||
{
|
||||
DebugConsole.Log(message?.ToString());
|
||||
|
||||
if (unity)
|
||||
return;
|
||||
|
||||
#if ML
|
||||
MelonLoader.MelonLogger.Log(message?.ToString());
|
||||
#else
|
||||
@ -125,23 +159,31 @@ namespace ExplorerBeta
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void LogWarning(object message)
|
||||
public static void LogWarning(object message, bool unity = false)
|
||||
{
|
||||
DebugConsole.Log(message?.ToString(), "FFFF00");
|
||||
|
||||
if (unity)
|
||||
return;
|
||||
|
||||
#if ML
|
||||
MelonLoader.MelonLogger.LogWarning(message?.ToString());
|
||||
#else
|
||||
ExplorerBepInPlugin.Logging?.LogWarning(message?.ToString());
|
||||
ExplorerBepInPlugin.Logging?.LogWarning(message?.ToString());
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void LogError(object message)
|
||||
public static void LogError(object message, bool unity = false)
|
||||
{
|
||||
DebugConsole.Log(message?.ToString(), "FF0000");
|
||||
|
||||
if (unity)
|
||||
return;
|
||||
|
||||
#if ML
|
||||
MelonLoader.MelonLogger.LogError(message?.ToString());
|
||||
#else
|
||||
ExplorerBepInPlugin.Logging?.LogError(message?.ToString());
|
||||
ExplorerBepInPlugin.Logging?.LogError(message?.ToString());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -6,32 +6,28 @@ using Explorer.Unstrip.ColorUtility;
|
||||
using ExplorerBeta.Input;
|
||||
using ExplorerBeta.Unstrip.Resources;
|
||||
using TMPro;
|
||||
using UnhollowerRuntimeLib;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
using UnityEngine.UI;
|
||||
#if CPP
|
||||
using UnhollowerRuntimeLib;
|
||||
#endif
|
||||
|
||||
namespace ExplorerBeta.UI.Main
|
||||
{
|
||||
// TODO:
|
||||
// - Maybe hook into Unity's debug logs
|
||||
// - Buttons for clear, save to file, etc..?
|
||||
|
||||
public class DebugConsole
|
||||
{
|
||||
public static DebugConsole Instance { get; private set; }
|
||||
|
||||
public static bool LogUnity { get; set; } = true;
|
||||
|
||||
public static GameObject CanvasRoot;
|
||||
//private static GameObject Panel;
|
||||
|
||||
public readonly List<string> AllMessages;
|
||||
public readonly List<Text> MessageHolders;
|
||||
|
||||
private TMP_InputField m_textInput;
|
||||
|
||||
// todo probably put this in UImanager, use for C# console too
|
||||
//internal static Font m_consoleFont;
|
||||
//private const int MAX_MESSAGES = 100;
|
||||
|
||||
public DebugConsole(GameObject parent)
|
||||
{
|
||||
Instance = this;
|
||||
@ -53,30 +49,52 @@ namespace ExplorerBeta.UI.Main
|
||||
|
||||
public void ConstructUI(GameObject parent)
|
||||
{
|
||||
var obj = UIFactory.CreateHorizontalGroup(parent, new Color(0.1f, 0.1f, 0.1f, 1.0f));
|
||||
var mainGroup = obj.GetComponent<HorizontalLayoutGroup>();
|
||||
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 = obj.GetComponent<Image>();
|
||||
var mainImage = mainObj.GetComponent<Image>();
|
||||
mainImage.maskable = true;
|
||||
|
||||
var mask = obj.AddComponent<Mask>();
|
||||
var mask = mainObj.AddComponent<Mask>();
|
||||
mask.showMaskGraphic = true;
|
||||
|
||||
var mainLayout = obj.AddComponent<LayoutElement>();
|
||||
var mainLayout = mainObj.AddComponent<LayoutElement>();
|
||||
mainLayout.minHeight = 40;
|
||||
mainLayout.preferredHeight = 230;
|
||||
mainLayout.flexibleHeight = 0;
|
||||
|
||||
var input = UIFactory.CreateTMPInput(obj);
|
||||
#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 inputLayout = input.AddComponent<LayoutElement>();
|
||||
var logAreaLayout = logAreaObj.AddComponent<LayoutElement>();
|
||||
logAreaLayout.preferredHeight = 300;
|
||||
logAreaLayout.flexibleHeight = 50;
|
||||
|
||||
var inputObj = UIFactory.CreateTMPInput(logAreaObj);
|
||||
|
||||
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 scroll = UIFactory.CreateScrollbar(obj);
|
||||
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;
|
||||
@ -86,14 +104,139 @@ namespace ExplorerBeta.UI.Main
|
||||
scroller.direction = Scrollbar.Direction.TopToBottom;
|
||||
var scrollColors = scroller.colors;
|
||||
scrollColors.normalColor = new Color(0.5f, 0.5f, 0.5f, 1.0f);
|
||||
//try { scrollColors.selectedColor = scrollColors.normalColor; } catch { }
|
||||
scroller.colors = scrollColors;
|
||||
|
||||
var tmpInput = input.GetComponent<TMP_InputField>();
|
||||
var tmpInput = inputObj.GetComponent<TMP_InputField>();
|
||||
tmpInput.scrollSensitivity = 15;
|
||||
tmpInput.verticalScrollbar = scroller;
|
||||
|
||||
m_textInput = input.GetComponent<TMP_InputField>();
|
||||
tmpInput.readOnly = true;
|
||||
|
||||
m_textInput = inputObj.GetComponent<TMP_InputField>();
|
||||
|
||||
#endregion
|
||||
|
||||
#region BOTTOM BAR
|
||||
|
||||
var bottomBarObj = UIFactory.CreateHorizontalGroup(mainObj);
|
||||
var 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.preferredHeight = 40;
|
||||
}
|
||||
else
|
||||
{
|
||||
logAreaObj.SetActive(true);
|
||||
hideBtnText.text = "Hide";
|
||||
mainLayout.preferredHeight = 230;
|
||||
}
|
||||
}
|
||||
|
||||
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 = "";
|
||||
}
|
||||
|
||||
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>(ToggleCallback));
|
||||
#else
|
||||
unityToggle.onValueChanged.AddListener(ToggleCallback);
|
||||
#endif
|
||||
|
||||
void ToggleCallback(bool val)
|
||||
{
|
||||
LogUnity = val;
|
||||
}
|
||||
|
||||
unityToggleText.text = "Print Unity Debug?";
|
||||
unityToggleText.alignment = TextAnchor.MiddleLeft;
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
public static void Log(string message)
|
||||
|
@ -8,6 +8,7 @@ using UnityEngine.UI;
|
||||
using UnityEngine.EventSystems;
|
||||
using ExplorerBeta.UI.Shared;
|
||||
using Explorer.UI.Main.Pages;
|
||||
using Explorer.UI.Main.Pages.Console;
|
||||
|
||||
namespace ExplorerBeta.UI.Main
|
||||
{
|
||||
@ -41,6 +42,7 @@ namespace ExplorerBeta.UI.Main
|
||||
|
||||
Pages.Add(new HomePage());
|
||||
Pages.Add(new SearchPage());
|
||||
// TODO remove page on games where it failed to init?
|
||||
Pages.Add(new ConsolePage());
|
||||
Pages.Add(new OptionsPage());
|
||||
|
||||
@ -60,13 +62,16 @@ namespace ExplorerBeta.UI.Main
|
||||
m_activePage?.Update();
|
||||
}
|
||||
|
||||
// todo
|
||||
private void SetPage(BaseMenuPage page)
|
||||
{
|
||||
if (m_activePage == page || page == null)
|
||||
return;
|
||||
|
||||
m_activePage?.Content?.SetActive(false);
|
||||
if (m_activePage is ConsolePage)
|
||||
{
|
||||
AutoCompleter.m_mainObj.SetActive(false);
|
||||
}
|
||||
|
||||
m_activePage = page;
|
||||
|
||||
@ -162,7 +167,11 @@ namespace ExplorerBeta.UI.Main
|
||||
var hideBtnObj = UIFactory.CreateButton(titleBar);
|
||||
|
||||
var hideBtn = hideBtnObj.GetComponent<Button>();
|
||||
#if CPP
|
||||
hideBtn.onClick.AddListener(new Action(() => { ExplorerCore.ShowMenu = false; }));
|
||||
#else
|
||||
hideBtn.onClick.AddListener(() => { ExplorerCore.ShowMenu = false; });
|
||||
#endif
|
||||
var colorBlock = hideBtn.colors;
|
||||
colorBlock.normalColor = new Color(65f/255f, 23f/255f, 23f/255f);
|
||||
colorBlock.pressedColor = new Color(35f/255f, 10f/255f, 10f/255f);
|
||||
@ -208,7 +217,11 @@ namespace ExplorerBeta.UI.Main
|
||||
|
||||
page.RefNavbarButton = btn;
|
||||
|
||||
#if CPP
|
||||
btn.onClick.AddListener(new Action(() => { SetPage(page); }));
|
||||
#else
|
||||
btn.onClick.AddListener(() => { SetPage(page); });
|
||||
#endif
|
||||
|
||||
var text = btnObj.GetComponentInChildren<Text>();
|
||||
text.text = page.Name;
|
||||
@ -235,6 +248,6 @@ namespace ExplorerBeta.UI.Main
|
||||
PageViewport = mainObj;
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
303
src/UI/Main/Pages/Console/AutoCompleter.cs
Normal file
303
src/UI/Main/Pages/Console/AutoCompleter.cs
Normal file
@ -0,0 +1,303 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using ExplorerBeta;
|
||||
using ExplorerBeta.Input;
|
||||
using ExplorerBeta.UI;
|
||||
using ExplorerBeta.UI.Main;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.UI;
|
||||
#if CPP
|
||||
using UnhollowerRuntimeLib;
|
||||
#endif
|
||||
|
||||
namespace Explorer.UI.Main.Pages.Console
|
||||
{
|
||||
public class AutoCompleter
|
||||
{
|
||||
public static AutoCompleter Instance;
|
||||
|
||||
public const int MAX_LABELS = 500;
|
||||
private const int UPDATES_PER_BATCH = 100;
|
||||
|
||||
public static GameObject m_mainObj;
|
||||
private static RectTransform m_thisRect;
|
||||
|
||||
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_hiddenSuggestionTexts = new List<Text>();
|
||||
|
||||
private static bool m_suggestionsDirty;
|
||||
private static AutoComplete[] m_suggestions = new AutoComplete[0];
|
||||
private static int m_lastBatchIndex;
|
||||
|
||||
private static string m_prevInput = "NULL";
|
||||
private static int m_lastCaretPos;
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
ConstructUI();
|
||||
|
||||
m_mainObj.SetActive(false);
|
||||
}
|
||||
|
||||
public static void Update()
|
||||
{
|
||||
if (!m_mainObj)
|
||||
return;
|
||||
|
||||
if (!ConsolePage.EnableSuggestions)
|
||||
{
|
||||
if (m_mainObj.activeSelf)
|
||||
m_mainObj.SetActive(false);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
RefreshButtons();
|
||||
|
||||
UpdatePosition();
|
||||
}
|
||||
|
||||
public static void SetSuggestions(AutoComplete[] suggestions)
|
||||
{
|
||||
m_suggestions = suggestions;
|
||||
|
||||
m_suggestionsDirty = true;
|
||||
m_lastBatchIndex = 0;
|
||||
}
|
||||
|
||||
private static void RefreshButtons()
|
||||
{
|
||||
if (!m_suggestionsDirty)
|
||||
return;
|
||||
|
||||
if (m_suggestions.Length < 1)
|
||||
{
|
||||
if (m_mainObj.activeSelf)
|
||||
m_mainObj?.SetActive(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_mainObj.activeSelf)
|
||||
{
|
||||
m_mainObj.SetActive(true);
|
||||
}
|
||||
|
||||
if (m_suggestions.Length < 1 || m_lastBatchIndex >= MAX_LABELS)
|
||||
{
|
||||
m_suggestionsDirty = false;
|
||||
return;
|
||||
}
|
||||
|
||||
int end = m_lastBatchIndex + UPDATES_PER_BATCH;
|
||||
for (int i = m_lastBatchIndex; i < end && i < MAX_LABELS; i++)
|
||||
{
|
||||
if (i >= m_suggestions.Length)
|
||||
{
|
||||
if (m_suggestionButtons[i].activeSelf)
|
||||
m_suggestionButtons[i].SetActive(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!m_suggestionButtons[i].activeSelf)
|
||||
m_suggestionButtons[i].SetActive(true);
|
||||
|
||||
var suggestion = m_suggestions[i];
|
||||
var label = m_suggestionTexts[i];
|
||||
var hiddenLabel = m_hiddenSuggestionTexts[i];
|
||||
|
||||
label.text = suggestion.Full;
|
||||
hiddenLabel.text = suggestion.Addition;
|
||||
|
||||
if (suggestion.Context == AutoComplete.Contexts.Namespace)
|
||||
{
|
||||
label.color = new Color(0.75f, 0.75f, 0.75f, 1.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
label.color = Color.white;
|
||||
}
|
||||
}
|
||||
|
||||
m_lastBatchIndex = i;
|
||||
}
|
||||
|
||||
m_lastBatchIndex++;
|
||||
}
|
||||
|
||||
private static void UpdatePosition()
|
||||
{
|
||||
var editor = ConsolePage.Instance.m_codeEditor;
|
||||
|
||||
if (editor.InputField.text.Length < 1)
|
||||
return;
|
||||
|
||||
var caretPos = editor.InputField.caretPosition;
|
||||
while (caretPos >= editor.inputText.textInfo.characterInfo.Length)
|
||||
caretPos--;
|
||||
|
||||
if (caretPos == m_lastCaretPos)
|
||||
return;
|
||||
|
||||
m_lastCaretPos = caretPos;
|
||||
|
||||
if (caretPos >= 0 && caretPos < editor.inputText.textInfo.characterInfo.Length)
|
||||
{
|
||||
var pos = editor.inputText.textInfo.characterInfo[caretPos].bottomLeft;
|
||||
|
||||
pos = MainMenu.Instance.MainPanel.transform.TransformPoint(pos);
|
||||
|
||||
m_mainObj.transform.position = new Vector3(pos.x + m_thisRect.rect.width / 2, pos.y - 12, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly char[] splitChars = new[] { '{', '}', ',', ';', '<', '>', '(', ')', '[', ']', '=', '|', '&' };
|
||||
|
||||
public static void CheckAutocomplete()
|
||||
{
|
||||
var m_codeEditor = ConsolePage.Instance.m_codeEditor;
|
||||
var input = m_codeEditor.InputField.text;
|
||||
var caretIndex = m_codeEditor.InputField.caretPosition;
|
||||
|
||||
if (!string.IsNullOrEmpty(input))
|
||||
{
|
||||
try
|
||||
{
|
||||
var start = caretIndex <= 0 ? 0 : input.LastIndexOfAny(splitChars, caretIndex - 1) + 1;
|
||||
input = input.Substring(start, caretIndex - start).Trim();
|
||||
}
|
||||
catch (ArgumentException) { }
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(input) && input != m_prevInput)
|
||||
{
|
||||
GetAutocompletes(input);
|
||||
}
|
||||
else
|
||||
{
|
||||
ClearAutocompletes();
|
||||
}
|
||||
|
||||
m_prevInput = input;
|
||||
}
|
||||
|
||||
public static void ClearAutocompletes()
|
||||
{
|
||||
if (ConsolePage.AutoCompletes.Any())
|
||||
{
|
||||
ConsolePage.AutoCompletes.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
public static void GetAutocompletes(string input)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Credit ManylMarco
|
||||
ConsolePage.AutoCompletes.Clear();
|
||||
var completions = ConsolePage.Instance.m_evaluator.GetCompletions(input, out string prefix);
|
||||
if (completions != null)
|
||||
{
|
||||
if (prefix == null)
|
||||
prefix = input;
|
||||
|
||||
ConsolePage.AutoCompletes.AddRange(completions
|
||||
.Where(x => !string.IsNullOrEmpty(x))
|
||||
.Select(x => new AutoComplete(x, prefix, AutoComplete.Contexts.Other))
|
||||
);
|
||||
}
|
||||
|
||||
var trimmed = input.Trim();
|
||||
if (trimmed.StartsWith("using"))
|
||||
trimmed = trimmed.Remove(0, 5).Trim();
|
||||
|
||||
var namespaces = AutoCompleteHelpers.Namespaces
|
||||
.Where(x => x.StartsWith(trimmed) && x.Length > trimmed.Length)
|
||||
.Select(x => new AutoComplete(
|
||||
x.Substring(trimmed.Length),
|
||||
x.Substring(0, trimmed.Length),
|
||||
AutoComplete.Contexts.Namespace));
|
||||
|
||||
ConsolePage.AutoCompletes.AddRange(namespaces);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ExplorerCore.Log("C# Console error:\r\n" + ex);
|
||||
ClearAutocompletes();
|
||||
}
|
||||
}
|
||||
|
||||
#region UI Construction
|
||||
|
||||
private static void ConstructUI()
|
||||
{
|
||||
var parent = UIManager.CanvasRoot;
|
||||
|
||||
var obj = UIFactory.CreateScrollView(parent, out GameObject content, new Color(0.1f, 0.1f, 0.1f, 0.95f));
|
||||
|
||||
m_mainObj = obj;
|
||||
|
||||
var mainRect = obj.GetComponent<RectTransform>();
|
||||
m_thisRect = mainRect;
|
||||
mainRect.pivot = new Vector2(0.5f, 0.5f);
|
||||
mainRect.anchorMin = new Vector2(0.45f, 0.45f);
|
||||
mainRect.anchorMax = new Vector2(0.65f, 0.6f);
|
||||
mainRect.offsetMin = Vector2.zero;
|
||||
mainRect.offsetMax = Vector2.zero;
|
||||
|
||||
var mainGroup = content.GetComponent<VerticalLayoutGroup>();
|
||||
mainGroup.childControlHeight = false;
|
||||
mainGroup.childControlWidth = true;
|
||||
mainGroup.childForceExpandHeight = false;
|
||||
mainGroup.childForceExpandWidth = true;
|
||||
|
||||
for (int i = 0; i < MAX_LABELS; i++)
|
||||
{
|
||||
var buttonObj = UIFactory.CreateButton(content);
|
||||
var btn = buttonObj.GetComponent<Button>();
|
||||
var btnColors = btn.colors;
|
||||
btnColors.normalColor = new Color(0f, 0f, 0f, 0f);
|
||||
btnColors.highlightedColor = new Color(0.5f, 0.5f, 0.5f, 1.0f);
|
||||
btn.colors = btnColors;
|
||||
|
||||
var nav = btn.navigation;
|
||||
nav.mode = Navigation.Mode.Vertical;
|
||||
btn.navigation = nav;
|
||||
|
||||
var btnLayout = buttonObj.AddComponent<LayoutElement>();
|
||||
btnLayout.minHeight = 20;
|
||||
|
||||
var text = btn.GetComponentInChildren<Text>();
|
||||
text.alignment = TextAnchor.MiddleLeft;
|
||||
text.color = Color.white;
|
||||
|
||||
var hiddenChild = UIFactory.CreateUIObject("HiddenText", buttonObj);
|
||||
hiddenChild.SetActive(false);
|
||||
var hiddenText = hiddenChild.AddComponent<Text>();
|
||||
m_hiddenSuggestionTexts.Add(hiddenText);
|
||||
|
||||
#if CPP
|
||||
btn.onClick.AddListener(new Action(UseAutocompleteButton));
|
||||
#else
|
||||
btn.onClick.AddListener(UseAutocompleteButton);
|
||||
#endif
|
||||
|
||||
void UseAutocompleteButton()
|
||||
{
|
||||
ConsolePage.Instance.UseAutocomplete(hiddenText.text);
|
||||
EventSystem.current.SetSelectedGameObject(ConsolePage.Instance.m_codeEditor.InputField.gameObject,
|
||||
null);
|
||||
}
|
||||
|
||||
m_suggestionButtons.Add(buttonObj);
|
||||
m_suggestionTexts.Add(text);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
@ -9,8 +9,6 @@ namespace Explorer.UI.Main.Pages.Console
|
||||
{
|
||||
public static class CSharpLexer
|
||||
{
|
||||
// todo option to disable auto-indent
|
||||
public static bool allowAutoIndent = true;
|
||||
public static char indentIncreaseCharacter = '{';
|
||||
public static char indentDecreaseCharacter = '}';
|
||||
|
||||
|
@ -8,6 +8,7 @@ using ExplorerBeta.Input;
|
||||
using Explorer.UI.Main.Pages.Console.Lexer;
|
||||
using ExplorerBeta;
|
||||
using System.Linq;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
namespace Explorer.UI.Main.Pages.Console
|
||||
{
|
||||
@ -17,7 +18,7 @@ namespace Explorer.UI.Main.Pages.Console
|
||||
|
||||
public TMP_InputField InputField { get; }
|
||||
|
||||
private readonly TextMeshProUGUI inputText;
|
||||
public readonly TextMeshProUGUI inputText;
|
||||
private readonly TextMeshProUGUI inputHighlightText;
|
||||
private readonly TextMeshProUGUI lineText;
|
||||
private readonly Image background;
|
||||
@ -25,7 +26,6 @@ namespace Explorer.UI.Main.Pages.Console
|
||||
private readonly Image lineNumberBackground;
|
||||
private readonly Image scrollbar;
|
||||
|
||||
private string lastText;
|
||||
private bool lineHighlightLocked;
|
||||
private readonly RectTransform inputTextTransform;
|
||||
private readonly RectTransform lineHighlightTransform;
|
||||
@ -90,33 +90,41 @@ namespace Explorer.UI.Main.Pages.Console
|
||||
inputLexer.UseMatchers(CSharpLexer.DelimiterSymbols, CSharpLexer.Matchers);
|
||||
|
||||
// subscribe to text input changing
|
||||
#if CPP
|
||||
this.InputField.onValueChanged.AddListener(new Action<string>((string s) => { OnInputChanged(); }));
|
||||
#else
|
||||
this.InputField.onValueChanged.AddListener((string s) => { OnInputChanged(); });
|
||||
#endif
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
// Check for new line
|
||||
if (InputManager.GetKeyDown(KeyCode.Return))
|
||||
if (ConsolePage.EnableAutoIndent && InputManager.GetKeyDown(KeyCode.Return))
|
||||
{
|
||||
AutoIndentCaret();
|
||||
}
|
||||
|
||||
bool focusKeyPressed = false;
|
||||
|
||||
// Check for any focus key pressed
|
||||
foreach (KeyCode key in lineChangeKeys)
|
||||
if (EventSystem.current?.currentSelectedGameObject?.name == "InputField (TMP)")
|
||||
{
|
||||
if (InputManager.GetKeyDown(key))
|
||||
bool focusKeyPressed = false;
|
||||
|
||||
// Check for any focus key pressed
|
||||
foreach (KeyCode key in lineChangeKeys)
|
||||
{
|
||||
focusKeyPressed = true;
|
||||
break;
|
||||
if (InputManager.GetKeyDown(key))
|
||||
{
|
||||
focusKeyPressed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update line highlight
|
||||
if (focusKeyPressed || InputManager.GetMouseButton(0))
|
||||
{
|
||||
UpdateHighlight();
|
||||
// Update line highlight
|
||||
if (focusKeyPressed || InputManager.GetMouseButton(0))
|
||||
{
|
||||
UpdateHighlight();
|
||||
ConsolePage.Instance.OnInputChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -126,25 +134,19 @@ namespace Explorer.UI.Main.Pages.Console
|
||||
|
||||
UpdateIndent();
|
||||
|
||||
if ((!forceUpdate && lastText == newText) || string.IsNullOrEmpty(newText))
|
||||
if (!forceUpdate && string.IsNullOrEmpty(newText))
|
||||
{
|
||||
if (string.IsNullOrEmpty(newText))
|
||||
{
|
||||
inputHighlightText.text = string.Empty;
|
||||
}
|
||||
|
||||
UpdateLineNumbers();
|
||||
UpdateHighlight();
|
||||
return;
|
||||
inputHighlightText.text = string.Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
inputHighlightText.text = SyntaxHighlightContent(newText);
|
||||
}
|
||||
|
||||
inputHighlightText.text = SyntaxHighlightContent(newText);
|
||||
|
||||
// Sync line numbers and update the line highlight
|
||||
UpdateLineNumbers();
|
||||
UpdateHighlight();
|
||||
|
||||
this.lastText = newText;
|
||||
ConsolePage.Instance.OnInputChanged();
|
||||
}
|
||||
|
||||
public void SetLineHighlight(int lineNumber, bool lockLineHighlight)
|
||||
@ -217,12 +219,12 @@ namespace Explorer.UI.Main.Pages.Console
|
||||
{
|
||||
int caret = InputField.caretPosition;
|
||||
|
||||
if (caret < 0 || caret >= inputText.textInfo.characterInfo.Count)
|
||||
if (caret < 0 || caret >= inputText.textInfo.characterInfo.Length)
|
||||
{
|
||||
while (caret >= 0 && caret >= inputText.textInfo.characterInfo.Count)
|
||||
while (caret >= 0 && caret >= inputText.textInfo.characterInfo.Length)
|
||||
caret--;
|
||||
|
||||
if (caret < 0 || caret >= inputText.textInfo.characterInfo.Count)
|
||||
if (caret < 0 || caret >= inputText.textInfo.characterInfo.Length)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -357,6 +359,7 @@ namespace Explorer.UI.Main.Pages.Console
|
||||
inputText.Rebuild(CanvasUpdate.Prelayout);
|
||||
InputField.ForceLabelUpdate();
|
||||
InputField.Rebuild(CanvasUpdate.Prelayout);
|
||||
|
||||
OnInputChanged(true);
|
||||
}
|
||||
|
||||
@ -396,10 +399,6 @@ namespace Explorer.UI.Main.Pages.Console
|
||||
scrollbar.color = scrollbarColor;
|
||||
}
|
||||
|
||||
private void ApplyLanguage()
|
||||
{
|
||||
}
|
||||
|
||||
private bool AllReferencesAssigned()
|
||||
{
|
||||
if (!InputField ||
|
||||
|
@ -19,21 +19,17 @@ namespace Explorer.UI.Main.Pages.Console.Lexer
|
||||
private MatchLexer[] matchers = null;
|
||||
private readonly HashSet<char> specialStartSymbols = new HashSet<char>();
|
||||
private readonly HashSet<char> specialEndSymbols = new HashSet<char>();
|
||||
private char current = ' ';
|
||||
private char previous = ' ';
|
||||
private int currentIndex = 0;
|
||||
private int currentLookaheadIndex = 0;
|
||||
|
||||
private char current = ' ';
|
||||
public char Previous { get; private set; } = ' ';
|
||||
|
||||
public bool EndOfStream
|
||||
{
|
||||
get { return currentLookaheadIndex >= inputString.Length; }
|
||||
}
|
||||
|
||||
public char Previous
|
||||
{
|
||||
get { return previous; }
|
||||
}
|
||||
|
||||
public void UseMatchers(char[] delimiters, MatchLexer[] matchers)
|
||||
{
|
||||
this.matchers = matchers;
|
||||
@ -45,10 +41,10 @@ namespace Explorer.UI.Main.Pages.Console.Lexer
|
||||
{
|
||||
foreach (char character in delimiters)
|
||||
{
|
||||
if (specialStartSymbols.Contains(character) == false)
|
||||
if (!specialStartSymbols.Contains(character))
|
||||
specialStartSymbols.Add(character);
|
||||
|
||||
if (specialEndSymbols.Contains(character) == false)
|
||||
if (!specialEndSymbols.Contains(character))
|
||||
specialEndSymbols.Add(character);
|
||||
}
|
||||
}
|
||||
@ -58,11 +54,11 @@ namespace Explorer.UI.Main.Pages.Console.Lexer
|
||||
foreach (MatchLexer lexer in matchers)
|
||||
{
|
||||
foreach (char special in lexer.StartChars)
|
||||
if (specialStartSymbols.Contains(special) == false)
|
||||
if (!specialStartSymbols.Contains(special))
|
||||
specialStartSymbols.Add(special);
|
||||
|
||||
foreach (char special in lexer.EndChars)
|
||||
if (specialEndSymbols.Contains(special) == false)
|
||||
if (!specialEndSymbols.Contains(special))
|
||||
specialEndSymbols.Add(special);
|
||||
}
|
||||
}
|
||||
@ -75,11 +71,11 @@ namespace Explorer.UI.Main.Pages.Console.Lexer
|
||||
|
||||
this.inputString = input;
|
||||
this.current = ' ';
|
||||
this.previous = ' ';
|
||||
this.Previous = ' ';
|
||||
this.currentIndex = 0;
|
||||
this.currentLookaheadIndex = 0;
|
||||
|
||||
while (EndOfStream == false)
|
||||
while (!EndOfStream)
|
||||
{
|
||||
bool didMatchLexer = false;
|
||||
|
||||
@ -91,7 +87,7 @@ namespace Explorer.UI.Main.Pages.Console.Lexer
|
||||
|
||||
bool isMatched = matcher.IsMatch(this);
|
||||
|
||||
if (isMatched == true)
|
||||
if (isMatched)
|
||||
{
|
||||
int endIndex = currentIndex;
|
||||
|
||||
@ -108,7 +104,7 @@ namespace Explorer.UI.Main.Pages.Console.Lexer
|
||||
}
|
||||
}
|
||||
|
||||
if (didMatchLexer == false)
|
||||
if (!didMatchLexer)
|
||||
{
|
||||
ReadNext();
|
||||
Commit();
|
||||
@ -118,10 +114,10 @@ namespace Explorer.UI.Main.Pages.Console.Lexer
|
||||
|
||||
public char ReadNext()
|
||||
{
|
||||
if (EndOfStream == true)
|
||||
if (EndOfStream)
|
||||
return '\0';
|
||||
|
||||
previous = current;
|
||||
Previous = current;
|
||||
|
||||
current = inputString[currentLookaheadIndex];
|
||||
currentLookaheadIndex++;
|
||||
@ -144,11 +140,11 @@ namespace Explorer.UI.Main.Pages.Console.Lexer
|
||||
int previousIndex = currentLookaheadIndex - 1;
|
||||
|
||||
if (previousIndex >= inputString.Length)
|
||||
previous = inputString[inputString.Length - 1];
|
||||
Previous = inputString[inputString.Length - 1];
|
||||
else if (previousIndex >= 0)
|
||||
previous = inputString[previousIndex];
|
||||
Previous = inputString[previousIndex];
|
||||
else
|
||||
previous = ' ';
|
||||
Previous = ' ';
|
||||
}
|
||||
|
||||
public void Commit()
|
||||
|
@ -18,7 +18,7 @@ namespace Explorer.UI.Main.Pages.Console.Lexer
|
||||
|
||||
private readonly HashSet<string> shortlist = new HashSet<string>();
|
||||
private readonly Stack<string> removeList = new Stack<string>();
|
||||
private string[] keywordCache = null;
|
||||
public string[] keywordCache = null;
|
||||
|
||||
public override bool IsImplicitMatch(ILexer lexer)
|
||||
{
|
||||
@ -34,7 +34,7 @@ namespace Explorer.UI.Main.Pages.Console.Lexer
|
||||
char currentChar = lexer.ReadNext();
|
||||
|
||||
for (int i = 0; i < keywordCache.Length; i++)
|
||||
if (CompareChar(keywordCache[i][0], currentChar))
|
||||
if (keywordCache[i][0] == currentChar)
|
||||
shortlist.Add(keywordCache[i]);
|
||||
|
||||
if (shortlist.Count == 0)
|
||||
@ -61,8 +61,7 @@ namespace Explorer.UI.Main.Pages.Console.Lexer
|
||||
|
||||
foreach (string keyword in shortlist)
|
||||
{
|
||||
if (currentIndex >= keyword.Length ||
|
||||
!CompareChar(keyword[currentIndex], currentChar))
|
||||
if (currentIndex >= keyword.Length || keyword[currentIndex] != currentChar)
|
||||
{
|
||||
removeList.Push(keyword);
|
||||
}
|
||||
@ -103,8 +102,5 @@ namespace Explorer.UI.Main.Pages.Console.Lexer
|
||||
keywordCache = list.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
private bool CompareChar(char a, char b) =>
|
||||
(a == b) || (char.ToUpper(a, CultureInfo.CurrentCulture) == char.ToUpper(b, CultureInfo.CurrentCulture));
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ using Mono.CSharp;
|
||||
|
||||
namespace Explorer.UI.Main.Pages.Console
|
||||
{
|
||||
internal class ScriptEvaluator : Evaluator, IDisposable
|
||||
public class ScriptEvaluator : Evaluator, IDisposable
|
||||
{
|
||||
private static readonly HashSet<string> StdLib = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase)
|
||||
{
|
||||
|
@ -36,30 +36,33 @@ namespace Explorer.UI.Main
|
||||
|
||||
public static void Help()
|
||||
{
|
||||
ExplorerCore.Log("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
|
||||
ExplorerCore.Log(" C# Console Help ");
|
||||
ExplorerCore.Log("");
|
||||
ExplorerCore.Log("The following helper methods are available:");
|
||||
ExplorerCore.Log("");
|
||||
ExplorerCore.Log("void Log(object message)");
|
||||
ExplorerCore.Log(" prints a message to the console window and debug log");
|
||||
ExplorerCore.Log(" usage: Log(\"hello world\");");
|
||||
ExplorerCore.Log("");
|
||||
ExplorerCore.Log("object CurrentTarget()");
|
||||
ExplorerCore.Log(" returns the target object of the current tab (in tab view mode only)");
|
||||
ExplorerCore.Log(" usage: var target = CurrentTarget();");
|
||||
ExplorerCore.Log("");
|
||||
ExplorerCore.Log("object[] AllTargets()");
|
||||
ExplorerCore.Log(" returns an object[] array containing all currently inspected objects");
|
||||
ExplorerCore.Log(" usage: var targets = AllTargets();");
|
||||
ExplorerCore.Log("");
|
||||
ExplorerCore.Log("void Inspect(object obj)");
|
||||
ExplorerCore.Log(" inspects the provided object in a new window.");
|
||||
ExplorerCore.Log(" usage: Inspect(Camera.main);");
|
||||
ExplorerCore.Log("");
|
||||
ExplorerCore.Log("void Inspect(Type type)");
|
||||
ExplorerCore.Log(" attempts to inspect the provided type with static-only reflection.");
|
||||
ExplorerCore.Log(" usage: Inspect(typeof(Camera));");
|
||||
var msg = "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r\n";
|
||||
msg += " C# Console Help \r\n";
|
||||
msg += "\r\n";
|
||||
msg += "The following helper methods are available:\r\n";
|
||||
msg += "\r\n";
|
||||
msg += "void Log(object message)\r\n";
|
||||
msg += " prints a message to the console window and debug log\r\n";
|
||||
msg += " usage: Log(\"hello world\");\r\n";
|
||||
msg += "\r\n";
|
||||
|
||||
ExplorerCore.Log(msg);
|
||||
|
||||
//ExplorerCore.Log("object CurrentTarget()");
|
||||
//ExplorerCore.Log(" returns the target object of the current tab (in tab view mode only)");
|
||||
//ExplorerCore.Log(" usage: var target = CurrentTarget();");
|
||||
//ExplorerCore.Log("");
|
||||
//ExplorerCore.Log("object[] AllTargets()");
|
||||
//ExplorerCore.Log(" returns an object[] array containing all currently inspected objects");
|
||||
//ExplorerCore.Log(" usage: var targets = AllTargets();");
|
||||
//ExplorerCore.Log("");
|
||||
//ExplorerCore.Log("void Inspect(object obj)");
|
||||
//ExplorerCore.Log(" inspects the provided object in a new window.");
|
||||
//ExplorerCore.Log(" usage: Inspect(Camera.main);");
|
||||
//ExplorerCore.Log("");
|
||||
//ExplorerCore.Log("void Inspect(Type type)");
|
||||
//ExplorerCore.Log(" attempts to inspect the provided type with static-only reflection.");
|
||||
//ExplorerCore.Log(" usage: Inspect(typeof(Camera));");
|
||||
}
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using Explorer.UI.Main.Pages.Console;
|
||||
using ExplorerBeta;
|
||||
@ -9,21 +10,28 @@ using ExplorerBeta.UI;
|
||||
using ExplorerBeta.UI.Main;
|
||||
using ExplorerBeta.Unstrip.Resources;
|
||||
using TMPro;
|
||||
using UnhollowerRuntimeLib;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
#if CPP
|
||||
using UnhollowerRuntimeLib;
|
||||
#endif
|
||||
|
||||
namespace Explorer.UI.Main.Pages
|
||||
{
|
||||
// TODO: Maybe add interface for managing the Using directives of the console.
|
||||
// Otherwise it's pretty much done.
|
||||
|
||||
public class ConsolePage : BaseMenuPage
|
||||
{
|
||||
public override string Name => "C# Console";
|
||||
|
||||
public static ConsolePage Instance { get; private set; }
|
||||
|
||||
private CodeEditor m_codeEditor;
|
||||
public static bool EnableSuggestions { get; set; } = true;
|
||||
public static bool EnableAutoIndent { get; set; } = true;
|
||||
|
||||
private ScriptEvaluator m_evaluator;
|
||||
public CodeEditor m_codeEditor;
|
||||
public ScriptEvaluator m_evaluator;
|
||||
|
||||
public static List<AutoComplete> AutoCompletes = new List<AutoComplete>();
|
||||
public static List<string> UsingDirectives;
|
||||
@ -52,6 +60,8 @@ namespace Explorer.UI.Main.Pages
|
||||
}
|
||||
|
||||
ConstructUI();
|
||||
|
||||
AutoCompleter.Init();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -63,16 +73,11 @@ namespace Explorer.UI.Main.Pages
|
||||
public override void Update()
|
||||
{
|
||||
m_codeEditor?.Update();
|
||||
|
||||
AutoCompleter.Update();
|
||||
}
|
||||
|
||||
internal string AsmToUsing(string asm, bool richText = false)
|
||||
{
|
||||
if (richText)
|
||||
{
|
||||
return $"<color=#569cd6>using</color> {asm};";
|
||||
}
|
||||
return $"using {asm};";
|
||||
}
|
||||
internal string AsmToUsing(string asm) => $"using {asm};";
|
||||
|
||||
public void AddUsing(string asm)
|
||||
{
|
||||
@ -121,111 +126,26 @@ namespace Explorer.UI.Main.Pages
|
||||
UsingDirectives = new List<string>();
|
||||
}
|
||||
|
||||
private static string m_prevInput = "NULL";
|
||||
|
||||
// TODO call from OnInputChanged
|
||||
|
||||
private void CheckAutocomplete()
|
||||
internal void OnInputChanged()
|
||||
{
|
||||
var input = m_codeEditor.InputField.text;
|
||||
var caretIndex = m_codeEditor.InputField.caretPosition;
|
||||
AutoCompleter.CheckAutocomplete();
|
||||
|
||||
if (!string.IsNullOrEmpty(input))
|
||||
{
|
||||
try
|
||||
{
|
||||
var splitChars = new[] { ',', ';', '<', '>', '(', ')', '[', ']', '=', '|', '&' };
|
||||
|
||||
// Credit ManlyMarco
|
||||
// Separate input into parts, grab only the part with cursor in it
|
||||
var start = caretIndex <= 0 ? 0 : input.LastIndexOfAny(splitChars, (int)(caretIndex - 1)) + 1;
|
||||
var end = caretIndex <= 0 ? input.Length : input.IndexOfAny(splitChars, (int)(caretIndex - 1));
|
||||
if (end < 0 || end < start) end = input.Length;
|
||||
input = input.Substring(start, end - start);
|
||||
}
|
||||
catch (ArgumentException) { }
|
||||
|
||||
if (!string.IsNullOrEmpty(input) && input != m_prevInput)
|
||||
{
|
||||
GetAutocompletes(input);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ClearAutocompletes();
|
||||
}
|
||||
|
||||
m_prevInput = input;
|
||||
AutoCompleter.SetSuggestions(AutoCompletes.ToArray());
|
||||
}
|
||||
|
||||
private void ClearAutocompletes()
|
||||
{
|
||||
if (AutoCompletes.Any())
|
||||
{
|
||||
AutoCompletes.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
private void UseAutocomplete(string suggestion)
|
||||
public void UseAutocomplete(string suggestion)
|
||||
{
|
||||
int cursorIndex = m_codeEditor.InputField.caretPosition;
|
||||
var input = m_codeEditor.InputField.text;
|
||||
input = input.Insert(cursorIndex, suggestion);
|
||||
m_codeEditor.InputField.text = input;
|
||||
m_codeEditor.InputField.caretPosition += suggestion.Length;
|
||||
|
||||
ClearAutocompletes();
|
||||
AutoCompleter.ClearAutocompletes();
|
||||
}
|
||||
|
||||
private void GetAutocompletes(string input)
|
||||
{
|
||||
try
|
||||
{
|
||||
//ExplorerCore.Log("Fetching suggestions for input " + input);
|
||||
|
||||
// Credit ManylMarco
|
||||
AutoCompletes.Clear();
|
||||
var completions = m_evaluator.GetCompletions(input, out string prefix);
|
||||
if (completions != null)
|
||||
{
|
||||
if (prefix == null)
|
||||
prefix = input;
|
||||
|
||||
AutoCompletes.AddRange(completions
|
||||
.Where(x => !string.IsNullOrEmpty(x))
|
||||
.Select(x => new AutoComplete(x, prefix, AutoComplete.Contexts.Other))
|
||||
);
|
||||
}
|
||||
|
||||
var trimmed = input.Trim();
|
||||
if (trimmed.StartsWith("using"))
|
||||
trimmed = trimmed.Remove(0, 5).Trim();
|
||||
|
||||
var namespaces = AutoCompleteHelpers.Namespaces
|
||||
.Where(x => x.StartsWith(trimmed) && x.Length > trimmed.Length)
|
||||
.Select(x => new AutoComplete(
|
||||
x.Substring(trimmed.Length),
|
||||
x.Substring(0, trimmed.Length),
|
||||
AutoComplete.Contexts.Namespace));
|
||||
|
||||
AutoCompletes.AddRange(namespaces);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ExplorerCore.Log("C# Console error:\r\n" + ex);
|
||||
ClearAutocompletes();
|
||||
}
|
||||
}
|
||||
|
||||
// Call on OnInputChanged, or maybe limit frequency if its too laggy
|
||||
|
||||
// update autocomplete buttons
|
||||
|
||||
private void RefreshAutocompleteButtons()
|
||||
{
|
||||
throw new NotImplementedException("TODO");
|
||||
}
|
||||
|
||||
#region UI Construction
|
||||
#region UI Construction
|
||||
|
||||
public void ConstructUI()
|
||||
{
|
||||
@ -241,6 +161,10 @@ namespace Explorer.UI.Main.Pages
|
||||
mainGroup.childForceExpandHeight = true;
|
||||
mainGroup.childForceExpandWidth = true;
|
||||
|
||||
#region TOP BAR
|
||||
|
||||
// Main group object
|
||||
|
||||
var topBarObj = UIFactory.CreateHorizontalGroup(Content);
|
||||
var topBarLayout = topBarObj.AddComponent<LayoutElement>();
|
||||
topBarLayout.minHeight = 50;
|
||||
@ -256,6 +180,7 @@ namespace Explorer.UI.Main.Pages
|
||||
topBarGroup.childForceExpandWidth = true;
|
||||
topBarGroup.childControlWidth = true;
|
||||
topBarGroup.childControlHeight = true;
|
||||
topBarGroup.childAlignment = TextAnchor.LowerCenter;
|
||||
|
||||
var topBarLabel = UIFactory.CreateLabel(topBarObj, TextAnchor.MiddleLeft);
|
||||
var topBarLabelLayout = topBarLabel.AddComponent<LayoutElement>();
|
||||
@ -265,24 +190,72 @@ namespace Explorer.UI.Main.Pages
|
||||
topBarText.text = "C# Console";
|
||||
topBarText.fontSize = 20;
|
||||
|
||||
var compileBtnObj = UIFactory.CreateButton(topBarObj);
|
||||
var compileBtnLayout = compileBtnObj.AddComponent<LayoutElement>();
|
||||
compileBtnLayout.preferredWidth = 80;
|
||||
compileBtnLayout.flexibleWidth = 0;
|
||||
var compileButton = compileBtnObj.GetComponent<Button>();
|
||||
var compileBtnColors = compileButton.colors;
|
||||
compileBtnColors.normalColor = new Color(14f/255f, 106f/255f, 14f/255f);
|
||||
compileButton.colors = compileBtnColors;
|
||||
var btnText = compileBtnObj.GetComponentInChildren<Text>();
|
||||
btnText.text = ">";
|
||||
btnText.fontSize = 25;
|
||||
btnText.color = Color.white;
|
||||
// Enable Suggestions toggle
|
||||
|
||||
var suggestToggleObj = UIFactory.CreateToggle(topBarObj, out Toggle suggestToggle, out Text suggestToggleText);
|
||||
#if CPP
|
||||
suggestToggle.onValueChanged.AddListener(new Action<bool>(SuggestToggleCallback));
|
||||
#else
|
||||
suggestToggle.onValueChanged.AddListener(SuggestToggleCallback);
|
||||
#endif
|
||||
void SuggestToggleCallback(bool val)
|
||||
{
|
||||
EnableSuggestions = val;
|
||||
AutoCompleter.Update();
|
||||
}
|
||||
|
||||
suggestToggleText.text = "Suggestions";
|
||||
suggestToggleText.alignment = TextAnchor.UpperLeft;
|
||||
var suggestTextPos = suggestToggleText.transform.localPosition;
|
||||
suggestTextPos.y = -14;
|
||||
suggestToggleText.transform.localPosition = suggestTextPos;
|
||||
|
||||
var suggestLayout = suggestToggleObj.AddComponent<LayoutElement>();
|
||||
suggestLayout.minWidth = 120;
|
||||
suggestLayout.flexibleWidth = 0;
|
||||
|
||||
var suggestRect = suggestToggleObj.transform.Find("Background");
|
||||
var suggestPos = suggestRect.localPosition;
|
||||
suggestPos.y = -14;
|
||||
suggestRect.localPosition = suggestPos;
|
||||
|
||||
// Enable Auto-indent toggle
|
||||
|
||||
var autoIndentToggleObj = UIFactory.CreateToggle(topBarObj, out Toggle autoIndentToggle, out Text autoIndentToggleText);
|
||||
#if CPP
|
||||
autoIndentToggle.onValueChanged.AddListener(new Action<bool>((bool val) =>
|
||||
{
|
||||
EnableAutoIndent = val;
|
||||
}));
|
||||
#else
|
||||
autoIndentToggle.onValueChanged.AddListener(OnIndentChanged);
|
||||
|
||||
void OnIndentChanged(bool val) => EnableAutoIndent = val;
|
||||
#endif
|
||||
autoIndentToggleText.text = "Auto-indent";
|
||||
autoIndentToggleText.alignment = TextAnchor.UpperLeft;
|
||||
var autoIndentTextPos = autoIndentToggleText.transform.localPosition;
|
||||
autoIndentTextPos.y = -14;
|
||||
autoIndentToggleText.transform.localPosition = autoIndentTextPos;
|
||||
|
||||
var autoIndentLayout = autoIndentToggleObj.AddComponent<LayoutElement>();
|
||||
autoIndentLayout.minWidth = 120;
|
||||
autoIndentLayout.flexibleWidth = 0;
|
||||
|
||||
var autoIndentRect = autoIndentToggleObj.transform.Find("Background");
|
||||
suggestPos = autoIndentRect.localPosition;
|
||||
suggestPos.y = -14;
|
||||
autoIndentRect.localPosition = suggestPos;
|
||||
|
||||
#endregion
|
||||
|
||||
#region CONSOLE INPUT
|
||||
|
||||
var consoleBase = UIFactory.CreateUIObject("CodeEditor", Content);
|
||||
|
||||
var consoleLayout = consoleBase.AddComponent<LayoutElement>();
|
||||
consoleLayout.preferredHeight = 500;
|
||||
consoleLayout.flexibleHeight = 5;
|
||||
consoleLayout.flexibleHeight = 50;
|
||||
|
||||
consoleBase.AddComponent<RectMask2D>();
|
||||
|
||||
@ -356,6 +329,11 @@ namespace Explorer.UI.Main.Pages
|
||||
var mainTextInput = mainTextObj.GetComponent<TextMeshProUGUI>();
|
||||
mainTextInput.fontSize = 18;
|
||||
|
||||
var placeHolderText = textAreaObj.transform.Find("Placeholder").GetComponent<TextMeshProUGUI>();
|
||||
placeHolderText.text = @"Welcome to the Explorer C# Console!
|
||||
|
||||
Use the <color=#c74e26>Help();</color> command for a list of available helper methods, or <color=#c74e26>Log(""[message]"");</color> to print something to console.";
|
||||
|
||||
var linesTextObj = UIFactory.CreateUIObject("LinesText", mainTextObj.gameObject);
|
||||
var linesTextRect = linesTextObj.GetComponent<RectTransform>();
|
||||
|
||||
@ -403,15 +381,49 @@ namespace Explorer.UI.Main.Pages
|
||||
tmpInput.GetComponentInChildren<RectMask2D>().enabled = false;
|
||||
inputObj.GetComponent<Image>().enabled = false;
|
||||
|
||||
// setup button callbacks
|
||||
#endregion
|
||||
|
||||
compileButton.onClick.AddListener(new Action(() =>
|
||||
#region COMPILE BUTTON
|
||||
|
||||
var compileBtnObj = UIFactory.CreateButton(Content);
|
||||
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.color = Color.white;
|
||||
|
||||
// Set compile button callback now that we have the Input Field reference
|
||||
#if CPP
|
||||
compileButton.onClick.AddListener(new Action(() =>
|
||||
{
|
||||
if (!string.IsNullOrEmpty(tmpInput.text))
|
||||
{
|
||||
Evaluate(tmpInput.text.Trim());
|
||||
}
|
||||
}));
|
||||
#else
|
||||
compileButton.onClick.AddListener(CompileCallback);
|
||||
|
||||
void CompileCallback()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(tmpInput.text))
|
||||
{
|
||||
Evaluate(tmpInput.text.Trim());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endregion
|
||||
|
||||
#region FONT
|
||||
|
||||
TMP_FontAsset fontToUse = null;
|
||||
#if CPP
|
||||
@ -439,17 +451,24 @@ namespace Explorer.UI.Main.Pages
|
||||
#endif
|
||||
if (fontToUse != null)
|
||||
{
|
||||
fontToUse.faceInfo.tabWidth = 10;
|
||||
fontToUse.tabSize = 10;
|
||||
var faceInfo = fontToUse.faceInfo;
|
||||
fontToUse.tabSize = 10;
|
||||
faceInfo.tabWidth = 10;
|
||||
#if CPP
|
||||
fontToUse.faceInfo = faceInfo;
|
||||
#else
|
||||
typeof(TMP_FontAsset)
|
||||
.GetField("m_FaceInfo", BindingFlags.NonPublic | BindingFlags.Instance)
|
||||
.SetValue(fontToUse, faceInfo);
|
||||
#endif
|
||||
|
||||
tmpInput.fontAsset = fontToUse;
|
||||
mainTextInput.font = fontToUse;
|
||||
highlightTextInput.font = fontToUse;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
try
|
||||
{
|
||||
m_codeEditor = new CodeEditor(inputField, mainTextInput, highlightTextInput, linesTextInput,
|
||||
|
@ -6,7 +6,9 @@ using ExplorerBeta;
|
||||
using ExplorerBeta.UI;
|
||||
using ExplorerBeta.UI.Main;
|
||||
using ExplorerBeta.UI.Shared;
|
||||
using ExplorerBeta.Unstrip.Scenes;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Explorer.UI.Main.Pages
|
||||
@ -15,16 +17,153 @@ namespace Explorer.UI.Main.Pages
|
||||
{
|
||||
public override string Name => "Home";
|
||||
|
||||
private PageHandler m_sceneListPages;
|
||||
// private PageHandler m_sceneListPages;
|
||||
private Dropdown m_sceneDropdown;
|
||||
|
||||
private Dictionary<string, int> m_sceneHandles = new Dictionary<string, int>();
|
||||
|
||||
// is tihs needed?
|
||||
private int m_currentSceneHandle;
|
||||
|
||||
private List<GameObject> m_currentObjectList = new List<GameObject>();
|
||||
private GameObject m_sceneListContent;
|
||||
private readonly List<Text> m_sceneListTexts = new List<Text>();
|
||||
// todo
|
||||
private GameObject m_currentSceneObject;
|
||||
|
||||
private int m_lastMaxIndex;
|
||||
|
||||
public override void Init()
|
||||
{
|
||||
ConstructMenu();
|
||||
|
||||
// get DontDestroyScene handle
|
||||
var test = new GameObject();
|
||||
GameObject.DontDestroyOnLoad(test);
|
||||
GetSceneHandle(test.scene);
|
||||
GameObject.Destroy(test);
|
||||
|
||||
RefreshActiveScenes();
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
|
||||
// refresh active scenes? maybe on a timer to limit frequency
|
||||
|
||||
// refresh scene objects on limited frequency
|
||||
}
|
||||
|
||||
private int GetSceneHandle(Scene scene)
|
||||
{
|
||||
if (!m_sceneHandles.ContainsKey(scene.name))
|
||||
{
|
||||
m_sceneHandles.Add(scene.name, scene.handle);
|
||||
}
|
||||
return scene.handle;
|
||||
}
|
||||
|
||||
private int GetSceneHandle(string sceneName)
|
||||
{
|
||||
if (!m_sceneHandles.ContainsKey(sceneName))
|
||||
return -1;
|
||||
else
|
||||
return m_sceneHandles[sceneName];
|
||||
}
|
||||
|
||||
public void SetScene(string name)
|
||||
{
|
||||
var handle = GetSceneHandle(name);
|
||||
|
||||
if (handle == -1)
|
||||
{
|
||||
ExplorerCore.LogWarning($"Error: Could not get handle for scene '{name}'");
|
||||
return;
|
||||
}
|
||||
|
||||
m_currentSceneHandle = handle;
|
||||
|
||||
var rootObjs = SceneUnstrip.GetRootGameObjects(handle);
|
||||
|
||||
SetSceneObjectList(rootObjs);
|
||||
}
|
||||
|
||||
private void RefreshActiveScenes(bool firstTime = false)
|
||||
{
|
||||
var activeScene = SceneManager.GetActiveScene().name;
|
||||
var otherScenes = new List<string>();
|
||||
|
||||
for (int i = 0; i < SceneManager.sceneCount; i++)
|
||||
{
|
||||
var scene = SceneManager.GetSceneAt(i);
|
||||
GetSceneHandle(scene);
|
||||
|
||||
if (!firstTime || scene.name != activeScene)
|
||||
otherScenes.Add(scene.name);
|
||||
}
|
||||
otherScenes.Add("DontDestroyOnLoad");
|
||||
|
||||
m_sceneDropdown.options.Clear();
|
||||
|
||||
if (firstTime)
|
||||
{
|
||||
m_sceneDropdown.options.Add(new Dropdown.OptionData
|
||||
{
|
||||
text = activeScene
|
||||
});
|
||||
}
|
||||
|
||||
foreach (var scene in otherScenes)
|
||||
{
|
||||
m_sceneDropdown.options.Add(new Dropdown.OptionData
|
||||
{
|
||||
text = scene
|
||||
});
|
||||
}
|
||||
|
||||
SetScene(activeScene);
|
||||
}
|
||||
|
||||
private void SceneButtonClicked(int index)
|
||||
{
|
||||
var obj = m_currentObjectList[index];
|
||||
|
||||
ExplorerCore.Log("Clicked " + obj.name);
|
||||
}
|
||||
|
||||
private void SetSceneObjectList(IEnumerable<GameObject> objects)
|
||||
{
|
||||
m_currentObjectList.Clear();
|
||||
|
||||
int index = 0;
|
||||
foreach (var obj in objects)
|
||||
{
|
||||
m_currentObjectList.Add(obj);
|
||||
|
||||
if (index >= m_sceneListTexts.Count)
|
||||
{
|
||||
AddSceneButton();
|
||||
}
|
||||
|
||||
m_sceneListTexts[index].text = obj.name;
|
||||
|
||||
var parent = m_sceneListTexts[index].transform.parent.gameObject;
|
||||
if (!parent.activeSelf)
|
||||
parent.SetActive(true);
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
var origIndex = index;
|
||||
while (index < m_sceneListTexts.Count && index < m_lastMaxIndex)
|
||||
{
|
||||
var obj = m_sceneListTexts[index].transform.parent.gameObject;
|
||||
|
||||
if (obj.activeSelf)
|
||||
obj.SetActive(false);
|
||||
|
||||
index++;
|
||||
}
|
||||
m_lastMaxIndex = origIndex;
|
||||
}
|
||||
|
||||
#region UI Construction
|
||||
@ -76,24 +215,70 @@ namespace Explorer.UI.Main.Pages
|
||||
|
||||
private void ConstructScenePane(GameObject leftPane)
|
||||
{
|
||||
m_sceneListPages = new PageHandler(100);
|
||||
m_sceneListPages.ConstructUI(leftPane);
|
||||
m_sceneListPages.OnPageChanged += RefreshSceneObjectList;
|
||||
var activeSceneLabelObj = UIFactory.CreateLabel(leftPane, TextAnchor.UpperLeft);
|
||||
var activeSceneLabel = activeSceneLabelObj.GetComponent<Text>();
|
||||
activeSceneLabel.text = "Scene Explorer";
|
||||
activeSceneLabel.fontSize = 25;
|
||||
var activeSceneLayout = activeSceneLabelObj.AddComponent<LayoutElement>();
|
||||
activeSceneLayout.minHeight = 30;
|
||||
activeSceneLayout.flexibleHeight = 0;
|
||||
|
||||
var scrollTest = UIFactory.CreateScrollView(leftPane, out GameObject content);
|
||||
var sceneDropdownObj = UIFactory.CreateDropdown(leftPane, out m_sceneDropdown);
|
||||
var dropdownLayout = sceneDropdownObj.AddComponent<LayoutElement>();
|
||||
dropdownLayout.minHeight = 40;
|
||||
dropdownLayout.flexibleHeight = 0;
|
||||
dropdownLayout.minWidth = 320;
|
||||
dropdownLayout.flexibleWidth = 2;
|
||||
|
||||
#if CPP
|
||||
m_sceneDropdown.onValueChanged.AddListener(new Action<int>((int val) => { SetSceneFromDropdown(val); }));
|
||||
#else
|
||||
m_sceneDropdown.onValueChanged.AddListener((int val) => { SetSceneFromDropdown(val); });
|
||||
#endif
|
||||
void SetSceneFromDropdown(int val)
|
||||
{
|
||||
var scene = m_sceneDropdown.options[val].text;
|
||||
SetScene(scene);
|
||||
}
|
||||
|
||||
// Scene list(TODO)
|
||||
|
||||
//m_sceneListPages = new PageHandler(100);
|
||||
//m_sceneListPages.ConstructUI(leftPane);
|
||||
//m_sceneListPages.OnPageChanged += RefreshSceneObjectList;
|
||||
|
||||
var scrollTest = UIFactory.CreateScrollView(leftPane, out m_sceneListContent, new Color(0.15f, 0.15f, 0.15f, 1));
|
||||
for (int i = 0; i < 50; i++)
|
||||
{
|
||||
var obj = UIFactory.CreateLabel(content, TextAnchor.MiddleCenter);
|
||||
var text = obj.GetComponent<Text>();
|
||||
text.text = "Hello world " + i;
|
||||
AddSceneButton();
|
||||
}
|
||||
m_lastMaxIndex = 51;
|
||||
}
|
||||
|
||||
private void RefreshSceneObjectList()
|
||||
private void AddSceneButton()
|
||||
{
|
||||
ExplorerCore.Log("Would update scene list here");
|
||||
var obj = UIFactory.CreateButton(m_sceneListContent);
|
||||
|
||||
var btn = obj.GetComponent<Button>();
|
||||
var colors = btn.colors;
|
||||
colors.normalColor = new Color(0.15f, 0.15f, 0.15f, 1);
|
||||
btn.colors = colors;
|
||||
|
||||
int thisIndex = m_sceneListTexts.Count();
|
||||
|
||||
#if CPP
|
||||
btn.onClick.AddListener(new Action(() => { SceneButtonClicked(thisIndex); }));
|
||||
#else
|
||||
btn.onClick.AddListener(() => { SceneButtonClicked(thisIndex); });
|
||||
#endif
|
||||
|
||||
var text = obj.GetComponentInChildren<Text>();
|
||||
text.text = "button " + thisIndex;
|
||||
text.alignment = TextAnchor.MiddleLeft;
|
||||
|
||||
m_sceneListTexts.Add(text);
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
@ -6,9 +6,11 @@ using UnityEngine.UI;
|
||||
using UnityEngine.EventSystems;
|
||||
using ExplorerBeta.Input;
|
||||
using ExplorerBeta.Helpers;
|
||||
using ExplorerBeta.Unstrip.ImageConversion;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
#if CPP
|
||||
using ExplorerBeta.Unstrip.ImageConversion;
|
||||
#endif
|
||||
|
||||
namespace ExplorerBeta.UI
|
||||
{
|
||||
@ -102,7 +104,7 @@ namespace ExplorerBeta.UI
|
||||
return;
|
||||
}
|
||||
|
||||
#region DRAGGING
|
||||
#region DRAGGING
|
||||
|
||||
public RectTransform DragableArea { get; set; }
|
||||
public bool WasDragging { get; set; }
|
||||
@ -132,9 +134,9 @@ namespace ExplorerBeta.UI
|
||||
UpdateResizeCache();
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region RESIZE
|
||||
#region RESIZE
|
||||
|
||||
private const int RESIZE_THICKNESS = 10;
|
||||
|
||||
@ -339,13 +341,13 @@ namespace ExplorerBeta.UI
|
||||
|
||||
var image = m_resizeCursorImage.AddComponent<Image>();
|
||||
image.sprite = sprite;
|
||||
var rect = image.transform.TryCast<RectTransform>();
|
||||
var rect = image.transform.GetComponent<RectTransform>();
|
||||
rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, 32);
|
||||
rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 32);
|
||||
|
||||
m_resizeCursorImage.SetActive(false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
}
|
||||
}
|
@ -79,8 +79,6 @@ namespace ExplorerBeta.UI.Shared
|
||||
|
||||
#region UI
|
||||
|
||||
// TODO
|
||||
|
||||
private GameObject m_pageUIHolder;
|
||||
private Text m_currentPageLabel;
|
||||
|
||||
@ -111,7 +109,11 @@ namespace ExplorerBeta.UI.Shared
|
||||
|
||||
var leftBtnObj = UIFactory.CreateButton(m_pageUIHolder);
|
||||
var leftBtn = leftBtnObj.GetComponent<Button>();
|
||||
#if CPP
|
||||
leftBtn.onClick.AddListener(new Action(() => { TurnPage(Turn.Left); }));
|
||||
#else
|
||||
leftBtn.onClick.AddListener(() => { TurnPage(Turn.Left); });
|
||||
#endif
|
||||
var leftBtnText = leftBtnObj.GetComponentInChildren<Text>();
|
||||
leftBtnText.text = "<";
|
||||
var leftBtnLayout = leftBtnObj.AddComponent<LayoutElement>();
|
||||
@ -131,7 +133,11 @@ namespace ExplorerBeta.UI.Shared
|
||||
|
||||
var rightBtnObj = UIFactory.CreateButton(m_pageUIHolder);
|
||||
var rightBtn = rightBtnObj.GetComponent<Button>();
|
||||
#if CPP
|
||||
rightBtn.onClick.AddListener(new Action(() => { TurnPage(Turn.Right); }));
|
||||
#else
|
||||
rightBtn.onClick.AddListener(() => { TurnPage(Turn.Right); });
|
||||
#endif
|
||||
var rightBtnText = rightBtnObj.GetComponentInChildren<Text>();
|
||||
rightBtnText.text = ">";
|
||||
var rightBtnLayout = rightBtnObj.AddComponent<LayoutElement>();
|
||||
@ -150,6 +156,6 @@ namespace ExplorerBeta.UI.Shared
|
||||
m_currentPageLabel.text = $"Page {m_currentPage + 1} / {LastPage + 1}";
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
@ -11,25 +12,10 @@ namespace ExplorerBeta.UI
|
||||
{
|
||||
public static class UIFactory
|
||||
{
|
||||
private static Vector2 s_ThickElementSize = new Vector2(160f, 30f);
|
||||
private static Vector2 s_ThinElementSize = new Vector2(160f, 20f);
|
||||
private static Color s_DefaultSelectableColor = new Color(1f, 1f, 1f, 1f);
|
||||
private static Color s_TextColor = new Color(0.95f, 0.95f, 0.95f, 1f);
|
||||
//private static Color s_PanelColor = new Color(0.1f, 0.1f, 0.1f, 1.0f);
|
||||
//private static Vector2 s_ImageElementSize = new Vector2(100f, 100f);
|
||||
|
||||
public static Resources UIResources { get; set; }
|
||||
|
||||
public struct Resources
|
||||
{
|
||||
public Sprite standard;
|
||||
public Sprite background;
|
||||
public Sprite inputField;
|
||||
public Sprite knob;
|
||||
public Sprite checkmark;
|
||||
public Sprite dropdown;
|
||||
public Sprite mask;
|
||||
}
|
||||
private static Vector2 thickSize = new Vector2(160f, 30f);
|
||||
private static Vector2 thinSize = new Vector2(160f, 20f);
|
||||
private static Color defaultTextColor = new Color(0.95f, 0.95f, 0.95f, 1f);
|
||||
private static Font m_defaultFont;
|
||||
|
||||
public static GameObject CreateUIObject(string name, GameObject parent, Vector2 size = default)
|
||||
{
|
||||
@ -48,10 +34,14 @@ namespace ExplorerBeta.UI
|
||||
|
||||
private static void SetDefaultTextValues(Text lbl)
|
||||
{
|
||||
lbl.color = s_TextColor;
|
||||
lbl.AssignDefaultFont();
|
||||
//lbl.alignment = alignment;
|
||||
//lbl.resizeTextForBestFit = true;
|
||||
lbl.color = defaultTextColor;
|
||||
|
||||
if (!m_defaultFont)
|
||||
{
|
||||
m_defaultFont = Resources.GetBuiltinResource<Font>("Arial.ttf");
|
||||
}
|
||||
|
||||
lbl.font = m_defaultFont;
|
||||
}
|
||||
|
||||
private static void SetDefaultColorTransitionValues(Selectable selectable)
|
||||
@ -65,9 +55,21 @@ namespace ExplorerBeta.UI
|
||||
// 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(new Action(() => { button.OnDeselect(EventSystem.current?.baseEventDataCache); }));
|
||||
}
|
||||
{
|
||||
#if CPP
|
||||
button.onClick.AddListener(new Action(() =>
|
||||
{
|
||||
button.OnDeselect(null);
|
||||
}));
|
||||
#else
|
||||
button.onClick.AddListener(Deselect);
|
||||
|
||||
void Deselect()
|
||||
{
|
||||
button.OnDeselect(null);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
selectable.colors = colors;
|
||||
}
|
||||
@ -94,7 +96,7 @@ namespace ExplorerBeta.UI
|
||||
|
||||
public static GameObject CreatePanel(GameObject parent, string name, out GameObject content)
|
||||
{
|
||||
GameObject panelObj = CreateUIObject($"Panel_{name}", parent, s_ThickElementSize);
|
||||
GameObject panelObj = CreateUIObject($"Panel_{name}", parent, thickSize);
|
||||
|
||||
RectTransform rect = panelObj.GetComponent<RectTransform>();
|
||||
rect.anchorMin = Vector2.zero;
|
||||
@ -173,7 +175,7 @@ namespace ExplorerBeta.UI
|
||||
|
||||
public static GameObject CreateLabel(GameObject parent, TextAnchor alignment)
|
||||
{
|
||||
GameObject labelObj = CreateUIObject("Label", parent, s_ThinElementSize);
|
||||
GameObject labelObj = CreateUIObject("Label", parent, thinSize);
|
||||
|
||||
var text = labelObj.AddComponent<Text>();
|
||||
SetDefaultTextValues(text);
|
||||
@ -185,16 +187,15 @@ namespace ExplorerBeta.UI
|
||||
|
||||
public static GameObject CreateButton(GameObject parent)
|
||||
{
|
||||
GameObject buttonObj = CreateUIObject("Button", parent, s_ThinElementSize);
|
||||
GameObject buttonObj = CreateUIObject("Button", parent, thinSize);
|
||||
|
||||
GameObject textObj = new GameObject("Text");
|
||||
textObj.AddComponent<RectTransform>();
|
||||
SetParentAndAlign(textObj, buttonObj);
|
||||
|
||||
Image image = buttonObj.AddComponent<Image>();
|
||||
image.sprite = UIResources.standard;
|
||||
image.type = Image.Type.Sliced;
|
||||
image.color = s_DefaultSelectableColor;
|
||||
image.color = new Color(1, 1, 1, 1);
|
||||
|
||||
SetDefaultColorTransitionValues(buttonObj.AddComponent<Button>());
|
||||
|
||||
@ -213,7 +214,7 @@ namespace ExplorerBeta.UI
|
||||
|
||||
public static GameObject CreateSlider(GameObject parent)
|
||||
{
|
||||
GameObject sliderObj = CreateUIObject("Slider", parent, s_ThinElementSize);
|
||||
GameObject sliderObj = CreateUIObject("Slider", parent, thinSize);
|
||||
|
||||
GameObject bgObj = CreateUIObject("Background", sliderObj);
|
||||
GameObject fillAreaObj = CreateUIObject("Fill Area", sliderObj);
|
||||
@ -222,9 +223,8 @@ namespace ExplorerBeta.UI
|
||||
GameObject handleObj = CreateUIObject("Handle", handleSlideAreaObj);
|
||||
|
||||
Image bgImage = bgObj.AddComponent<Image>();
|
||||
bgImage.sprite = UIResources.background;
|
||||
bgImage.type = Image.Type.Sliced;
|
||||
bgImage.color = s_DefaultSelectableColor;
|
||||
bgImage.color = new Color(0.15f, 0.15f, 0.15f, 1.0f);
|
||||
|
||||
RectTransform bgRect = bgObj.GetComponent<RectTransform>();
|
||||
bgRect.anchorMin = new Vector2(0f, 0.25f);
|
||||
@ -238,9 +238,8 @@ namespace ExplorerBeta.UI
|
||||
fillAreaRect.sizeDelta = new Vector2(-20f, 0f);
|
||||
|
||||
Image fillImage = fillObj.AddComponent<Image>();
|
||||
fillImage.sprite = UIResources.standard;
|
||||
fillImage.type = Image.Type.Sliced;
|
||||
fillImage.color = s_DefaultSelectableColor;
|
||||
fillImage.color = new Color(0.3f, 0.3f, 0.3f, 1.0f);
|
||||
|
||||
fillObj.GetComponent<RectTransform>().sizeDelta = new Vector2(10f, 0f);
|
||||
|
||||
@ -250,8 +249,7 @@ namespace ExplorerBeta.UI
|
||||
handleSlideRect.anchorMax = new Vector2(1f, 1f);
|
||||
|
||||
Image handleImage = handleObj.AddComponent<Image>();
|
||||
handleImage.sprite = UIResources.knob;
|
||||
handleImage.color = s_DefaultSelectableColor;
|
||||
handleImage.color = new Color(0.5f, 0.5f, 0.5f, 1.0f);
|
||||
|
||||
handleObj.GetComponent<RectTransform>().sizeDelta = new Vector2(20f, 0f);
|
||||
|
||||
@ -267,7 +265,7 @@ namespace ExplorerBeta.UI
|
||||
|
||||
public static GameObject CreateScrollbar(GameObject parent)
|
||||
{
|
||||
GameObject scrollObj = CreateUIObject("Scrollbar", parent, s_ThinElementSize);
|
||||
GameObject scrollObj = CreateUIObject("Scrollbar", parent, thinSize);
|
||||
|
||||
GameObject slideAreaObj = CreateUIObject("Sliding Area", scrollObj);
|
||||
GameObject handleObj = CreateUIObject("Handle", slideAreaObj);
|
||||
@ -277,7 +275,6 @@ namespace ExplorerBeta.UI
|
||||
scrollImage.color = new Color(0.1f, 0.1f, 0.1f);
|
||||
|
||||
Image handleImage = handleObj.AddComponent<Image>();
|
||||
handleImage.sprite = UIResources.standard;
|
||||
handleImage.type = Image.Type.Sliced;
|
||||
handleImage.color = new Color(0.4f, 0.4f, 0.4f);
|
||||
|
||||
@ -297,26 +294,39 @@ namespace ExplorerBeta.UI
|
||||
return scrollObj;
|
||||
}
|
||||
|
||||
public static GameObject CreateToggle(GameObject parent)
|
||||
public static GameObject CreateToggle(GameObject parent, out Toggle toggle, out Text text)
|
||||
{
|
||||
GameObject toggleObj = CreateUIObject("Toggle", parent, s_ThinElementSize);
|
||||
GameObject toggleObj = CreateUIObject("Toggle", parent, thinSize);
|
||||
|
||||
GameObject bgObj = CreateUIObject("Background", toggleObj);
|
||||
GameObject checkObj = CreateUIObject("Checkmark", bgObj);
|
||||
GameObject labelObj = CreateUIObject("Label", toggleObj);
|
||||
|
||||
Toggle toggle = toggleObj.AddComponent<Toggle>();
|
||||
toggle = toggleObj.AddComponent<Toggle>();
|
||||
toggle.isOn = true;
|
||||
var toggleComp = toggle;
|
||||
#if CPP
|
||||
toggle.onValueChanged.AddListener(new Action<bool>((bool val) =>
|
||||
{
|
||||
toggleComp.OnDeselect(null);
|
||||
}));
|
||||
#else
|
||||
toggle.onValueChanged.AddListener(Deselect);
|
||||
|
||||
void Deselect(bool _)
|
||||
{
|
||||
toggleComp.OnDeselect(null);
|
||||
}
|
||||
#endif
|
||||
|
||||
Image bgImage = bgObj.AddComponent<Image>();
|
||||
bgImage.sprite = UIResources.standard;
|
||||
bgImage.type = Image.Type.Sliced;
|
||||
bgImage.color = s_DefaultSelectableColor;
|
||||
bgImage.color = new Color(0.1f, 0.1f, 0.1f, 1.0f);
|
||||
|
||||
Image checkImage = checkObj.AddComponent<Image>();
|
||||
checkImage.sprite = UIResources.checkmark;
|
||||
checkImage.color = new Color(90f/255f, 115f/255f, 90f/255f, 1.0f);
|
||||
|
||||
Text text = labelObj.AddComponent<Text>();
|
||||
text = labelObj.AddComponent<Text>();
|
||||
text.text = "Toggle";
|
||||
SetDefaultTextValues(text);
|
||||
|
||||
@ -334,7 +344,7 @@ namespace ExplorerBeta.UI
|
||||
checkRect.anchorMin = new Vector2(0.5f, 0.5f);
|
||||
checkRect.anchorMax = new Vector2(0.5f, 0.5f);
|
||||
checkRect.anchoredPosition = Vector2.zero;
|
||||
checkRect.sizeDelta = new Vector2(20f, 20f);
|
||||
checkRect.sizeDelta = new Vector2(14f, 14f);
|
||||
|
||||
RectTransform labelRect = labelObj.GetComponent<RectTransform>();
|
||||
labelRect.anchorMin = new Vector2(0f, 0f);
|
||||
@ -353,7 +363,9 @@ namespace ExplorerBeta.UI
|
||||
mainImage.color = new Color(38f / 255f, 38f / 255f, 38f / 255f, 1.0f);
|
||||
|
||||
var mainInput = mainObj.AddComponent<TMP_InputField>();
|
||||
mainInput.navigation.mode = Navigation.Mode.None;
|
||||
var nav = mainInput.navigation;
|
||||
nav.mode = Navigation.Mode.None;
|
||||
mainInput.navigation = nav;
|
||||
mainInput.richText = true;
|
||||
mainInput.isRichTextEditingAllowed = true;
|
||||
mainInput.lineType = TMP_InputField.LineType.MultiLineNewline;
|
||||
@ -426,15 +438,14 @@ namespace ExplorerBeta.UI
|
||||
|
||||
public static GameObject CreateInputField(GameObject parent)
|
||||
{
|
||||
GameObject inputObj = CreateUIObject("InputField", parent, s_ThickElementSize);
|
||||
GameObject inputObj = CreateUIObject("InputField", parent, thickSize);
|
||||
|
||||
GameObject placeholderObj = CreateUIObject("Placeholder", inputObj);
|
||||
GameObject textObj = CreateUIObject("Text", inputObj);
|
||||
|
||||
Image inputImage = inputObj.AddComponent<Image>();
|
||||
inputImage.sprite = UIResources.inputField;
|
||||
inputImage.type = Image.Type.Sliced;
|
||||
inputImage.color = s_DefaultSelectableColor;
|
||||
inputImage.color = new Color(0.1f, 0.1f, 0.1f, 1.0f);
|
||||
|
||||
InputField inputField = inputObj.AddComponent<InputField>();
|
||||
SetDefaultColorTransitionValues(inputField);
|
||||
@ -470,12 +481,11 @@ namespace ExplorerBeta.UI
|
||||
return inputObj;
|
||||
}
|
||||
|
||||
public static GameObject CreateDropdown(GameObject parent)
|
||||
public static GameObject CreateDropdown(GameObject parent, out Dropdown dropdown)
|
||||
{
|
||||
GameObject dropdownObj = CreateUIObject("Dropdown", parent, s_ThickElementSize);
|
||||
GameObject dropdownObj = CreateUIObject("Dropdown", parent, thickSize);
|
||||
|
||||
GameObject labelObj = CreateUIObject("Label", dropdownObj);
|
||||
GameObject arrowObj = CreateUIObject("Arrow", dropdownObj);
|
||||
GameObject templateObj = CreateUIObject("Template", dropdownObj);
|
||||
GameObject viewportObj = CreateUIObject("Viewport", templateObj);
|
||||
GameObject contentObj = CreateUIObject("Content", viewportObj);
|
||||
@ -500,19 +510,24 @@ namespace ExplorerBeta.UI
|
||||
itemLabelText.alignment = TextAnchor.MiddleLeft;
|
||||
|
||||
Image itemBgImage = itemBgObj.AddComponent<Image>();
|
||||
itemBgImage.color = new Color32(245, 245, 245, byte.MaxValue);
|
||||
itemBgImage.color = new Color(0.5f, 0.5f, 0.5f, 1.0f);
|
||||
|
||||
Image itemCheckImage = itemCheckObj.AddComponent<Image>();
|
||||
itemCheckImage.sprite = UIResources.checkmark;
|
||||
|
||||
Toggle itemToggle = itemObj.AddComponent<Toggle>();
|
||||
itemToggle.targetGraphic = itemBgImage;
|
||||
itemToggle.graphic = itemCheckImage;
|
||||
itemToggle.isOn = true;
|
||||
Toggle itemToggle = itemObj.AddComponent<Toggle>();
|
||||
itemToggle.targetGraphic = itemBgImage;
|
||||
itemToggle.isOn = true;
|
||||
var colors = itemToggle.colors;
|
||||
colors.normalColor = new Color(0.15f, 0.15f, 0.15f, 1.0f);
|
||||
colors.highlightedColor = new Color(0.25f, 0.25f, 0.25f, 1.0f);
|
||||
itemToggle.colors = colors;
|
||||
|
||||
#if CPP
|
||||
itemToggle.onValueChanged.AddListener(new Action<bool>((bool val) => { itemToggle.OnDeselect(null); }));
|
||||
#else
|
||||
itemToggle.onValueChanged.AddListener((bool val) => { itemToggle.OnDeselect(null); });
|
||||
#endif
|
||||
Image templateImage = templateObj.AddComponent<Image>();
|
||||
templateImage.sprite = UIResources.standard;
|
||||
templateImage.type = Image.Type.Sliced;
|
||||
templateImage.color = new Color(0.15f, 0.15f, 0.15f, 1.0f);
|
||||
|
||||
ScrollRect scrollRect = templateObj.AddComponent<ScrollRect>();
|
||||
scrollRect.content = contentObj.GetComponent<RectTransform>();
|
||||
@ -526,37 +541,29 @@ namespace ExplorerBeta.UI
|
||||
viewportObj.AddComponent<Mask>().showMaskGraphic = false;
|
||||
|
||||
Image viewportImage = viewportObj.AddComponent<Image>();
|
||||
viewportImage.sprite = UIResources.mask;
|
||||
viewportImage.type = Image.Type.Sliced;
|
||||
|
||||
Text labelText = labelObj.AddComponent<Text>();
|
||||
SetDefaultTextValues(labelText);
|
||||
labelText.alignment = TextAnchor.MiddleLeft;
|
||||
|
||||
arrowObj.AddComponent<Image>().sprite = UIResources.dropdown;
|
||||
Image dropdownImage = dropdownObj.AddComponent<Image>();
|
||||
dropdownImage.sprite = UIResources.standard;
|
||||
dropdownImage.color = s_DefaultSelectableColor;
|
||||
dropdownImage.color = new Color(0.2f, 0.2f, 0.2f, 1);
|
||||
dropdownImage.type = Image.Type.Sliced;
|
||||
|
||||
Dropdown dropdown = dropdownObj.AddComponent<Dropdown>();
|
||||
dropdown = dropdownObj.AddComponent<Dropdown>();
|
||||
dropdown.targetGraphic = dropdownImage;
|
||||
SetDefaultColorTransitionValues(dropdown);
|
||||
dropdown.template = templateObj.GetComponent<RectTransform>();
|
||||
dropdown.captionText = labelText;
|
||||
dropdown.itemText = itemLabelText;
|
||||
itemLabelText.text = "Option A";
|
||||
itemLabelText.text = "1";
|
||||
dropdown.options.Add(new Dropdown.OptionData
|
||||
{
|
||||
text = "Option A"
|
||||
text = "2"
|
||||
});
|
||||
dropdown.options.Add(new Dropdown.OptionData
|
||||
{
|
||||
text = "Option B"
|
||||
});
|
||||
dropdown.options.Add(new Dropdown.OptionData
|
||||
{
|
||||
text = "Option C"
|
||||
text = "3"
|
||||
});
|
||||
|
||||
dropdown.RefreshShownValue();
|
||||
@ -567,12 +574,6 @@ namespace ExplorerBeta.UI
|
||||
labelRect.offsetMin = new Vector2(10f, 6f);
|
||||
labelRect.offsetMax = new Vector2(-25f, -7f);
|
||||
|
||||
RectTransform arrowRect = arrowObj.GetComponent<RectTransform>();
|
||||
arrowRect.anchorMin = new Vector2(1f, 0.5f);
|
||||
arrowRect.anchorMax = new Vector2(1f, 0.5f);
|
||||
arrowRect.sizeDelta = new Vector2(20f, 20f);
|
||||
arrowRect.anchoredPosition = new Vector2(-15f, 0f);
|
||||
|
||||
RectTransform templateRect = templateObj.GetComponent<RectTransform>();
|
||||
templateRect.anchorMin = new Vector2(0f, 0f);
|
||||
templateRect.anchorMax = new Vector2(1f, 0f);
|
||||
@ -603,12 +604,6 @@ namespace ExplorerBeta.UI
|
||||
itemBgRect.anchorMax = Vector2.one;
|
||||
itemBgRect.sizeDelta = Vector2.zero;
|
||||
|
||||
RectTransform itemCheckRect = itemCheckObj.GetComponent<RectTransform>();
|
||||
itemCheckRect.anchorMin = new Vector2(0f, 0.5f);
|
||||
itemCheckRect.anchorMax = new Vector2(0f, 0.5f);
|
||||
itemCheckRect.sizeDelta = new Vector2(20f, 20f);
|
||||
itemCheckRect.anchoredPosition = new Vector2(10f, 0f);
|
||||
|
||||
RectTransform itemLabelRect = itemLabelObj.GetComponent<RectTransform>();
|
||||
itemLabelRect.anchorMin = Vector2.zero;
|
||||
itemLabelRect.anchorMax = Vector2.one;
|
||||
@ -698,7 +693,7 @@ namespace ExplorerBeta.UI
|
||||
scrollImage.color = (color == default) ? new Color(0.3f, 0.3f, 0.3f, 1f) : color;
|
||||
|
||||
Image viewportImage = viewportObj.AddComponent<Image>();
|
||||
viewportImage.sprite = UIResources.mask;
|
||||
//viewportImage.sprite = Theme.mask;
|
||||
viewportImage.type = Image.Type.Sliced;
|
||||
viewportImage.color = new Color(1, 1, 1, 1);
|
||||
|
||||
|
@ -19,10 +19,6 @@ namespace ExplorerBeta.UI
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
var res = UIFactory.UIResources = new UIFactory.Resources();
|
||||
var bg = CreateSprite(MakeSolidTexture(new Color(0.16f, 0.16f, 0.16f), 1, 1));
|
||||
res.background = bg;
|
||||
|
||||
// Create core UI Canvas and Event System handler
|
||||
CreateRootCanvas();
|
||||
|
||||
@ -82,6 +78,7 @@ namespace ExplorerBeta.UI
|
||||
}
|
||||
|
||||
// Fix for games which override the InputModule pointer events (eg, VRChat)
|
||||
#if CPP
|
||||
if (InputModule.m_InputPointerEvent != null)
|
||||
{
|
||||
var evt = InputModule.m_InputPointerEvent;
|
||||
@ -90,6 +87,7 @@ namespace ExplorerBeta.UI
|
||||
evt.eligibleForClick = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (PanelDragger.Instance != null)
|
||||
|
@ -16,13 +16,18 @@ namespace ExplorerBeta.Unstrip.Scenes
|
||||
|
||||
internal delegate void d_GetRootGameObjects(int handle, IntPtr list);
|
||||
|
||||
public static GameObject[] GetRootGameObjects(Scene scene)
|
||||
public static GameObject[] GetRootGameObjects(Scene scene) => GetRootGameObjects(scene.handle);
|
||||
|
||||
public static GameObject[] GetRootGameObjects(int handle)
|
||||
{
|
||||
var list = new Il2CppSystem.Collections.Generic.List<GameObject>(GetRootCount(scene));
|
||||
if (handle == -1)
|
||||
return new GameObject[0];
|
||||
|
||||
var list = new Il2CppSystem.Collections.Generic.List<GameObject>(GetRootCount(handle));
|
||||
|
||||
var iCall = ICallHelper.GetICall<d_GetRootGameObjects>("UnityEngine.SceneManagement.Scene::GetRootGameObjectsInternal");
|
||||
|
||||
iCall.Invoke(scene.handle, list.Pointer);
|
||||
iCall.Invoke(handle, list.Pointer);
|
||||
|
||||
return list.ToArray();
|
||||
}
|
||||
@ -31,10 +36,12 @@ namespace ExplorerBeta.Unstrip.Scenes
|
||||
|
||||
internal delegate int GetRootCountInternal_delegate(int handle);
|
||||
|
||||
public static int GetRootCount(Scene scene)
|
||||
public static int GetRootCount(Scene scene) => GetRootCount(scene.handle);
|
||||
|
||||
public static int GetRootCount(int handle)
|
||||
{
|
||||
var iCall = ICallHelper.GetICall<GetRootCountInternal_delegate>("UnityEngine.SceneManagement.Scene::GetRootCountInternal");
|
||||
return iCall.Invoke(scene.handle);
|
||||
return iCall.Invoke(handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user