Ejemplo n.º 1
0
        public void SetRoot(Node root)
        {
            mRoot = root;
            if (mSceneFrame == null || mHierarchyFrame == null || mNodeFrame == null)
            {
                mSceneFrame = new SceneFrame {
                    preview = preview
                };
                mHierarchyFrame  = new HierarchyFrame();
                mNodeFrame       = new NodeFrame();
                frames           = new UserFrame[] { mSceneFrame, mHierarchyFrame, mNodeFrame };
                mSceneFrame.rect = new Rect(0, 0, rect.width,
                                            Mathf.RoundToInt(rect.height * 2 / 3));
                mHierarchyFrame.rect = new Rect(0, mSceneFrame.rect.yMax + UserSetting.FrameIntervalSpace,
                                                Mathf.RoundToInt((rect.width - UserSetting.FrameIntervalSpace) / 2),
                                                rect.height - mSceneFrame.rect.yMax - UserSetting.FrameIntervalSpace);
                mNodeFrame.rect = new Rect(mHierarchyFrame.rect.width + UserSetting.FrameIntervalSpace,
                                           mHierarchyFrame.rect.y, rect.width - mHierarchyFrame.rect.width - UserSetting.FrameIntervalSpace,
                                           mHierarchyFrame.rect.height);
                UserDatabase.selection.onChange += () =>
                {
                    var nodes = UserDatabase.selection.nodes;
                    mNodeFrame.target = nodes != null && nodes.Length > 0
                        ? new PersistentObject(CoreUtil.CopyArray(nodes))
                        : null;
                    if (nodes != null && nodes.Length > 0)
                    {
                        foreach (var node in nodes)
                        {
                            var current = node.parent;
                            while (current.parent != null)
                            {
                                UserDatabase.caches.SetHierarchyFoldout(current, true);
                                current = current.parent;
                            }
                        }

                        mHierarchyFrame.ScrollTo(UserDatabase.selection.node);
                    }
                };
                UserDatabase.highlight.onChange += () =>
                {
                    var node = UserDatabase.highlight.node;
                    if (node != null)
                    {
                        var current = node.parent;
                        while (current.parent != null)
                        {
                            UserDatabase.caches.SetHierarchyFoldout(current, true);
                            current = current.parent;
                        }

                        mHierarchyFrame.Highlight(node);
                    }
                };
            }

            mSceneFrame.root     = mRoot;
            mHierarchyFrame.root = mRoot;
            UserDatabase.selection.onChange();
        }
