unity-atoms/Packages/Core/Editor/Drawers/AtomReferenceDrawer.cs
Adam Ramberg 8a6b8a97a6
Added Variable Instancer, Event Reference, Atom Collection and Atom List (old Atom List renamed to Atom Value List) (#110)
AtomVariableInstancer
- Added AtomVariableInstancer as an option to AtomReference.
- Added AtomVariableInstancer to generator.
- Added editor icon for AtomVariableInstancer.

AtomEventReference
- Added an AtomEventReference class (and AtomEventX2Reference). It’s similar to an AtomReference, but for Events. Let’s you pick between an Event, Variable (will select the Changed event) and a VariableInstancer (see above).
- Added AtomEventReference and AtomEventX2Reference to generator.
- Added a drawer for AtomEventReference.
- Listeners are now using AtomEventReference instead of AtomEvent.
- Refactoring of VoidHooks since Listeners are now using AtomEventReference.

AtomCollection
- Created an AtomCollection - a collection of Atoms associated with key strings (AtomReferences).
- Added new editor icon for collections.
- Created a SerializableDictionary class, which AtomCollection is using.
- Custom property drawer for SerializableDictionary.
- SerializableDictionary supports nested structures meaning that a AtomCollection can have a KVP that is pointing to another AtomCollection.
- AtomCollections have 3 events: Added, Removed, Cleared.
- Added an option to sync an InstanceVariable to collection - adding it to the collection when created (using gameObject’s instance id as key) and removing it from the collection when destroyed.

AtomList
- Renamed old AtomList to AtomValueList
- Added AtomList, like Collection, but a list
- Added new icon for AtomList
- Created a AtomBaseVariableList class, which AtomList is using.
- Custom property drawer for AtomBaseVariableList.
- AtomLists have 3 events: Added, Removed, Cleared.
- Added an option to sync an InstanceVariable to list - adding it to the list when created and removing it from the list when destroyed.
2020-02-23 02:39:43 +01:00

94 lines
3.9 KiB
C#

using UnityEditor;
using UnityEngine;
namespace UnityAtoms.Editor
{
/// <summary>
/// A custom property drawer for References. Makes it possible to choose between a value, Variable, Constant or a Variable Instancer.
/// </summary>
[CustomPropertyDrawer(typeof(AtomReferenceBase), true)]
public class AtomReferenceDrawer : PropertyDrawer
{
private static readonly string[] _popupOptions =
{ "Use Value", "Use Constant", "Use Variable", "Use Variable Instancer" };
private static GUIStyle _popupStyle;
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
SerializedProperty usage = property.FindPropertyRelative("_usage");
SerializedProperty value = property.FindPropertyRelative("_value");
SerializedProperty constant = property.FindPropertyRelative("_constant");
SerializedProperty variable = property.FindPropertyRelative("_variable");
SerializedProperty variableInstancer = property.FindPropertyRelative("_variableInstancer");
return EditorGUI.GetPropertyHeight(GetPropToUse(usage, value, constant, variable, variableInstancer), label);
}
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
if (_popupStyle == null)
{
_popupStyle = new GUIStyle(GUI.skin.GetStyle("PaneOptions"));
_popupStyle.imagePosition = ImagePosition.ImageOnly;
}
label = EditorGUI.BeginProperty(position, label, property);
position = EditorGUI.PrefixLabel(position, label);
EditorGUI.BeginChangeCheck();
// Get properties
SerializedProperty usage = property.FindPropertyRelative("_usage");
SerializedProperty value = property.FindPropertyRelative("_value");
SerializedProperty constant = property.FindPropertyRelative("_constant");
SerializedProperty variable = property.FindPropertyRelative("_variable");
SerializedProperty variableInstancer = property.FindPropertyRelative("_variableInstancer");
// Calculate rect for configuration button
Rect buttonRect = new Rect(position);
buttonRect.yMin += _popupStyle.margin.top;
buttonRect.width = _popupStyle.fixedWidth + _popupStyle.margin.right;
position.xMin = buttonRect.xMax;
// Store old indent level and set it to 0, the PrefixLabel takes care of it
int indent = EditorGUI.indentLevel;
EditorGUI.indentLevel = 0;
usage.intValue = EditorGUI.Popup(buttonRect, usage.intValue, _popupOptions, _popupStyle);
EditorGUI.PropertyField(position,
GetPropToUse(usage, value, constant, variable, variableInstancer),
GUIContent.none);
if (EditorGUI.EndChangeCheck())
property.serializedObject.ApplyModifiedProperties();
EditorGUI.indentLevel = indent;
EditorGUI.EndProperty();
}
private SerializedProperty GetPropToUse(SerializedProperty usage, SerializedProperty value, SerializedProperty constant, SerializedProperty variable, SerializedProperty variableInstancer)
{
var usageIntVal = (AtomReferenceBase.Usage)usage.intValue;
if (usageIntVal == AtomReferenceBase.Usage.Constant)
{
return constant;
}
else if (usageIntVal == AtomReferenceBase.Usage.Variable)
{
return variable;
}
else if (usageIntVal == AtomReferenceBase.Usage.VariableInstancer)
{
return variableInstancer;
}
else // if (usageIntVal == AtomReferenceBase.Usage.Value)
{
return value;
}
}
}
}