示例#1
0
        public override void OnGUI(Rect position)
        {
            if (!_initialised)
            {
                _originalPosition = editorWindow.position.position;
                _initialised      = true;
            }

            Event e        = Event.current;
            bool  additive = e.control || e.command || e.shift;

            GUIUtility.hotControl = 0;

            int highlightedIndex = -1;

            // Scrolling behaviour.
            if (e.type == EventType.ScrollWheel)
            {
                _scrollDelta = Math.Sign(e.delta.y);
            }

            if (_scrollDelta != 0)
            {
                ScrollPosition += _scrollDelta;
                ScrollPosition  = Mathf.Clamp(ScrollPosition, 0, TotalSelection.Count - 1);
                Rect tempRect = editorWindow.position;
                tempRect.position     = new Vector2(_originalPosition.x, _originalPosition.y - ScrollPosition * Height);
                editorWindow.position = tempRect;
                _scrollDelta          = 0;
            }

            //Top and bottom borders (to fix a weird issue where the top 5 pixels of the window do not receive mouse events)
            EditorGUI.DrawRect(new Rect(0, 0, Width, 5), GUI.color);
            EditorGUI.DrawRect(new Rect(0, 6 + Height * TotalSelection.Count, Width, 5), GUI.color);

            Rect separatorTopRect = new Rect(0, 5, Width, 1);

            EditorGUI.DrawRect(separatorTopRect, BoxBorderColor);

            for (var i = 0; i < TotalSelection.Count; i++)
            {
                SelectionItem selectionItem = TotalSelection[i];
                GameObject    gameObject    = selectionItem.GameObject;
                GUIContent[]  icons         = selectionItem.Icons;

                Rect     boxRect = new Rect(0, 5 + 1 + i * Height, Width, Height);
                GUIStyle labelStyle;

                bool isInSelection = _currentSelection.Contains(gameObject);
                bool containsMouse = boxRect.Contains(e.mousePosition);
                if (containsMouse)
                {
                    highlightedIndex = i;
                }

                EditorGUI.DrawRect(boxRect, BoxBorderColor);

                if (isInSelection)
                {
                    if (containsMouse)
                    {
                        // If we're not holding it will solely select this object, otherwise it will be a deselection.
                        GUI.color = !additive
                                                        ? new Color(0f, 0.5f, 1f)
                                                        : new Color(0.58f, 0.62f, 0.75f);
                    }
                    else
                    {
                        // If we're not holding control and we're not hovering it will deselect these, so show that preview.
                        // Otherwise, we will be selecting additionally.
                        GUI.color = !additive
                                                        ? new Color(0.58f, 0.62f, 0.75f)
                                                        : new Color(0f, 0.5f, 1f);
                    }

                    labelStyle = MiniLabelWhite;
                }
                else
                {
                    if (containsMouse)                     // Going to select.
                    {
                        GUI.color  = new Color(0f, 0.5f, 1f);
                        labelStyle = MiniLabelWhite;
                    }
                    else                     // Not in selection.
                    {
                        GUI.color  = Color.white;
                        labelStyle = MiniLabelBlack;
                    }
                }

                Rect innerBoxRect = new Rect(boxRect.x + 1, boxRect.y, boxRect.width - 2, boxRect.height - 1);
                EditorGUI.DrawRect(innerBoxRect, GUI.color);
                GUI.color = Color.white;
                GUI.Label(new Rect(boxRect.x + 20, boxRect.y, Width - 20, boxRect.height), gameObject.name, labelStyle);

                int   maxLength = Mathf.Min(icons.Length, MaxIcons);
                float width     = Height * maxLength;

                if (icons.Length > 0)
                {
                    Rect iconsRect = new Rect(boxRect.x + boxRect.width - width, boxRect.y, width,
                                              Height);

                    // Behaviour for scrolling icons when the cursor is over the selection (only if the icon count is greater than MaxIcons)
                    if (containsMouse && maxLength < icons.Length)
                    {
                        if (_currentlyHoveringIndex != i)
                        {
                            _currentlyHoveringIndex = i;
                            _iconOffset             = 0;
                        }

                        float max = icons.Length - maxLength;
                        _iconOffset = Mathf.MoveTowards(_iconOffset, _iconOffsetTarget,
                                                        (float)(EditorApplication.timeSinceStartup - lastTime));
                        if (_iconOffset <= 0)
                        {
                            _iconOffset       = 0;
                            _iconOffsetTarget = max;
                        }
                        else if (_iconOffset >= max)
                        {
                            _iconOffset       = max;
                            _iconOffsetTarget = 0;
                        }
                    }

                    using (new GUI.GroupScope(iconsRect))
                    {
                        for (var j = 0; j < icons.Length; j++)
                        {
                            GUIContent icon = icons[j];
                            GUI.Label(
                                new Rect(width - (maxLength - j) * Height - _iconOffset * Height, 0, Height, Height),
                                icon);
                        }
                    }
                }

                // If the selection is being hovered we may need to modify the currently previewing selection
                // or if the control key has changes states.
                if (containsMouse && (i != _lastHighlightedIndex || _additionWasLastHeldForPreview != additive))
                {
                    _lastHighlightedIndex = i;
                    if (!additive)
                    {
                        _additionWasLastHeldForPreview = false;
                        ResetHierarchyToExpandedStateExcept(gameObject);
                        // If we're not selecting more (ie. have control held) we should just set the selection to be the hovered item.
                        Selection.objects          = Array.Empty <Object>();
                        Selection.activeGameObject = gameObject;
                    }
                    else
                    {
                        _additionWasLastHeldForPreview = true;
                        // Otherwise we need to alter the current selection to add or remove the currently hovered selection.
                        if (isInSelection)
                        {
                            ResetHierarchyToExpandedState();
                            // Remove the GameObject.
                            Object[] newSelection = new Object[_currentSelection.Count - 1];
                            int      n            = 0;
                            foreach (GameObject o in _currentSelection)
                            {
                                if (o == gameObject)
                                {
                                    continue;
                                }
                                newSelection[n++] = o;
                            }

                            Selection.objects = newSelection;
                        }
                        else
                        {
                            ResetHierarchyToExpandedStateExcept(gameObject);
                            // Add the GameObject.
                            Object[] newSelection = new Object[_currentSelection.Count + 1];
                            int      n            = 0;
                            foreach (GameObject o in _currentSelection)
                            {
                                newSelection[n++] = o;
                            }
                            newSelection[n]   = gameObject;
                            Selection.objects = newSelection;
                        }
                    }
                }

                // Clicked in the box!
                if (containsMouse && e.isMouse && e.type == EventType.MouseUp)
                {
                    MakeSelection(i, additive);
                    e.Use();
                    if (!additive)
                    {
                        break;
                    }
                }
            }

            if (highlightedIndex == -1 && _lastHighlightedIndex != -1)
            {
                RevertPreviewSelection();
            }

            if (e.isKey && e.type == EventType.KeyUp)
            {
                switch (e.keyCode)
                {
                case KeyCode.Escape:
                    RevertPreviewSelection();
                    EndSelection();
                    break;

                case KeyCode.Return:
                    if (highlightedIndex >= 0)
                    {
                        MakeSelection(highlightedIndex, additive);
                    }
                    break;
                }
            }
            else if (e.isMouse && e.type == EventType.MouseUp)
            {
                if (highlightedIndex == -1)
                {
                    RevertPreviewSelection();
                }
                EndSelection();
            }

            if (e.type != EventType.Repaint && e.type != EventType.Layout)
            {
                e.Use();
            }

            lastTime = EditorApplication.timeSinceStartup;
        }