Ejemplo n.º 2
0
        private void OnCommonEvent()
        {
            var controlId = GUIUtility.GetControlID(FocusType.Keyboard);
            var eventType = Event.current.GetTypeForControl(controlId);

            switch (eventType)
            {
            case EventType.MouseMove:
            {
                if (!nativeRect.Contains(Event.current.mousePosition))
                {
                    break;
                }
                var selectedNodes = UserDatabase.selection.nodes;
                if (selectedNodes == null || selectedNodes.Length == 0)
                {
                    break;
                }
                var flag = false;
                foreach (var selectedNode in selectedNodes)
                {
                    PersistentGUI.BeginMatrix(GUI.matrix * selectedNode.guiMatrix);
                    var mousePos  = Event.current.mousePosition;
                    var localRect = selectedNode.localRect;
                    var scale     = selectedNode.worldScale;
                    scale.x = Mathf.Max(scale.x, 0.01f);
                    scale.y = Mathf.Max(scale.y, 0.01f);
                    var dragRects = CalcDragSizeRect(localRect, 4f / scale.x, 4f / scale.y);
                    var dir       = Array.FindIndex(dragRects, r => r.Contains(mousePos));
                    switch (dir)
                    {
                    case Direction.Top:
                    case Direction.Bottom:
                    {
                        Cursor.SetState(Cursor.State.Vertical);
                        Event.current.Use();
                        break;
                    }

                    case Direction.Left:
                    case Direction.Right:
                    {
                        Cursor.SetState(Cursor.State.Horizontal);
                        Event.current.Use();
                        break;
                    }

                    case Direction.TopRight:
                    case Direction.BottomLeft:
                    {
                        Cursor.SetState(Cursor.State.Diagonal1);
                        Event.current.Use();
                        break;
                    }

                    case Direction.TopLeft:
                    case Direction.BottomRight:
                    {
                        Cursor.SetState(Cursor.State.Diagonal2);
                        Event.current.Use();
                        break;
                    }
                    }

                    PersistentGUI.EndMatrix();
                    if (dir >= 0)
                    {
                        Cursor.matrix = Node.BuildGUIRotationMatrix(selectedNode);
                        flag          = true;
                        break;
                    }
                }

                if (!flag)
                {
                    Cursor.SetState(Cursor.State.Default);
                    Cursor.matrix = Matrix4x4.identity;
                    Event.current.Use();
                }

                break;
            }

            case EventType.MouseDown:
            {
                if (!nativeRect.Contains(Event.current.mousePosition))
                {
                    break;
                }
                if (Event.current.button != 0)
                {
                    break;
                }
                GUIUtility.hotControl = controlId;
                var dragState = (DragState)GUIUtility.GetStateObject(typeof(DragState), controlId);
                dragState.dir      = -1;
                dragState.mousePos = Event.current.mousePosition;
                var selectedNodes = UserDatabase.selection.nodes;
                if (selectedNodes == null || selectedNodes.Length == 0)
                {
                    break;
                }
                foreach (var selectedNode in selectedNodes)
                {
                    PersistentGUI.BeginMatrix(GUI.matrix * selectedNode.guiMatrix);
                    var mousePos  = Event.current.mousePosition;
                    var localRect = selectedNode.localRect;
                    var scale     = selectedNode.worldScale;
                    scale.x = Mathf.Max(scale.x, 0.01f);
                    scale.y = Mathf.Max(scale.y, 0.01f);
                    var dragRects = CalcDragSizeRect(localRect, 4f / scale.x, 4f / scale.y);
                    var dir       = Array.FindIndex(dragRects, r => r.Contains(mousePos));
                    if (dir >= 0 || localRect.Contains(mousePos))
                    {
                        dragState.dir           = dir;
                        dragState.localPosition = selectedNodes.Select(i => i.localPosition).ToArray();
                        dragState.size          = selectedNodes.Select(i => i.size).ToArray();
                        break;
                    }

                    PersistentGUI.EndMatrix();
                }

                break;
            }

            case EventType.MouseDrag:
            {
                if (!nativeRect.Contains(Event.current.mousePosition))
                {
                    break;
                }
                if (Event.current.button != 0 || GUIUtility.hotControl != controlId)
                {
                    break;
                }
                var selectedNodes = UserUtil.FilterNested(UserDatabase.selection.nodes);
                if (selectedNodes == null || selectedNodes.Length == 0)
                {
                    break;
                }
                foreach (var selectedNode in selectedNodes)
                {
                    PersistentGUI.BeginMatrix(GUI.matrix * selectedNode.guiMatrix);
                    var delta = Event.current.delta;
                    var scale = selectedNode.localScale;
                    scale.x = Mathf.Abs(scale.x);
                    scale.y = Mathf.Abs(scale.y);
                    var pivot = selectedNode.pivot;
                    selectedNode.pivot = Vector2.zero;
                    var deltaMatrix = Matrix4x4.TRS(Vector3.zero,
                                                    Quaternion.Euler(0, 0, selectedNode.localAngle), scale);
                    var dragState = (DragState)GUIUtility.GetStateObject(typeof(DragState), controlId);
                    switch (dragState.dir)
                    {
                    case Direction.Top:
                    {
                        var offset = deltaMatrix.MultiplyVector(new Vector2(0, delta.y));
                        selectedNode.localPosition += new Vector2(offset.x, offset.y);
                        selectedNode.size          += new Vector2(0, -delta.y);
                        break;
                    }

                    case Direction.Bottom:
                    {
                        selectedNode.size += new Vector2(0, delta.y);
                        break;
                    }

                    case Direction.Left:
                    {
                        var offset = deltaMatrix.MultiplyVector(new Vector2(delta.x, 0));
                        selectedNode.localPosition += new Vector2(offset.x, offset.y);
                        selectedNode.size          += new Vector2(-delta.x, 0);
                        break;
                    }

                    case Direction.Right:
                    {
                        selectedNode.size += new Vector2(delta.x, 0);
                        break;
                    }

                    case Direction.TopLeft:
                    {
                        var offset = deltaMatrix.MultiplyVector(new Vector2(delta.x, delta.y));
                        selectedNode.localPosition += new Vector2(offset.x, offset.y);
                        selectedNode.size          += new Vector2(-delta.x, -delta.y);
                        break;
                    }

                    case Direction.TopRight:
                    {
                        var offset = deltaMatrix.MultiplyVector(new Vector2(0, delta.y));
                        selectedNode.localPosition += new Vector2(offset.x, offset.y);
                        selectedNode.size          += new Vector2(delta.x, -delta.y);
                        break;
                    }

                    case Direction.BottomRight:
                    {
                        selectedNode.size += new Vector2(delta.x, delta.y);
                        break;
                    }

                    case Direction.BottomLeft:
                    {
                        var offset = deltaMatrix.MultiplyVector(new Vector2(delta.x, 0));
                        selectedNode.localPosition += new Vector2(offset.x, offset.y);
                        selectedNode.size          += new Vector2(-delta.x, delta.y);
                        break;
                    }

                    default:
                    {
                        var offset = deltaMatrix.MultiplyVector(new Vector2(delta.x, delta.y));
                        selectedNode.localPosition += new Vector2(offset.x, offset.y);
                        break;
                    }
                    }

                    selectedNode.pivot = pivot;
                    PersistentGUI.EndMatrix();
                    Event.current.Use();
                }

                break;
            }

            case EventType.MouseUp:
            {
                if (!nativeRect.Contains(Event.current.mousePosition))
                {
                    break;
                }
                if (Event.current.button == 1)
                {
                    UserMenu.ShowNodeContext(root);
                    Event.current.Use();
                }

                if (GUIUtility.hotControl != controlId)
                {
                    break;
                }
                var dragState = (DragState)GUIUtility.GetStateObject(typeof(DragState), controlId);
                if (Event.current.button == 0)
                {
                    var selectedNodes = UserDatabase.selection.nodes;
                    if (selectedNodes != null && selectedNodes.Length > 0 && dragState.localPosition != null &&
                        selectedNodes.Length == dragState.localPosition.Length)
                    {
                        var commands = new List <Command>();
                        for (var i = 0; i < selectedNodes.Length; i++)
                        {
                            var selectedNode = selectedNodes[i];
                            PersistentGUI.BeginMatrix(GUI.matrix * selectedNode.guiMatrix);
                            var localPosition        = dragState.localPosition[i];
                            var size                 = dragState.size[i];
                            var currentLocalPosition = selectedNode.localPosition;
                            var currentSize          = selectedNode.size;
                            if (Vector2.Distance(localPosition, currentLocalPosition) >
                                UserSetting.DistanceComparisionTolerance ||
                                Vector2.Distance(size, currentSize) > UserSetting.DistanceComparisionTolerance)
                            {
                                selectedNode.localPosition = localPosition;
                                selectedNode.size          = size;
                                commands.Add(new UpdateMemberCommand(selectedNode, "localPosition",
                                                                     currentLocalPosition));
                                commands.Add(new UpdateMemberCommand(selectedNode, "size", currentSize));
                            }

                            PersistentGUI.EndMatrix();
                        }

                        if (commands.Count > 0)
                        {
                            Command.Execute(new CombinedCommand(commands.ToArray()));
                            Event.current.Use();
                        }
                    }
                }

                var mousePos = Event.current.mousePosition;
                if (Event.current.button == 0 &&
                    Vector2.Distance(dragState.mousePos, mousePos) <
                    UserSetting.DistanceComparisionTolerance)
                {
                    var hits = Raycaster.RaycastAll(mousePos, root);
                    if (hits.Length > 0)
                    {
                        var current = UserDatabase.selection.node;
                        if (current == null)
                        {
                            UserUtil.SelectNodes(new[] { hits[0] });
                            Event.current.Use();
                        }
                        else
                        {
                            var hold  = hits[0];
                            var nodes = CoreUtil.CopyArray(UserDatabase.selection.nodes);
                            foreach (var node in nodes)
                            {
                                var index = Array.IndexOf(hits, node);
                                if (index >= 0)
                                {
                                    ArrayUtility.Remove(ref nodes, node);
                                    var next = index + 1;
                                    if (next >= hits.Length)
                                    {
                                        next = 0;
                                    }
                                    hold = hits[next];
                                    break;
                                }
                            }

                            if (Event.current.control)
                            {
                                if (nodes.Length > 0)
                                {
                                    ArrayUtility.Add(ref nodes, hold);
                                }
                            }
                            else
                            {
                                nodes = new Node[] { hold };
                            }

                            UserUtil.SelectNodes(nodes);
                            Event.current.Use();
                        }
                    }
                    else
                    {
                        UserUtil.SelectNodes(null);
                        Event.current.Use();
                    }
                }

                GUIUtility.hotControl = 0;

                break;
            }

            case EventType.KeyDown:
            {
                if (!focused)
                {
                    break;
                }
                switch (Event.current.keyCode)
                {
                case KeyCode.Delete:
                {
                    UserUtil.DeleteNodes();
                    Event.current.Use();
                    break;
                }

                case KeyCode.LeftArrow:
                case KeyCode.RightArrow:
                case KeyCode.UpArrow:
                case KeyCode.DownArrow:
                {
                    var selectedNodes = UserUtil.FilterNested(UserDatabase.selection.nodes);
                    if (selectedNodes == null || selectedNodes.Length == 0)
                    {
                        break;
                    }
                    foreach (var selectedNode in selectedNodes)
                    {
                        var distance = 1;
                        if (Event.current.control)
                        {
                            distance = 5;
                        }
                        else if (Event.current.shift)
                        {
                            distance = 10;
                        }
                        switch (Event.current.keyCode)
                        {
                        case KeyCode.LeftArrow:
                        {
                            Command.Execute(new UpdateMemberCommand(selectedNode, "localPosition",
                                                                    selectedNode.localPosition + new Vector2(-distance, 0)));
                            Event.current.Use();
                            break;
                        }

                        case KeyCode.UpArrow:
                        {
                            Command.Execute(new UpdateMemberCommand(selectedNode, "localPosition",
                                                                    selectedNode.localPosition + new Vector2(0, -distance)));
                            Event.current.Use();
                            break;
                        }

                        case KeyCode.RightArrow:
                        {
                            Command.Execute(new UpdateMemberCommand(selectedNode, "localPosition",
                                                                    selectedNode.localPosition + new Vector2(distance, 0)));
                            Event.current.Use();
                            break;
                        }

                        case KeyCode.DownArrow:
                        {
                            Command.Execute(new UpdateMemberCommand(selectedNode, "localPosition",
                                                                    selectedNode.localPosition + new Vector2(0, distance)));
                            Event.current.Use();
                            break;
                        }
                        }
                    }

                    break;
                }
                }

                break;
            }

            case EventType.ValidateCommand:
            {
                if (!focused)
                {
                    break;
                }
                if (Event.current.commandName == "Copy" ||
                    Event.current.commandName == "Paste" ||
                    Event.current.commandName == "Duplicate")
                {
                    Event.current.Use();
                }
                break;
            }

            case EventType.ExecuteCommand:
            {
                if (!focused)
                {
                    break;
                }
                switch (Event.current.commandName)
                {
                case "Copy":
                {
                    UserUtil.CopyNodes(root);
                    Event.current.Use();
                    break;
                }

                case "Paste":
                {
                    UserUtil.PasteNodes(root);
                    Event.current.Use();
                    break;
                }

                case "Duplicate":
                {
                    UserUtil.DuplicateNodes(root);
                    Event.current.Use();
                    break;
                }
                }

                break;
            }
            }
        }
