Skip to content

Commit 2eb9d1d

Browse files
committed
Re-implement array editor in the separate popup
Add simple byte array editor
1 parent c6cd04b commit 2eb9d1d

File tree

5 files changed

+152
-11
lines changed

5 files changed

+152
-11
lines changed

UInspectorPlus/Helpers.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,19 @@ internal static bool IsInterface(Type type, Type interfaceType) {
487487
return true;
488488
return false;
489489
}
490+
491+
internal static Type GetGenericListType(Type targetType) {
492+
if (targetType.IsArray)
493+
return targetType.GetElementType();
494+
bool hasNonGeneric = false;
495+
foreach (Type type in targetType.GetInterfaces()) {
496+
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IList<>))
497+
return type.GetGenericArguments()[0];
498+
if (type == typeof(IList))
499+
hasNonGeneric = true;
500+
}
501+
return hasNonGeneric ? typeof(object) : null;
502+
}
490503

491504
internal static GUIStyle GetGUIStyle(string styleName) {
492505
return GUI.skin.FindStyle(styleName) ?? EditorGUIUtility.GetBuiltinSkin(EditorSkin.Inspector).FindStyle(styleName);

UInspectorPlus/HexEdit.cs

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
using System;
2+
using System.Globalization;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using System.Text;
6+
using UnityEngine;
7+
using UnityEditor;
8+
9+
namespace UInspectorPlus {
10+
internal class HexEdit {
11+
[SerializeField] Vector2 scrollPos;
12+
public byte[] data;
13+
public int columns = 16;
14+
GUIContent temp = new GUIContent();
15+
16+
public float Height {
17+
get {
18+
if (data == null) return 0;
19+
return (data.Length + columns) / columns * (EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing);
20+
}
21+
}
22+
23+
public void DrawGUI(bool hasLabel = false, params GUILayoutOption[] options) {
24+
Draw(EditorGUILayout.GetControlRect(hasLabel, Height, options));
25+
}
26+
27+
public void Draw(Rect viewport) {
28+
float height = EditorGUIUtility.singleLineHeight;
29+
float padHeight = height + EditorGUIUtility.standardVerticalSpacing;
30+
if (data != null) {
31+
temp.text = data.Length.ToString("X8");
32+
Vector2 labelSize = GUI.skin.label.CalcSize(temp);
33+
Rect contentRect = new Rect(0, 0, labelSize.x + (columns * 1.7F + 2) * height, Height);
34+
GUI.Box(viewport, GUIContent.none, GUI.skin.textArea);
35+
scrollPos = GUI.BeginScrollView(viewport, scrollPos, contentRect);
36+
bool changed = GUI.changed;
37+
GUI.changed = false;
38+
for (int start = Mathf.FloorToInt(scrollPos.y / padHeight) * columns,
39+
end = Math.Min(data.Length, start + Mathf.CeilToInt(viewport.height / padHeight) * columns),
40+
col = start; col < end; col++) {
41+
if (col % columns == 0) {
42+
temp.text = col.ToString("X8");
43+
GUI.Label(new Rect(0, col / columns * padHeight, labelSize.x, labelSize.y), temp);
44+
}
45+
string newValue = GUI.TextField(
46+
new Rect(
47+
labelSize.x + (col % columns * 1.2F + 1) * height,
48+
col / columns * padHeight,
49+
height * 1.6F, height
50+
),
51+
data[col].ToString("X2"),
52+
2, GUI.skin.label
53+
);
54+
if (GUI.changed) {
55+
GUI.changed = false;
56+
changed = true;
57+
int val;
58+
if (int.TryParse(newValue, NumberStyles.HexNumber, null, out val))
59+
data[col] = unchecked((byte)val);
60+
}
61+
string newStr = GUI.TextField(
62+
new Rect(
63+
labelSize.x + (columns * 1.2F + col % columns * 0.5F + 2) * height,
64+
col / columns * padHeight,
65+
height * 0.8F, height
66+
),
67+
Byte2String(data[col]),
68+
1, GUI.skin.label
69+
);
70+
if (GUI.changed) {
71+
GUI.changed = false;
72+
changed = true;
73+
data[col] = unchecked((byte)newStr[0]);
74+
}
75+
}
76+
GUI.changed = changed;
77+
GUI.EndScrollView();
78+
}
79+
}
80+
81+
private static string Byte2String(byte b) {
82+
if (b < 32 || b >= 127) return ".";
83+
return ((char)b).ToString();
84+
}
85+
}
86+
}

UInspectorPlus/InspectorDrawer.cs

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
using UnityEngine;
22
using UnityEditor;
3+
using UnityEditorInternal;
34
using System;
5+
using System.Collections;
46
using System.Collections.Generic;
57
using System.Reflection;
68
using System.Linq;
@@ -15,7 +17,10 @@ class InspectorDrawer {
1517
public bool changed;
1618
public string searchText;
1719
public event Action OnRequireRedraw;
18-
Type targetType;
20+
Type targetType, elementType;
21+
HexEdit hexEdit;
22+
List<MethodPropertyDrawer> arrayContentDrawer;
23+
ReorderableList arrayHandler;
1924

2025
public InspectorDrawer(object target, bool shown, bool showProps, bool showPrivateFields, bool showObsolete, bool showMethods) {
2126
this.target = target;
@@ -24,6 +29,7 @@ public InspectorDrawer(object target, bool shown, bool showProps, bool showPriva
2429
if (showPrivateFields)
2530
flag |= BindingFlags.NonPublic;
2631
targetType = target.GetType();
32+
elementType = Helper.GetGenericListType(targetType);
2733
var fields = targetType.GetFields(flag);
2834
var props = !showProps ? null : targetType.GetProperties(flag).Where(prop => prop.GetIndexParameters().Length == 0).ToArray();
2935
isInternalType = !(target is MonoBehaviour) || Attribute.IsDefined(target.GetType(), typeof(ExecuteInEditMode));
@@ -68,7 +74,7 @@ public InspectorDrawer(object target, bool shown, bool showProps, bool showPriva
6874
}
6975

7076
public void Draw(bool drawHeader = true, bool readOnly = false) {
71-
if(target == null) {
77+
if (target == null) {
7278
EditorGUILayout.InspectorTitlebar(false, null as UnityObject);
7379
return;
7480
}
@@ -80,6 +86,44 @@ public void Draw(bool drawHeader = true, bool readOnly = false) {
8086
}
8187
EditorGUI.indentLevel++;
8288
EditorGUILayout.BeginVertical();
89+
if (elementType != null) {
90+
if (targetType == typeof(byte[])) {
91+
if (hexEdit == null)
92+
hexEdit = new HexEdit();
93+
hexEdit.data = target as byte[];
94+
if (hexEdit.data != null)
95+
hexEdit.DrawGUI(false, GUILayout.MinHeight(EditorGUIUtility.singleLineHeight), GUILayout.ExpandHeight(true));
96+
} else {
97+
if (arrayHandler == null) {
98+
if (arrayContentDrawer == null) {
99+
arrayContentDrawer = new List<MethodPropertyDrawer>();
100+
for (int i = 0; i < (target as IList).Count; i++)
101+
ListAddItem();
102+
}
103+
arrayHandler = new ReorderableList(target as IList, elementType);
104+
arrayHandler.headerHeight = EditorGUIUtility.singleLineHeight;
105+
arrayHandler.elementHeight = EditorGUIUtility.singleLineHeight + 2;
106+
arrayHandler.drawElementCallback = (r, i, c, d) => {
107+
arrayContentDrawer[i].Value = (target as IList)[i];
108+
arrayContentDrawer[i].Draw(false, Helper.ScaleRect(r, offsetHeight: -2));
109+
if (arrayContentDrawer[i].Changed)
110+
(target as IList)[i] = arrayContentDrawer[i].Value;
111+
};
112+
arrayHandler.drawHeaderCallback = r => GUI.Label(r, target.ToString(), EditorStyles.boldLabel);
113+
arrayHandler.onCanAddCallback = l => target != null && !(target as IList).IsFixedSize;
114+
arrayHandler.onCanRemoveCallback = arrayHandler.onCanAddCallback.Invoke;
115+
arrayHandler.onAddCallback = l => {
116+
ReorderableList.defaultBehaviours.DoAddButton(l);
117+
ListAddItem();
118+
};
119+
arrayHandler.onRemoveCallback = l => {
120+
ReorderableList.defaultBehaviours.DoRemoveButton(l);
121+
arrayContentDrawer.RemoveAt(0);
122+
};
123+
}
124+
arrayHandler.DoLayoutList();
125+
}
126+
}
83127
foreach (var item in drawer) {
84128
var methodDrawer = item as ComponentMethodDrawer;
85129
var fieldDrawer = item as MethodPropertyDrawer;
@@ -124,6 +168,12 @@ public void Draw(bool drawHeader = true, bool readOnly = false) {
124168
EditorGUI.indentLevel--;
125169
}
126170

171+
void ListAddItem(object value = null) {
172+
var drawer = new MethodPropertyDrawer(elementType, "", value, true, false);
173+
drawer.OnRequireRedraw += RequireRedraw;
174+
arrayContentDrawer.Add(drawer);
175+
}
176+
127177
public void UpdateValues(bool updateProps) {
128178
if(target == null) return;
129179
foreach (var drawerItem in drawer) {

UInspectorPlus/MethodPropertyDrawer.cs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,6 @@ public bool ReferenceMode {
114114
InitFieldTypes();
115115
} else {
116116
rawValue = GetReferencedValue();
117-
// SetArray();
118117
}
119118
selectedFieldIndex = -1;
120119
selectedField = null;
@@ -157,13 +156,6 @@ public object Value {
157156
get {
158157
if (referenceMode) {
159158
rawValue = GetReferencedValue();
160-
/*
161-
} else if (currentType == PropertyType.Array) {
162-
var array = Array.CreateInstance(requiredType.GetElementType(), arrayContentDrawer.Count);
163-
for (int i = 0; i < arrayContentDrawer.Count; i++)
164-
array.SetValue(arrayContentDrawer[i].Value, i);
165-
rawValue = array;
166-
*/
167159
}
168160
var convertedValue = rawValue;
169161
if (rawValue != null && requiredType != typeof(object) && requiredType.IsInstanceOfType(rawValue)) {
@@ -179,7 +171,6 @@ public object Value {
179171
set {
180172
rawValue = value;
181173
changed = false;
182-
// SetArray();
183174
}
184175
}
185176

UInspectorPlus/UInspectorPlus.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
<ItemGroup>
4747
<Compile Include="ComponentMethodDrawer.cs" />
4848
<Compile Include="Helpers.cs" />
49+
<Compile Include="HexEdit.cs" />
4950
<Compile Include="InspectorChildWindow.cs" />
5051
<Compile Include="InspectorDrawer.cs" />
5152
<Compile Include="InspectorPlus.cs" />

0 commit comments

Comments
 (0)