Reorderable List:

- Added support for HorizontalLayout and GridLayout
- Change Property  RectTransform Content to LayoutGroup ContentLayout

--HG--
branch : develop_5.2
release
Ziboo 2015-10-29 14:12:26 +01:00
parent dfb423b6d0
commit 953770528d
9 changed files with 142 additions and 70 deletions

View File

@ -1,27 +1,41 @@
using System; using System;
using UnityEngine; using UnityEngine;
using UnityEngine.Events; using UnityEngine.Events;
using UnityEngine.UI;
public class ReorderableList : MonoBehaviour public class ReorderableList : MonoBehaviour
{ {
public RectTransform Content; public LayoutGroup ContentLayout;
public bool IsDraggable = true; public bool IsDraggable = true;
public RectTransform DraggableArea; public RectTransform DraggableArea;
public bool CloneDraggedObject = false; public bool CloneDraggedObject = false;
public bool IsDropable = true; public bool IsDropable = true;
public ReorderableListHandler OnElementDropped = new ReorderableListHandler(); public ReorderableListHandler OnElementDropped = new ReorderableListHandler();
private RectTransform _content;
private ReorderableListContent _listContent; private ReorderableListContent _listContent;
public RectTransform Content
{
get
{
if (_content == null)
{
_content = ContentLayout.GetComponent<RectTransform>();
}
return _content;
}
}
private void Awake() private void Awake()
{ {
if (Content == null) if (ContentLayout == null)
{ {
Debug.LogError("You need to set the content for the list", gameObject); Debug.LogError("You need to have a LayoutGroup content set for the list", gameObject);
return; return;
} }
if (DraggableArea == null) if (DraggableArea == null)
@ -29,10 +43,12 @@ public class ReorderableList : MonoBehaviour
Debug.LogError("You need to set a draggable area for the list", gameObject); Debug.LogError("You need to set a draggable area for the list", gameObject);
return; return;
} }
_listContent = Content.gameObject.AddComponent<ReorderableListContent>(); _listContent = ContentLayout.gameObject.AddComponent<ReorderableListContent>();
_listContent.Init(this); _listContent.Init(this);
} }
#region Nested type: ReorderableListEventStruct
[Serializable] [Serializable]
public struct ReorderableListEventStruct public struct ReorderableListEventStruct
{ {
@ -45,8 +61,14 @@ public class ReorderableList : MonoBehaviour
public ReorderableList ToList; public ReorderableList ToList;
} }
#endregion
#region Nested type: ReorderableListHandler
[Serializable] [Serializable]
public class ReorderableListHandler : UnityEvent<ReorderableListEventStruct> public class ReorderableListHandler : UnityEvent<ReorderableListEventStruct>
{ {
} }
#endregion
} }

View File

@ -1,12 +1,12 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 6b333d67eb08d464d823874f6a1666c2 guid: 6b333d67eb08d464d823874f6a1666c2
timeCreated: 1446072130 timeCreated: 1446072130
licenseType: Pro licenseType: Pro
MonoImporter: MonoImporter:
serializedVersion: 2 serializedVersion: 2
defaultReferences: [] defaultReferences: []
executionOrder: 0 executionOrder: 0
icon: {instanceID: 0} icon: {instanceID: 0}
userData: userData:
assetBundleName: assetBundleName:
assetBundleVariant: assetBundleVariant:

View File

@ -1,8 +1,8 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 9b8d590979bc3264ab9a7df11a0e8c3c guid: 9b8d590979bc3264ab9a7df11a0e8c3c
timeCreated: 1446061891 timeCreated: 1446061891
licenseType: Pro licenseType: Pro
DefaultImporter: DefaultImporter:
userData: userData:
assetBundleName: assetBundleName:
assetBundleVariant: assetBundleVariant:

View File

@ -1,12 +1,12 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 252dd148b2c1dbe40b7d938a553e3caf guid: 252dd148b2c1dbe40b7d938a553e3caf
timeCreated: 1446062045 timeCreated: 1446062045
licenseType: Pro licenseType: Pro
MonoImporter: MonoImporter:
serializedVersion: 2 serializedVersion: 2
defaultReferences: [] defaultReferences: []
executionOrder: 0 executionOrder: 0
icon: {instanceID: 0} icon: {instanceID: 0}
userData: userData:
assetBundleName: assetBundleName:
assetBundleVariant: assetBundleVariant:

View File

@ -1,5 +1,5 @@
using System; using System;
using UnityEngine; using UnityEngine;
using System.Collections; using System.Collections;
using UnityEngine.UI; using UnityEngine.UI;
@ -26,4 +26,4 @@ public class ReorderableListDebug : MonoBehaviour
DebugLabel.text += string.Format("From {0} at Index {1} \n", droppedStruct.FromList.name,droppedStruct.FromIndex); DebugLabel.text += string.Format("From {0} at Index {1} \n", droppedStruct.FromList.name,droppedStruct.FromIndex);
DebugLabel.text += string.Format("To {0} at Index {1} \n", droppedStruct.ToList.name,droppedStruct.ToIndex); DebugLabel.text += string.Format("To {0} at Index {1} \n", droppedStruct.ToList.name,droppedStruct.ToIndex);
} }
} }

