Пример #1
0
        void IDropHandler.OnDrop(PointerEventData eventData)
        {
            object[] assignableObjects = RuntimeInspectorUtils.GetAssignableObjectsFromDraggedReferenceItem(eventData, elementType);
            if (assignableObjects != null && assignableObjects.Length > 0)
            {
                int prevLength = Length;
                if (!OnSizeChanged(null, (prevLength + assignableObjects.Length).ToString(RuntimeInspectorUtils.numberFormat)))
                {
                    return;
                }

                if (isArray)
                {
                    Array _array = (Array)Value;
                    for (int i = 0; i < assignableObjects.Length; i++)
                    {
                        _array.SetValue(assignableObjects[i], prevLength + i);
                    }

                    Value = _array;
                }
                else
                {
                    IList _list = (IList)Value;
                    for (int i = 0; i < assignableObjects.Length; i++)
                    {
                        _list[prevLength + i] = assignableObjects[i];
                    }

                    Value = _list;
                }

                if (!IsExpanded)
                {
                    IsExpanded = true;
                }
            }
        }
        void IDropHandler.OnDrop(PointerEventData eventData)
        {
            ((IPointerExitHandler)this).OnPointerExit(eventData);

            if (!hierarchy.CanReorganizeItems || hierarchy.IsInSearchMode)
            {
                return;
            }

            Transform[] droppedTransforms = RuntimeInspectorUtils.GetAssignableObjectsFromDraggedReferenceItem <Transform>(eventData);
            if (droppedTransforms == null || droppedTransforms.Length == 0)
            {
                return;
            }

            // Sorting the selection is necessary to preserve the sibling index order of the dragged Transforms
            if (droppedTransforms.Length > 1)
            {
                System.Array.Sort(droppedTransforms, (transform1, transform2) => CompareHierarchySiblingIndices(transform1, transform2));
            }

            bool shouldFocusObjectInHierarchy = false;

            float         contentYPos = pointerLastYPos + content.anchoredPosition.y;
            int           dataIndex   = (int)contentYPos / hierarchy.Skin.LineHeight;
            HierarchyData target      = hierarchy.GetDataAt(dataIndex);

            if (target == null)
            {
                // Dropped Transform(s) onto the blank space at the bottom of the Hierarchy
                for (int i = 0; i < droppedTransforms.Length; i++)
                {
                    if (droppedTransforms[i].parent != null)
                    {
                        droppedTransforms[i].SetParent(null, true);
                        shouldFocusObjectInHierarchy = true;
                    }
                }

                if (!shouldFocusObjectInHierarchy)
                {
                    return;
                }
            }
            else
            {
                int   insertDirection;
                float relativePosition = contentYPos % hierarchy.Skin.LineHeight;
                if (relativePosition < siblingIndexModificationArea)
                {
                    insertDirection = -1;
                }
                else if (relativePosition > hierarchy.Skin.LineHeight - siblingIndexModificationArea)
                {
                    insertDirection = 1;
                }
                else
                {
                    insertDirection = 0;
                }

                // Inserting above/below a scene or pseudo-scene is a special case
                if (insertDirection != 0 && !(target is HierarchyDataTransform))
                {
                    if (insertDirection < 0 && dataIndex > 0)
                    {
                        // In an hierarchy with consecutive items A and B, insert below A instead of inserting above B because it makes calculations easier
                        HierarchyData _target = hierarchy.GetDataAt(dataIndex - 1);
                        if (_target != null)
                        {
                            target          = _target;
                            insertDirection = 1;
                        }
                    }
                    else if (insertDirection > 0 && dataIndex < hierarchy.ItemCount - 1)
                    {
                        // In an hierarchy with consecutive items A and B where B is a Transform, insert above B instead of inserting below A because it makes calculations easier
                        HierarchyData _target = hierarchy.GetDataAt(dataIndex + 1);
                        if (_target != null && _target is HierarchyDataTransform)
                        {
                            target          = _target;
                            insertDirection = -1;
                        }
                    }
                }

                HierarchyDataRoot newScene  = null;
                Transform         newParent = null;
                int newSiblingIndex         = -1;
                if (!(target is HierarchyDataTransform))
                {
                    // Dropped onto a scene or pseudo-scene
                    newScene = (HierarchyDataRoot)target;
                }
                else
                {
                    // Dropped onto a Transform
                    newParent = ((HierarchyDataTransform)target).BoundTransform;
                    if (!newParent)
                    {
                        return;
                    }

                    if (insertDirection != 0)
                    {
                        if (insertDirection > 0 && target.Height > 1)
                        {
                            // Dropped below an expanded Transform, make dropped object a child of it
                            newSiblingIndex = 0;
                        }
                        else if (target.Depth == 1 && target.Root is HierarchyDataRootPseudoScene)
                        {
                            // Dropped above or below a root pseudo-scene object, don't actually change the parent
                            if (insertDirection < 0)
                            {
                                newSiblingIndex = ((HierarchyDataRootPseudoScene)target.Root).IndexOf(newParent);
                            }
                            else
                            {
                                newSiblingIndex = ((HierarchyDataRootPseudoScene)target.Root).IndexOf(newParent) + 1;
                            }

                            newParent = null;
                        }
                        else
                        {
                            // Dropped above or below a regular Transform, calculate target sibling index
                            if (insertDirection < 0)
                            {
                                newSiblingIndex = newParent.GetSiblingIndex();
                            }
                            else
                            {
                                newSiblingIndex = newParent.GetSiblingIndex() + 1;
                            }

                            // To be able to drop the object at that sibling index, object's parent must also be changed
                            newParent = newParent.parent;
                        }
                    }

                    if (!newParent)
                    {
                        newScene = target.Root;
                    }
                }

                int successfullyDroppedTransformCount = 0;
                for (int i = 0; i < droppedTransforms.Length; i++)
                {
                    bool _shouldFocusObjectInHierarchy, decrementSiblingIndex;
                    if (DropTransformOnto(droppedTransforms[i], target, newScene, newParent, (newSiblingIndex >= 0) ? (newSiblingIndex + successfullyDroppedTransformCount) : newSiblingIndex, out decrementSiblingIndex, out _shouldFocusObjectInHierarchy))
                    {
                        successfullyDroppedTransformCount++;
                        shouldFocusObjectInHierarchy |= _shouldFocusObjectInHierarchy;

                        if (decrementSiblingIndex)
                        {
                            newSiblingIndex--;
                        }
                    }
                }

                if (successfullyDroppedTransformCount == 0)
                {
                    return;
                }
            }

            // Don't reveal the selection unless it's necessary (i.e. selection is already fully visible)
            if (shouldFocusObjectInHierarchy)
            {
                hierarchy.SelectInternal(droppedTransforms, RuntimeHierarchy.SelectOptions.FocusOnSelection | RuntimeHierarchy.SelectOptions.ForceRevealSelection);
            }
            else
            {
                hierarchy.Refresh();
            }
        }