Skip to content

Commit bf5d2ba

Browse files
authored
Merge pull request #120 from brunomikoski/feature/custom-editor-drawer
Feature/custom editor drawer
2 parents dbd2af9 + 3203206 commit bf5d2ba

6 files changed

Lines changed: 116 additions & 32 deletions

File tree

CHANGELOG.MD

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

77
## [Unreleased]
8+
## [2.0.3]
9+
### Changed
10+
- Collection now uses the appropriated Editor for each CollectionItem when displayed on the Collection
11+
- Fixed expanded state not being saved on the Collection
812

913
## [2.0.2]
1014
### Changed
@@ -424,6 +428,7 @@ public bool IsValidConsumable(Consumable consumable)
424428
### Added
425429
- First initial working version
426430

431+
[2.0.3]: https://github.com/badawe/ScriptableObjectCollection/releases/tag/v2.0.3
427432
[2.0.2]: https://github.com/badawe/ScriptableObjectCollection/releases/tag/v2.0.2
428433
[2.0.1]: https://github.com/badawe/ScriptableObjectCollection/releases/tag/v2.0.1
429434
[2.0.0]: https://github.com/badawe/ScriptableObjectCollection/releases/tag/v2.0.0

Scripts/Editor/Core/CustomEditors/CollectionCustomEditor.cs

Lines changed: 38 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ public sealed class CollectionCustomEditor : Editor
2828
private ReorderableList reorderableList;
2929
private SerializedProperty itemsSerializedProperty;
3030
private int lastCheckedForValidItemsArraySize;
31+
private readonly Dictionary<int, Rect> itemIndexToRect = new();
32+
private float? reorderableListYPosition;
3133

