Skip to content

Commit 6b63b0d

Browse files
authored
Merge pull request #6 from Thundernerd/feature/cleanup_refactor
Feature/cleanup refactor
2 parents ef97ba9 + 81cfffc commit 6b63b0d

15 files changed

+405
-278
lines changed

Editor/Drawers.meta

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Editor/SerializableInterfacePropertyDrawer.Styles.cs renamed to Editor/Drawers/CustomObjectDrawer.Styles.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
using UnityEditor;
22
using UnityEngine;
33

4-
namespace TNRD
4+
namespace TNRD.Drawers
55
{
6-
internal sealed partial class SerializableInterfacePropertyDrawer
6+
public partial class CustomObjectDrawer
77
{
88
private static class Styles
99
{

Editor/Drawers/CustomObjectDrawer.Styles.cs.meta

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
using UnityEditor;
2+
using UnityEngine;
3+
4+
namespace TNRD.Drawers
5+
{
6+
public partial class CustomObjectDrawer
7+
{
8+
public delegate void ButtonClickedDelegate(Rect position);
9+
10+
public delegate void ClickedDelegate();
11+
12+
public delegate void DeletePressedDelegate();
13+
14+
public delegate void PropertiesClickedDelegate();
15+
16+
private bool isSelected;
17+
18+
private Event Event => Event.current;
19+
20+
public event ButtonClickedDelegate ButtonClicked;
21+
public event ClickedDelegate Clicked;
22+
public event DeletePressedDelegate DeletePressed;
23+
public event PropertiesClickedDelegate PropertiesClicked;
24+
25+
public void OnGUI(Rect position, GUIContent label, GUIContent content)
26+
{
27+
Rect positionWithoutThumb = new Rect(position);
28+
positionWithoutThumb.xMax -= 20;
29+
30+
position = DrawPrefixLabel(position, label);
31+
DrawObjectField(position, content);
32+
DrawButton(position);
33+
34+
HandleMouseDown(position, positionWithoutThumb);
35+
HandleKeyDown();
36+
}
37+
38+
private Rect DrawPrefixLabel(Rect position, GUIContent label)
39+
{
40+
GUIStyle labelStyle = isSelected ? Styles.SelectedLabelStyle : Styles.RegularLabelStyle;
41+
Rect result = EditorGUI.PrefixLabel(position, label, labelStyle);
42+
return result;
43+
}
44+
45+
private void DrawObjectField(Rect position, GUIContent objectFieldContent)
46+
{
47+
Rect positionWithoutThumb = new Rect(position);
48+
positionWithoutThumb.xMax -= 20;
49+
50+
if (Event.type == EventType.Repaint)
51+
{
52+
EditorStyles.objectField.Draw(position,
53+
objectFieldContent,
54+
position.Contains(Event.mousePosition),
55+
false,
56+
false,
57+
isSelected);
58+
}
59+
}
60+
61+
private void ForceRepaintEditors()
62+
{
63+
foreach (Editor activeEditor in ActiveEditorTracker.sharedTracker.activeEditors)
64+
{
65+
activeEditor.Repaint();
66+
}
67+
}
68+
69+
private void DrawButton(Rect position)
70+
{
71+
Rect buttonRect = new Rect(position);
72+
buttonRect.yMin += 1;
73+
buttonRect.yMax -= 1;
74+
buttonRect.xMin = buttonRect.xMax - 20;
75+
buttonRect.xMax -= 1;
76+
77+
if (GUI.Button(buttonRect, string.Empty, "objectFieldButton"))
78+
{
79+
ButtonClicked?.Invoke(position);
80+
}
81+
}
82+
83+
private void HandleMouseDown(Rect position, Rect positionWithoutThumb)
84+
{
85+
if (Event.type != EventType.MouseDown)
86+
return;
87+
88+
if (Event.button == 0)
89+
{
90+
isSelected = positionWithoutThumb.Contains(Event.mousePosition);
91+
ForceRepaintEditors();
92+
Clicked?.Invoke();
93+
}
94+
else if (Event.button == 1 && positionWithoutThumb.Contains(Event.mousePosition))
95+
{
96+
GenericMenu menu = new GenericMenu();
97+
menu.AddItem(new GUIContent("Properties..."), false, () => { PropertiesClicked?.Invoke(); });
98+
menu.DropDown(position);
99+
Event.Use();
100+
}
101+
}
102+
103+
private void HandleKeyDown()
104+
{
105+
if (!isSelected)
106+
return;
107+
108+
if (Event.type == EventType.KeyDown && Event.keyCode == KeyCode.Delete)
109+
{
110+
DeletePressed?.Invoke();
111+
}
112+
}
113+
}
114+
}

Editor/Drawers/CustomObjectDrawer.cs.meta

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Editor/Drawers/IReferenceDrawer.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
using UnityEngine;
2+
3+
namespace TNRD.Drawers
4+
{
5+
internal interface IReferenceDrawer
6+
{
7+
float GetHeight();
8+
void OnGUI(Rect position);
9+
}
10+
}

Editor/Drawers/IReferenceDrawer.cs.meta

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
using System;
2+
using System.Reflection;
3+
using UnityEditor;
4+
using UnityEngine;
5+
6+
namespace TNRD.Drawers
7+
{
8+
internal class RawReferenceDrawer : ReferenceDrawer, IReferenceDrawer
9+
{
10+
private readonly GUIContent label;
11+
private readonly FieldInfo fieldInfo;
12+
13+
private object RawReferenceValue
14+
{
15+
get
16+
{
17+
#if UNITY_2021_1_OR_NEWER
18+
return RawReferenceProperty.managedReferenceValue;
19+
#else
20+
ISerializableInterface instance =
21+
(ISerializableInterface)fieldInfo.GetValue(Property.serializedObject.targetObject);
22+
return instance.GetRawReference();
23+
#endif
24+
}
25+
}
26+
27+
/// <inheritdoc />
28+
public RawReferenceDrawer(SerializedProperty property, GUIContent label, Type genericType, FieldInfo fieldInfo)
29+
: base(property, genericType)
30+
{
31+
this.label = label;
32+
this.fieldInfo = fieldInfo;
33+
}
34+
35+
/// <inheritdoc />
36+
public float GetHeight()
37+
{
38+
if (RawReferenceValue == null)
39+
return EditorGUIUtility.singleLineHeight;
40+
41+
return EditorGUIUtility.singleLineHeight +
42+
EditorGUIUtility.standardVerticalSpacing +
43+
EditorGUI.GetPropertyHeight(RawReferenceProperty, true);
44+
}
45+
46+
/// <inheritdoc />
47+
public void OnGUI(Rect position)
48+
{
49+
Rect objectFieldRect = new Rect(position)
50+
{
51+
height = EditorGUIUtility.singleLineHeight
52+
};
53+
54+
object rawReferenceValue = RawReferenceValue;
55+
56+
GUIContent content = rawReferenceValue == null
57+
? EditorGUIUtility.ObjectContent((MonoScript)null, typeof(MonoScript))
58+
: new GUIContent(rawReferenceValue.GetType().Name, IconUtility.ScriptIcon);
59+
60+
CustomObjectDrawer.OnGUI(objectFieldRect, label, content);
61+
if (rawReferenceValue == null)
62+
return;
63+
64+
Rect objectDrawerRect = new Rect(position);
65+
objectDrawerRect.yMin += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
66+
67+
EditorGUI.PropertyField(objectDrawerRect,
68+
RawReferenceProperty,
69+
new GUIContent(rawReferenceValue.GetType().Name),
70+
true);
71+
}
72+
73+
/// <inheritdoc />
74+
protected override void OnPropertiesClicked()
75+
{
76+
Type type = RawReferenceValue.GetType();
77+
string typeName = type.Name;
78+
79+
string[] guids = AssetDatabase.FindAssets($"t:Script {typeName}");
80+
foreach (string guid in guids)
81+
{
82+
string assetPath = AssetDatabase.GUIDToAssetPath(guid);
83+
MonoScript monoScript = AssetDatabase.LoadAssetAtPath<MonoScript>(assetPath);
84+
if (monoScript.GetClass() == type)
85+
{
86+
PropertyEditorUtility.Show(monoScript);
87+
return;
88+
}
89+
}
90+
}
91+
}
92+
}

Editor/Drawers/RawReferenceDrawer.cs.meta

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Editor/Drawers/ReferenceDrawer.cs

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
using System;
2+
using UnityEditor;
3+
using UnityEditor.IMGUI.Controls;
4+
using UnityEngine;
5+
using UnityEngine.SceneManagement;
6+
using Object = UnityEngine.Object;
7+
8+
namespace TNRD.Drawers
9+
{
10+
internal abstract class ReferenceDrawer
11+
{
12+
protected readonly SerializedProperty Property;
13+
protected readonly Type GenericType;
14+
protected readonly CustomObjectDrawer CustomObjectDrawer;
15+
16+
protected SerializedProperty ReferenceModeProperty => Property.FindPropertyRelative("mode");
17+
protected SerializedProperty RawReferenceProperty => Property.FindPropertyRelative("rawReference");
18+
protected SerializedProperty UnityReferenceProperty => Property.FindPropertyRelative("unityReference");
19+
20+
protected ReferenceDrawer(SerializedProperty property, Type genericType)
21+
{
22+
Property = property;
23+
GenericType = genericType;
24+
25+
CustomObjectDrawer = new CustomObjectDrawer();
26+
CustomObjectDrawer.ButtonClicked += OnButtonClicked;
27+
CustomObjectDrawer.Clicked += OnClicked;
28+
CustomObjectDrawer.DeletePressed += OnDeletePressed;
29+
CustomObjectDrawer.PropertiesClicked += OnPropertiesClicked;
30+
}
31+
32+
private void OnButtonClicked(Rect position)
33+
{
34+
AdvancedDropdownState state = new AdvancedDropdownState();
35+
SerializableInterfaceAdvancedDropdown dropdown =
36+
new SerializableInterfaceAdvancedDropdown(state, GenericType, GetRelevantScene());
37+
dropdown.ItemSelectedEvent += OnItemSelected;
38+
dropdown.Show(position);
39+
}
40+
41+
private Scene? GetRelevantScene()
42+
{
43+
Object target = Property.serializedObject.targetObject;
44+
45+
if (target is ScriptableObject)
46+
return null;
47+
if (target is Component component)
48+
return component.gameObject.scene;
49+
if (target is GameObject gameObject)
50+
return gameObject.scene;
51+
52+
return null;
53+
}
54+
55+
private void OnClicked()
56+
{
57+
switch ((ReferenceMode)ReferenceModeProperty.enumValueIndex)
58+
{
59+
case ReferenceMode.Raw:
60+
// No support for pinging raw objects for now (I guess this would ping the MonoScript?)
61+
break;
62+
case ReferenceMode.Unity:
63+
EditorGUIUtility.PingObject(UnityReferenceProperty.objectReferenceValue);
64+
break;
65+
default:
66+
throw new ArgumentOutOfRangeException();
67+
}
68+
}
69+
70+
private void OnDeletePressed()
71+
{
72+
RawReferenceProperty.managedReferenceValue = null;
73+
UnityReferenceProperty.objectReferenceValue = null;
74+
Property.serializedObject.ApplyModifiedProperties();
75+
}
76+
77+
private void OnItemSelected(ReferenceMode mode, object reference)
78+
{
79+
ReferenceModeProperty.enumValueIndex = (int)mode;
80+
81+
switch (mode)
82+
{
83+
case ReferenceMode.Raw:
84+
RawReferenceProperty.managedReferenceValue = reference;
85+
break;
86+
case ReferenceMode.Unity:
87+
UnityReferenceProperty.objectReferenceValue = (Object)reference;
88+
break;
89+
default:
90+
throw new ArgumentOutOfRangeException(nameof(mode), mode, null);
91+
}
92+
93+
Property.serializedObject.ApplyModifiedProperties();
94+
}
95+
96+
protected abstract void OnPropertiesClicked();
97+
}
98+
}

0 commit comments

Comments
 (0)