-
-
Notifications
You must be signed in to change notification settings - Fork 21
Expand file tree
/
Copy pathSerializableInterfaceAdvancedDropdown.cs
More file actions
106 lines (90 loc) · 3.38 KB
/
SerializableInterfaceAdvancedDropdown.cs
File metadata and controls
106 lines (90 loc) · 3.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
using System;
using System.Linq;
using System.Reflection;
using TNRD.Builders;
using TNRD.Items;
using UnityEditor;
using UnityEditor.IMGUI.Controls;
using UnityEngine;
using UnityEngine.Assertions;
using UnityEngine.SceneManagement;
namespace TNRD.Utilities
{
internal sealed class SerializableInterfaceAdvancedDropdown : AdvancedDropdown
{
private readonly Type interfaceType;
private readonly MethodInfo sortChildrenMethod;
private readonly bool canSort;
private readonly bool classesOnly;
private readonly Scene? relevantScene;
private readonly SerializedProperty property;
public delegate void ItemSelectedDelegate(SerializedProperty property, ReferenceMode mode, object reference);
public event ItemSelectedDelegate ItemSelectedEvent; // Suffixed with Event because of the override
/// <inheritdoc />
public SerializableInterfaceAdvancedDropdown(
AdvancedDropdownState state,
Type interfaceType,
Scene? relevantScene,
SerializedProperty property,
bool classesOnly
)
: base(state)
{
Assert.IsNotNull(interfaceType);
sortChildrenMethod = typeof(AdvancedDropdownItem)
.GetMethod("SortChildren", BindingFlags.Instance | BindingFlags.NonPublic);
canSort = sortChildrenMethod != null;
minimumSize = new Vector2(0, 300);
this.interfaceType = interfaceType;
this.relevantScene = relevantScene;
this.property = property;
this.classesOnly = classesOnly;
}
/// <inheritdoc />
protected override AdvancedDropdownItem BuildRoot()
{
AdvancedDropdownItemWrapper item = new AdvancedDropdownItemWrapper(interfaceType.Name);
item.AddChild(new ClassesItemBuilder(interfaceType).Build());
if (!classesOnly)
{
item.AddChild(new AssetsItemBuilder(interfaceType).Build());
item.AddChild(new SceneItemBuilder(interfaceType, relevantScene).Build());
}
item.AddChild(new NoneDropdownItem());
if (canSort)
{
sortChildrenMethod.Invoke(item,
new object[]
{
(Comparison<AdvancedDropdownItem>)Sort, true
});
}
return item;
}
private int Sort(AdvancedDropdownItem a, AdvancedDropdownItem b)
{
// For aesthetic reasons. Always puts the None first
if (a is NoneDropdownItem)
return -1;
if (b is NoneDropdownItem)
return 1;
int childrenA = a.children.Count();
int childrenB = b.children.Count();
if (childrenA > 0 && childrenB > 0)
return a.CompareTo(b);
if (childrenA == 0 && childrenB == 0)
return a.CompareTo(b);
if (childrenA > 0 && childrenB == 0)
return -1;
return 1;
}
/// <inheritdoc />
protected override void ItemSelected(AdvancedDropdownItem item)
{
if (item is IDropdownItem dropdownItem)
{
ItemSelectedEvent?.Invoke(property, dropdownItem.Mode, dropdownItem.GetValue());
}
}
}
}