3234
private static bool IsWaitingForNewTypeBeCreated
3335
{
@@ -185,39 +187,50 @@ private void DrawCollectionItemAtIndex(Rect rect, int index, bool isActive, bool
185187
{
186188
rect.y += EditorGUIUtility.standardVerticalSpacing;
187189

188-
SerializedObject collectionItemSerializedObject = new SerializedObject(collectionItemSerializedProperty.objectReferenceValue);
189-
190-
EditorGUI.indentLevel++;
191-
192-
SerializedProperty iterator = collectionItemSerializedObject.GetIterator();
193-
194-
using (EditorGUI.ChangeCheckScope changeCheck = new EditorGUI.ChangeCheckScope())
190+
if (itemIndexToRect.TryGetValue(index, out Rect actualRect) && reorderableListYPosition.HasValue)
195191
{
196-
for (bool enterChildren = true; iterator.NextVisible(enterChildren); enterChildren = false)
197-
{
198-
bool guiEnabled = GUI.enabled;
199-
if (iterator.displayName.Equals("Script"))
200-
GUI.enabled = false;
192+
actualRect.y = rect.y + reorderableListYPosition.Value + reorderableList.headerHeight;
193+
194+
// Have to indent the rect here because otherwise it overlaps with the drag handle
195+
EditorGUI.indentLevel++;
196+
actualRect = EditorGUI.IndentedRect(actualRect);
197+
EditorGUI.indentLevel--;
198+
199+
GUILayout.BeginArea(actualRect);
200+
EditorGUI.indentLevel++;
201201

202-
EditorGUI.PropertyField(rect, iterator, true);
203-
GUI.enabled = guiEnabled;
202+
Editor editor = EditorCache.GetOrCreateEditorForObject(collectionItemSerializedProperty.objectReferenceValue);
203+
editor.OnInspectorGUI();
204204

205-
rect.y += EditorGUI.GetPropertyHeight(iterator, true) +
206-
EditorGUIUtility.standardVerticalSpacing;
207-
}
205+
EditorGUI.indentLevel--;
206+
GUILayout.EndArea();
208207

209-
if (changeCheck.changed)
210-
iterator.serializedObject.ApplyModifiedProperties();
208+
collectionItemSerializedProperty.serializedObject.ApplyModifiedProperties();
209+
rect.y += actualRect.height;
211210
}
211+
else
212+
{
213+
Rect verticalRect = EditorGUILayout.BeginVertical();
214+
215+
Editor editor = EditorCache.GetOrCreateEditorForObject(collectionItemSerializedProperty.objectReferenceValue);
216+
editor.OnInspectorGUI();
212217

213-
EditorGUI.indentLevel--;
218+
EditorGUILayout.EndVertical();
219+
220+
if (Event.current.type == EventType.Repaint)
221+
{
222+
itemIndexToRect[index] = verticalRect;
223+
}
224+
}
214225
}
215226

216227
CheckForContextInputOnItem(collectionItemSerializedProperty, index, originY, rect);
217-
228+
218229
heights[index] = rect.y - originY;
219230
}
220231

232+
233+
221234
private void SetAllExpanded(bool expanded)
222235
{
223236
for (int i = 0; i < reorderableList.count; i++)
@@ -344,6 +357,10 @@ public override void OnInspectorGUI()
344357
DrawSearchField();
345358
DrawSynchronizeButton();
346359
reorderableList.DoLayoutList();
360+
if (Event.current.type == EventType.Repaint)
361+
{
362+
reorderableListYPosition = GUILayoutUtility.GetLastRect().y;
363+
}
347364
DrawBottomMenu();
348365
}
349366
DrawSettings();

Scripts/Editor/Core/PropertyDrawers/SOCItemPropertyDrawer.cs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -103,21 +103,21 @@ private void DrawEditorPreview(ref Rect rect, ScriptableObject scriptableObject)
103103
if (scriptableObject == null)
104104
return;
105105

106-
if (!CollectionUtility.IsFoldoutOpen(scriptableObject, currentObject))
106+
if (!CollectionUtility.IsCollectionItemExpanded((ISOCItem) scriptableObject))
107107
return;
108108

109109
rect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
110110
rect.width -= 10;
111111
rect.y += 10;
112112
float beginPositionY = rect.y;
113113

114-
SerializedObject collectionItemSerializedObject = new SerializedObject(scriptableObject);
114+
SerializedObject collectionItemSerializedObject = new(scriptableObject);
115115

116116
EditorGUI.indentLevel++;
117117
rect = EditorGUI.IndentedRect(rect);
118118
SerializedProperty iterator = collectionItemSerializedObject.GetIterator();
119119

120-
using (EditorGUI.ChangeCheckScope changeCheck = new EditorGUI.ChangeCheckScope())
120+
using (EditorGUI.ChangeCheckScope changeCheck = new())
121121
{
122122
for (bool enterChildren = true; iterator.NextVisible(enterChildren); enterChildren = false)
123123
{
@@ -225,7 +225,7 @@ private void DrawGotoButton(ref Rect popupRect, ScriptableObject collectionItem)
225225
if (GUI.Button(buttonRect, CollectionEditorGUI.ARROW_RIGHT_CHAR))
226226
{
227227
Selection.activeObject = socItem.Collection;
228-
CollectionUtility.SetFoldoutOpen(true, collectionItem, socItem.Collection);
228+
CollectionUtility.SetOnlyCollectionItemExpanded((ISOCItem) collectionItem, socItem.Collection);
229229
}
230230
}
231231

@@ -241,12 +241,14 @@ private void DrawEditFoldoutButton(ref Rect popupRect, ScriptableObject targetIt
241241
buttonRect.x += popupRect.width;
242242

243243
GUIContent guiContent = CollectionEditorGUI.EditGUIContent;
244-
if (CollectionUtility.IsFoldoutOpen(targetItem, currentObject))
244+
245+
if (CollectionUtility.IsCollectionItemExpanded((ISOCItem) targetItem))
245246
guiContent = CollectionEditorGUI.CloseGUIContent;
246247

247248
if (GUI.Button(buttonRect, guiContent))
248249
{
249-
CollectionUtility.SetFoldoutOpen(!CollectionUtility.IsFoldoutOpen(targetItem, currentObject), targetItem, currentObject);
250+
CollectionUtility.SetCollectionItemExpanded(!CollectionUtility.IsCollectionItemExpanded((ISOCItem) targetItem), (ISOCItem) targetItem);
251+
250252
ObjectUtility.SetDirty(targetItem);
251253
}
252254
}

Scripts/Editor/Core/Utility/CopyCollectionItemUtility.cs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,24 @@
1-
using UnityEditor;
1+
using System.Collections.Generic;
2+
using UnityEditor;
23
using UnityEngine;
34

45
namespace BrunoMikoski.ScriptableObjectCollections
56
{
7+
public static class EditorCache
8+
{
9+
private static Dictionary<object, Editor> typeToEditorCache = new();
10+
11+
public static Editor GetOrCreateEditorForObject(Object targetObject)
12+
{
13+
if (typeToEditorCache.TryGetValue(targetObject, out Editor editor))
14+
return editor;
15+
16+
editor = Editor.CreateEditor(targetObject);
17+
typeToEditorCache.Add(targetObject, editor);
18+
return editor;
19+
}
20+
21+
}
622
public static class CopyCollectionItemUtility
723
{
824
private static ScriptableObject source;

Scripts/Editor/Utils/CollectionUtility.cs

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
using System;
22
using System.Collections.Generic;
3+
using UnityEditor;
4+
using UnityEngine;
35
using Object = UnityEngine.Object;
46

57
namespace BrunoMikoski.ScriptableObjectCollections
@@ -36,12 +38,54 @@ public static bool IsFoldoutOpen(params Object[] objects)
3638

3739
return value;
3840
}
41+
3942

40-
public static void SetFoldoutOpen(bool value, params Object[] objects)
43+
public static void SetCollectionItemExpanded(bool isExpanded, ISOCItem targetItem)
4144
{
42-
int hashCount = GetHasCount(objects);
45+
ScriptableObjectCollection collection = targetItem.Collection;
46+
SetCollectionItemExpanded(isExpanded, targetItem, collection);
47+
}
48+
49+
public static bool IsCollectionItemExpanded(ISOCItem targetItem)
50+
{
51+
SerializedObject collectionSerializedObject = new SerializedObject(targetItem.Collection);
52+
SerializedProperty itemsProperty = collectionSerializedObject.FindProperty("items");
53+
for (int i = 0; i < itemsProperty.arraySize; i++)
54+
{
55+
SerializedProperty itemProperty = itemsProperty.GetArrayElementAtIndex(i);
56+
if (itemProperty.objectReferenceValue == (Object) targetItem)
57+
{
58+
return itemProperty.isExpanded;
59+
}
60+
}
61+
62+
return false;
63+
}
4364

44-
objectToFoldOut[hashCount] = value;
65+
public static void SetCollectionItemExpanded(bool isExpanded, ISOCItem collectionItem, ScriptableObjectCollection collection)
66+
{
67+
SerializedObject collectionSerializedObject = new SerializedObject(collection);
68+
SerializedProperty itemsProperty = collectionSerializedObject.FindProperty("items");
69+
for (int i = 0; i < itemsProperty.arraySize; i++)
70+
{
71+
SerializedProperty itemProperty = itemsProperty.GetArrayElementAtIndex(i);
72+
if (itemProperty.objectReferenceValue == (Object) collectionItem)
73+
{
74+
itemProperty.isExpanded = isExpanded;
75+
break;
76+
}
77+
}
78+
}
79+
80+
public static void SetOnlyCollectionItemExpanded(ISOCItem collectionItem, ScriptableObjectCollection collection)
81+
{
82+
SerializedObject collectionSerializedObject = new SerializedObject(collection);
83+
SerializedProperty itemsProperty = collectionSerializedObject.FindProperty("items");
84+
for (int i = 0; i < itemsProperty.arraySize; i++)
85+
{
86+
SerializedProperty itemProperty = itemsProperty.GetArrayElementAtIndex(i);
87+
itemProperty.isExpanded = itemProperty.objectReferenceValue == (Object) collectionItem;
88+
}
4589
}
4690
}
4791
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "com.brunomikoski.scriptableobjectcollection",
33
"displayName": "Scriptable Object Collection",
4-
"version": "2.0.2",
4+
"version": "2.0.3",
55
"unity": "2021.2",
66
"description": "A library to help improve the usability of Unity3D Scriptable Objects by grouping then into a collection and exposing then by code or nice inspectors!",
77
"keywords": [

0 commit comments

Comments
 (0)