Add list header drag and drop

This commit is contained in:
VladV 2023-03-23 14:49:25 +04:00
parent 513a250c64
commit 78d032d4d5
2 changed files with 75 additions and 2 deletions

View File

@ -1,10 +1,12 @@
using System;
using System.Collections;
using System.Linq;
using TriInspectorUnityInternalBridge;
using TriInspector.Utilities;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
using Object = UnityEngine.Object;
namespace TriInspector.Elements
{
@ -121,10 +123,15 @@ namespace TriInspector.Elements
}
private void AddElementCallback(ReorderableList reorderableList)
{
AddElementCallback(reorderableList, null);
}
private void AddElementCallback(ReorderableList reorderableList, Object addedReferenceValue)
{
if (_property.TryGetSerializedProperty(out _))
{
ReorderableListProxy.defaultBehaviours.DoAddButton(reorderableList);
ReorderableListProxy.DoAddButton(reorderableList, addedReferenceValue);
_property.NotifyValueChanged();
return;
}
@ -139,6 +146,12 @@ namespace TriInspector.Elements
{
var array = Array.CreateInstance(_property.ArrayElementType, template.Length + 1);
Array.Copy(template, array, template.Length);
if (addedReferenceValue != null)
{
array.SetValue(addedReferenceValue, array.Length - 1);
}
value = array;
}
else
@ -148,7 +161,10 @@ namespace TriInspector.Elements
value = (IList) Activator.CreateInstance(_property.FieldType);
}
var newElement = CreateDefaultElementValue(_property);
var newElement = addedReferenceValue != null
? addedReferenceValue
: CreateDefaultElementValue(_property);
value.Add(newElement);
}
@ -293,6 +309,29 @@ namespace TriInspector.Elements
var label = _reorderableListGui.count == 0 ? "Empty" : $"{_reorderableListGui.count} items";
GUI.Label(arraySizeRect, label, Styles.ItemsCount);
if (Event.current.type == EventType.DragUpdated && rect.Contains(Event.current.mousePosition))
{
DragAndDrop.visualMode = DragAndDrop.objectReferences.All(obj => TryGetDragAndDropObject(obj, out _))
? DragAndDropVisualMode.Copy
: DragAndDropVisualMode.Rejected;
Event.current.Use();
}
else if (Event.current.type == EventType.DragPerform && rect.Contains(Event.current.mousePosition))
{
DragAndDrop.AcceptDrag();
foreach (var obj in DragAndDrop.objectReferences)
{
if (TryGetDragAndDropObject(obj, out var addedReferenceValue))
{
AddElementCallback(_reorderableListGui, addedReferenceValue);
}
}
Event.current.Use();
}
}
private void DrawElementCallback(Rect rect, int index, bool isActive, bool isFocused)
@ -336,6 +375,34 @@ namespace TriInspector.Elements
return template;
}
private bool TryGetDragAndDropObject(Object obj, out Object result)
{
if (obj == null)
{
result = null;
return false;
}
var elementType = _property.ArrayElementType;
var objType = obj.GetType();
if (elementType == objType || elementType.IsAssignableFrom(objType))
{
result = obj;
return true;
}
if (obj is GameObject go && typeof(Component).IsAssignableFrom(elementType) &&
go.TryGetComponent(elementType, out var component))
{
result = component;
return true;
}
result = null;
return false;
}
private static class Styles
{
public static readonly GUIStyle ItemsCount;

View File

@ -2,6 +2,7 @@ using System;
using System.Reflection;
using UnityEditorInternal;
using UnityEngine;
using Object = UnityEngine.Object;
namespace TriInspectorUnityInternalBridge
{
@ -59,5 +60,10 @@ namespace TriInspectorUnityInternalBridge
ClearCacheMethod?.Invoke(list, Array.Empty<object>());
#endif
}
public static void DoAddButton(ReorderableList list, Object value)
{
defaultBehaviours.DoAddButton(list, value);
}
}
}