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 = $"{b}";
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("" + ValueType.Name + "", 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("Apply", 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($"Binary:", 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);
}
}
}
}