mirror of
https://github.com/sinai-dev/UnityExplorer.git
synced 2025-06-17 06:28:42 +08:00
263 lines
8.2 KiB
C#
263 lines
8.2 KiB
C#
![]() |
using System;
|
|||
|
using System.Collections;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.Reflection;
|
|||
|
using UnityEngine;
|
|||
|
#if CPP
|
|||
|
using UnhollowerRuntimeLib;
|
|||
|
#endif
|
|||
|
using Explorer.UI.Shared;
|
|||
|
using Explorer.CacheObject;
|
|||
|
using Explorer.Config;
|
|||
|
|
|||
|
namespace Explorer.UI
|
|||
|
{
|
|||
|
public class InteractivePrimitive : InteractiveValue
|
|||
|
{
|
|||
|
private string m_valueToString;
|
|||
|
private bool m_isBool;
|
|||
|
private bool m_isString;
|
|||
|
|
|||
|
public MethodInfo ParseMethod => m_parseMethod ?? (m_parseMethod = Value.GetType().GetMethod("Parse", new Type[] { typeof(string) }));
|
|||
|
private MethodInfo m_parseMethod;
|
|||
|
|
|||
|
private bool m_canBitwiseOperate;
|
|||
|
private bool m_inBitwiseMode;
|
|||
|
private string m_bitwiseOperatorInput = "0";
|
|||
|
private string m_binaryInput;
|
|||
|
|
|||
|
public override void Init()
|
|||
|
{
|
|||
|
if (ValueType == null)
|
|||
|
{
|
|||
|
ValueType = Value?.GetType();
|
|||
|
|
|||
|
// has to be a string at this point
|
|||
|
if (ValueType == null)
|
|||
|
{
|
|||
|
ValueType = typeof(string);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (ValueType == typeof(string))
|
|||
|
{
|
|||
|
m_isString = true;
|
|||
|
}
|
|||
|
else if (ValueType == typeof(bool))
|
|||
|
{
|
|||
|
m_isBool = true;
|
|||
|
}
|
|||
|
|
|||
|
m_canBitwiseOperate = typeof(int).IsAssignableFrom(ValueType);
|
|||
|
|
|||
|
UpdateValue();
|
|||
|
}
|
|||
|
|
|||
|
public override void UpdateValue()
|
|||
|
{
|
|||
|
base.UpdateValue();
|
|||
|
|
|||
|
RefreshToString();
|
|||
|
}
|
|||
|
|
|||
|
private void RefreshToString()
|
|||
|
{
|
|||
|
m_valueToString = Value?.ToString();
|
|||
|
|
|||
|
if (m_canBitwiseOperate && Value != null)
|
|||
|
{
|
|||
|
var _int = (int)Value;
|
|||
|
m_binaryInput = Convert.ToString(_int, toBase: 2);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public override void DrawValue(Rect window, float width)
|
|||
|
{
|
|||
|
if (m_isBool)
|
|||
|
{
|
|||
|
var b = (bool)Value;
|
|||
|
var label = $"<color={(b ? "lime" : "red")}>{b}</color>";
|
|||
|
|
|||
|
if (OwnerCacheObject.CanWrite)
|
|||
|
{
|
|||
|
Value = GUILayout.Toggle(b, label, new GUILayoutOption[] { GUILayout.Width(60) });
|
|||
|
DrawApplyButton();
|
|||
|
//if (b != (bool)Value)
|
|||
|
//{
|
|||
|
// Value = b;
|
|||
|
// OwnerCacheObject.SetValue();
|
|||
|
//}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
GUILayout.Label(label, new GUILayoutOption[0]);
|
|||
|
}
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
// all other non-bool values use TextField
|
|||
|
|
|||
|
GUIHelper.BeginVertical(new GUILayoutOption[0]);
|
|||
|
|
|||
|
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
|||
|
|
|||
|
GUILayout.Label("<color=#2df7b2><i>" + ValueType.Name + "</i></color>", new GUILayoutOption[] { GUILayout.Width(50) });
|
|||
|
|
|||
|
m_valueToString = GUIHelper.TextArea(m_valueToString, new GUILayoutOption[] { GUIHelper.ExpandWidth(true) });
|
|||
|
|
|||
|
DrawApplyButton();
|
|||
|
|
|||
|
if (ModConfig.Instance.Bitwise_Support && m_canBitwiseOperate)
|
|||
|
{
|
|||
|
m_inBitwiseMode = GUILayout.Toggle(m_inBitwiseMode, "Bitwise?", new GUILayoutOption[0]);
|
|||
|
}
|
|||
|
|
|||
|
GUIHelper.Space(10);
|
|||
|
|
|||
|
GUILayout.EndHorizontal();
|
|||
|
|
|||
|
if (ModConfig.Instance.Bitwise_Support && m_inBitwiseMode)
|
|||
|
{
|
|||
|
DrawBitwise();
|
|||
|
}
|
|||
|
|
|||
|
GUILayout.EndVertical();
|
|||
|
}
|
|||
|
|
|||
|
private void DrawApplyButton()
|
|||
|
{
|
|||
|
if (OwnerCacheObject.CanWrite)
|
|||
|
{
|
|||
|
if (GUILayout.Button("<color=#00FF00>Apply</color>", new GUILayoutOption[] { GUILayout.Width(60) }))
|
|||
|
{
|
|||
|
if (m_isBool)
|
|||
|
{
|
|||
|
OwnerCacheObject.SetValue();
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
SetValueFromInput();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private void DrawBitwise()
|
|||
|
{
|
|||
|
if (OwnerCacheObject.CanWrite)
|
|||
|
{
|
|||
|
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
|||
|
|
|||
|
GUI.skin.label.alignment = TextAnchor.MiddleRight;
|
|||
|
GUILayout.Label("RHS:", new GUILayoutOption[] { GUILayout.Width(35) });
|
|||
|
GUI.skin.label.alignment = TextAnchor.UpperLeft;
|
|||
|
|
|||
|
if (GUILayout.Button("~", new GUILayoutOption[] { GUILayout.Width(25) }))
|
|||
|
{
|
|||
|
if (int.TryParse(m_bitwiseOperatorInput, out int bit))
|
|||
|
{
|
|||
|
Value = ~bit;
|
|||
|
RefreshToString();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (GUILayout.Button("<<", new GUILayoutOption[] { GUILayout.Width(25) }))
|
|||
|
{
|
|||
|
if (int.TryParse(m_bitwiseOperatorInput, out int bit))
|
|||
|
{
|
|||
|
Value = (int)Value << bit;
|
|||
|
RefreshToString();
|
|||
|
}
|
|||
|
}
|
|||
|
if (GUILayout.Button(">>", new GUILayoutOption[] { GUILayout.Width(25) }))
|
|||
|
{
|
|||
|
if (int.TryParse(m_bitwiseOperatorInput, out int bit))
|
|||
|
{
|
|||
|
Value = (int)Value >> bit;
|
|||
|
RefreshToString();
|
|||
|
}
|
|||
|
}
|
|||
|
if (GUILayout.Button("|", new GUILayoutOption[] { GUILayout.Width(25) }))
|
|||
|
{
|
|||
|
if (int.TryParse(m_bitwiseOperatorInput, out int bit))
|
|||
|
{
|
|||
|
Value = (int)Value | bit;
|
|||
|
RefreshToString();
|
|||
|
}
|
|||
|
}
|
|||
|
if (GUILayout.Button("&", new GUILayoutOption[] { GUILayout.Width(25) }))
|
|||
|
{
|
|||
|
if (int.TryParse(m_bitwiseOperatorInput, out int bit))
|
|||
|
{
|
|||
|
Value = (int)Value & bit;
|
|||
|
RefreshToString();
|
|||
|
}
|
|||
|
}
|
|||
|
if (GUILayout.Button("^", new GUILayoutOption[] { GUILayout.Width(25) }))
|
|||
|
{
|
|||
|
if (int.TryParse(m_bitwiseOperatorInput, out int bit))
|
|||
|
{
|
|||
|
Value = (int)Value ^ bit;
|
|||
|
RefreshToString();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
m_bitwiseOperatorInput = GUIHelper.TextField(m_bitwiseOperatorInput, new GUILayoutOption[] { GUILayout.Width(55) });
|
|||
|
|
|||
|
GUILayout.EndHorizontal();
|
|||
|
}
|
|||
|
|
|||
|
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
|
|||
|
GUILayout.Label($"<color=cyan>Binary:</color>", new GUILayoutOption[] { GUILayout.Width(60) });
|
|||
|
m_binaryInput = GUIHelper.TextField(m_binaryInput, new GUILayoutOption[0]);
|
|||
|
if (OwnerCacheObject.CanWrite)
|
|||
|
{
|
|||
|
if (GUILayout.Button("Apply", new GUILayoutOption[0]))
|
|||
|
{
|
|||
|
SetValueFromBinaryInput();
|
|||
|
}
|
|||
|
}
|
|||
|
GUILayout.EndHorizontal();
|
|||
|
}
|
|||
|
|
|||
|
public void SetValueFromInput()
|
|||
|
{
|
|||
|
if (m_isString)
|
|||
|
{
|
|||
|
Value = m_valueToString;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
Value = ParseMethod.Invoke(null, new object[] { m_valueToString });
|
|||
|
}
|
|||
|
catch (Exception e)
|
|||
|
{
|
|||
|
ExplorerCore.Log("Exception parsing value: " + e.GetType() + ", " + e.Message);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
OwnerCacheObject.SetValue();
|
|||
|
RefreshToString();
|
|||
|
}
|
|||
|
|
|||
|
private void SetValueFromBinaryInput()
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
var method = typeof(Convert).GetMethod($"To{ValueType.Name}", new Type[] { typeof(string), typeof(int) });
|
|||
|
Value = method.Invoke(null, new object[] { m_binaryInput, 2 });
|
|||
|
|
|||
|
OwnerCacheObject.SetValue();
|
|||
|
RefreshToString();
|
|||
|
}
|
|||
|
catch (Exception e)
|
|||
|
{
|
|||
|
ExplorerCore.Log("Exception setting value: " + e.GetType() + ", " + e.Message);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|