Ejemplo n.º 3
0
        private void OnNodeGUI(Node node)
        {
            var nodeRect = EditorGUILayout.GetControlRect(false, EditorGUIUtility.singleLineHeight);

            nodeRect.height += EditorGUIUtility.standardVerticalSpacing;
            var selected = selectedNodes != null && selectedNodes.Contains(node);

            if (selected)
            {
                EditorGUI.DrawRect(nodeRect,
                                   focused ? UserSetting.HierarchySelectedFocusedColor : UserSetting.HierarchySelectedColor);
            }
            var controlId  = GUIUtility.GetControlID(FocusType.Keyboard);
            var eventType  = Event.current.GetTypeForControl(controlId);
            var mousePos   = Event.current.mousePosition;
            var foldout    = UserDatabase.caches.GetHierarchyFoldout(node);
            var topRect    = new Rect(nodeRect.x, nodeRect.y - 2, nodeRect.width, 4);
            var bottomRect = new Rect(nodeRect.x, nodeRect.yMax - 1, nodeRect.width, 4);
            var centerRect = new Rect(nodeRect.x, nodeRect.y + 2, nodeRect.width, nodeRect.height - 4);
            var fsize      = EditorStyles.foldout.CalcSize(GUIContent.none);
            var frect      = new Rect(nodeRect.x + PersistentGUI.indent, nodeRect.y, fsize.x, fsize.y);

            switch (eventType)
            {
            case EventType.Repaint:
            {
                if (node.childCount > 0)
                {
                    EditorStyles.foldout.Draw(frect, GUIContent.none, controlId, foldout);
                }
                if (UserDatabase.highlight.node == node)
                {
                    if (mHighlightProgress == 0)
                    {
                        UserDatabase.highlight.node = null;
                    }
                    else
                    {
                        var color = UserSetting.HierarchyHighlightColor;
                        color.a = (float)mHighlightProgress / mHighlightDuration;
                        PersistentGUI.DrawAAPolyLine(nodeRect, 2, color);
                    }
                    mHighlightProgress -= 1;
                }
                break;
            }

            case EventType.MouseDown:
            {
                if (node.childCount > 0 &&
                    frect.Contains(mousePos))
                {
                    foldout = !foldout;
                    UserDatabase.caches.SetHierarchyFoldout(node, foldout);
                    Event.current.Use();
                }
                else if (nodeRect.Contains(mousePos) &&
                         (Event.current.button == 0 ||
                          Event.current.button == 1))
                {
                    var nodes = UserDatabase.selection.nodes != null
                            ? CoreUtil.CopyArray(UserDatabase.selection.nodes)
                            : new Node[0];

                    if (Event.current.control)
                    {
                        if (selected)
                        {
                            ArrayUtility.Remove(ref nodes, node);
                        }
                        else
                        {
                            ArrayUtility.Add(ref nodes, node);
                            var list = GUIUtility.GetStateObject(typeof(List <Node>), controlId) as List <Node>;
                            list.Add(node);
                        }

                        mTemps = nodes;
                    }
                    else if (Event.current.shift && nodes.Length > 0)
                    {
                        var filter = new List <Node>();
                        var list   = new List <Node>();
                        foreach (var n in root)
                        {
                            FlattenNode(list, n);
                        }
                        var index  = list.IndexOf(node);
                        var nIndex = nodes.Select(n => list.IndexOf(n)).Min();
                        var from   = Mathf.Min(nIndex, index);
                        var to     = Mathf.Max(nIndex, index);
                        for (var i = @from; i <= to; i++)
                        {
                            if (!filter.Contains(list[i]))
                            {
                                filter.Add(list[i]);
                            }
                        }

                        mTemps = filter.ToArray();
                    }
                    else
                    {
                        if (!selected)
                        {
                            mTemps = new[] { node }
                        }
                        ;
                        if (node.childCount > 0 && Event.current.clickCount == 2)
                        {
                            foldout = !foldout;
                            UserDatabase.caches.SetHierarchyFoldout(node, foldout);
                        }
                    }

                    Event.current.Use();
                }

                break;
            }

            case EventType.MouseUp:
            {
                if (!focused || frect.Contains(mousePos))
                {
                    break;
                }
                if (UserDragDrop.dragging)
                {
                    var nodes = UserDragDrop.data as Node[];
                    if (nodes != null && nodes.Length > 0)
                    {
                        if (topRect.Contains(mousePos))
                        {
                            UserUtil.MoveNodes(nodes, node.parent, node.GetSiblingIndex());
                            UserDragDrop.StopDrag();
                            Cursor.SetState(Cursor.State.Default);
                            UserDatabase.caches.SetHierarchyFoldout(node.parent, true);
                            Event.current.Use();
                        }
                        else if (bottomRect.Contains(mousePos))
                        {
                            UserUtil.MoveNodes(nodes, node.parent, node.GetSiblingIndex() + 1);
                            UserDragDrop.StopDrag();
                            Cursor.SetState(Cursor.State.Default);
                            UserDatabase.caches.SetHierarchyFoldout(node.parent, true);
                            Event.current.Use();
                        }
                        else if (centerRect.Contains(mousePos))
                        {
                            UserUtil.MoveNodes(nodes, node, -1);
                            UserDragDrop.StopDrag();
                            Cursor.SetState(Cursor.State.Default);
                            UserDatabase.caches.SetHierarchyFoldout(node, true);
                            Event.current.Use();
                        }
                    }
                }
                else
                {
                    if (Event.current.button == 0 && nodeRect.Contains(mousePos))
                    {
                        var nodes = UserDatabase.selection.nodes != null
                                ? CoreUtil.CopyArray(UserDatabase.selection.nodes)
                                : new Node[0];

                        if (Event.current.control)
                        {
                            if (selected)
                            {
                                var list =
                                    GUIUtility.QueryStateObject(typeof(List <Node>), controlId) as List <Node>;
                                if (list != null && list.Count > 0)
                                {
                                    if (list[0] != node)
                                    {
                                        ArrayUtility.Remove(ref nodes, node);
                                        UserUtil.SelectNodes(nodes);
                                    }

                                    list.Clear();
                                }
                            }
                        }
                        else if (!Event.current.shift)
                        {
                            if (selected)
                            {
                                UserUtil.SelectNodes(new[] { node });
                            }
                        }

                        if (Event.current.button != 1)
                        {
                            Event.current.Use();
                        }
                    }
                }

                break;
            }

            case EventType.MouseDrag:
            {
                if (focused && Event.current.button == 0 && !UserDragDrop.dragging)
                {
                    var nodes = selectedNodes;
                    if (nodes != null && nodes.Contains(node) && nodeRect.Contains(mousePos))
                    {
                        var data = new Node[nodes.Length];
                        Array.Copy(nodes, data, data.Length);
                        UserDragDrop.StartDrag(data);
                        Cursor.SetState(Cursor.State.DragAnything);
                        Event.current.Use();
                    }
                }

                break;
            }
            }

            EditorGUI.LabelField(new Rect(nodeRect.x + 12, nodeRect.y, nodeRect.width, nodeRect.height),
                                 new GUIContent(node.name));
            if (UserDragDrop.dragging)
            {
                var indentOffset = PersistentGUI.indent + 12;
                if (topRect.Contains(mousePos))
                {
                    PersistentGUI.DrawAAPolyLine(
                        new Rect(topRect.x + indentOffset, topRect.y, topRect.width - indentOffset, topRect.height), 2,
                        UserSetting.HierarchyDragTipsColor);
                }
                else if (centerRect.Contains(mousePos))
                {
                    PersistentGUI.DrawAAPolyLine(
                        new Rect(centerRect.x + indentOffset, centerRect.y, centerRect.width - indentOffset,
                                 centerRect.height), 2, UserSetting.HierarchyDragTipsColor);
                }
            }

            if (foldout && node.childCount > 0)
            {
                EditorGUI.indentLevel += 1;
                for (int i = 0; i < node.childCount; i++)
                {
                    OnNodeGUI(node.GetChild(i));
                }

                EditorGUI.indentLevel -= 1;
            }
            else
            {
                if (UserDragDrop.dragging)
                {
                    if (bottomRect.Contains(mousePos))
                    {
                        var indentOffset = PersistentGUI.indent + 12;
                        PersistentGUI.DrawAAPolyLine(
                            new Rect(bottomRect.x + indentOffset, bottomRect.y, bottomRect.width - indentOffset,
                                     bottomRect.height), 2, UserSetting.HierarchyDragTipsColor);
                    }
                }
            }
        }