Skip to content

Commit

Permalink
Reorderable types! ReorderableCollection slightly changed.
Browse files Browse the repository at this point in the history
  • Loading branch information
Deadcows committed Oct 19, 2019
1 parent 5980551 commit ccd9c77
Show file tree
Hide file tree
Showing 3 changed files with 142 additions and 24 deletions.
73 changes: 49 additions & 24 deletions Types/EditorTypes/ReorderableCollection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,39 +16,65 @@ public bool IsExpanded

public void Draw()
{
if (!_property.isExpanded) DrawHeader();
else _list.DoLayoutList();
if (_property.isExpanded)
{
var headerRect = GUILayoutUtility.GetRect(0, 0, GUILayout.ExpandWidth(true));
headerRect.height = 20;
_list.DoLayoutList();
DrawHeader(headerRect);
}
else DrawHeader(GUILayoutUtility.GetRect(0, 20, GUILayout.ExpandWidth(true)));
}

public void Draw(Rect rect)
{
if (_property.isExpanded) _list.DoList(rect);
DrawHeader(rect);
}

public float Height
{
get { return _property.isExpanded ? _list.GetHeight() : EditorGUIUtility.singleLineHeight + 12; }
}

public SerializedProperty Property
{
get { return _property; }
}


public Action<SerializedProperty, Rect, int> CustomDrawer;

/// <summary>
/// Return Height, Receive element index.
/// Use EditorApplication.delayCall to perform custom logic
/// </summary>
public Func<int, int> CustomDrawerHeight;

/// <summary>
/// Return false to perform default logic, Receive element index.
/// Use EditorApplication.delayCall to perform custom logic.
/// </summary>
public Func<int, bool> CustomAdd;

/// <summary>
/// Return false to perform default logic, Receive element index.
/// Use EditorApplication.delayCall to perform custom logic.
/// </summary>
public Func<int, bool> CustomRemove;


private ReorderableList _list;
private SerializedProperty _property;
private readonly string _customHeader;

public ReorderableCollection(SerializedProperty property, bool withAddButton = true,
bool withRemoveButton = true)
bool withRemoveButton = true, string customHeader = null)
{
_property = property;
_property.isExpanded = true;
_customHeader = customHeader;

CreateList(property, withAddButton, withRemoveButton);
CreateList(property, withAddButton, withRemoveButton, customHeader == null);
}

~ReorderableCollection()
Expand All @@ -57,41 +83,40 @@ public void Draw()
_list = null;
}

private void DrawHeader()
private void DrawHeader(Rect rect)
{
EditorGUILayout.BeginHorizontal();
_property.isExpanded = EditorGUILayout.ToggleLeft(string.Format("{0}[]", _property.displayName),
var headerRect = new Rect(rect);
headerRect.height = EditorGUIUtility.singleLineHeight;

ReorderableList.defaultBehaviours.DrawHeaderBackground(headerRect);

headerRect.width -= 50;
headerRect.x += 6;
headerRect.y += 2;
_property.isExpanded = EditorGUI.ToggleLeft(headerRect,
(_customHeader != null ? _customHeader : _property.displayName) + "[" + _property.arraySize + "]",
_property.isExpanded,
EditorStyles.boldLabel);
EditorGUILayout.LabelField(string.Format("size: {0}", _property.arraySize));
EditorGUILayout.EndHorizontal();
}

private void CreateList(SerializedProperty property, bool withAddButton, bool withRemoveButton)
private void CreateList(SerializedProperty property, bool withAddButton, bool withRemoveButton, bool displayHeader)
{
_list = new ReorderableList(property.serializedObject, property, true, true, withAddButton,
_list = new ReorderableList(property.serializedObject, property, true, displayHeader, withAddButton,
withRemoveButton);
_list.onChangedCallback += list => Apply();
_list.onAddCallback += AddElement;
_list.onRemoveCallback += RemoveElement;
_list.drawHeaderCallback += DrawElementHeader;
_list.onCanRemoveCallback += (list) => _list.count > 0;
_list.drawElementCallback += DrawElement;
_list.elementHeightCallback += GetElementHeight;
}

private void DrawElementHeader(Rect rect)
{
_property.isExpanded =
EditorGUI.ToggleLeft(rect, _property.displayName, _property.isExpanded, EditorStyles.boldLabel);
}

private void AddElement(ReorderableList list)
{
if (CustomAdd == null || !CustomAdd(_property.arraySize))
ReorderableList.defaultBehaviours.DoAddButton(list);
}

private void RemoveElement(ReorderableList list)
{
if (CustomRemove == null || !CustomRemove(list.index))
Expand All @@ -101,7 +126,7 @@ private void RemoveElement(ReorderableList list)
private void DrawElement(Rect rect, int index, bool active, bool focused)
{
EditorGUI.BeginChangeCheck();

var property = _property.GetArrayElementAtIndex(index);
rect.height = GetElementHeight(index);
rect.y += 1;
Expand All @@ -112,7 +137,7 @@ private void DrawElement(Rect rect, int index, bool active, bool focused)
var element = _property.GetArrayElementAtIndex(index);
var newRect = rect;
newRect.x += 20;

if (element.propertyType == SerializedPropertyType.Generic) EditorGUI.LabelField(newRect, element.displayName);
EditorGUI.PropertyField(rect, property, GUIContent.none, true);
}
Expand All @@ -124,7 +149,7 @@ private void DrawElement(Rect rect, int index, bool active, bool focused)
private float GetElementHeight(int index)
{
if (CustomDrawerHeight != null) return CustomDrawerHeight(index);

var element = _property.GetArrayElementAtIndex(index);
var height = EditorGUI.GetPropertyHeight(element, GUIContent.none, true);
return Mathf.Max(EditorGUIUtility.singleLineHeight, height + 4.0f);
Expand Down
82 changes: 82 additions & 0 deletions Types/Reorderable.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
using System;
using System.Collections.Generic;
using UnityEngine;


namespace MyBox
{
#region Default Reordable Types

[Serializable]
public class ReorderableGameObject : ReorderableArray<GameObject>
{
}

[Serializable]
public class ReorderableGameObjectList : ReorderableList<GameObject>
{
}

[Serializable]
public class ReorderableTransform : ReorderableArray<Transform>
{
}

[Serializable]
public class ReorderableTransformList : ReorderableList<Transform>
{
}

#endregion


[Serializable]
public class ReorderableArray<T> : Internal.ReorderableBase
{
public T[] Collection;
}

[Serializable]
public class ReorderableList<T> : Internal.ReorderableBase
{
public List<T> Collection;
}
}

namespace MyBox.Internal
{
[Serializable]
public class ReorderableBase
{
}
}


#if UNITY_EDITOR
namespace MyBox.Internal
{
using UnityEditor;
using EditorTools;

[CustomPropertyDrawer(typeof(ReorderableBase), true)]
public class ReorderableTypePropertyDrawer : PropertyDrawer
{
private ReorderableCollection _reorderable;

public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
return _reorderable != null ? _reorderable.Height : base.GetPropertyHeight(property, label);
}

public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
if (_reorderable == null)
_reorderable = new ReorderableCollection(property.FindPropertyRelative("Collection"), true, true, property.displayName);

EditorGUI.BeginProperty(position, label, property);
_reorderable.Draw(position);
EditorGUI.EndProperty();
}
}
}
#endif
11 changes: 11 additions & 0 deletions Types/Reorderable.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit ccd9c77

Please sign in to comment.