From c8b7085f279b890ac80982d7e90bb25ec70b5928 Mon Sep 17 00:00:00 2001 From: "LARS-LAPTOP2\\larsme" Date: Fri, 22 Feb 2019 18:34:55 +0100 Subject: [PATCH] More Options for ReordableList: - Max item count, after which no more items can be dropped - IsDisplacable option: If true, an item can be dropped into a full list by displacing one of its items, it may replace the dragged item in its origin list, be dropped in space or be deleted depending on the dragged item's origin list and the displaced item - Added respective Events - fixed ever increasing number of _listContent components - Stopped dragged item from blocking Raycasts --- .../ReorderableList/ReorderableList.unity | 232 ++++++++++++++-- .../ReorderableList/ReorderableList.cs | 25 +- .../ReorderableList/ReorderableListElement.cs | 258 +++++++++++++++--- 3 files changed, 445 insertions(+), 70 deletions(-) diff --git a/Examples/ReorderableList/ReorderableList.unity b/Examples/ReorderableList/ReorderableList.unity index b8e11c9..3a363c6 100644 --- a/Examples/ReorderableList/ReorderableList.unity +++ b/Examples/ReorderableList/ReorderableList.unity @@ -38,7 +38,7 @@ RenderSettings: m_ReflectionIntensity: 1 m_CustomReflection: {fileID: 0} m_Sun: {fileID: 0} - m_IndirectSpecularColor: {r: 0.37311953, g: 0.38074014, b: 0.3587274, a: 1} + m_IndirectSpecularColor: {r: 0.3731193, g: 0.38073996, b: 0.35872692, a: 1} --- !u!157 &3 LightmapSettings: m_ObjectHideFlags: 0 @@ -189,6 +189,8 @@ MonoBehaviour: IsDraggable: 1 CloneDraggedObject: 1 IsDropable: 0 + IsDisplacable: 0 + maxItems: 2147483647 OnElementDropped: m_PersistentCalls: m_Calls: [] @@ -209,6 +211,26 @@ MonoBehaviour: m_Calls: [] m_TypeName: UnityEngine.UI.Extensions.ReorderableList+ReorderableListHandler, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + OnElementDisplacedFrom: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.Extensions.ReorderableList+ReorderableListHandler, + Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + OnElementDisplacedTo: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.Extensions.ReorderableList+ReorderableListHandler, + Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + OnElementDisplacedFromReturned: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.Extensions.ReorderableList+ReorderableListHandler, + Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + OnElementDisplacedToReturned: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.Extensions.ReorderableList+ReorderableListHandler, + Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null --- !u!114 &7473526 MonoBehaviour: m_ObjectHideFlags: 0 @@ -321,7 +343,7 @@ RectTransform: m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 1} m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 0, y: 0.0000127977155} + m_AnchoredPosition: {x: 0, y: 0.000008085421} m_SizeDelta: {x: 0, y: 0} m_Pivot: {x: 0.5, y: 1} --- !u!114 &32192511 @@ -520,9 +542,11 @@ MonoBehaviour: Is Draggable = true - Clone Dragged Object = false + IsDroppable = true - Is Droppable = false' + MaxItems = 4, IsDisplacable = True + + Clone Dragged Object = false' --- !u!222 &177188057 CanvasRenderer: m_ObjectHideFlags: 0 @@ -544,7 +568,7 @@ MonoBehaviour: m_MinWidth: -1 m_MinHeight: -1 m_PreferredWidth: -1 - m_PreferredHeight: 88.49 + m_PreferredHeight: 180 m_FlexibleWidth: -1 m_FlexibleHeight: -1 m_LayoutPriority: 1 @@ -584,7 +608,7 @@ RectTransform: m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 1} m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 0, y: 0.0000127977155} + m_AnchoredPosition: {x: 0, y: 0.000015258789} m_SizeDelta: {x: 0, y: 0} m_Pivot: {x: 0.5, y: 1} --- !u!114 &178427160 @@ -909,7 +933,7 @@ MonoBehaviour: m_MinWidth: -1 m_MinHeight: -1 m_PreferredWidth: -1 - m_PreferredHeight: 88.49 + m_PreferredHeight: 180 m_FlexibleWidth: -1 m_FlexibleHeight: -1 m_LayoutPriority: 1 @@ -1230,7 +1254,7 @@ MonoBehaviour: m_MinWidth: -1 m_MinHeight: -1 m_PreferredWidth: -1 - m_PreferredHeight: 88.49 + m_PreferredHeight: 180 m_FlexibleWidth: -1 m_FlexibleHeight: -1 m_LayoutPriority: 1 @@ -1472,6 +1496,8 @@ MonoBehaviour: IsDraggable: 1 CloneDraggedObject: 0 IsDropable: 1 + IsDisplacable: 0 + maxItems: 4 OnElementDropped: m_PersistentCalls: m_Calls: [] @@ -1492,6 +1518,26 @@ MonoBehaviour: m_Calls: [] m_TypeName: UnityEngine.UI.Extensions.ReorderableList+ReorderableListHandler, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + OnElementDisplacedFrom: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.Extensions.ReorderableList+ReorderableListHandler, + Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + OnElementDisplacedTo: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.Extensions.ReorderableList+ReorderableListHandler, + Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + OnElementDisplacedFromReturned: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.Extensions.ReorderableList+ReorderableListHandler, + Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + OnElementDisplacedToReturned: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.Extensions.ReorderableList+ReorderableListHandler, + Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null --- !u!114 &437265566 MonoBehaviour: m_ObjectHideFlags: 0 @@ -1750,6 +1796,8 @@ MonoBehaviour: IsDraggable: 1 CloneDraggedObject: 0 IsDropable: 1 + IsDisplacable: 0 + maxItems: 2147483647 OnElementDropped: m_PersistentCalls: m_Calls: [] @@ -1770,6 +1818,26 @@ MonoBehaviour: m_Calls: [] m_TypeName: UnityEngine.UI.Extensions.ReorderableList+ReorderableListHandler, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + OnElementDisplacedFrom: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.Extensions.ReorderableList+ReorderableListHandler, + Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + OnElementDisplacedTo: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.Extensions.ReorderableList+ReorderableListHandler, + Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + OnElementDisplacedFromReturned: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.Extensions.ReorderableList+ReorderableListHandler, + Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + OnElementDisplacedToReturned: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.Extensions.ReorderableList+ReorderableListHandler, + Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null --- !u!114 &500962420 MonoBehaviour: m_ObjectHideFlags: 0 @@ -1970,7 +2038,7 @@ RectTransform: m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 1} m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0.0000076293945} m_SizeDelta: {x: 0, y: 0} m_Pivot: {x: 0.5, y: 1} --- !u!114 &622440035 @@ -2220,7 +2288,7 @@ RectTransform: m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 1} - m_AnchoredPosition: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0.0000069301664} m_SizeDelta: {x: 0, y: 0} m_Pivot: {x: 0, y: 0.5} --- !u!114 &670178503 @@ -2330,6 +2398,10 @@ MonoBehaviour: Is Draggable = true + IsDroppable = true + + MaxItems = 4, IsDisplacable = False + Clone Dragged Object = false Is Droppable = true' @@ -2354,7 +2426,7 @@ MonoBehaviour: m_MinWidth: -1 m_MinHeight: -1 m_PreferredWidth: -1 - m_PreferredHeight: 88.49 + m_PreferredHeight: 180 m_FlexibleWidth: -1 m_FlexibleHeight: -1 m_LayoutPriority: 1 @@ -2542,7 +2614,7 @@ MonoBehaviour: m_MinWidth: -1 m_MinHeight: -1 m_PreferredWidth: -1 - m_PreferredHeight: 88.49 + m_PreferredHeight: 180 m_FlexibleWidth: -1 m_FlexibleHeight: -1 m_LayoutPriority: 1 @@ -2760,7 +2832,7 @@ MonoBehaviour: m_MinWidth: -1 m_MinHeight: -1 m_PreferredWidth: -1 - m_PreferredHeight: 88.49 + m_PreferredHeight: 180 m_FlexibleWidth: -1 m_FlexibleHeight: -1 m_LayoutPriority: 1 @@ -2972,6 +3044,8 @@ MonoBehaviour: IsDraggable: 1 CloneDraggedObject: 0 IsDropable: 1 + IsDisplacable: 0 + maxItems: 2147483647 OnElementDropped: m_PersistentCalls: m_Calls: [] @@ -2992,6 +3066,26 @@ MonoBehaviour: m_Calls: [] m_TypeName: UnityEngine.UI.Extensions.ReorderableList+ReorderableListHandler, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + OnElementDisplacedFrom: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.Extensions.ReorderableList+ReorderableListHandler, + Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + OnElementDisplacedTo: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.Extensions.ReorderableList+ReorderableListHandler, + Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + OnElementDisplacedFromReturned: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.Extensions.ReorderableList+ReorderableListHandler, + Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + OnElementDisplacedToReturned: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.Extensions.ReorderableList+ReorderableListHandler, + Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null --- !u!114 &835752199 MonoBehaviour: m_ObjectHideFlags: 0 @@ -3206,7 +3300,7 @@ MonoBehaviour: m_MinWidth: -1 m_MinHeight: -1 m_PreferredWidth: -1 - m_PreferredHeight: 88.49 + m_PreferredHeight: 180 m_FlexibleWidth: -1 m_FlexibleHeight: -1 m_LayoutPriority: 1 @@ -3266,6 +3360,8 @@ MonoBehaviour: IsDraggable: 0 CloneDraggedObject: 0 IsDropable: 1 + IsDisplacable: 0 + maxItems: 2147483647 OnElementDropped: m_PersistentCalls: m_Calls: [] @@ -3286,6 +3382,26 @@ MonoBehaviour: m_Calls: [] m_TypeName: UnityEngine.UI.Extensions.ReorderableList+ReorderableListHandler, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + OnElementDisplacedFrom: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.Extensions.ReorderableList+ReorderableListHandler, + Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + OnElementDisplacedTo: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.Extensions.ReorderableList+ReorderableListHandler, + Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + OnElementDisplacedFromReturned: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.Extensions.ReorderableList+ReorderableListHandler, + Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + OnElementDisplacedToReturned: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.Extensions.ReorderableList+ReorderableListHandler, + Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null --- !u!114 &962628936 MonoBehaviour: m_ObjectHideFlags: 0 @@ -3564,8 +3680,8 @@ RectTransform: m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 0, y: 75} - m_SizeDelta: {x: 0, y: -150} + m_AnchoredPosition: {x: 0, y: 35.6} + m_SizeDelta: {x: 0, y: -111.2} m_Pivot: {x: 0.5, y: 0.5} --- !u!114 &1036076373 MonoBehaviour: @@ -3584,7 +3700,7 @@ MonoBehaviour: m_Top: 0 m_Bottom: 0 m_ChildAlignment: 0 - m_Spacing: 50 + m_Spacing: 40 m_ChildForceExpandWidth: 1 m_ChildForceExpandHeight: 1 m_ChildControlWidth: 1 @@ -3685,7 +3801,7 @@ MonoBehaviour: m_MinWidth: -1 m_MinHeight: -1 m_PreferredWidth: -1 - m_PreferredHeight: 88.49 + m_PreferredHeight: 180 m_FlexibleWidth: -1 m_FlexibleHeight: -1 m_LayoutPriority: 1 @@ -4482,7 +4598,7 @@ RectTransform: m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 1} m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0.0000076293945} m_SizeDelta: {x: 0, y: 0} m_Pivot: {x: 0.5, y: 1} --- !u!114 &1527828930 @@ -5203,7 +5319,7 @@ RectTransform: m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 0} m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 138} + m_SizeDelta: {x: 0, y: 91.2} m_Pivot: {x: 0.5, y: 0} --- !u!114 &1739629088 MonoBehaviour: @@ -5228,9 +5344,9 @@ MonoBehaviour: m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} m_FontSize: 20 m_FontStyle: 0 - m_BestFit: 0 - m_MinSize: 10 - m_MaxSize: 40 + m_BestFit: 1 + m_MinSize: 1 + m_MaxSize: 300 m_Alignment: 4 m_AlignByGeometry: 0 m_RichText: 1 @@ -5292,7 +5408,7 @@ RectTransform: m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 1} m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 0, y: 0.0000127977155} + m_AnchoredPosition: {x: 0, y: 0.000038146973} m_SizeDelta: {x: 0, y: 0} m_Pivot: {x: 0.5, y: 1} --- !u!114 &1789326610 @@ -5561,7 +5677,9 @@ MonoBehaviour: DraggableArea: {fileID: 853621234} IsDraggable: 1 CloneDraggedObject: 0 - IsDropable: 0 + IsDropable: 1 + IsDisplacable: 0 + maxItems: 4 OnElementDropped: m_PersistentCalls: m_Calls: [] @@ -5582,6 +5700,26 @@ MonoBehaviour: m_Calls: [] m_TypeName: UnityEngine.UI.Extensions.ReorderableList+ReorderableListHandler, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + OnElementDisplacedFrom: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.Extensions.ReorderableList+ReorderableListHandler, + Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + OnElementDisplacedTo: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.Extensions.ReorderableList+ReorderableListHandler, + Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + OnElementDisplacedFromReturned: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.Extensions.ReorderableList+ReorderableListHandler, + Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + OnElementDisplacedToReturned: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.Extensions.ReorderableList+ReorderableListHandler, + Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null --- !u!114 &1893066122 MonoBehaviour: m_ObjectHideFlags: 0 @@ -6016,6 +6154,8 @@ MonoBehaviour: IsDraggable: 1 CloneDraggedObject: 1 IsDropable: 0 + IsDisplacable: 0 + maxItems: 2147483647 OnElementDropped: m_PersistentCalls: m_Calls: [] @@ -6036,6 +6176,26 @@ MonoBehaviour: m_Calls: [] m_TypeName: UnityEngine.UI.Extensions.ReorderableList+ReorderableListHandler, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + OnElementDisplacedFrom: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.Extensions.ReorderableList+ReorderableListHandler, + Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + OnElementDisplacedTo: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.Extensions.ReorderableList+ReorderableListHandler, + Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + OnElementDisplacedFromReturned: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.Extensions.ReorderableList+ReorderableListHandler, + Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + OnElementDisplacedToReturned: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.Extensions.ReorderableList+ReorderableListHandler, + Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null --- !u!114 &1960731673 MonoBehaviour: m_ObjectHideFlags: 0 @@ -6256,6 +6416,8 @@ MonoBehaviour: IsDraggable: 1 CloneDraggedObject: 1 IsDropable: 0 + IsDisplacable: 0 + maxItems: 2147483647 OnElementDropped: m_PersistentCalls: m_Calls: [] @@ -6276,6 +6438,26 @@ MonoBehaviour: m_Calls: [] m_TypeName: UnityEngine.UI.Extensions.ReorderableList+ReorderableListHandler, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + OnElementDisplacedFrom: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.Extensions.ReorderableList+ReorderableListHandler, + Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + OnElementDisplacedTo: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.Extensions.ReorderableList+ReorderableListHandler, + Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + OnElementDisplacedFromReturned: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.Extensions.ReorderableList+ReorderableListHandler, + Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + OnElementDisplacedToReturned: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.Extensions.ReorderableList+ReorderableListHandler, + Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null --- !u!114 &2076596391 MonoBehaviour: m_ObjectHideFlags: 0 diff --git a/Scripts/Controls/ReorderableList/ReorderableList.cs b/Scripts/Controls/ReorderableList/ReorderableList.cs index 1f0da59..30e256e 100644 --- a/Scripts/Controls/ReorderableList/ReorderableList.cs +++ b/Scripts/Controls/ReorderableList/ReorderableList.cs @@ -6,6 +6,7 @@ using UnityEngine.Events; namespace UnityEngine.UI.Extensions { + [RequireComponent(typeof(RectTransform)), DisallowMultipleComponent] [AddComponentMenu("UI/Extensions/Re-orderable list")] public class ReorderableList : MonoBehaviour @@ -17,18 +18,29 @@ namespace UnityEngine.UI.Extensions [Tooltip("Can items be dragged from the container?")] public bool IsDraggable = true; + [Tooltip("Should the draggable components be removed or cloned?")] public bool CloneDraggedObject = false; [Tooltip("Can new draggable items be dropped in to the container?")] public bool IsDropable = true; - + + [Tooltip("Should dropped items displace a current item if the list is full?\n " + + "Depending on the dropped items origin list, the displaced item may be added, dropped in space or deleted.")] + public bool IsDisplacable = false; + + public int maxItems = int.MaxValue; + [Header("UI Re-orderable Events")] public ReorderableListHandler OnElementDropped = new ReorderableListHandler(); public ReorderableListHandler OnElementGrabbed = new ReorderableListHandler(); public ReorderableListHandler OnElementRemoved = new ReorderableListHandler(); public ReorderableListHandler OnElementAdded = new ReorderableListHandler(); + public ReorderableListHandler OnElementDisplacedFrom = new ReorderableListHandler(); + public ReorderableListHandler OnElementDisplacedTo = new ReorderableListHandler(); + public ReorderableListHandler OnElementDisplacedFromReturned = new ReorderableListHandler(); + public ReorderableListHandler OnElementDisplacedToReturned = new ReorderableListHandler(); private RectTransform _content; private ReorderableListContent _listContent; @@ -49,7 +61,7 @@ namespace UnityEngine.UI.Extensions { Transform t = transform; Canvas canvas = null; - + int lvlLimit = 100; int lvl = 0; @@ -66,17 +78,18 @@ namespace UnityEngine.UI.Extensions } return canvas; } - + /// /// Refresh related list content /// public void Refresh() { + Destroy(_listContent); _listContent = ContentLayout.gameObject.AddComponent(); _listContent.Init(this); } - private void Awake() + private void Start() { if (ContentLayout == null) @@ -97,6 +110,7 @@ namespace UnityEngine.UI.Extensions Refresh(); } + #region Nested type: ReorderableListEventStruct [Serializable] @@ -118,6 +132,7 @@ namespace UnityEngine.UI.Extensions #endregion + #region Nested type: ReorderableListHandler [Serializable] @@ -133,4 +148,4 @@ namespace UnityEngine.UI.Extensions #endregion } -} \ No newline at end of file +} diff --git a/Scripts/Controls/ReorderableList/ReorderableListElement.cs b/Scripts/Controls/ReorderableList/ReorderableListElement.cs index fc01c40..4c227fe 100644 --- a/Scripts/Controls/ReorderableList/ReorderableListElement.cs +++ b/Scripts/Controls/ReorderableList/ReorderableListElement.cs @@ -22,21 +22,33 @@ namespace UnityEngine.UI.Extensions private readonly List _raycastResults = new List(); private ReorderableList _currentReorderableListRaycasted; + + private int _fromIndex; private RectTransform _draggingObject; private LayoutElement _draggingObjectLE; private Vector2 _draggingObjectOriginalSize; + private RectTransform _fakeElement; private LayoutElement _fakeElementLE; - private int _fromIndex; + + private int _displacedFromIndex; + private RectTransform _displacedObject; + private LayoutElement _displacedObjectLE; + private Vector2 _displacedObjectOriginalSize; + private ReorderableList _displacedObjectOriginList; + private bool _isDragging; private RectTransform _rect; private ReorderableList _reorderableList; + private CanvasGroup _canvasGroup; internal bool isValid; + #region IBeginDragHandler Members public void OnBeginDrag(PointerEventData eventData) { + _canvasGroup.blocksRaycasts = false; isValid = true; if (_reorderableList == null) return; @@ -48,22 +60,23 @@ namespace UnityEngine.UI.Extensions return; } - //If CloneDraggedObject just set draggingObject to this gameobject + //If not CloneDraggedObject just set draggingObject to this gameobject if (_reorderableList.CloneDraggedObject == false) { _draggingObject = _rect; _fromIndex = _rect.GetSiblingIndex(); + _displacedFromIndex = -1; //Send OnElementRemoved Event if (_reorderableList.OnElementRemoved != null) { _reorderableList.OnElementRemoved.Invoke(new ReorderableList.ReorderableListEventStruct - { - DroppedObject = _draggingObject.gameObject, - IsAClone = _reorderableList.CloneDraggedObject, - SourceObject = _reorderableList.CloneDraggedObject ? gameObject : _draggingObject.gameObject, - FromList = _reorderableList, - FromIndex = _fromIndex, - }); + { + DroppedObject = _draggingObject.gameObject, + IsAClone = _reorderableList.CloneDraggedObject, + SourceObject = _reorderableList.CloneDraggedObject ? gameObject : _draggingObject.gameObject, + FromList = _reorderableList, + FromIndex = _fromIndex, + }); } if (isValid == false) { @@ -71,9 +84,9 @@ namespace UnityEngine.UI.Extensions return; } } - //Else Duplicate else { + //Else Duplicate GameObject clone = (GameObject)Instantiate(gameObject); _draggingObject = clone.GetComponent(); } @@ -83,6 +96,7 @@ namespace UnityEngine.UI.Extensions _draggingObjectLE = _draggingObject.GetComponent(); _draggingObject.SetParent(_reorderableList.DraggableArea, true); _draggingObject.SetAsLastSibling(); + _reorderableList.Refresh(); //Create a fake element for previewing placement _fakeElement = new GameObject("Fake").AddComponent(); @@ -94,13 +108,13 @@ namespace UnityEngine.UI.Extensions if (_reorderableList.OnElementGrabbed != null) { _reorderableList.OnElementGrabbed.Invoke(new ReorderableList.ReorderableListEventStruct - { - DroppedObject = _draggingObject.gameObject, - IsAClone = _reorderableList.CloneDraggedObject, - SourceObject = _reorderableList.CloneDraggedObject ? gameObject : _draggingObject.gameObject, - FromList = _reorderableList, - FromIndex = _fromIndex, - }); + { + DroppedObject = _draggingObject.gameObject, + IsAClone = _reorderableList.CloneDraggedObject, + SourceObject = _reorderableList.CloneDraggedObject ? gameObject : _draggingObject.gameObject, + FromList = _reorderableList, + FromIndex = _fromIndex, + }); if (!isValid) { @@ -114,6 +128,7 @@ namespace UnityEngine.UI.Extensions #endregion + #region IDragHandler Members public void OnDrag(PointerEventData eventData) @@ -132,6 +147,8 @@ namespace UnityEngine.UI.Extensions canvas.renderMode != RenderMode.ScreenSpaceOverlay ? canvas.worldCamera : null, out worldPoint); _draggingObject.position = worldPoint; + ReorderableList _oldReorderableListRaycasted = _currentReorderableListRaycasted; + //Check everything under the cursor to find a ReorderableList EventSystem.current.RaycastAll(eventData, _raycastResults); for (int i = 0; i < _raycastResults.Count; i++) @@ -144,17 +161,28 @@ namespace UnityEngine.UI.Extensions } //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 + || (_oldReorderableListRaycasted != _reorderableList && !IsTransferable) + || ((_fakeElement.parent == _currentReorderableListRaycasted.Content + ? _currentReorderableListRaycasted.Content.childCount - 1 + : _currentReorderableListRaycasted.Content.childCount) >= _currentReorderableListRaycasted.maxItems && !_currentReorderableListRaycasted.IsDisplacable) + || _currentReorderableListRaycasted.maxItems <= 0) { RefreshSizes(); _fakeElement.transform.SetParent(_reorderableList.DraggableArea, false); - + // revert the displaced element when not hovering over its list + if (_displacedObject != null) + { + revertDisplacedElement(); + } } - //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 { - if (_fakeElement.parent != _currentReorderableListRaycasted) + if (_currentReorderableListRaycasted.Content.childCount < _currentReorderableListRaycasted.maxItems && _fakeElement.parent != _currentReorderableListRaycasted.Content) + { _fakeElement.SetParent(_currentReorderableListRaycasted.Content, false); + } float minDistance = float.PositiveInfinity; int targetIndex = 0; @@ -176,7 +204,24 @@ namespace UnityEngine.UI.Extensions targetIndex = j; } } - + if ((_currentReorderableListRaycasted != _oldReorderableListRaycasted || targetIndex != _displacedFromIndex) + && _currentReorderableListRaycasted.Content.childCount == _currentReorderableListRaycasted.maxItems) + { + Transform toDisplace = _currentReorderableListRaycasted.Content.GetChild(targetIndex); + if (_displacedObject != null) + { + revertDisplacedElement(); + if (_currentReorderableListRaycasted.Content.childCount > _currentReorderableListRaycasted.maxItems) + { + displaceElement(targetIndex, toDisplace); + } + } + else if (_fakeElement.parent != _currentReorderableListRaycasted.Content) + { + _fakeElement.SetParent(_currentReorderableListRaycasted.Content, false); + displaceElement(targetIndex, toDisplace); + } + } RefreshSizes(); _fakeElement.SetSiblingIndex(targetIndex); _fakeElement.gameObject.SetActive(true); @@ -186,6 +231,117 @@ namespace UnityEngine.UI.Extensions #endregion + + #region Displacement + + private void displaceElement(int targetIndex, Transform displaced) + { + _displacedFromIndex = targetIndex; + _displacedObjectOriginList = _currentReorderableListRaycasted; + _displacedObject = displaced.GetComponent(); + _displacedObjectLE = _displacedObject.GetComponent(); + _displacedObjectOriginalSize = _displacedObject.rect.size; + + var args = new ReorderableList.ReorderableListEventStruct + { + DroppedObject = _displacedObject.gameObject, + FromList = _currentReorderableListRaycasted, + FromIndex = targetIndex, + }; + + + int c = _fakeElement.parent == _reorderableList.Content + ? _reorderableList.Content.childCount - 1 + : _reorderableList.Content.childCount; + + if (_reorderableList.IsDropable && c < _reorderableList.maxItems && _displacedObject.GetComponent().IsTransferable) + { + _displacedObjectLE.preferredWidth = _draggingObjectOriginalSize.x; + _displacedObjectLE.preferredHeight = _draggingObjectOriginalSize.y; + _displacedObject.SetParent(_reorderableList.Content, false); + _displacedObject.rotation = _reorderableList.transform.rotation; + _displacedObject.SetSiblingIndex(_fromIndex); + // Force refreshing both lists because otherwise we get inappropriate FromList in ReorderableListEventStruct + _reorderableList.Refresh(); + _currentReorderableListRaycasted.Refresh(); + + args.ToList = _reorderableList; + args.ToIndex = _fromIndex; + _reorderableList.OnElementDisplacedTo.Invoke(args); + _reorderableList.OnElementAdded.Invoke(args); + } + else if (_displacedObject.GetComponent().isDroppableInSpace) + { + _displacedObject.SetParent(_currentReorderableListRaycasted.DraggableArea, true); + _currentReorderableListRaycasted.Refresh(); + _displacedObject.position += new Vector3(_draggingObjectOriginalSize.x / 2, _draggingObjectOriginalSize.y / 2, 0); + } + else + { + _displacedObject.SetParent(null, true); + _displacedObjectOriginList.Refresh(); + _displacedObject.gameObject.SetActive(false); + } + _displacedObjectOriginList.OnElementDisplacedFrom.Invoke(args); + _reorderableList.OnElementRemoved.Invoke(args); + } + + private void revertDisplacedElement() + { + var args = new ReorderableList.ReorderableListEventStruct + { + DroppedObject = _displacedObject.gameObject, + FromList = _displacedObjectOriginList, + FromIndex = _displacedFromIndex, + }; + if (_displacedObject.parent != null) + { + args.ToList = _reorderableList; + args.ToIndex = _fromIndex; + } + + _displacedObjectLE.preferredWidth = _displacedObjectOriginalSize.x; + _displacedObjectLE.preferredHeight = _displacedObjectOriginalSize.y; + _displacedObject.SetParent(_displacedObjectOriginList.Content, false); + _displacedObject.rotation = _displacedObjectOriginList.transform.rotation; + _displacedObject.SetSiblingIndex(_displacedFromIndex); + _displacedObject.gameObject.SetActive(true); + + // Force refreshing both lists because otherwise we get inappropriate FromList in ReorderableListEventStruct + _reorderableList.Refresh(); + _displacedObjectOriginList.Refresh(); + + if (args.ToList != null) + { + _reorderableList.OnElementDisplacedToReturned.Invoke(args); + _reorderableList.OnElementRemoved.Invoke(args); + } + _displacedObjectOriginList.OnElementDisplacedFromReturned.Invoke(args); + _displacedObjectOriginList.OnElementAdded.Invoke(args); + + _displacedFromIndex = -1; + _displacedObjectOriginList = null; + _displacedObject = null; + _displacedObjectLE = null; + + } + + + public void finishDisplacingElement() + { + if (_displacedObject.parent == null) + { + Destroy(_displacedObject.gameObject); + } + _displacedFromIndex = -1; + _displacedObjectOriginList = null; + _displacedObject = null; + _displacedObjectLE = null; + } + + #endregion + + #region IEndDragHandler Members public void OnEndDrag(PointerEventData eventData) @@ -194,10 +350,9 @@ namespace UnityEngine.UI.Extensions if (_draggingObject != null) { - //If we have a, ReorderableList that is dropable + //If we have a ReorderableList that is dropable //Put the dragged object into the content and at the right index - if (_currentReorderableListRaycasted != null && _currentReorderableListRaycasted.IsDropable - && (IsTransferable || _currentReorderableListRaycasted == _reorderableList )) + if (_currentReorderableListRaycasted != null && _fakeElement.parent == _currentReorderableListRaycasted.Content) { var args = new ReorderableList.ReorderableListEventStruct { @@ -223,14 +378,21 @@ namespace UnityEngine.UI.Extensions _draggingObject.SetParent(_currentReorderableListRaycasted.Content, false); _draggingObject.rotation = _currentReorderableListRaycasted.transform.rotation; _draggingObject.SetSiblingIndex(_fakeElement.GetSiblingIndex()); - - _reorderableList.OnElementAdded.Invoke(args); - // Force refreshing both lists because otherwise we get inappropriate FromList in ReorderableListEventStruct _reorderableList.Refresh(); _currentReorderableListRaycasted.Refresh(); - if(!isValid) throw new Exception("It's too late to cancel the Transfer! Do so in OnElementDropped!"); + _reorderableList.OnElementAdded.Invoke(args); + + + if (_displacedObject != null) + { + finishDisplacingElement(); + } + + if (!isValid) + throw new Exception("It's too late to cancel the Transfer! Do so in OnElementDropped!"); + } //We don't have an ReorderableList @@ -239,14 +401,14 @@ namespace UnityEngine.UI.Extensions if (this.isDroppableInSpace) { _reorderableList.OnElementDropped.Invoke(new ReorderableList.ReorderableListEventStruct - { - DroppedObject = _draggingObject.gameObject, - IsAClone = _reorderableList.CloneDraggedObject, - SourceObject = - _reorderableList.CloneDraggedObject ? gameObject : _draggingObject.gameObject, - FromList = _reorderableList, - FromIndex = _fromIndex - }); + { + DroppedObject = _draggingObject.gameObject, + IsAClone = _reorderableList.CloneDraggedObject, + SourceObject = + _reorderableList.CloneDraggedObject ? gameObject : _draggingObject.gameObject, + FromList = _reorderableList, + FromIndex = _fromIndex + }); } else { @@ -254,14 +416,19 @@ namespace UnityEngine.UI.Extensions } } } - + //Delete fake element if (_fakeElement != null) + { Destroy(_fakeElement.gameObject); + _fakeElement = null; + } + _canvasGroup.blocksRaycasts = true; } #endregion + void CancelDrag() { _isDragging = false; @@ -290,16 +457,26 @@ namespace UnityEngine.UI.Extensions ToIndex = _fromIndex }; + _reorderableList.Refresh(); _reorderableList.OnElementAdded.Invoke(args); - if (!isValid) throw new Exception("Transfer is already Cancelled."); + if (!isValid) + throw new Exception("Transfer is already Cancelled."); } //Delete fake element if (_fakeElement != null) + { Destroy(_fakeElement.gameObject); + _fakeElement = null; + } + if (_displacedObject != null) + { + revertDisplacedElement(); + } + _canvasGroup.blocksRaycasts = true; } private void RefreshSizes() @@ -314,7 +491,7 @@ namespace UnityEngine.UI.Extensions size = firstChild.GetComponent().rect.size; } } - + _draggingObject.sizeDelta = size; _fakeElementLE.preferredHeight = _draggingObjectLE.preferredHeight = size.y; _fakeElementLE.preferredWidth = _draggingObjectLE.preferredWidth = size.x; @@ -325,6 +502,7 @@ namespace UnityEngine.UI.Extensions { _reorderableList = reorderableList; _rect = GetComponent(); + _canvasGroup = gameObject.GetOrAddComponent(); } } }