Make InputFieldRef helper, InteractiveString and IOUtility

This commit is contained in:
Sinai
2021-05-07 17:06:56 +10:00
parent 4931117b1e
commit d8f532d913
20 changed files with 405 additions and 206 deletions

View File

@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace UnityExplorer
{
public static class IOUtility
{
public static string EnsureValid(string path)
{
path = RemoveInvalidChars(path);
var dir = Path.GetDirectoryName(path);
if (!Directory.Exists(dir))
Directory.CreateDirectory(dir);
return path;
}
public static string RemoveInvalidChars(string path)
{
return string.Concat(path.Split(Path.GetInvalidPathChars()));
}
}
}

View File

@ -66,17 +66,17 @@ namespace UnityExplorer.UI.CacheObject
if (KeyInputWanted)
{
kvpCell.KeyInputField.gameObject.SetActive(true);
kvpCell.KeyInputField.UIRoot.SetActive(true);
kvpCell.KeyInputTypeLabel.gameObject.SetActive(true);
kvpCell.KeyLabel.gameObject.SetActive(false);
kvpCell.KeyInspectButton.Button.gameObject.SetActive(false);
kvpCell.KeyInputField.text = KeyInputText;
kvpCell.KeyInputField.Text = KeyInputText;
kvpCell.KeyInputTypeLabel.text = KeyInputTypeText;
}
else
{
kvpCell.KeyInputField.gameObject.SetActive(false);
kvpCell.KeyInputField.UIRoot.SetActive(false);
kvpCell.KeyInputTypeLabel.gameObject.SetActive(false);
kvpCell.KeyLabel.gameObject.SetActive(true);
kvpCell.KeyInspectButton.Button.gameObject.SetActive(InspectWanted);

View File

@ -18,7 +18,6 @@ namespace UnityExplorer.UI.CacheObject
{
NotEvaluated,
Exception,
//NullValue,
Boolean,
Number,
String,
@ -159,17 +158,25 @@ namespace UnityExplorer.UI.CacheObject
{
if (type == typeof(bool))
return ValueState.Boolean;
else if (type.IsPrimitive || type == typeof(decimal))
return ValueState.Number;
else if (type == typeof(string))
return ValueState.String;
else if (type.IsEnum)
return ValueState.Enum;
// todo Color and ValueStruct
else if (type == typeof(Color) || type == typeof(Color32))
return ValueState.Color;
// else if (InteractiveValueStruct.SupportsType(type))
// return ValueState.ValueStruct;
else if (typeof(IDictionary).IsAssignableFrom(type))
return ValueState.Dictionary;
else if (typeof(IEnumerable).IsAssignableFrom(type))
return ValueState.Collection;
else
@ -313,19 +320,20 @@ namespace UnityExplorer.UI.CacheObject
}
// inputfield for numbers
cell.InputField.gameObject.SetActive(args.inputActive);
cell.InputField.UIRoot.SetActive(args.inputActive);
if (args.inputActive)
{
cell.InputField.text = Value.ToString();
cell.InputField.readOnly = !CanWrite;
cell.InputField.Text = Value.ToString();
cell.InputField.InputField.readOnly = !CanWrite;
}
// apply for bool and numbers
cell.ApplyButton.Button.gameObject.SetActive(args.applyActive);
// Inspect and IValue (subcontent) buttons - only if last value not null.
// Inspect button only if last value not null.
cell.InspectButton.Button.gameObject.SetActive(args.inspectActive && !LastValueWasNull);
// allow IValue for null strings though.
// allow IValue for null strings though
cell.SubContentButton.Button.gameObject.SetActive(args.subContentButtonActive && (!LastValueWasNull || State == ValueState.String));
}
@ -333,12 +341,6 @@ namespace UnityExplorer.UI.CacheObject
public virtual void OnCellApplyClicked()
{
if (CellView == null)
{
ExplorerCore.LogWarning("Trying to apply CacheMember but current cell reference is null!");
return;
}
if (State == ValueState.Boolean)
SetUserValue(this.CellView.Toggle.isOn);
else
@ -351,7 +353,7 @@ namespace UnityExplorer.UI.CacheObject
}
var val = numberParseMethods[type.AssemblyQualifiedName]
.Invoke(null, new object[] { CellView.InputField.text });
.Invoke(null, new object[] { CellView.InputField.Text });
SetUserValue(val);
}

View File

@ -18,7 +18,7 @@ namespace UnityExplorer.UI.CacheObject.Views
public LayoutElement KeyGroupLayout;
public Text KeyLabel;
public ButtonRef KeyInspectButton;
public InputField KeyInputField;
public InputFieldRef KeyInputField;
public Text KeyInputTypeLabel;
public static Color EvenColor = new Color(0.07f, 0.07f, 0.07f);
@ -75,10 +75,10 @@ namespace UnityExplorer.UI.CacheObject.Views
// input field
var keyInputObj = UIFactory.CreateInputField(keyGroup, "KeyInput", "empty", out KeyInputField);
UIFactory.SetLayoutElement(keyInputObj, minHeight: 25, flexibleHeight: 0, flexibleWidth: 0, preferredWidth: 200);
KeyInputField = UIFactory.CreateInputField(keyGroup, "KeyInput", "empty");
UIFactory.SetLayoutElement(KeyInputField.UIRoot, minHeight: 25, flexibleHeight: 0, flexibleWidth: 0, preferredWidth: 200);
//KeyInputField.lineType = InputField.LineType.MultiLineNewline;
KeyInputField.readOnly = true;
KeyInputField.InputField.readOnly = true;
return root;
}

View File

@ -50,7 +50,7 @@ namespace UnityExplorer.UI.CacheObject.Views
public Text ValueLabel;
public Toggle Toggle;
public Text ToggleText;
public InputField InputField;
public InputFieldRef InputField;
public ButtonRef InspectButton;
public ButtonRef SubContentButton;
@ -152,8 +152,8 @@ namespace UnityExplorer.UI.CacheObject.Views
ToggleText.color = SignatureHighlighter.KeywordBlue;
Toggle.onValueChanged.AddListener(ToggleClicked);
var inputObj = UIFactory.CreateInputField(rightHoriGroup, "InputField", "...", out InputField);
UIFactory.SetLayoutElement(inputObj, minWidth: 150, flexibleWidth: 0, minHeight: 25, flexibleHeight: 0);
InputField = UIFactory.CreateInputField(rightHoriGroup, "InputField", "...");
UIFactory.SetLayoutElement(InputField.UIRoot, minWidth: 150, flexibleWidth: 0, minHeight: 25, flexibleHeight: 0);
// Inspect and apply buttons

View File

@ -33,7 +33,7 @@ namespace UnityExplorer.UI.CacheObject.Views
private readonly List<Text> genericArgLabels = new List<Text>();
private readonly List<TypeCompleter> genericAutocompleters = new List<TypeCompleter>();
private readonly List<InputField> inputFieldCache = new List<InputField>();
private readonly List<InputFieldRef> inputFieldCache = new List<InputFieldRef>();
public void OnBorrowedFromPool(CacheMember owner)
{
@ -53,7 +53,7 @@ namespace UnityExplorer.UI.CacheObject.Views
public void OnReturnToPool()
{
foreach (var input in inputFieldCache)
input.text = "";
input.Text = "";
this.Owner = null;
}
@ -223,11 +223,11 @@ namespace UnityExplorer.UI.CacheObject.Views
labelList.Add(label);
label.horizontalOverflow = HorizontalWrapMode.Wrap;
var inputObj = UIFactory.CreateInputField(horiGroup, "InputField", "...", out InputField inputField);
UIFactory.SetLayoutElement(inputObj, minHeight: 25, flexibleHeight: 50, minWidth: 100, flexibleWidth: 1000);
inputField.lineType = InputField.LineType.MultiLineNewline;
inputObj.AddComponent<ContentSizeFitter>().verticalFit = ContentSizeFitter.FitMode.PreferredSize;
inputField.onValueChanged.AddListener((string val) => { inputArray[index] = val; });
var inputField = UIFactory.CreateInputField(horiGroup, "InputField", "...");
UIFactory.SetLayoutElement(inputField.UIRoot, minHeight: 25, flexibleHeight: 50, minWidth: 100, flexibleWidth: 1000);
inputField.InputField.lineType = InputField.LineType.MultiLineNewline;
inputField.UIRoot.AddComponent<ContentSizeFitter>().verticalFit = ContentSizeFitter.FitMode.PreferredSize;
inputField.OnValueChanged += (string val) => { inputArray[index] = val; };
inputFieldCache.Add(inputField);
if (autocomplete)

View File

@ -0,0 +1,135 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.Core.Config;
using UnityExplorer.UI.CacheObject;
using UnityExplorer.UI.Widgets;
namespace UnityExplorer.UI.IValues
{
public class InteractiveString : InteractiveValue
{
private string RealValue;
public string EditedValue = "";
public InputFieldRef inputField;
public ButtonRef ApplyButton;
public GameObject SaveFileRow;
public InputFieldRef SaveFilePath;
public override void OnBorrowed(CacheObjectBase owner)
{
base.OnBorrowed(owner);
inputField.InputField.readOnly = !owner.CanWrite;
ApplyButton.Button.gameObject.SetActive(owner.CanWrite);
SaveFilePath.Text = Path.Combine(ConfigManager.Default_Output_Path.Value, "untitled.txt");
}
private bool IsStringTooLong(string s)
{
if (s == null)
return false;
return s.Length >= UIManager.MAX_INPUTFIELD_CHARS;
}
public override void SetValue(object value)
{
RealValue = value as string;
SaveFileRow.SetActive(IsStringTooLong(RealValue));
if (value == null)
{
inputField.Text = "";
EditedValue = "";
}
else
{
EditedValue = (string)value;
inputField.Text = EditedValue;
}
}
private void OnApplyClicked()
{
CurrentOwner.SetValueFromIValue(EditedValue);
}
private void OnInputChanged(string input)
{
EditedValue = input;
if (IsStringTooLong(EditedValue))
{
ExplorerCore.LogWarning("InputField length has reached maximum character count!");
}
}
private void OnSaveFileClicked()
{
if (RealValue == null)
return;
if (string.IsNullOrEmpty(SaveFilePath.Text))
{
ExplorerCore.LogWarning("Cannot save an empty file path!");
return;
}
var path = IOUtility.EnsureValid(SaveFilePath.Text);
if (File.Exists(path))
File.Delete(path);
File.WriteAllText(path, RealValue);
}
public override GameObject CreateContent(GameObject parent)
{
UIRoot = UIFactory.CreateVerticalGroup(parent, "InteractiveString", false, false, true, true, 3, new Vector4(4, 4, 4, 4),
new Color(0.06f, 0.06f, 0.06f));
// Save to file helper
SaveFileRow = UIFactory.CreateUIObject("SaveFileRow", UIRoot);
UIFactory.SetLayoutElement(SaveFileRow, flexibleWidth: 9999);
UIFactory.SetLayoutGroup<VerticalLayoutGroup>(SaveFileRow, false, true, true, true, 3);
UIFactory.CreateLabel(SaveFileRow, "Info", "<color=red>String is too long! Save to file if you want to see the full string.</color>",
TextAnchor.MiddleLeft);
var horizRow = UIFactory.CreateUIObject("Horiz", SaveFileRow);
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(horizRow, false, false, true, true, 4);
var saveButton = UIFactory.CreateButton(horizRow, "SaveButton", "Save file");
UIFactory.SetLayoutElement(saveButton.Button.gameObject, minHeight: 25, minWidth: 100, flexibleWidth: 0);
saveButton.OnClick += OnSaveFileClicked;
SaveFilePath = UIFactory.CreateInputField(horizRow, "SaveInput", "...");
UIFactory.SetLayoutElement(SaveFilePath.UIRoot, minHeight: 25, flexibleWidth: 9999);
// Main Input / apply
ApplyButton = UIFactory.CreateButton(UIRoot, "ApplyButton", "Apply", new Color(0.2f, 0.27f, 0.2f));
UIFactory.SetLayoutElement(ApplyButton.Button.gameObject, minHeight: 25, minWidth: 100, flexibleWidth: 0);
ApplyButton.OnClick += OnApplyClicked;
inputField = UIFactory.CreateInputField(UIRoot, "InputField", "empty");
inputField.UIRoot.AddComponent<ContentSizeFitter>().verticalFit = ContentSizeFitter.FitMode.PreferredSize;
UIFactory.SetLayoutElement(inputField.UIRoot, minHeight: 25, flexibleHeight: 500, flexibleWidth: 9999);
inputField.InputField.lineType = InputField.LineType.MultiLineNewline;
inputField.OnValueChanged += OnInputChanged;
return UIRoot;
}
}
}

View File

@ -9,10 +9,29 @@ using UnityExplorer.UI.ObjectPool;
namespace UnityExplorer.UI.IValues
{
public class InteractiveValue : IPooledObject
public abstract class InteractiveValue : IPooledObject
{
public GameObject UIRoot { get; set; }
public static Type GetIValueTypeForState(ValueState state)
{
switch (state)
{
case ValueState.String:
return typeof(InteractiveString);
//case ValueState.Enum:
// return typeof(InteractiveEnum);
case ValueState.Collection:
return typeof(InteractiveList);
case ValueState.Dictionary:
return typeof(InteractiveDictionary);
//case ValueState.ValueStruct:
// return typeof(InteractiveValueStruct);
//case ValueState.Color:
// return typeof(InteractiveColor);
default: return typeof(InteractiveValue);
}
}
public GameObject UIRoot { get; set; }
public float DefaultHeight => -1f;
public virtual bool CanWrite => this.CurrentOwner.CanWrite;
@ -20,30 +39,6 @@ namespace UnityExplorer.UI.IValues
public CacheObjectBase CurrentOwner => m_owner;
private CacheObjectBase m_owner;
//public object EditedValue { get; private set; }
public virtual void SetLayout() { }
public static Type GetIValueTypeForState(ValueState state)
{
switch (state)
{
//case ValueState.String:
// return null;
//case ValueState.Enum:
// return null;
case ValueState.Collection:
return typeof(InteractiveList);
case ValueState.Dictionary:
return typeof(InteractiveDictionary);
//case ValueState.ValueStruct:
// return null;
//case ValueState.Color:
// return null;
default: return typeof(InteractiveValue);
}
}
public virtual void OnBorrowed(CacheObjectBase owner)
{
if (this.m_owner != null)
@ -63,26 +58,26 @@ namespace UnityExplorer.UI.IValues
this.m_owner = null;
}
public virtual void SetValue(object value) { }
public abstract void SetValue(object value);
//public virtual void SetValue(object value)
public virtual void SetLayout() { }
public abstract GameObject CreateContent(GameObject parent);
//
//public virtual GameObject CreateContent(GameObject parent)
//{
// this.EditedValue = value;
// UIRoot = UIFactory.CreateUIObject(this.GetType().Name, parent);
// UIRoot.AddComponent<ContentSizeFitter>().verticalFit = ContentSizeFitter.FitMode.PreferredSize;
// UIFactory.SetLayoutGroup<VerticalLayoutGroup>(UIRoot, true, true, true, true, 3, childAlignment: TextAnchor.MiddleLeft);
//
// UIFactory.CreateLabel(UIRoot, "Label", "this is an ivalue", TextAnchor.MiddleLeft);
// UIFactory.CreateInputField(UIRoot, "InputFIeld", "...", out var input);
// UIFactory.SetLayoutElement(input.gameObject, minHeight: 25, flexibleHeight: 500);
// input.lineType = InputField.LineType.MultiLineNewline;
// input.gameObject.AddComponent<ContentSizeFitter>().verticalFit = ContentSizeFitter.FitMode.PreferredSize;
//
// return UIRoot;
//}
public virtual GameObject CreateContent(GameObject parent)
{
UIRoot = UIFactory.CreateUIObject(this.GetType().Name, parent);
UIRoot.AddComponent<ContentSizeFitter>().verticalFit = ContentSizeFitter.FitMode.PreferredSize;
UIFactory.SetLayoutGroup<VerticalLayoutGroup>(UIRoot, true, true, true, true, 3, childAlignment: TextAnchor.MiddleLeft);
UIFactory.CreateLabel(UIRoot, "Label", "this is an ivalue", TextAnchor.MiddleLeft);
UIFactory.CreateInputField(UIRoot, "InputFIeld", "...", out var input);
UIFactory.SetLayoutElement(input.gameObject, minHeight: 25, flexibleHeight: 500);
input.lineType = InputField.LineType.MultiLineNewline;
input.gameObject.AddComponent<ContentSizeFitter>().verticalFit = ContentSizeFitter.FitMode.PreferredSize;
return UIRoot;
}
}
}

View File

@ -52,15 +52,15 @@ namespace UnityExplorer.UI.Inspectors
private bool TextureViewerWanted;
private GameObject unityObjectRow;
private ButtonRef gameObjectButton;
private InputField nameInput;
private InputField instanceIdInput;
private InputFieldRef nameInput;
private InputFieldRef instanceIdInput;
private ButtonRef textureButton;
private GameObject textureViewer;
private readonly Color disabledButtonColor = new Color(0.24f, 0.24f, 0.24f);
private readonly Color enabledButtonColor = new Color(0.2f, 0.27f, 0.2f);
private readonly Dictionary<BindingFlags, ButtonRef> scopeFilterButtons = new Dictionary<BindingFlags, ButtonRef>();
private InputField filterInputField;
private InputFieldRef filterInputField;
//private LayoutElement memberTitleLayout;
@ -143,7 +143,7 @@ namespace UnityExplorer.UI.Inspectors
// Get cache members, and set filter to default
this.members = CacheMember.GetCacheMembers(Target, TargetType, this);
this.filterInputField.text = "";
this.filterInputField.Text = "";
SetFilter("", StaticOnly ? BindingFlags.Static : BindingFlags.Instance);
refreshWanted = true;
}
@ -345,9 +345,10 @@ namespace UnityExplorer.UI.Inspectors
var nameLabel = UIFactory.CreateLabel(filterRow, "NameFilterLabel", "Filter names:", TextAnchor.MiddleLeft, Color.grey);
UIFactory.SetLayoutElement(nameLabel.gameObject, minHeight: 25, minWidth: 90, flexibleWidth: 0);
var nameFilterObj = UIFactory.CreateInputField(filterRow, "NameFilterInput", "...", out filterInputField);
UIFactory.SetLayoutElement(nameFilterObj, minHeight: 25, flexibleWidth: 300);
filterInputField.onValueChanged.AddListener((string val) => { SetFilter(val); });
filterInputField = UIFactory.CreateInputField(filterRow, "NameFilterInput", "...");
UIFactory.SetLayoutElement(filterInputField.UIRoot, minHeight: 25, flexibleWidth: 300);
filterInputField.OnValueChanged += (string val) => { SetFilter(val); };
var spacer = UIFactory.CreateUIObject("Spacer", filterRow);
UIFactory.SetLayoutElement(spacer, minWidth: 25);
@ -407,8 +408,8 @@ namespace UnityExplorer.UI.Inspectors
ObjectRef = (UnityEngine.Object)Target.TryCast(typeof(UnityEngine.Object));
unityObjectRow.SetActive(true);
nameInput.text = ObjectRef.name;
instanceIdInput.text = ObjectRef.GetInstanceID().ToString();
nameInput.Text = ObjectRef.name;
instanceIdInput.Text = ObjectRef.GetInstanceID().ToString();
if (typeof(Component).IsAssignableFrom(TargetType))
{
@ -483,16 +484,16 @@ namespace UnityExplorer.UI.Inspectors
var nameLabel = UIFactory.CreateLabel(unityObjectRow, "NameLabel", "Name:", TextAnchor.MiddleLeft, Color.grey);
UIFactory.SetLayoutElement(nameLabel.gameObject, minHeight: 25, minWidth: 45, flexibleWidth: 0);
var nameInputObj = UIFactory.CreateInputField(unityObjectRow, "NameInput", "untitled", out nameInput);
UIFactory.SetLayoutElement(nameInputObj, minHeight: 25, minWidth: 100, flexibleWidth: 1000);
nameInput.readOnly = true;
nameInput = UIFactory.CreateInputField(unityObjectRow, "NameInput", "untitled");
UIFactory.SetLayoutElement(nameInput.UIRoot, minHeight: 25, minWidth: 100, flexibleWidth: 1000);
nameInput.InputField.readOnly = true;
var instanceLabel = UIFactory.CreateLabel(unityObjectRow, "InstanceLabel", "Instance ID:", TextAnchor.MiddleRight, Color.grey);
UIFactory.SetLayoutElement(instanceLabel.gameObject, minHeight: 25, minWidth: 100, flexibleWidth: 0);
var instanceInputObj = UIFactory.CreateInputField(unityObjectRow, "InstanceIDInput", "ERROR", out instanceIdInput);
UIFactory.SetLayoutElement(instanceInputObj, minHeight: 25, minWidth: 100, flexibleWidth: 0);
instanceIdInput.readOnly = true;
instanceIdInput = UIFactory.CreateInputField(unityObjectRow, "InstanceIDInput", "ERROR");
UIFactory.SetLayoutElement(instanceIdInput.UIRoot, minHeight: 25, minWidth: 100, flexibleWidth: 0);
instanceIdInput.InputField.readOnly = true;
unityObjectRow.SetActive(false);
@ -501,7 +502,7 @@ namespace UnityExplorer.UI.Inspectors
// Texture viewer helper
private InputField textureSavePathInput;
private InputFieldRef textureSavePathInput;
private Image textureImage;
private LayoutElement textureImageLayout;
@ -529,8 +530,8 @@ namespace UnityExplorer.UI.Inspectors
UIFactory.SetLayoutElement(saveBtn.Button.gameObject, minHeight: 25, minWidth: 100, flexibleWidth: 0);
saveBtn.OnClick += OnSaveTextureClicked;
var inputObj = UIFactory.CreateInputField(saveRowObj, "SaveInput", "...", out textureSavePathInput);
UIFactory.SetLayoutElement(inputObj, minHeight: 25, minWidth: 100, flexibleWidth: 9999);
textureSavePathInput = UIFactory.CreateInputField(saveRowObj, "SaveInput", "...");
UIFactory.SetLayoutElement(textureSavePathInput.UIRoot, minHeight: 25, minWidth: 100, flexibleWidth: 9999);
// Actual texture viewer
@ -553,7 +554,7 @@ namespace UnityExplorer.UI.Inspectors
if (string.IsNullOrEmpty(name))
name = "untitled";
textureSavePathInput.text = Path.Combine(ConfigManager.Default_Output_Path.Value, $"{name}.png");
textureSavePathInput.Text = Path.Combine(ConfigManager.Default_Output_Path.Value, $"{name}.png");
var sprite = TextureUtilProvider.Instance.CreateSprite(TextureRef);
textureImage.sprite = sprite;
@ -570,22 +571,20 @@ namespace UnityExplorer.UI.Inspectors
return;
}
if (string.IsNullOrEmpty(textureSavePathInput.text))
if (string.IsNullOrEmpty(textureSavePathInput.Text))
{
ExplorerCore.LogWarning("Save path cannot be empty!");
return;
}
var path = textureSavePathInput.text;
var path = textureSavePathInput.Text;
if (!path.EndsWith(".png", StringComparison.InvariantCultureIgnoreCase))
{
ExplorerCore.LogWarning("Desired save path must end with '.png'!");
return;
}
var dir = Path.GetDirectoryName(path);
if (!Directory.Exists(dir))
Directory.CreateDirectory(dir);
path = IOUtility.EnsureValid(path);
if (File.Exists(path))
File.Delete(path);

