Skip to content

Commit 19b4bb2

Browse files
committed
Added foldout UnityEventDrawers.
1 parent a3b570d commit 19b4bb2

File tree

3 files changed

+142
-1
lines changed

3 files changed

+142
-1
lines changed

Editor/Utilities/UnityEventDrawer.cs

+130
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
#if UNITY_2020_1_OR_NEWER
2+
using UnityEditor;
3+
using UnityEngine;
4+
using UnityEngine.Events;
5+
using System.Reflection;
6+
using UnityEditorInternal;
7+
8+
namespace Lachee.Utilities.Editor
9+
{
10+
[CustomPropertyDrawer(typeof(UnityEventBase), true)]
11+
public class UnityEventDrawer : UnityEditorInternal.UnityEventDrawer
12+
{
13+
#region Private Functions i steal from UnityEventDrawerer
14+
private static readonly FieldInfo fi_reoderableList;
15+
private static readonly FieldInfo fi_dummyEvent;
16+
private static readonly FieldInfo fi_text;
17+
private static readonly MethodInfo mi_RestoreState;
18+
private static readonly MethodInfo mi_GetDummyEvent;
19+
20+
static UnityEventDrawer()
21+
{
22+
var T = typeof(UnityEditorInternal.UnityEventDrawer);
23+
fi_reoderableList = T.GetField("m_ReorderableList", BindingFlags.NonPublic | BindingFlags.Instance);
24+
fi_dummyEvent = T.GetField("m_DummyEvent", BindingFlags.NonPublic | BindingFlags.Instance);
25+
fi_text = T.GetField("m_Text", BindingFlags.NonPublic | BindingFlags.Instance);
26+
mi_GetDummyEvent = T.GetMethod("GetDummyEvent", BindingFlags.NonPublic | BindingFlags.Static);
27+
mi_RestoreState = T.GetMethod("RestoreState", BindingFlags.NonPublic | BindingFlags.Instance);
28+
}
29+
30+
private static UnityEventBase GetDummyEvent(SerializedProperty prop)
31+
=> (UnityEventBase)mi_GetDummyEvent.Invoke(null, new object[] { prop });
32+
33+
private ReorderableList reorderableList
34+
{
35+
get => (ReorderableList)fi_reoderableList.GetValue(this);
36+
}
37+
private UnityEventBase dummyEvent
38+
{
39+
get => (UnityEventBase)fi_dummyEvent.GetValue(this);
40+
set => fi_dummyEvent.SetValue(this, value);
41+
}
42+
private string text
43+
{
44+
get => (string)fi_text.GetValue(this);
45+
set => fi_text.SetValue(this, value);
46+
}
47+
private State RestoreState(SerializedProperty property)
48+
=> (State)mi_RestoreState.Invoke(this, new[] { property });
49+
#endregion
50+
51+
private readonly GUIContent iconToolbarPlus = EditorGUIUtility.TrIconContent("Toolbar Plus", "Add new event listener");
52+
private readonly GUIStyle headerBackground = "LODSliderBG";
53+
private readonly GUIStyle preButton = "RL FooterButton";
54+
private readonly Color headerColor = new Color(0.85f, 0.85f, 0.85f);
55+
56+
private bool? _isFolded;
57+
private bool isFolded
58+
{
59+
get => _isFolded.GetValueOrDefault(EditorPrefs.GetBool($"com.lachee.utilities.UnityEventsFoldout", true));
60+
set
61+
{
62+
_isFolded = value;
63+
EditorPrefs.SetBool($"com.lachee.utilities.UnityEventsFoldout", value);
64+
}
65+
}
66+
67+
private float CalculateBackgroundHeight(SerializedProperty property)
68+
{
69+
var list = reorderableList;
70+
if (list == null || list.count == 0 || isFolded)
71+
return EditorGUIUtility.singleLineHeight + 2f;
72+
73+
return base.GetPropertyHeight(property, GUIContent.none);
74+
}
75+
76+
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
77+
{
78+
RestoreState(property);
79+
80+
text = label.text;
81+
dummyEvent = GetDummyEvent(property);
82+
83+
float lineHeight = EditorGUIUtility.singleLineHeight;
84+
85+
// Draw the folder
86+
if (reorderableList.count > 0)
87+
{
88+
isFolded = !EditorGUI.Foldout(new Rect(position.x, position.y, position.width, lineHeight), !isFolded, GUIContent.none);
89+
}
90+
else
91+
{
92+
_isFolded = true;
93+
}
94+
95+
// Draw the event box
96+
Rect headerRect = new Rect(position.x + 2, position.y, position.width - 2, CalculateBackgroundHeight(property));
97+
Rect headerLabel = new Rect(headerRect.x + 6, headerRect.y + 1, headerRect.width - 100, lineHeight);
98+
Rect headerAddButton = new Rect(headerRect.x + headerRect.width - 25, headerRect.y + 2, 24, headerRect.height + 4);
99+
100+
// Draw the base GUI if we are unfolded
101+
if (!isFolded)
102+
{
103+
base.OnGUI(headerRect, property, label);
104+
}
105+
else
106+
{
107+
if (Event.current.type == EventType.Repaint)
108+
{
109+
GUI.backgroundColor = headerColor;
110+
headerBackground.Draw(headerRect, GUIContent.none, false, false, false, false);
111+
GUI.backgroundColor = Color.white;
112+
}
113+
114+
DrawEventHeader(headerLabel);
115+
if (GUI.Button(headerAddButton, iconToolbarPlus, preButton))
116+
{
117+
isFolded = false;
118+
OnAddEvent(reorderableList);
119+
}
120+
}
121+
}
122+
123+
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
124+
{
125+
return CalculateBackgroundHeight(property) + 5f;
126+
}
127+
128+
}
129+
}
130+
#endif

Editor/Utilities/UnityEventDrawer.cs.meta

+11
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "com.lachee.utilities",
3-
"version": "1.4.7",
3+
"version": "1.5.0",
44
"displayName": "Lachee's Utilities",
55
"description": "Bunch of utility functionality",
66
"unity": "2019.1",

0 commit comments

Comments
 (0)