示例#2
0
        void OnGUI()
        {
            Event e = Event.current;

            GUIUtility.hotControl = 0;

            int indexCurrentlyHighlighted = -1;

            //Scrolling behaviour
            if (e.type == EventType.ScrollWheel)
            {
                scrollDelta = Math.Sign(e.delta.y);
            }

            if (scrollDelta != 0)
            {
                scrollPosition += scrollDelta;
                scrollPosition  = Mathf.Clamp(scrollPosition, 0, totalSelection.Count - 1);
                Rect tempRect = position;
                tempRect.position = new Vector2(originalPosition.x, originalPosition.y - scrollPosition * NSelection.height);
                ShowAsDropDown(new Rect(tempRect.position, Vector2.zero), tempRect.size);
                scrollDelta = 0;
            }


            //Top and bottom borders (to fix a weird issue where the top 5 pixels of the window do not receive mouse events)
            EditorGUI.DrawRect(new Rect(0, 0, NSelection.width, 5), GUI.color);
            EditorGUI.DrawRect(new Rect(0, 6 + NSelection.height * totalSelection.Count, NSelection.width, 5), GUI.color);


            Rect separatorTopRect = new Rect(0, 5, NSelection.width, 1);

            EditorGUI.DrawRect(separatorTopRect, boxBorderColor);

            for (var i = 0; i < totalSelection.Count; i++)
            {
                SelectionItem selectionItem = totalSelection[i];
                GameObject    gameObject    = selectionItem.GameObject;
                GUIContent[]  icons         = selectionItem.Icons;

                Rect     boxRect = new Rect(0, 5 + 1 + i * NSelection.height, NSelection.width, NSelection.height);
                GUIStyle labelStyle;

                bool isInSelection = currentSelection.Contains(gameObject);
                bool contains      = boxRect.Contains(e.mousePosition);
                if (contains)
                {
                    indexCurrentlyHighlighted = i;
                }

                EditorGUI.DrawRect(boxRect, boxBorderColor);

                if (isInSelection)
                {
                    if (contains)
                    {
                        //If we're not holding shift it will solely select this object
                        if (!e.shift)
                        {
                            GUI.color = new Color(0f, 0.5f, 1f);
                        }
                        else                         //Otherwise it will be a deselection
                        {
                            GUI.color = new Color(0.58f, 0.62f, 0.75f);
                        }
                    }
                    else
                    {
                        //If we're not holding shift and we're not hovering it will deselect these, so show that preview.
                        if (!e.shift)
                        {
                            GUI.color = new Color(0.58f, 0.62f, 0.75f);
                        }
                        else                         // Otherwise, we will be selecting additionally
                        {
                            GUI.color = new Color(0f, 0.5f, 1f);
                        }
                    }

                    labelStyle = miniLabelWhite;
                }
                else
                {
                    if (contains)                     //Going To Select
                    {
                        GUI.color  = new Color(0f, 0.5f, 1f);
                        labelStyle = miniLabelWhite;
                    }
                    else                     //Not In Selection
                    {
                        GUI.color  = Color.white;
                        labelStyle = miniLabelBlack;
                    }
                }

                Rect innerBoxRect = new Rect(boxRect.x + 1, boxRect.y, boxRect.width - 2, boxRect.height - 1);
                EditorGUI.DrawRect(innerBoxRect, GUI.color);
                GUI.color = Color.white;
                GUI.Label(new Rect(boxRect.x + 20, boxRect.y, NSelection.width - 20, boxRect.height), gameObject.name, labelStyle);

                if (icons.Length > 0)
                {
                    int   maxLength = Mathf.Min(icons.Length, maxIcons);
                    float width     = NSelection.height * maxLength;
                    Rect  iconsRect = new Rect(boxRect.x + boxRect.width - maxLength * NSelection.height, boxRect.y, width, NSelection.height);

                    //Behaviour for scrolling icons when the cursor is over the selection (only if the icon count is greater than maxIcons)
                    if (contains && maxLength < icons.Length)
                    {
                        if (currentlyHoveringIndex != i)
                        {
                            currentlyHoveringIndex = i;
                            iconOffset             = 0;
                        }

                        float max = icons.Length - maxLength;
                        iconOffset = Mathf.MoveTowards(iconOffset, iconOffsetTarget, (float)(EditorApplication.timeSinceStartup - lastTime));
                        if (iconOffset <= 0)
                        {
                            iconOffset       = 0;
                            iconOffsetTarget = max;
                        }
                        else if (iconOffset >= max)
                        {
                            iconOffset       = max;
                            iconOffsetTarget = 0;
                        }
                    }

                    using (new GUI.GroupScope(iconsRect))
                    {
                        for (var j = 0; j < icons.Length; j++)
                        {
                            GUIContent icon = icons[j];
                            GUI.Label(new Rect(width - (maxLength - j) * NSelection.height - iconOffset * NSelection.height, 0, NSelection.height, NSelection.height), icon);
                        }
                    }
                }

                //If the selection is being hovered we may need to modify the currently previewing selection
                //or if the shift key has changes states.
                if (contains && (i != lastIndexHighlighted || shiftWasHeldForPreview != e.shift))
                {
                    ResetHierarchyToExpandedState();
                    lastIndexHighlighted = i;
                    if (!e.shift)
                    {
                        shiftWasHeldForPreview = false;
                        //If we're not selecting more (ie. have shift held) we should just set the selection to be the hovered item
                        Selection.objects          = new Object[0];
                        Selection.activeGameObject = gameObject;
                    }
                    else
                    {
                        shiftWasHeldForPreview = true;
                        //Otherwise we need to alter the current selection to add or remove the currently hovered selection
                        if (isInSelection)
                        {
                            //Remove the GameObject
                            Object[] newSelection = new Object[currentSelection.Count - 1];
                            int      n            = 0;
                            foreach (GameObject o in currentSelection)
                            {
                                if (o == gameObject)
                                {
                                    continue;
                                }
                                newSelection[n++] = o;
                            }

                            Selection.objects = newSelection;
                        }
                        else
                        {
                            //Add the GameObject
                            Object[] newSelection = new Object[currentSelection.Count + 1];
                            int      n            = 0;
                            foreach (GameObject o in currentSelection)
                            {
                                newSelection[n++] = o;
                            }
                            newSelection[n]   = gameObject;
                            Selection.objects = newSelection;
                        }
                    }
                }

                //Clicked in the box!
                if (contains && e.isMouse && e.type == EventType.MouseUp)
                {
                    MakeSelection(i, e.shift);
                    e.Use();
                    if (!e.shift)
                    {
                        break;
                    }
                }
            }

            if (indexCurrentlyHighlighted == -1 && lastIndexHighlighted != -1)
            {
                RevertPreviewSelection();
            }

            if (e.isKey && e.type == EventType.KeyUp)
            {
                switch (e.keyCode)
                {
                case KeyCode.Escape:
                    RevertPreviewSelection();
                    EndSelection();
                    break;

                case KeyCode.Return:
                    if (indexCurrentlyHighlighted >= 0)
                    {
                        MakeSelection(indexCurrentlyHighlighted, e.shift);
                    }
                    break;
                }
            }
            else if (e.isMouse && e.type == EventType.MouseUp)
            {
                if (indexCurrentlyHighlighted == -1)
                {
                    RevertPreviewSelection();
                }
                EndSelection();
            }

            if (e.type != EventType.Repaint && e.type != EventType.Layout)
            {
                e.Use();
            }

            Focus();

            Repaint();

            lastTime = EditorApplication.timeSinceStartup;
        }