Tanoda
DefinitionBaseEditor.cs
Go to the documentation of this file.
1/******************************************************************************
2 * Copyright (C) Ultraleap, Inc. 2011-2020. *
3 * *
4 * Use subject to the terms of the Apache License 2.0 available at *
5 * http://www.apache.org/licenses/LICENSE-2.0, or another agreement *
6 * between Ultraleap and you, your company or other organization. *
7 ******************************************************************************/
8
9using System;
10using System.IO;
11using System.Linq;
12using System.Text;
13using UnityEngine;
14using UnityEditor;
15using UnityEditorInternal;
16
17namespace Leap.Unity.Packaging {
18
19 [CustomEditor(typeof(DefinitionBase))]
20 public abstract class DefinitionBaseEditor<T> : CustomEditorBase<T> where T : DefinitionBase {
21
22 protected override void OnEnable() {
23 base.OnEnable();
24
25 specifyCustomDrawer("_definitionName", drawDefName);
26 specifyCustomDrawer("_showInBuildMenu", drawGenerateBuildDropdown);
27 }
28
29 protected abstract void OnBuild();
30
31 protected abstract int GetBuildMenuPriority();
32
33 protected abstract string GetBuildMethodName();
34
35 protected void drawExportFolder(SerializedProperty prop, string buildText, string label) {
36 EditorGUILayout.BeginHorizontal();
37
38 string folder;
39 if (target.TryGetPackageExportFolder(out folder, promptIfNotDefined: false)) {
40 EditorGUILayout.TextField(label, folder);
41 } else {
42 EditorGUILayout.LabelField(label);
43 }
44
45 if (GUILayout.Button("Change", GUILayout.ExpandWidth(false))) {
46 target.PrompUserToSetExportPath();
47 }
48
49 EditorGUILayout.EndHorizontal();
50
51 if (GUILayout.Button(buildText, GUILayout.MinHeight(EditorGUIUtility.singleLineHeight * 2))) {
52 EditorApplication.delayCall += () => OnBuild();
53 }
54 GUILayout.Space(EditorGUIUtility.singleLineHeight * 2);
55 }
56
57 private void drawDefName(SerializedProperty property) {
58 string newName = EditorGUILayout.DelayedTextField("Package Name", property.stringValue);
59 string filteredName = new string(newName.Where(c => char.IsLetterOrDigit(c) || c == ' ').ToArray()).Trim();
60
61 if (filteredName != "" && filteredName != property.stringValue) {
62 property.stringValue = filteredName;
63
64 if (target.ShowInBuildMenu) {
65 property.serializedObject.ApplyModifiedProperties();
66 generateBuildMenuScript();
67 }
68 }
69 }
70
71 private void drawGenerateBuildDropdown(SerializedProperty property) {
72 EditorGUI.BeginChangeCheck();
73 EditorGUILayout.PropertyField(property);
74 if (EditorGUI.EndChangeCheck()) {
75 property.serializedObject.ApplyModifiedProperties();
76 generateBuildMenuScript();
77 }
78 }
79
80 private void generateBuildMenuScript() {
81 string typeName = typeof(T).Name;
82
83 var definitions = AssetDatabase.FindAssets("t:" + typeName).
84 Select(guid => AssetDatabase.GUIDToAssetPath(guid)).
85 Select(path => AssetDatabase.LoadAssetAtPath<DefinitionBase>(path)).
86 OrderBy(def => def.DefinitionName).
87 ToArray();
88
89 StringBuilder builder = new StringBuilder();
90 builder.AppendLine("using UnityEditor;");
91 builder.AppendLine();
92 builder.AppendLine("namespace Leap.Unity.Packaging {");
93 builder.AppendLine();
94 builder.AppendLine(" public class " + typeName + "BuildMenuItems { ");
95
96 foreach (var def in definitions) {
97 if (!def.ShowInBuildMenu) continue;
98
99 string guid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(def));
100
101 builder.AppendLine("");
102 builder.AppendLine(" // " + def.DefinitionName);
103 builder.AppendLine(" [MenuItem(\"Build/" + def.DefinitionName + "\", priority = " + GetBuildMenuPriority() + ")]");
104 builder.AppendLine(" public static void Build_" + guid + "() {");
105 builder.AppendLine(" " + typeName + "." + GetBuildMethodName() + "(\"" + guid + "\");");
106 builder.AppendLine(" }");
107 }
108
109 builder.AppendLine(" }");
110 builder.AppendLine("}");
111 builder.AppendLine();
112
113 File.WriteAllText("Assets/Plugins/LeapMotion/Internal/Package/Editor/" + typeName + "BuildMenuItems.cs", builder.ToString());
114 AssetDatabase.Refresh();
115 }
116
117 protected ReorderableList createList(string propertyName, Action<Rect, SerializedProperty> drawMethod) {
118 SerializedProperty listProperty = serializedObject.FindProperty(propertyName);
119
120 var list = new ReorderableList(serializedObject, listProperty,
121 draggable: true,
122 displayHeader: true,
123 displayAddButton: true,
124 displayRemoveButton: true);
125
126 list.drawElementCallback += (rect, index, isActive, isFocused) => {
127 SerializedProperty property = list.serializedProperty.GetArrayElementAtIndex(index);
128 drawMethod(rect, property);
129 };
130
131 list.drawHeaderCallback += (rect) => {
132 GUI.Label(rect, listProperty.displayName);
133 };
134
135 list.elementHeight = EditorGUIUtility.singleLineHeight;
136
137 specifyCustomDrawer(propertyName, p => list.DoLayoutList());
138
139 return list;
140 }
141 }
142}
void specifyCustomDrawer(string propertyName, Action< SerializedProperty > propertyDrawer)
Specify a callback to be used to draw a specific named property. Should be called in OnEnable.
ReorderableList createList(string propertyName, Action< Rect, SerializedProperty > drawMethod)
void drawExportFolder(SerializedProperty prop, string buildText, string label)