View File

@ -3,8 +3,9 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine.UI;
using UnityExplorer.UI.Models;
namespace UnityExplorer.UI.Widgets
namespace UnityExplorer.UI
{
// A simple helper class to handle a button's OnClick more effectively.

View File

@ -0,0 +1,59 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.UI.Models;
namespace UnityExplorer.UI
{
public class InputFieldRef : UIBehaviourModel
{
public InputFieldRef(InputField InputField)
{
this.InputField = InputField;
Rect = InputField.GetComponent<RectTransform>();
PlaceholderText = InputField.placeholder.TryCast<Text>();
InputField.onValueChanged.AddListener(OnInputChanged);
}
public event Action<string> OnValueChanged;
public InputField InputField;
public Text PlaceholderText;
private readonly RectTransform Rect;
public string Text
{
get => InputField.text;
set => InputField.text = value;
}
private bool updatedWanted;
private void OnInputChanged(string value)
{
updatedWanted = true;
}
public override void Update()
{
if (updatedWanted)
{
LayoutRebuilder.ForceRebuildLayoutImmediate(Rect);
OnValueChanged?.Invoke(InputField.text);
updatedWanted = false;
}
}
public override GameObject UIRoot => InputField.gameObject;
public override void ConstructUI(GameObject parent)
{
throw new NotImplementedException();
}
}
}

View File

@ -43,7 +43,7 @@ namespace UnityExplorer.UI.Panels
private GameObject sceneFilterRow;
private GameObject childFilterRow;
private GameObject unityObjectClassRow;
private InputField nameInputField;
private InputFieldRef nameInputField;
private Text resultsLabel;
@ -54,16 +54,16 @@ namespace UnityExplorer.UI.Panels
cachedCellTexts.Clear();
if (m_context == SearchContext.Singleton)
currentResults = SearchProvider.SingletonSearch(nameInputField.text);
currentResults = SearchProvider.SingletonSearch(nameInputField.Text);
else if (m_context == SearchContext.StaticClass)
currentResults = SearchProvider.StaticClassSearch(nameInputField.text);
currentResults = SearchProvider.StaticClassSearch(nameInputField.Text);
else
{
string compType = "";
if (m_context == SearchContext.UnityObject)
compType = this.desiredTypeInput;
currentResults = SearchProvider.UnityObjectSearch(nameInputField.text, compType, m_context, m_childFilter, m_sceneFilter);
currentResults = SearchProvider.UnityObjectSearch(nameInputField.Text, compType, m_context, m_childFilter, m_sceneFilter);
}
dataHandler.RefreshData();
@ -180,11 +180,11 @@ namespace UnityExplorer.UI.Panels
var unityClassLbl = UIFactory.CreateLabel(unityObjectClassRow, "UnityClassLabel", "Custom Type:", TextAnchor.MiddleLeft);
UIFactory.SetLayoutElement(unityClassLbl.gameObject, minWidth: 110, flexibleWidth: 0);
var classInputObj = UIFactory.CreateInputField(unityObjectClassRow, "ClassInput", "...", out var classInputField);
UIFactory.SetLayoutElement(classInputObj, minHeight: 25, flexibleHeight: 0, flexibleWidth: 9999);
var classInputField = UIFactory.CreateInputField(unityObjectClassRow, "ClassInput", "...");
UIFactory.SetLayoutElement(classInputField.UIRoot, minHeight: 25, flexibleHeight: 0, flexibleWidth: 9999);
typeAutocompleter = new TypeCompleter(typeof(UnityEngine.Object), classInputField);
classInputField.onValueChanged.AddListener(OnTypeInputChanged);
classInputField.OnValueChanged += OnTypeInputChanged;
//unityObjectClassRow.SetActive(false);
@ -226,8 +226,8 @@ namespace UnityExplorer.UI.Panels
var nameLbl = UIFactory.CreateLabel(nameRow, "NameFilterLabel", "Name contains:", TextAnchor.MiddleLeft);
UIFactory.SetLayoutElement(nameLbl.gameObject, minWidth: 110, flexibleWidth: 0);
var nameInputObj = UIFactory.CreateInputField(nameRow, "NameFilterInput", "...", out this.nameInputField);
UIFactory.SetLayoutElement(nameInputObj, minHeight: 25, flexibleHeight: 0, flexibleWidth: 9999);
nameInputField = UIFactory.CreateInputField(nameRow, "NameFilterInput", "...");
UIFactory.SetLayoutElement(nameInputField.UIRoot, minHeight: 25, flexibleHeight: 0, flexibleWidth: 9999);
// Search button

View File

@ -173,11 +173,12 @@ namespace UnityExplorer.UI.Panels
UIFactory.SetLayoutElement(filterRow, minHeight: 25, flexibleHeight: 0);
//Filter input field
var inputFieldObj = UIFactory.CreateInputField(filterRow, "FilterInput", "Search...", out InputField inputField, 13);
inputField.targetGraphic.color = new Color(0.2f, 0.2f, 0.2f);
RuntimeProvider.Instance.SetColorBlock(inputField, new Color(0.4f, 0.4f, 0.4f), new Color(0.2f, 0.2f, 0.2f), new Color(0.08f, 0.08f, 0.08f));
UIFactory.SetLayoutElement(inputFieldObj, minHeight: 25);
inputField.onValueChanged.AddListener(OnFilterInput);
var inputField = UIFactory.CreateInputField(filterRow, "FilterInput", "Search...");
inputField.InputField.targetGraphic.color = new Color(0.2f, 0.2f, 0.2f);
RuntimeProvider.Instance.SetColorBlock(inputField.InputField, new Color(0.4f, 0.4f, 0.4f), new Color(0.2f, 0.2f, 0.2f),
new Color(0.08f, 0.08f, 0.08f));
UIFactory.SetLayoutElement(inputField.UIRoot, minHeight: 25);
inputField.OnValueChanged += OnFilterInput;
// refresh row

View File

@ -20,12 +20,12 @@ namespace UnityExplorer.UI.Panels
public static CSConsolePanel Instance { get; private set; }
public InputField InputField { get; private set; }
public InputFieldRef InputField { get; private set; }
public Text InputText { get; private set; }
public Text HighlightText { get; private set; }
public Action<string> OnInputChanged;
private float m_timeOfLastInputInvoke;
//private float m_timeOfLastInputInvoke;
public Action OnResetClicked;
public Action OnCompileClicked;
@ -40,15 +40,15 @@ namespace UnityExplorer.UI.Panels
public void UseSuggestion(string suggestion)
{
string input = InputField.text;
string input = InputField.Text;
input = input.Insert(m_lastCaretPosition, suggestion);
InputField.text = input;
InputField.Text = input;
m_desiredCaretFix = m_lastCaretPosition += suggestion.Length;
var color = InputField.selectionColor;
var color = InputField.InputField.selectionColor;
color.a = 0f;
InputField.selectionColor = color;
InputField.InputField.selectionColor = color;
}
private void InvokeOnValueChanged(string value)
@ -56,10 +56,10 @@ namespace UnityExplorer.UI.Panels
if (value.Length == UIManager.MAX_INPUTFIELD_CHARS)
ExplorerCore.LogWarning($"Reached maximum InputField character length! ({UIManager.MAX_INPUTFIELD_CHARS})");
if (m_timeOfLastInputInvoke.OccuredEarlierThanDefault())
return;
m_timeOfLastInputInvoke = Time.realtimeSinceStartup;
//if (m_timeOfLastInputInvoke.OccuredEarlierThanDefault())
// return;
//
//m_timeOfLastInputInvoke = Time.realtimeSinceStartup;
OnInputChanged?.Invoke(value);
}
@ -71,23 +71,23 @@ namespace UnityExplorer.UI.Panels
{
if (!m_fixWaiting)
{
EventSystem.current.SetSelectedGameObject(InputField.gameObject, null);
EventSystem.current.SetSelectedGameObject(InputField.UIRoot, null);
m_fixWaiting = true;
}
else
{
InputField.caretPosition = m_desiredCaretFix;
InputField.selectionFocusPosition = m_desiredCaretFix;
var color = InputField.selectionColor;
InputField.InputField.caretPosition = m_desiredCaretFix;
InputField.InputField.selectionFocusPosition = m_desiredCaretFix;
var color = InputField.InputField.selectionColor;
color.a = m_defaultInputFieldAlpha;
InputField.selectionColor = color;
InputField.InputField.selectionColor = color;
m_fixWaiting = false;
m_desiredCaretFix = -1;
}
}
else if (InputField.caretPosition > 0)
m_lastCaretPosition = InputField.caretPosition;
else if (InputField.InputField.caretPosition > 0)
m_lastCaretPosition = InputField.InputField.caretPosition;
}
// Saving
@ -160,15 +160,15 @@ namespace UnityExplorer.UI.Panels
//var inputObj = UIFactory.CreateSrollInputField(this.content, "ConsoleInput", CSConsoleManager.STARTUP_TEXT,
// out InputFieldScroller consoleScroll, fontSize);
var inputObj = UIFactory.CreateSrollInputField(this.content, "ConsoleInput", CSConsoleManager.STARTUP_TEXT, out var inputField, fontSize);
InputField = inputField.InputField;
m_defaultInputFieldAlpha = InputField.selectionColor.a;
InputField.onValueChanged.AddListener(InvokeOnValueChanged);
var inputObj = UIFactory.CreateSrollInputField(this.content, "ConsoleInput", CSConsoleManager.STARTUP_TEXT, out var inputScroller, fontSize);
InputField = inputScroller.InputField;
m_defaultInputFieldAlpha = InputField.InputField.selectionColor.a;
InputField.OnValueChanged += InvokeOnValueChanged;
var placeHolderText = InputField.placeholder.GetComponent<Text>();
var placeHolderText = InputField.PlaceholderText;
placeHolderText.fontSize = fontSize;
InputText = InputField.textComponent;
InputText = InputField.InputField.textComponent;
InputText.supportRichText = false;
InputText.color = new Color(1, 1, 1, 0.5f);

