예제 #1
0
        public void RefreshNameOf(Transform target)
        {
            if (target)
            {
                Scene targetScene = target.gameObject.scene;
                for (int i = sceneData.Count - 1; i >= 0; i--)
                {
                    HierarchyDataRoot data = sceneData[i];
                    if ((data is HierarchyDataRootPseudoScene) || ((HierarchyDataRootScene)data).Scene == targetScene)
                    {
                        sceneData[i].RefreshNameOf(target);
                    }
                }

                if (m_isInSearchMode)
                {
                    RefreshSearchResults();

                    for (int i = searchSceneData.Count - 1; i >= 0; i--)
                    {
                        searchSceneData[i].RefreshNameOf(target);
                    }
                }

                for (int i = drawers.Count - 1; i >= 0; i--)
                {
                    if (drawers[i].gameObject.activeSelf && drawers[i].Data.BoundTransform == target)
                    {
                        drawers[i].RefreshName();
                    }
                }

                shouldRecalculateContentWidth = true;
            }
        }
예제 #2
0
        public bool Select(Transform selection, bool forceSelection = false)
        {
            if (!selection)
            {
                Deselect();
                return(true);
            }
            else
            {
                if (!forceSelection && selection == m_currentSelection)
                {
                    return(true);
                }

                CurrentSelection = selection;

                // Make sure that the contents of the hierarchy are up-to-date
                Refresh();

                Scene selectionScene = selection.gameObject.scene;
                for (int i = 0; i < sceneData.Count; i++)
                {
                    HierarchyDataRoot data = sceneData[i];
                    if ((data is HierarchyDataRootPseudoScene) || ((HierarchyDataRootScene)data).Scene == selectionScene)
                    {
                        HierarchyDataTransform selectionItem = sceneData[i].FindTransform(selection);
                        if (selectionItem != null)
                        {
                            RefreshListView();

                            // Focus on selected HierarchyItem
                            int itemIndex = selectionItem.AbsoluteIndex;
                            for (int j = 0; j < i; j++)
                            {
                                itemIndex += sceneData[i].Height;
                            }

                            LayoutRebuilder.ForceRebuildLayoutImmediate(drawArea);
                            scrollView.verticalNormalizedPosition = Mathf.Clamp01(1f - (float)itemIndex / totalItemCount);

                            return(true);
                        }
                    }
                }
            }

            return(false);
        }
 public HierarchyDataRootSearch(RuntimeHierarchy hierarchy, HierarchyDataRoot reference) : base(hierarchy)
 {
     this.reference = reference;
 }
        private bool DropTransformOnto(Transform droppedTransform, HierarchyData target, HierarchyDataRoot newScene, Transform newParent, int newSiblingIndex, out bool decrementSiblingIndex, out bool shouldFocusObjectInHierarchy)
        {
            shouldFocusObjectInHierarchy = false;
            decrementSiblingIndex        = false;

            // If we are only changing the sibling index of the dropped Transform and not its parent, then make sure
            // that the target sibling index won't be affected when the dropped Transform is shifted in the Hierarchy
            if (droppedTransform.parent == newParent)
            {
                if (newParent || (newScene is HierarchyDataRootScene && ((HierarchyDataRootScene)newScene).Scene == droppedTransform.gameObject.scene))
                {
                    if (newSiblingIndex > droppedTransform.GetSiblingIndex())
                    {
                        newSiblingIndex--;
                        decrementSiblingIndex = true;
                    }
                }
                else if (newScene is HierarchyDataRootPseudoScene)
                {
                    int pseudoSceneSiblingIndex = newScene.IndexOf(droppedTransform);
                    if (pseudoSceneSiblingIndex >= 0 && newSiblingIndex > pseudoSceneSiblingIndex)
                    {
                        newSiblingIndex--;
                        decrementSiblingIndex = true;
                    }
                }
            }

            if (newParent)              // Drop inside a Transform
            {
                if (!hierarchy.CanDropDraggedParentOnChild)
                {
                    // Avoid setting child object as parent of the parent object
                    if (newParent.IsChildOf(droppedTransform))
                    {
                        return(false);
                    }
                }
                else
                {
                    Transform curr = newParent;
                    while (curr.parent != null && curr.parent != droppedTransform)
                    {
                        curr = curr.parent;
                    }

                    // First, set the child object's parent as the dropped object's current parent so that
                    // the dropped object can then become a child of the former child object
                    if (curr.parent == droppedTransform)
                    {
                        HierarchyDataRootPseudoScene pseudoScene = target.Root as HierarchyDataRootPseudoScene;
                        int pseudoSceneChildIndex;
                        if (pseudoScene != null && (pseudoSceneChildIndex = pseudoScene.IndexOf(droppedTransform)) >= 0)
                        {
                            // Dropped object was a root pseudo-scene object, swap the child and parent objects in the pseudo-scene, as well
                            if (hierarchy.CanDropDraggedObjectsToPseudoScenes)
                            {
                                pseudoScene.InsertChild(pseudoSceneChildIndex, curr);
                                pseudoScene.RemoveChild(droppedTransform);
                            }
                        }

                        int siblingIndex = droppedTransform.GetSiblingIndex();
                        curr.SetParent(droppedTransform.parent, true);
                        curr.SetSiblingIndex(siblingIndex);

                        shouldFocusObjectInHierarchy = true;
                    }
                }

                droppedTransform.SetParent(newParent, true);
            }
            else             // Drop at the root of a scene
            {
                if (newScene is HierarchyDataRootPseudoScene)
                {
                    if (!hierarchy.CanDropDraggedObjectsToPseudoScenes)
                    {
                        return(false);
                    }

                    // Add object to pseudo-scene
                    if (newSiblingIndex < 0)
                    {
                        ((HierarchyDataRootPseudoScene)newScene).AddChild(droppedTransform);
                    }
                    else
                    {
                        ((HierarchyDataRootPseudoScene)newScene).InsertChild(newSiblingIndex, droppedTransform);

                        // Don't try to change the actual sibling index of the Transform
                        newSiblingIndex = -1;
                        target          = newScene;
                    }
                }
                else if (newScene is HierarchyDataRootScene)
                {
                    if (droppedTransform.parent != null)
                    {
                        droppedTransform.SetParent(null, true);
                    }

                    // Change dropped object's scene
                    Scene scene = ((HierarchyDataRootScene)newScene).Scene;
                    if (droppedTransform.gameObject.scene != scene)
                    {
                        SceneManager.MoveGameObjectToScene(droppedTransform.gameObject, scene);
                    }

                    if (newSiblingIndex < 0)
                    {
                        // If object was dropped onto the scene, add it to the bottom of the scene
                        newSiblingIndex = scene.rootCount + 1;
                        shouldFocusObjectInHierarchy = true;
                    }
                }
            }

            if (newSiblingIndex >= 0)
            {
                droppedTransform.SetSiblingIndex(newSiblingIndex);
            }

            shouldFocusObjectInHierarchy |= (newSiblingIndex < 0 && !target.IsExpanded);
            return(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();
            }
        }
        void IDropHandler.OnDrop(PointerEventData eventData)
        {
            ((IPointerExitHandler)this).OnPointerExit(eventData);

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

            Transform droppedTransform = RuntimeInspectorUtils.GetAssignableObjectFromDraggedReferenceItem(eventData, typeof(Transform)) as Transform;

            if (!droppedTransform)
            {
                return;
            }

            int  newSiblingIndex = -1;
            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 object onto the blank space at the bottom of the Hierarchy
                if (droppedTransform.parent == null)
                {
                    return;
                }

                droppedTransform.SetParent(null, true);
                shouldFocusObjectInHierarchy = true;
            }
            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 Hierarchy AB, if inserting above B, then instead insert below A; it is easier for calculations
                        HierarchyData _target = hierarchy.GetDataAt(dataIndex - 1);
                        if (_target != null)
                        {
                            target          = _target;
                            insertDirection = 1;
                        }
                    }
                    else if (insertDirection > 0 && dataIndex < hierarchy.ItemCount - 1)
                    {
                        // In Hierarchy AB, if inserting below A, then instead insert above B if B is a Transform; it is easier for calculations
                        HierarchyData _target = hierarchy.GetDataAt(dataIndex + 1);
                        if (_target != null && _target is HierarchyDataTransform)
                        {
                            target          = _target;
                            insertDirection = -1;
                        }
                    }
                }

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

                    // Dropped onto itself, ignore
                    if (!newParent || droppedTransform == 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 we are only changing the sibling index of the dropped Transform and not the parent, then make sure
                            // that the target sibling index won't be affected when the dropped Transform is shifted in the Hierarchy
                            if (newParent == droppedTransform.parent && (newParent || (target.Root is HierarchyDataRootScene && ((HierarchyDataRootScene)target.Root).Scene == droppedTransform.gameObject.scene)))
                            {
                                if (newSiblingIndex > droppedTransform.GetSiblingIndex())
                                {
                                    newSiblingIndex--;
                                }
                            }
                        }
                    }

                    if (!newParent)
                    {
                        newScene = target.Root;
                    }
                    else
                    {
                        if (!canDropParentOnChild)
                        {
                            // Avoid setting child object as parent of the parent object
                            if (newParent.IsChildOf(droppedTransform))
                            {
                                return;
                            }
                        }
                        else
                        {
                            // First, set the child object's parent as dropped object's current parent so that
                            // the dropped object can then become a child of the former child object
                            Transform curr = newParent;
                            while (curr.parent != null && curr.parent != droppedTransform)
                            {
                                curr = curr.parent;
                            }

                            if (curr.parent == droppedTransform)
                            {
                                if (droppedTransform.parent == null && target.Root is HierarchyDataRootPseudoScene)
                                {
                                    // Dropped object was a root pseudo-scene object, swap the child and parent objects in the pseudo-scene, as well
                                    if (!canAddObjectsToPseudoScenes)
                                    {
                                        return;
                                    }

                                    HierarchyDataRootPseudoScene pseudoScene = (HierarchyDataRootPseudoScene)target.Root;
                                    pseudoScene.InsertChild(pseudoScene.IndexOf(newParent), curr);
                                    pseudoScene.RemoveChild(newParent);
                                }

                                int siblingIndex = droppedTransform.GetSiblingIndex();
                                curr.SetParent(droppedTransform.parent, true);
                                curr.SetSiblingIndex(siblingIndex);

                                shouldFocusObjectInHierarchy = true;
                            }
                        }

                        droppedTransform.SetParent(newParent, true);
                    }
                }

                if (newScene != null)
                {
                    if (newScene is HierarchyDataRootPseudoScene)
                    {
                        if (!canAddObjectsToPseudoScenes)
                        {
                            return;
                        }

                        // Add object to pseudo-scene
                        if (newSiblingIndex < 0)
                        {
                            ((HierarchyDataRootPseudoScene)newScene).AddChild(droppedTransform);
                        }
                        else
                        {
                            ((HierarchyDataRootPseudoScene)newScene).InsertChild(newSiblingIndex, droppedTransform);

                            // Don't try to change the actual sibling index of the Transform
                            newSiblingIndex = -1;
                            target          = newScene;
                        }
                    }
                    else if (newScene is HierarchyDataRootScene)
                    {
                        if (droppedTransform.parent != null)
                        {
                            droppedTransform.SetParent(null, true);
                        }

                        // Change dropped object's scene
                        Scene scene = ((HierarchyDataRootScene)newScene).Scene;
                        if (droppedTransform.gameObject.scene != scene)
                        {
                            SceneManager.MoveGameObjectToScene(droppedTransform.gameObject, scene);
                        }

                        if (newSiblingIndex < 0)
                        {
                            // If object was dropped onto the scene, add it to the bottom of the scene
                            newSiblingIndex = scene.rootCount + 1;
                            shouldFocusObjectInHierarchy = true;
                        }
                    }
                }

                if (newSiblingIndex >= 0)
                {
                    droppedTransform.SetSiblingIndex(newSiblingIndex);
                }
            }

            // Selecting the object in Hierarchy automatically expands collapsed parent entries and snaps the scroll view to the
            // selected object. However, this snapping can be distracting, so don't select the object unless it is necessary
            if (shouldFocusObjectInHierarchy || (newSiblingIndex < 0 && !target.IsExpanded))
            {
                hierarchy.Select(droppedTransform, true);
            }
            else
            {
                hierarchy.Refresh();
            }
        }