View File

@ -1,12 +1,12 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 86c224aef3e999140b78d1d7135ba33f guid: 86c224aef3e999140b78d1d7135ba33f
timeCreated: 1446072313 timeCreated: 1446072313
licenseType: Pro licenseType: Pro
MonoImporter: MonoImporter:
serializedVersion: 2 serializedVersion: 2
defaultReferences: [] defaultReferences: []
executionOrder: 0 executionOrder: 0
icon: {instanceID: 0} icon: {instanceID: 0}
userData: userData:
assetBundleName: assetBundleName:
assetBundleVariant: assetBundleVariant:

View File

@ -9,12 +9,16 @@ public class ReorderableListElement : MonoBehaviour, IDragHandler, IBeginDragHan
private readonly List<RaycastResult> _raycastResults = new List<RaycastResult>(); private readonly List<RaycastResult> _raycastResults = new List<RaycastResult>();
private ReorderableList _currentReorderableListRaycasted; private ReorderableList _currentReorderableListRaycasted;
private RectTransform _draggingObject; private RectTransform _draggingObject;
private ReorderableList _reorderableList; private LayoutElement _draggingObjectLE;
private Vector2 _draggingObjectOriginalSize;
private RectTransform _fakeElement; private RectTransform _fakeElement;
private LayoutElement _fakeElementLE;
private int _fromIndex; private int _fromIndex;
private bool _isDragging; private bool _isDragging;
private RectTransform _rect; private RectTransform _rect;
private ReorderableList _reorderableList;
#region IBeginDragHandler Members
public void OnBeginDrag(PointerEventData eventData) public void OnBeginDrag(PointerEventData eventData)
{ {
@ -39,21 +43,29 @@ public class ReorderableListElement : MonoBehaviour, IDragHandler, IBeginDragHan
{ {
GameObject clone = Instantiate(gameObject); GameObject clone = Instantiate(gameObject);
_draggingObject = clone.GetComponent<RectTransform>(); _draggingObject = clone.GetComponent<RectTransform>();
_draggingObject.sizeDelta = gameObject.GetComponent<RectTransform>().sizeDelta;
} }
//Put _dragging object into the draggin area //Put _dragging object into the draggin area
_draggingObjectOriginalSize = gameObject.GetComponent<RectTransform>().rect.size;
_draggingObjectLE = _draggingObject.GetComponent<LayoutElement>();
_draggingObject.SetParent(_reorderableList.DraggableArea, false); _draggingObject.SetParent(_reorderableList.DraggableArea, false);
_draggingObject.SetAsLastSibling(); _draggingObject.SetAsLastSibling();
//Create a fake element for previewing placement //Create a fake element for previewing placement
_fakeElement = new GameObject("Fake").AddComponent<RectTransform>(); _fakeElement = new GameObject("Fake").AddComponent<RectTransform>();
_fakeElement.gameObject.AddComponent<LayoutElement>().preferredHeight = _rect.rect.height; _fakeElementLE = _fakeElement.gameObject.AddComponent<LayoutElement>();
RefreshSizes();
_isDragging = true; _isDragging = true;
} }
#endregion
#region IDragHandler Members
public void OnDrag(PointerEventData eventData) public void OnDrag(PointerEventData eventData)
{ {
if (!_isDragging) if (!_isDragging)
@ -77,7 +89,9 @@ public class ReorderableListElement : MonoBehaviour, IDragHandler, IBeginDragHan
//If nothing found or the list is not dropable, put the fake element outsite //If nothing found or the list is not dropable, put the fake element outsite
if (_currentReorderableListRaycasted == null || _currentReorderableListRaycasted.IsDropable == false) if (_currentReorderableListRaycasted == null || _currentReorderableListRaycasted.IsDropable == false)
{ {
RefreshSizes();
_fakeElement.transform.SetParent(_reorderableList.DraggableArea, false); _fakeElement.transform.SetParent(_reorderableList.DraggableArea, false);
} }
//Else find the best position on the list and put fake element on the right index //Else find the best position on the list and put fake element on the right index
else else
@ -87,10 +101,17 @@ public class ReorderableListElement : MonoBehaviour, IDragHandler, IBeginDragHan
float minDistance = float.PositiveInfinity; float minDistance = float.PositiveInfinity;
int targetIndex = 0; int targetIndex = 0;
float dist = 0;
for (int j = 0; j < _currentReorderableListRaycasted.Content.childCount; j++) for (int j = 0; j < _currentReorderableListRaycasted.Content.childCount; j++)
{ {
var c = _currentReorderableListRaycasted.Content.GetChild(j).GetComponent<RectTransform>(); var c = _currentReorderableListRaycasted.Content.GetChild(j).GetComponent<RectTransform>();
float dist = Mathf.Abs(c.position.y - eventData.position.y);
if (_currentReorderableListRaycasted.ContentLayout is VerticalLayoutGroup)
dist = Mathf.Abs(c.position.y - eventData.position.y);
else if (_currentReorderableListRaycasted.ContentLayout is HorizontalLayoutGroup)
dist = Mathf.Abs(c.position.x - eventData.position.x);
else if (_currentReorderableListRaycasted.ContentLayout is GridLayoutGroup)
dist = (Mathf.Abs(c.position.x - eventData.position.x) + Mathf.Abs(c.position.y - eventData.position.y));
if (dist < minDistance) if (dist < minDistance)
{ {
@ -99,11 +120,17 @@ public class ReorderableListElement : MonoBehaviour, IDragHandler, IBeginDragHan
} }
} }
RefreshSizes();
_fakeElement.SetSiblingIndex(targetIndex); _fakeElement.SetSiblingIndex(targetIndex);
_fakeElement.gameObject.SetActive(true); _fakeElement.gameObject.SetActive(true);
} }
} }
#endregion
#region IEndDragHandler Members
public void OnEndDrag(PointerEventData eventData) public void OnEndDrag(PointerEventData eventData)
{ {
_isDragging = false; _isDragging = false;
@ -114,8 +141,10 @@ public class ReorderableListElement : MonoBehaviour, IDragHandler, IBeginDragHan
//Put the dragged object into the content and at the right index //Put the dragged object into the content and at the right index
if (_currentReorderableListRaycasted != null && _currentReorderableListRaycasted.IsDropable) if (_currentReorderableListRaycasted != null && _currentReorderableListRaycasted.IsDropable)
{ {
RefreshSizes();
_draggingObject.SetParent(_currentReorderableListRaycasted.Content, false); _draggingObject.SetParent(_currentReorderableListRaycasted.Content, false);
_draggingObject.SetSiblingIndex(_fakeElement.GetSiblingIndex()); _draggingObject.SetSiblingIndex(_fakeElement.GetSiblingIndex());
//Send OnelementDropped Event //Send OnelementDropped Event
_reorderableList.OnElementDropped.Invoke(new ReorderableList.ReorderableListEventStruct _reorderableList.OnElementDropped.Invoke(new ReorderableList.ReorderableListEventStruct
@ -129,7 +158,7 @@ public class ReorderableListElement : MonoBehaviour, IDragHandler, IBeginDragHan
ToIndex = _fakeElement.GetSiblingIndex() - 1 ToIndex = _fakeElement.GetSiblingIndex() - 1
}); });
} }
//We don't have an ReorderableList //We don't have an ReorderableList
else else
{ {
//If it's a clone, delete it //If it's a clone, delete it
@ -137,9 +166,10 @@ public class ReorderableListElement : MonoBehaviour, IDragHandler, IBeginDragHan
{ {
Destroy(_draggingObject.gameObject); Destroy(_draggingObject.gameObject);
} }
//Else replace the draggedObject to his first place //Else replace the draggedObject to his first place
else else
{ {
RefreshSizes();
_draggingObject.SetParent(_reorderableList.Content, false); _draggingObject.SetParent(_reorderableList.Content, false);
_draggingObject.SetSiblingIndex(_fromIndex); _draggingObject.SetSiblingIndex(_fromIndex);
} }
@ -151,6 +181,26 @@ public class ReorderableListElement : MonoBehaviour, IDragHandler, IBeginDragHan
Destroy(_fakeElement.gameObject); Destroy(_fakeElement.gameObject);
} }
#endregion
private void RefreshSizes()
{
Vector2 size = _draggingObjectOriginalSize;
if (_currentReorderableListRaycasted != null && _currentReorderableListRaycasted.IsDropable)
{
var firstChild = _currentReorderableListRaycasted.Content.GetChild(0);
if (firstChild != null)
{
size = firstChild.GetComponent<RectTransform>().rect.size;
}
}
_draggingObject.sizeDelta = size;
_fakeElementLE.preferredHeight = _draggingObjectLE.preferredHeight = size.y;
_fakeElementLE.preferredWidth = _draggingObjectLE.preferredWidth = size.x;
}
public void Init(ReorderableList reorderableList) public void Init(ReorderableList reorderableList)
{ {
_reorderableList = reorderableList; _reorderableList = reorderableList;

View File

@ -1,12 +1,12 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 916e98f1b982a9a4082fcc45c87b66c5 guid: 916e98f1b982a9a4082fcc45c87b66c5
timeCreated: 1446072130 timeCreated: 1446072130
licenseType: Pro licenseType: Pro
MonoImporter: MonoImporter:
serializedVersion: 2 serializedVersion: 2
defaultReferences: [] defaultReferences: []
executionOrder: 0 executionOrder: 0
icon: {instanceID: 0} icon: {instanceID: 0}
userData: userData:
assetBundleName: assetBundleName:
assetBundleVariant: assetBundleVariant: