182 lines
6.8 KiB
C#
182 lines
6.8 KiB
C#
using UnityEngine;
|
|
using UnityEditor;
|
|
using UnityEditorInternal;
|
|
|
|
namespace SK.Framework
|
|
{
|
|
[CustomPropertyDrawer(typeof(Variables))]
|
|
public class VariableArrayDrawer : PropertyDrawer
|
|
{
|
|
private const float HORIZONTAL_GAP = 5;
|
|
private const float VERTICAL_GAP = 5;
|
|
|
|
private ReorderableList list;
|
|
|
|
private ReorderableList GetList(SerializedProperty property)
|
|
{
|
|
if (list == null)
|
|
{
|
|
list = new ReorderableList(property.serializedObject, property, true, true, true, true)
|
|
{
|
|
elementHeight = 21,
|
|
drawElementCallback = DrawElement,
|
|
drawHeaderCallback = DrawHeader,
|
|
onAddDropdownCallback = OnAddElement,
|
|
onRemoveCallback = OnRemoveElement,
|
|
drawElementBackgroundCallback = DrawElementBackground
|
|
};
|
|
}
|
|
else
|
|
{
|
|
list.serializedProperty = property;
|
|
}
|
|
return list;
|
|
}
|
|
|
|
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
|
|
{
|
|
float height = base.GetPropertyHeight(property, label) + 60;
|
|
var variables = property.FindPropertyRelative("variables");
|
|
for (int i = 0; i < variables.arraySize; i++)
|
|
height += EditorGUI.GetPropertyHeight(variables.GetArrayElementAtIndex(i)) + VERTICAL_GAP;
|
|
return height;
|
|
}
|
|
|
|
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
|
|
{
|
|
var list = GetList(property.FindPropertyRelative("variables"));
|
|
list.DoList(position);
|
|
}
|
|
|
|
private void OnAddElement(Rect rect, ReorderableList list)
|
|
{
|
|
var variables = list.serializedProperty;
|
|
int index = variables.arraySize > 0 ? variables.arraySize : 0;
|
|
DrawContextMenu(variables, index);
|
|
}
|
|
|
|
private void OnRemoveElement(ReorderableList list)
|
|
{
|
|
var variables = list.serializedProperty;
|
|
AskRemoveVariable(variables, list.index);
|
|
}
|
|
|
|
private void DrawElementBackground(Rect rect, int index, bool isActive, bool isFocused)
|
|
{
|
|
ReorderableList.defaultBehaviours.DrawElementBackground(rect, index, isActive, false, true);
|
|
}
|
|
|
|
private void DrawHeader(Rect rect)
|
|
{
|
|
GUI.Label(rect, "Variables");
|
|
}
|
|
|
|
private void DrawElement(Rect rect, int index, bool isActive, bool isFocused)
|
|
{
|
|
var variables = list.serializedProperty;
|
|
if (index < 0 || index >= variables.arraySize)
|
|
return;
|
|
|
|
var variable = variables.GetArrayElementAtIndex(index);
|
|
|
|
float x = rect.x;
|
|
float y = rect.y + 2;
|
|
float width = rect.width - 40;
|
|
float height = rect.height;
|
|
|
|
Rect variableRect = new Rect(x, y, width, height);
|
|
EditorGUI.PropertyField(variableRect, variable, GUIContent.none);
|
|
|
|
var buttonLeftRect = new Rect(variableRect.xMax + HORIZONTAL_GAP, y - 1, 18, 18);
|
|
var buttonRightRect = new Rect(buttonLeftRect.xMax, y - 1, 18, 18);
|
|
|
|
if (GUI.Button(buttonLeftRect, new GUIContent("+"), EditorStyles.miniButtonLeft))
|
|
{
|
|
DuplicateVariable(variables, index);
|
|
}
|
|
if (GUI.Button(buttonRightRect, new GUIContent("-"), EditorStyles.miniButtonRight))
|
|
{
|
|
AskRemoveVariable(variables, index);
|
|
}
|
|
}
|
|
|
|
protected virtual void DrawContextMenu(SerializedProperty variables, int index)
|
|
{
|
|
GenericMenu menu = new GenericMenu();
|
|
foreach (VariableType variableType in System.Enum.GetValues(typeof(VariableType)))
|
|
{
|
|
var type = variableType;
|
|
menu.AddItem(new GUIContent(variableType.ToString()), false, context =>
|
|
{
|
|
AddVariable(variables, index, type);
|
|
}, null);
|
|
}
|
|
menu.ShowAsContext();
|
|
}
|
|
|
|
protected virtual void AddVariable(SerializedProperty variables, int index, VariableType type)
|
|
{
|
|
if (index < 0 || index > variables.arraySize)
|
|
return;
|
|
|
|
variables.serializedObject.Update();
|
|
variables.InsertArrayElementAtIndex(index);
|
|
SerializedProperty variableProperty = variables.GetArrayElementAtIndex(index);
|
|
variableProperty.FindPropertyRelative("variableType").enumValueIndex = (int)type;
|
|
|
|
variableProperty.FindPropertyRelative("name").stringValue = "";
|
|
variableProperty.FindPropertyRelative("objectValue").objectReferenceValue = null;
|
|
variableProperty.FindPropertyRelative("dataValue").stringValue = "";
|
|
|
|
variables.serializedObject.ApplyModifiedProperties();
|
|
GUI.FocusControl(null);
|
|
}
|
|
|
|
protected virtual void DuplicateVariable(SerializedProperty variables, int index)
|
|
{
|
|
if (index < 0 || index >= variables.arraySize)
|
|
return;
|
|
|
|
variables.serializedObject.Update();
|
|
variables.InsertArrayElementAtIndex(index);
|
|
SerializedProperty variableProperty = variables.GetArrayElementAtIndex(index + 1);
|
|
|
|
variableProperty.FindPropertyRelative("name").stringValue = "";
|
|
variableProperty.FindPropertyRelative("objectValue").objectReferenceValue = null;
|
|
variableProperty.FindPropertyRelative("dataValue").stringValue = "";
|
|
|
|
variables.serializedObject.ApplyModifiedProperties();
|
|
GUI.FocusControl(null);
|
|
}
|
|
|
|
protected virtual void AskRemoveVariable(SerializedProperty variables, int index)
|
|
{
|
|
if (variables == null || index < 0 || index >= variables.arraySize)
|
|
return;
|
|
|
|
var variable = variables.GetArrayElementAtIndex(index);
|
|
var name = variable.FindPropertyRelative("name").stringValue;
|
|
if (string.IsNullOrEmpty(name))
|
|
{
|
|
RemoveVariable(variables, index);
|
|
return;
|
|
}
|
|
|
|
if (EditorUtility.DisplayDialog("Confirm delete", string.Format("Are you sure you want to delete the item named \"{0}\"?", name), "Yes", "Cancel"))
|
|
{
|
|
RemoveVariable(variables, index);
|
|
}
|
|
}
|
|
|
|
protected virtual void RemoveVariable(SerializedProperty variables, int index)
|
|
{
|
|
if (index < 0 || index >= variables.arraySize)
|
|
return;
|
|
|
|
variables.serializedObject.Update();
|
|
variables.DeleteArrayElementAtIndex(index);
|
|
variables.serializedObject.ApplyModifiedProperties();
|
|
GUI.FocusControl(null);
|
|
}
|
|
}
|
|
} |