View File

@ -454,36 +454,10 @@ namespace UnityExplorer.UI
return toggleObj;
}
// Little helper class to force rebuild of an input field's layout on value change.
// This is limited to once per frame per input field, so its not too expensive.
private class InputFieldRefresher
{
private float timeOfLastRebuild;
private readonly RectTransform rectTransform;
public InputFieldRefresher(InputField inputField)
{
if (!inputField)
return;
rectTransform = inputField.GetComponent<RectTransform>();
inputField.onValueChanged.AddListener((string val) =>
{
if (timeOfLastRebuild.OccuredEarlierThanDefault())
{
timeOfLastRebuild = Time.realtimeSinceStartup;
LayoutRebuilder.ForceRebuildLayoutImmediate(rectTransform);
}
});
}
}
/// <summary>
/// Create a standard InputField control.
/// </summary>
public static GameObject CreateInputField(GameObject parent, string name, string placeHolderText, out InputField inputField,
int fontSize = 14, int alignment = 3, int wrap = 0)
public static InputFieldRef CreateInputField(GameObject parent, string name, string placeHolderText)
{
GameObject mainObj = CreateUIObject(name, parent);
//SetLayoutGroup<VerticalLayoutGroup>(mainObj, true, true, true, true);
@ -492,7 +466,7 @@ namespace UnityExplorer.UI
mainImage.type = Image.Type.Sliced;
mainImage.color = new Color(0.04f, 0.04f, 0.04f, 0.75f);
inputField = mainObj.AddComponent<InputField>();
var inputField = mainObj.AddComponent<InputField>();
Navigation nav = inputField.navigation;
nav.mode = Navigation.Mode.None;
inputField.navigation = nav;
@ -521,9 +495,9 @@ namespace UnityExplorer.UI
SetDefaultTextValues(placeholderText);
placeholderText.text = placeHolderText ?? "...";
placeholderText.color = new Color(0.5f, 0.5f, 0.5f, 1.0f);
placeholderText.horizontalOverflow = (HorizontalWrapMode)wrap;
placeholderText.alignment = (TextAnchor)alignment;
placeholderText.fontSize = fontSize;
placeholderText.horizontalOverflow = HorizontalWrapMode.Wrap;
placeholderText.alignment = TextAnchor.MiddleLeft;
placeholderText.fontSize = 14;
RectTransform placeHolderRect = placeHolderObj.GetComponent<RectTransform>();
placeHolderRect.anchorMin = Vector2.zero;
@ -540,9 +514,9 @@ namespace UnityExplorer.UI
SetDefaultTextValues(inputText);
inputText.text = "";
inputText.color = new Color(1f, 1f, 1f, 1f);
inputText.horizontalOverflow = (HorizontalWrapMode)wrap;
inputText.alignment = (TextAnchor)alignment;
inputText.fontSize = fontSize;
inputText.horizontalOverflow = HorizontalWrapMode.Wrap;
inputText.alignment = TextAnchor.MiddleLeft;
inputText.fontSize = 14;
RectTransform inputTextRect = inputTextObj.GetComponent<RectTransform>();
inputTextRect.anchorMin = Vector2.zero;
@ -555,9 +529,7 @@ namespace UnityExplorer.UI
inputField.textComponent = inputText;
inputField.characterLimit = UIManager.MAX_INPUTFIELD_CHARS;
new InputFieldRefresher(inputField);
return mainObj;
return new InputFieldRef(inputField);
}
/// <summary>
@ -919,7 +891,10 @@ namespace UnityExplorer.UI
// Input Field
var content = CreateInputField(viewportObj, name, placeHolderText ?? "...", out InputField inputField, fontSize, 0);
var inputField = CreateInputField(viewportObj, "InputField", placeHolderText);
var content = inputField.UIRoot;
//var content = CreateInputField(viewportObj, name, placeHolderText ?? "...", out InputField inputField, fontSize, 0);
SetLayoutElement(content, flexibleHeight: 9999, flexibleWidth: 9999);
var contentRect = content.GetComponent<RectTransform>();
contentRect.pivot = new Vector2(0, 1);
@ -927,8 +902,8 @@ namespace UnityExplorer.UI
contentRect.anchorMax = new Vector2(1, 1);
contentRect.offsetMin = new Vector2(2, 0);
contentRect.offsetMax = new Vector2(2, 0);
inputField.lineType = InputField.LineType.MultiLineNewline;
inputField.targetGraphic.color = color;
inputField.InputField.lineType = InputField.LineType.MultiLineNewline;
inputField.InputField.targetGraphic.color = color;
// Slider

View File

@ -76,11 +76,11 @@ namespace UnityExplorer.UI.Widgets.AutoComplete
if (suggestions.Any() && CurrentHandler != null)
{
if (!CurrentHandler.InputField.gameObject.activeInHierarchy)
if (!CurrentHandler.InputField.UIRoot.activeInHierarchy)
ReleaseOwnership(CurrentHandler);
else
{
lastCaretPos = CurrentHandler.InputField.caretPosition;
lastCaretPos = CurrentHandler.InputField.InputField.caretPosition;
UpdatePosition();
}
}
@ -142,13 +142,13 @@ namespace UnityExplorer.UI.Widgets.AutoComplete
private void UpdatePosition()
{
if (CurrentHandler == null || !CurrentHandler.InputField.isFocused)
if (CurrentHandler == null || !CurrentHandler.InputField.InputField.isFocused)
return;
Vector3 pos;
var input = CurrentHandler.InputField;
var textGen = input.textComponent.cachedTextGenerator;
var textGen = input.InputField.textComponent.cachedTextGenerator;
int caretPos = 0;
if (CurrentHandler.AnchorToCaretPosition)
{
@ -159,7 +159,7 @@ namespace UnityExplorer.UI.Widgets.AutoComplete
}
pos = textGen.characters[caretPos].cursorPos;
pos = input.transform.TransformPoint(pos);
pos = input.UIRoot.transform.TransformPoint(pos);
uiRoot.transform.position = new Vector3(pos.x + 10, pos.y - 20, 0);

View File

@ -9,7 +9,7 @@ namespace UnityExplorer.UI.Widgets.AutoComplete
{
public interface ISuggestionProvider
{
InputField InputField { get; }
InputFieldRef InputField { get; }
bool AnchorToCaretPosition { get; }
void OnSuggestionClicked(Suggestion suggestion);

View File

@ -21,20 +21,20 @@ namespace UnityExplorer.UI.Widgets.AutoComplete
public Type BaseType { get; set; }
public Type[] GenericConstraints { get; set; }
public InputField InputField { get; }
public InputFieldRef InputField { get; }
public bool AnchorToCaretPosition => false;
private readonly List<Suggestion> suggestions = new List<Suggestion>();
private float timeOfLastCheck;
//private float timeOfLastCheck;
private HashSet<Type> allowedTypes;
public TypeCompleter(Type baseType, InputField inputField)
public TypeCompleter(Type baseType, InputFieldRef inputField)
{
BaseType = baseType;
InputField = inputField;
inputField.onValueChanged.AddListener(OnInputFieldChanged);
inputField.OnValueChanged += OnInputFieldChanged;
if (BaseType != null)
CacheTypes();
@ -47,9 +47,9 @@ namespace UnityExplorer.UI.Widgets.AutoComplete
public void OnSuggestionClicked(Suggestion suggestion)
{
timeOfLastCheck = Time.realtimeSinceStartup;
//timeOfLastCheck = Time.realtimeSinceStartup;
InputField.text = suggestion.UnderlyingValue;
InputField.Text = suggestion.UnderlyingValue;
SuggestionClicked?.Invoke(suggestion);
suggestions.Clear();
@ -58,10 +58,10 @@ namespace UnityExplorer.UI.Widgets.AutoComplete
private void OnInputFieldChanged(string value)
{
if (!timeOfLastCheck.OccuredEarlierThanDefault())
return;
timeOfLastCheck = Time.realtimeSinceStartup;
//if (!timeOfLastCheck.OccuredEarlierThanDefault())
// return;
//
//timeOfLastCheck = Time.realtimeSinceStartup;
value = value ?? "";

View File

@ -19,28 +19,28 @@ namespace UnityExplorer.UI.Utility
{
get
{
if (InputField)
return InputField.gameObject;
if (InputField.UIRoot)
return InputField.UIRoot;
return null;
}
}
internal AutoSliderScrollbar Slider;
internal InputField InputField;
internal InputFieldRef InputField;
internal RectTransform ContentRect;
internal RectTransform ViewportRect;
internal static CanvasScaler RootScaler;
public InputFieldScroller(AutoSliderScrollbar sliderScroller, InputField inputField)
public InputFieldScroller(AutoSliderScrollbar sliderScroller, InputFieldRef inputField)
{
this.Slider = sliderScroller;
this.InputField = inputField;
inputField.onValueChanged.AddListener(OnTextChanged);
inputField.OnValueChanged += OnTextChanged;
ContentRect = inputField.GetComponent<RectTransform>();
ContentRect = inputField.UIRoot.GetComponent<RectTransform>();
ViewportRect = ContentRect.transform.parent.GetComponent<RectTransform>();
if (!RootScaler)
@ -88,22 +88,22 @@ namespace UnityExplorer.UI.Utility
internal void ProcessInputText()
{
var curInputRect = InputField.textComponent.rectTransform.rect;
var curInputRect = InputField.InputField.textComponent.rectTransform.rect;
var scaleFactor = RootScaler.scaleFactor;
// Current text settings
var texGenSettings = InputField.textComponent.GetGenerationSettings(curInputRect.size);
var texGenSettings = InputField.InputField.textComponent.GetGenerationSettings(curInputRect.size);
texGenSettings.generateOutOfBounds = false;
texGenSettings.scaleFactor = scaleFactor;
// Preferred text rect height
var textGen = InputField.textComponent.cachedTextGeneratorForLayout;
var textGen = InputField.InputField.textComponent.cachedTextGeneratorForLayout;
m_desiredContentHeight = textGen.GetPreferredHeight(m_lastText, texGenSettings) + 10;
// jump to bottom
if (InputField.caretPosition == InputField.text.Length
&& InputField.text.Length > 0
&& InputField.text[InputField.text.Length - 1] == '\n')
if (InputField.InputField.caretPosition == InputField.Text.Length
&& InputField.Text.Length > 0
&& InputField.Text[InputField.Text.Length - 1] == '\n')
{
m_wantJumpToBottom = true;
}

View File

@ -256,11 +256,14 @@
<Compile Include="UI\Inspectors\InspectorBase.cs" />
<Compile Include="UI\IValues\InteractiveDictionary.cs" />
<Compile Include="UI\IValues\InteractiveList.cs" />
<Compile Include="UI\IValues\InteractiveString.cs" />
<Compile Include="UI\IValues\InteractiveValue.cs" />
<Compile Include="UI\Inspectors\ReflectionInspector.cs" />
<Compile Include="UI\Models\InputFieldRef.cs" />
<Compile Include="UI\ObjectPool\IPooledObject.cs" />
<Compile Include="UI\ObjectPool\Pool.cs" />
<Compile Include="UI\Panels\CSConsolePanel.cs" />
<Compile Include="Core\Utility\IOUtility.cs" />
<Compile Include="UI\Widgets\AutoComplete\ISuggestionProvider.cs" />
<Compile Include="UI\Widgets\AutoComplete\Suggestion.cs" />
<Compile Include="Core\Config\ConfigElement.cs" />
@ -330,7 +333,7 @@
<Compile Include="Inspectors_OLD\InteractiveValues\InteractiveNumber.cs" />
<Compile Include="Inspectors_OLD\InteractiveValues\InteractiveString.cs" />
<Compile Include="Inspectors_OLD\InteractiveValues\InteractiveValue.cs" />
<Compile Include="UI\Widgets\ButtonRef.cs" />
<Compile Include="UI\Models\ButtonRef.cs" />
<Compile Include="UI\ObjectExplorer\ObjectSearch.cs" />
<Compile Include="UI\ObjectExplorer\SceneExplorer.cs" />
<Compile Include="UI\Widgets\ScrollPool\DataHeightCache.cs" />