コード例 #1
0
        /// <summary> Show right-click context menu for hovered reroute </summary>
        void ShowRerouteContextMenu(RerouteReference reroute)
        {
            var contextMenu = new GenericMenu();

            contextMenu.AddItem(new GUIContent("Remove"), false, () => reroute.RemovePoint());
            contextMenu.DropDown(new Rect(Event.current.mousePosition, Vector2.zero));
        }
コード例 #2
0
ファイル: NodeEditorGUI.cs プロジェクト: willhome/xNode
        /// <summary> Show right-click context menu for hovered reroute </summary>
        void ShowRerouteContextMenu(RerouteReference reroute)
        {
            GenericMenu contextMenu = new GenericMenu();

            contextMenu.AddItem(new GUIContent("Remove"), false, () => reroute.RemovePoint());
            contextMenu.DropDown(new Rect(Event.current.mousePosition, Vector2.zero));
            if (NodeEditorPreferences.GetSettings().autoSave)
            {
                AssetDatabase.SaveAssets();
            }
        }
コード例 #3
0
        public void Controls()
        {
            wantsMouseMove = true;
            Event e = Event.current;

            switch (e.type)
            {
            case EventType.DragUpdated:
            case EventType.DragPerform:
                DragAndDrop.visualMode = DragAndDropVisualMode.Generic;
                if (e.type == EventType.DragPerform)
                {
                    DragAndDrop.AcceptDrag();
                    graphEditor.OnDropObjects(DragAndDrop.objectReferences);
                }
                break;

            case EventType.MouseMove:
                //Keyboard commands will not get correct mouse position from Event
                lastMousePosition = e.mousePosition;
                break;

            case EventType.ScrollWheel:
                float oldZoom = zoom;
                if (e.delta.y > 0)
                {
                    zoom += 0.1f * zoom;
                }
                else
                {
                    zoom -= 0.1f * zoom;
                }
                if (NodeEditorPreferences.GetSettings().zoomToMouse)
                {
                    panOffset += (1 - oldZoom / zoom) * (WindowToGridPosition(e.mousePosition) + panOffset);
                }
                break;

            case EventType.MouseDrag:
                if (e.button == 0)
                {
                    if (IsDraggingPort)
                    {
                        if (IsHoveringPort && hoveredPort.IsInput && draggedOutput.CanConnectTo(hoveredPort))
                        {
                            if (!draggedOutput.IsConnectedTo(hoveredPort))
                            {
                                draggedOutputTarget = hoveredPort;
                            }
                        }
                        else
                        {
                            draggedOutputTarget = null;
                        }
                        Repaint();
                    }
                    else if (currentActivity == NodeActivity.HoldNode)
                    {
                        RecalculateDragOffsets(e);
                        currentActivity = NodeActivity.DragNode;
                        Repaint();
                    }
                    if (currentActivity == NodeActivity.DragNode)
                    {
                        // Holding ctrl inverts grid snap
                        bool gridSnap = NodeEditorPreferences.GetSettings().gridSnap;
                        if (e.control)
                        {
                            gridSnap = !gridSnap;
                        }

                        Vector2 mousePos = WindowToGridPosition(e.mousePosition);
                        // Move selected nodes with offset
                        for (int i = 0; i < Selection.objects.Length; i++)
                        {
                            if (Selection.objects[i] is XNode.Node)
                            {
                                XNode.Node node    = Selection.objects[i] as XNode.Node;
                                Vector2    initial = node.position;
                                node.position = mousePos + dragOffset[i];
                                if (gridSnap)
                                {
                                    node.position.x = (Mathf.Round((node.position.x + 8) / 16) * 16) - 8;
                                    node.position.y = (Mathf.Round((node.position.y + 8) / 16) * 16) - 8;
                                }

                                // Offset portConnectionPoints instantly if a node is dragged so they aren't delayed by a frame.
                                Vector2 offset = node.position - initial;
                                if (offset.sqrMagnitude > 0)
                                {
                                    foreach (XNode.NodePort output in node.Outputs)
                                    {
                                        Rect rect;
                                        if (portConnectionPoints.TryGetValue(output, out rect))
                                        {
                                            rect.position += offset;
                                            portConnectionPoints[output] = rect;
                                        }
                                    }

                                    foreach (XNode.NodePort input in node.Inputs)
                                    {
                                        Rect rect;
                                        if (portConnectionPoints.TryGetValue(input, out rect))
                                        {
                                            rect.position += offset;
                                            portConnectionPoints[input] = rect;
                                        }
                                    }
                                }
                            }
                        }
                        // Move selected reroutes with offset
                        for (int i = 0; i < selectedReroutes.Count; i++)
                        {
                            Vector2 pos = mousePos + dragOffset[Selection.objects.Length + i];
                            if (gridSnap)
                            {
                                pos.x = (Mathf.Round(pos.x / 16) * 16);
                                pos.y = (Mathf.Round(pos.y / 16) * 16);
                            }
                            selectedReroutes[i].SetPoint(pos);
                        }
                        Repaint();
                    }
                    else if (currentActivity == NodeActivity.HoldGrid)
                    {
                        currentActivity        = NodeActivity.DragGrid;
                        preBoxSelection        = Selection.objects;
                        preBoxSelectionReroute = selectedReroutes.ToArray();
                        dragBoxStart           = WindowToGridPosition(e.mousePosition);
                        Repaint();
                    }
                    else if (currentActivity == NodeActivity.DragGrid)
                    {
                        Vector2 boxStartPos = GridToWindowPosition(dragBoxStart);
                        Vector2 boxSize     = e.mousePosition - boxStartPos;
                        if (boxSize.x < 0)
                        {
                            boxStartPos.x += boxSize.x; boxSize.x = Mathf.Abs(boxSize.x);
                        }
                        if (boxSize.y < 0)
                        {
                            boxStartPos.y += boxSize.y; boxSize.y = Mathf.Abs(boxSize.y);
                        }
                        selectionBox = new Rect(boxStartPos, boxSize);
                        Repaint();
                    }
                }
                else if (e.button == 1 || e.button == 2)
                {
                    panOffset += e.delta * zoom;
                    isPanning  = true;
                }
                break;

            case EventType.MouseDown:
                Repaint();
                if (e.button == 0)
                {
                    draggedOutputReroutes.Clear();

                    if (IsHoveringPort)
                    {
                        if (hoveredPort.IsOutput)
                        {
                            draggedOutput     = hoveredPort;
                            autoConnectOutput = hoveredPort;
                        }
                        else
                        {
                            hoveredPort.VerifyConnections();
                            autoConnectOutput = null;
                            if (hoveredPort.IsConnected)
                            {
                                XNode.Node     node   = hoveredPort.node;
                                XNode.NodePort output = hoveredPort.Connection;
                                int            outputConnectionIndex = output.GetConnectionIndex(hoveredPort);
                                draggedOutputReroutes = output.GetReroutePoints(outputConnectionIndex);
                                hoveredPort.Disconnect(output);
                                draggedOutput       = output;
                                draggedOutputTarget = hoveredPort;
                                if (NodeEditor.onUpdateNode != null)
                                {
                                    NodeEditor.onUpdateNode(node);
                                }
                            }
                        }
                    }
                    else if (IsHoveringNode && IsHoveringTitle(hoveredNode))
                    {
                        // If mousedown on node header, select or deselect
                        if (!Selection.Contains(hoveredNode))
                        {
                            SelectNode(hoveredNode, e.control || e.shift);
                            if (!e.control && !e.shift)
                            {
                                selectedReroutes.Clear();
                            }
                        }
                        else if (e.control || e.shift)
                        {
                            DeselectNode(hoveredNode);
                        }

                        // Cache double click state, but only act on it in MouseUp - Except ClickCount only works in mouseDown.
                        isDoubleClick = (e.clickCount == 2);

                        e.Use();
                        currentActivity = NodeActivity.HoldNode;
                    }
                    else if (IsHoveringReroute)
                    {
                        // If reroute isn't selected
                        if (!selectedReroutes.Contains(hoveredReroute))
                        {
                            // Add it
                            if (e.control || e.shift)
                            {
                                selectedReroutes.Add(hoveredReroute);
                            }
                            // Select it
                            else
                            {
                                selectedReroutes = new List <RerouteReference>()
                                {
                                    hoveredReroute
                                };
                                Selection.activeObject = null;
                            }
                        }
                        // Deselect
                        else if (e.control || e.shift)
                        {
                            selectedReroutes.Remove(hoveredReroute);
                        }
                        e.Use();
                        currentActivity = NodeActivity.HoldNode;
                    }
                    // If mousedown on grid background, deselect all
                    else if (!IsHoveringNode)
                    {
                        currentActivity = NodeActivity.HoldGrid;
                        if (!e.control && !e.shift)
                        {
                            selectedReroutes.Clear();
                            Selection.activeObject = null;
                        }
                    }
                }
                break;

            case EventType.MouseUp:
                if (e.button == 0)
                {
                    //Port drag release
                    if (IsDraggingPort)
                    {
                        //If connection is valid, save it
                        if (draggedOutputTarget != null)
                        {
                            XNode.Node node = draggedOutputTarget.node;
                            if (graph.nodes.Count != 0)
                            {
                                draggedOutput.Connect(draggedOutputTarget);
                            }

                            // ConnectionIndex can be -1 if the connection is removed instantly after creation
                            int connectionIndex = draggedOutput.GetConnectionIndex(draggedOutputTarget);
                            if (connectionIndex != -1)
                            {
                                draggedOutput.GetReroutePoints(connectionIndex).AddRange(draggedOutputReroutes);
                                if (NodeEditor.onUpdateNode != null)
                                {
                                    NodeEditor.onUpdateNode(node);
                                }
                                EditorUtility.SetDirty(graph);
                            }
                        }
                        // Open context menu for auto-connection
                        else if (NodeEditorPreferences.GetSettings().dragToCreate&& autoConnectOutput != null)
                        {
                            GenericMenu menu = new GenericMenu();
                            graphEditor.AddContextMenuItems(menu);
                            menu.DropDown(new Rect(Event.current.mousePosition, Vector2.zero));
                        }
                        //Release dragged connection
                        draggedOutput       = null;
                        draggedOutputTarget = null;
                        EditorUtility.SetDirty(graph);
                        if (NodeEditorPreferences.GetSettings().autoSave)
                        {
                            AssetDatabase.SaveAssets();
                        }
                    }
                    else if (currentActivity == NodeActivity.DragNode)
                    {
                        IEnumerable <XNode.Node> nodes = Selection.objects.Where(x => x is XNode.Node).Select(x => x as XNode.Node);
                        foreach (XNode.Node node in nodes)
                        {
                            EditorUtility.SetDirty(node);
                        }
                        if (NodeEditorPreferences.GetSettings().autoSave)
                        {
                            AssetDatabase.SaveAssets();
                        }
                    }
                    else if (!IsHoveringNode)
                    {
                        // If click outside node, release field focus
                        if (!isPanning)
                        {
                            EditorGUI.FocusTextInControl(null);
                            EditorGUIUtility.editingTextField = false;
                        }
                        if (NodeEditorPreferences.GetSettings().autoSave)
                        {
                            AssetDatabase.SaveAssets();
                        }
                    }

                    // If click node header, select it.
                    if (currentActivity == NodeActivity.HoldNode && !(e.control || e.shift))
                    {
                        selectedReroutes.Clear();
                        SelectNode(hoveredNode, false);

                        // Double click to center node
                        if (isDoubleClick)
                        {
                            Vector2 nodeDimension = nodeSizes.ContainsKey(hoveredNode) ? nodeSizes[hoveredNode] / 2 : Vector2.zero;
                            panOffset = -hoveredNode.position - nodeDimension;
                        }
                    }

                    // If click reroute, select it.
                    if (IsHoveringReroute && !(e.control || e.shift))
                    {
                        selectedReroutes = new List <RerouteReference>()
                        {
                            hoveredReroute
                        };
                        Selection.activeObject = null;
                    }

                    Repaint();
                    currentActivity = NodeActivity.Idle;
                }
                else if (e.button == 1 || e.button == 2)
                {
                    if (!isPanning)
                    {
                        if (IsDraggingPort)
                        {
                            draggedOutputReroutes.Add(WindowToGridPosition(e.mousePosition));
                        }
                        else if (currentActivity == NodeActivity.DragNode && Selection.activeObject == null && selectedReroutes.Count == 1)
                        {
                            selectedReroutes[0].InsertPoint(selectedReroutes[0].GetPoint());
                            selectedReroutes[0] = new RerouteReference(selectedReroutes[0].port, selectedReroutes[0].connectionIndex, selectedReroutes[0].pointIndex + 1);
                        }
                        else if (IsHoveringReroute)
                        {
                            ShowRerouteContextMenu(hoveredReroute);
                        }
                        else if (IsHoveringPort)
                        {
                            ShowPortContextMenu(hoveredPort);
                        }
                        else if (IsHoveringNode && IsHoveringTitle(hoveredNode))
                        {
                            if (!Selection.Contains(hoveredNode))
                            {
                                SelectNode(hoveredNode, false);
                            }
                            autoConnectOutput = null;
                            GenericMenu menu = new GenericMenu();
                            NodeEditor.GetEditor(hoveredNode, this).AddContextMenuItems(menu);
                            menu.DropDown(new Rect(Event.current.mousePosition, Vector2.zero));
                            e.Use();     // Fixes copy/paste context menu appearing in Unity 5.6.6f2 - doesn't occur in 2018.3.2f1 Probably needs to be used in other places.
                        }
                        else if (!IsHoveringNode)
                        {
                            autoConnectOutput = null;
                            GenericMenu menu = new GenericMenu();
                            graphEditor.AddContextMenuItems(menu);
                            menu.DropDown(new Rect(Event.current.mousePosition, Vector2.zero));
                        }
                    }
                    isPanning = false;
                }
                // Reset DoubleClick
                isDoubleClick = false;
                break;

            case EventType.KeyDown:
                if (EditorGUIUtility.editingTextField)
                {
                    break;
                }
                else if (e.keyCode == KeyCode.F)
                {
                    Home();
                }
                if (NodeEditorUtilities.IsMac())
                {
                    if (e.keyCode == KeyCode.Return)
                    {
                        RenameSelectedNode();
                    }
                }
                else
                {
                    if (e.keyCode == KeyCode.F2)
                    {
                        RenameSelectedNode();
                    }
                }
                if (e.keyCode == KeyCode.A)
                {
                    if (Selection.objects.Any(x => graph.nodes.Contains(x as XNode.Node)))
                    {
                        foreach (XNode.Node node in graph.nodes)
                        {
                            DeselectNode(node);
                        }
                    }
                    else
                    {
                        foreach (XNode.Node node in graph.nodes)
                        {
                            SelectNode(node, true);
                        }
                    }
                    Repaint();
                }
                break;

            case EventType.ValidateCommand:
            case EventType.ExecuteCommand:
                if (e.commandName == "SoftDelete")
                {
                    if (e.type == EventType.ExecuteCommand)
                    {
                        RemoveSelectedNodes();
                    }
                    e.Use();
                }
                else if (NodeEditorUtilities.IsMac() && e.commandName == "Delete")
                {
                    if (e.type == EventType.ExecuteCommand)
                    {
                        RemoveSelectedNodes();
                    }
                    e.Use();
                }
                else if (e.commandName == "Duplicate")
                {
                    if (e.type == EventType.ExecuteCommand)
                    {
                        DuplicateSelectedNodes();
                    }
                    e.Use();
                }
                else if (e.commandName == "Copy")
                {
                    if (e.type == EventType.ExecuteCommand)
                    {
                        CopySelectedNodes();
                    }
                    e.Use();
                }
                else if (e.commandName == "Paste")
                {
                    if (e.type == EventType.ExecuteCommand)
                    {
                        PasteNodes(WindowToGridPosition(lastMousePosition));
                    }
                    e.Use();
                }
                Repaint();
                break;

            case EventType.Ignore:
                // If release mouse outside window
                if (e.rawType == EventType.MouseUp && currentActivity == NodeActivity.DragGrid)
                {
                    Repaint();
                    currentActivity = NodeActivity.Idle;
                }
                break;
            }
        }
コード例 #4
0
ファイル: NodeEditorGUI.cs プロジェクト: willhome/xNode
        /// <summary> Draws all connections </summary>
        public void DrawConnections()
        {
            Vector2 mousePos = Event.current.mousePosition;
            List <RerouteReference> selection = preBoxSelectionReroute != null ? new List <RerouteReference>(preBoxSelectionReroute) : new List <RerouteReference>();

            hoveredReroute = new RerouteReference();

            Color col = GUI.color;

            foreach (XNode.Node node in graph.nodes)
            {
                //If a null node is found, return. This can happen if the nodes associated script is deleted. It is currently not possible in Unity to delete a null asset.
                if (node == null)
                {
                    continue;
                }

                // Draw full connections and output > reroute
                foreach (XNode.NodePort output in node.Outputs)
                {
                    //Needs cleanup. Null checks are ugly
                    Rect fromRect;
                    if (!_portConnectionPoints.TryGetValue(output, out fromRect))
                    {
                        continue;
                    }

                    Color connectionColor = graphEditor.GetTypeColor(output.ValueType);

                    for (int k = 0; k < output.ConnectionCount; k++)
                    {
                        XNode.NodePort input = output.GetConnection(k);

                        // Error handling
                        if (input == null)
                        {
                            continue;                //If a script has been updated and the port doesn't exist, it is removed and null is returned. If this happens, return.
                        }
                        if (!input.IsConnectedTo(output))
                        {
                            input.Connect(output);
                        }
                        Rect toRect;
                        if (!_portConnectionPoints.TryGetValue(input, out toRect))
                        {
                            continue;
                        }

                        Vector2        from          = fromRect.center;
                        Vector2        to            = Vector2.zero;
                        List <Vector2> reroutePoints = output.GetReroutePoints(k);
                        // Loop through reroute points and draw the path
                        for (int i = 0; i < reroutePoints.Count; i++)
                        {
                            to = reroutePoints[i];
                            DrawConnection(from, to, connectionColor);
                            from = to;
                        }
                        to = toRect.center;

                        DrawConnection(from, to, connectionColor);

                        // Loop through reroute points again and draw the points
                        for (int i = 0; i < reroutePoints.Count; i++)
                        {
                            RerouteReference rerouteRef = new RerouteReference(output, k, i);
                            // Draw reroute point at position
                            Rect rect = new Rect(reroutePoints[i], new Vector2(12, 12));
                            rect.position = new Vector2(rect.position.x - 6, rect.position.y - 6);
                            rect          = GridToWindowRect(rect);

                            // Draw selected reroute points with an outline
                            if (selectedReroutes.Contains(rerouteRef))
                            {
                                GUI.color = NodeEditorPreferences.GetSettings().highlightColor;
                                GUI.DrawTexture(rect, NodeEditorResources.dotOuter);
                            }

                            GUI.color = connectionColor;
                            GUI.DrawTexture(rect, NodeEditorResources.dot);
                            if (rect.Overlaps(selectionBox))
                            {
                                selection.Add(rerouteRef);
                            }
                            if (rect.Contains(mousePos))
                            {
                                hoveredReroute = rerouteRef;
                            }
                        }
                    }
                }
            }
            GUI.color = col;
            if (Event.current.type != EventType.Layout && currentActivity == NodeActivity.DragGrid)
            {
                selectedReroutes = selection;
            }
        }
コード例 #5
0
        public void Controls()
        {
            wantsMouseMove = true;
            Event e = Event.current;

            switch (e.type)
            {
            case EventType.MouseMove:
                break;

            case EventType.ScrollWheel:
                if (e.delta.y > 0)
                {
                    zoom += 0.1f * zoom;
                }
                else
                {
                    zoom -= 0.1f * zoom;
                }
                break;

            case EventType.MouseDrag:
                if (e.button == 0)
                {
                    if (IsDraggingPort)
                    {
                        if (IsHoveringPort)
                        {
                            if (hoveredPort.IsInput)
                            {
                                if (!draggedOutput.IsConnectedTo(hoveredPort))
                                {
                                    draggedOutputTarget = hoveredPort;
                                }
                            }
                        }
                        else
                        {
                            draggedOutputTarget = null;
                        }
                        Repaint();
                    }
                    else if (currentActivity == NodeActivity.HoldNode)
                    {
                        RecalculateDragOffsets(e);
                        currentActivity = NodeActivity.DragNode;
                        Repaint();
                    }
                    if (currentActivity == NodeActivity.DragNode)
                    {
                        // Holding ctrl inverts grid snap
                        bool gridSnap = NodeEditorPreferences.GetSettings().gridSnap;
                        if (e.control)
                        {
                            gridSnap = !gridSnap;
                        }

                        Vector2 mousePos = WindowToGridPosition(e.mousePosition);
                        // Move selected nodes with offset
                        for (int i = 0; i < Selection.objects.Length; i++)
                        {
                            if (Selection.objects[i] is XNode.Node)
                            {
                                XNode.Node node    = Selection.objects[i] as XNode.Node;
                                Vector2    initial = node.position;
                                node.position = mousePos + dragOffset[i];
                                if (gridSnap)
                                {
                                    node.position.x = (Mathf.Round((node.position.x + 8) / 16) * 16) - 8;
                                    node.position.y = (Mathf.Round((node.position.y + 8) / 16) * 16) - 8;
                                }

                                // Offset portConnectionPoints instantly if a node is dragged so they aren't delayed by a frame.
                                Vector2 offset = node.position - initial;
                                if (offset.sqrMagnitude > 0)
                                {
                                    foreach (XNode.NodePort output in node.Outputs)
                                    {
                                        Rect rect;
                                        if (portConnectionPoints.TryGetValue(output, out rect))
                                        {
                                            rect.position += offset;
                                            portConnectionPoints[output] = rect;
                                        }
                                    }

                                    foreach (XNode.NodePort input in node.Inputs)
                                    {
                                        Rect rect;
                                        if (portConnectionPoints.TryGetValue(input, out rect))
                                        {
                                            rect.position += offset;
                                            portConnectionPoints[input] = rect;
                                        }
                                    }
                                }
                            }
                        }
                        // Move selected reroutes with offset
                        for (int i = 0; i < selectedReroutes.Count; i++)
                        {
                            Vector2 pos = mousePos + dragOffset[Selection.objects.Length + i];
                            if (gridSnap)
                            {
                                pos.x = (Mathf.Round(pos.x / 16) * 16);
                                pos.y = (Mathf.Round(pos.y / 16) * 16);
                            }
                            selectedReroutes[i].SetPoint(pos);
                        }
                        Repaint();
                    }
                    else if (currentActivity == NodeActivity.HoldGrid)
                    {
                        currentActivity        = NodeActivity.DragGrid;
                        preBoxSelection        = Selection.objects;
                        preBoxSelectionReroute = selectedReroutes.ToArray();
                        dragBoxStart           = WindowToGridPosition(e.mousePosition);
                        Repaint();
                    }
                    else if (currentActivity == NodeActivity.DragGrid)
                    {
                        Vector2 boxStartPos = GridToWindowPosition(dragBoxStart);
                        Vector2 boxSize     = e.mousePosition - boxStartPos;
                        if (boxSize.x < 0)
                        {
                            boxStartPos.x += boxSize.x; boxSize.x = Mathf.Abs(boxSize.x);
                        }
                        if (boxSize.y < 0)
                        {
                            boxStartPos.y += boxSize.y; boxSize.y = Mathf.Abs(boxSize.y);
                        }
                        selectionBox = new Rect(boxStartPos, boxSize);
                        Repaint();
                    }
                }
                else if (e.button == 1 || e.button == 2)
                {
                    Vector2 tempOffset = panOffset;
                    tempOffset += e.delta * zoom;
                    // Round value to increase crispyness of UI text
                    tempOffset.x = Mathf.Round(tempOffset.x);
                    tempOffset.y = Mathf.Round(tempOffset.y);
                    panOffset    = tempOffset;
                    isPanning    = true;
                }
                break;

            case EventType.MouseDown:
                Repaint();
                if (e.button == 0)
                {
                    draggedOutputReroutes.Clear();

                    if (IsHoveringPort)
                    {
                        if (hoveredPort.IsOutput)
                        {
                            draggedOutput = hoveredPort;
                        }
                        else
                        {
                            hoveredPort.VerifyConnections();
                            if (hoveredPort.IsConnected)
                            {
                                XNode.Node     node   = hoveredPort.node;
                                XNode.NodePort output = hoveredPort.Connection;
                                int            outputConnectionIndex = output.GetConnectionIndex(hoveredPort);
                                draggedOutputReroutes = output.GetReroutePoints(outputConnectionIndex);
                                hoveredPort.Disconnect(output);
                                draggedOutput       = output;
                                draggedOutputTarget = hoveredPort;
                                if (NodeEditor.onUpdateNode != null)
                                {
                                    NodeEditor.onUpdateNode(node);
                                }
                            }
                        }
                    }
                    else if (IsHoveringNode && IsHoveringTitle(hoveredNode))
                    {
                        // If mousedown on node header, select or deselect
                        if (!Selection.Contains(hoveredNode))
                        {
                            SelectNode(hoveredNode, e.control || e.shift);
                            if (!e.control && !e.shift)
                            {
                                selectedReroutes.Clear();
                            }
                        }
                        else if (e.control || e.shift)
                        {
                            DeselectNode(hoveredNode);
                        }
                        e.Use();
                        currentActivity = NodeActivity.HoldNode;
                    }
                    else if (IsHoveringReroute)
                    {
                        // If reroute isn't selected
                        if (!selectedReroutes.Contains(hoveredReroute))
                        {
                            // Add it
                            if (e.control || e.shift)
                            {
                                selectedReroutes.Add(hoveredReroute);
                            }
                            // Select it
                            else
                            {
                                selectedReroutes = new List <RerouteReference>()
                                {
                                    hoveredReroute
                                };
                                Selection.activeObject = null;
                            }
                        }
                        // Deselect
                        else if (e.control || e.shift)
                        {
                            selectedReroutes.Remove(hoveredReroute);
                        }
                        e.Use();
                        currentActivity = NodeActivity.HoldNode;
                    }
                    // If mousedown on grid background, deselect all
                    else if (!IsHoveringNode)
                    {
                        currentActivity = NodeActivity.HoldGrid;
                        if (!e.control && !e.shift)
                        {
                            selectedReroutes.Clear();
                            Selection.activeObject = null;
                        }
                        if (e.clickCount == 2)
                        {
                            // Add a new node on double click
                            // Start by making it the "ObjectSelector" node
                            var pos    = WindowToGridPosition(Event.current.mousePosition);
                            var offset = new Vector2(-110, -30);
                            ObjectSelectorEditor.Position = pos + offset;
                            CreateNode(typeof(ObjectSelector), pos + offset);
                            e.Use();
                        }
                    }
                }
                break;

            case EventType.MouseUp:
                if (e.button == 0)
                {
                    //Port drag release
                    if (IsDraggingPort)
                    {
                        //If connection is valid, save it
                        if (draggedOutputTarget != null)
                        {
                            XNode.Node node = draggedOutputTarget.node;
                            if (graph.nodes.Count != 0)
                            {
                                draggedOutput.Connect(draggedOutputTarget);
                            }

                            // ConnectionIndex can be -1 if the connection is removed instantly after creation
                            int connectionIndex = draggedOutput.GetConnectionIndex(draggedOutputTarget);
                            if (connectionIndex != -1)
                            {
                                draggedOutput.GetReroutePoints(connectionIndex).AddRange(draggedOutputReroutes);
                                if (NodeEditor.onUpdateNode != null)
                                {
                                    NodeEditor.onUpdateNode(node);
                                }
                                EditorUtility.SetDirty(graph);
                            }
                        }
                        //Release dragged connection
                        draggedOutput       = null;
                        draggedOutputTarget = null;
                        EditorUtility.SetDirty(graph);
                        if (NodeEditorPreferences.GetSettings().autoSave)
                        {
                            AssetDatabase.SaveAssets();
                        }
                    }
                    else if (currentActivity == NodeActivity.DragNode)
                    {
                        IEnumerable <XNode.Node> nodes = Selection.objects.Where(x => x is XNode.Node).Select(x => x as XNode.Node);
                        foreach (XNode.Node node in nodes)
                        {
                            EditorUtility.SetDirty(node);
                        }
                        if (NodeEditorPreferences.GetSettings().autoSave)
                        {
                            AssetDatabase.SaveAssets();
                        }
                    }
                    else if (!IsHoveringNode)
                    {
                        // If click outside node, release field focus
                        if (!isPanning)
                        {
                            EditorGUI.FocusTextInControl(null);
                        }
                        if (NodeEditorPreferences.GetSettings().autoSave)
                        {
                            AssetDatabase.SaveAssets();
                        }
                    }

                    // If click node header, select it.
                    if (currentActivity == NodeActivity.HoldNode && !(e.control || e.shift))
                    {
                        selectedReroutes.Clear();
                        SelectNode(hoveredNode, false);
                    }

                    // If click reroute, select it.
                    if (IsHoveringReroute && !(e.control || e.shift))
                    {
                        selectedReroutes = new List <RerouteReference>()
                        {
                            hoveredReroute
                        };
                        Selection.activeObject = null;
                    }

                    Repaint();
                    currentActivity = NodeActivity.Idle;
                }
                else if (e.button == 1 || e.button == 2)
                {
                    if (!isPanning)
                    {
                        if (IsDraggingPort)
                        {
                            draggedOutputReroutes.Add(WindowToGridPosition(e.mousePosition));
                        }
                        else if (currentActivity == NodeActivity.DragNode && Selection.activeObject == null && selectedReroutes.Count == 1)
                        {
                            selectedReroutes[0].InsertPoint(selectedReroutes[0].GetPoint());
                            selectedReroutes[0] = new RerouteReference(selectedReroutes[0].port, selectedReroutes[0].connectionIndex, selectedReroutes[0].pointIndex + 1);
                        }
                        else if (IsHoveringReroute)
                        {
                            ShowRerouteContextMenu(hoveredReroute);
                        }
                        else if (IsHoveringPort)
                        {
                            ShowPortContextMenu(hoveredPort);
                        }
                        else if (IsHoveringNode && IsHoveringTitle(hoveredNode))
                        {
                            if (!Selection.Contains(hoveredNode))
                            {
                                SelectNode(hoveredNode, false);
                            }
                            ShowNodeContextMenu();
                        }
                        else if (!IsHoveringNode)
                        {
                            ShowGraphContextMenu();
                        }
                    }
                    isPanning = false;
                }
                break;

            case EventType.KeyDown:
                if (EditorGUIUtility.editingTextField)
                {
                    break;
                }
                else if (e.keyCode == KeyCode.F)
                {
                    Home();
                }
                if (SystemInfo.operatingSystemFamily == OperatingSystemFamily.MacOSX)
                {
                    if (e.keyCode == KeyCode.Return)
                    {
                        RenameSelectedNode();
                    }
                }
                else
                {
                    if (e.keyCode == KeyCode.F2)
                    {
                        RenameSelectedNode();
                    }
                }
                break;

            case EventType.ValidateCommand:
                if (e.commandName == "SoftDelete")
                {
                    RemoveSelectedNodes();
                }
                else if (SystemInfo.operatingSystemFamily == OperatingSystemFamily.MacOSX && e.commandName == "Delete")
                {
                    RemoveSelectedNodes();
                }
                else if (e.commandName == "Duplicate")
                {
                    DublicateSelectedNodes();
                }
                Repaint();
                break;

            case EventType.Ignore:
                // If release mouse outside window
                if (e.rawType == EventType.MouseUp && currentActivity == NodeActivity.DragGrid)
                {
                    Repaint();
                    currentActivity = NodeActivity.Idle;
                }
                break;
            }
        }
コード例 #6
0
ファイル: NodeEditorGUI.cs プロジェクト: KurtGokhan/xNode
        public void DrawLinks()
        {
            Vector2 mousePos = Event.current.mousePosition;
            List <RerouteReference> selection = preBoxSelectionReroute != null ? new List <RerouteReference>(preBoxSelectionReroute) : new List <RerouteReference>();

            hoveredReroute = new RerouteReference();

            List <Vector2> gridPoints = new List <Vector2>(2);

            Color col = GUI.color;

            foreach (XNode.Node node in graph.nodes)
            {
                //If a null node is found, return. This can happen if the nodes associated script is deleted. It is currently not possible in Unity to delete a null asset.
                if (node == null)
                {
                    continue;
                }

                var links = XNode.NodeDataCache.GetOutputLinks(node.GetType()).Select(x => new NodeLinkPort(node, x));

                // Draw full connections and output > reroute
                foreach (var output in links)
                {
                    //Needs cleanup. Null checks are ugly
                    Rect fromRect;
                    if (!linkConnectionPoints.TryGetValue(output, out fromRect))
                    {
                        continue;
                    }

                    Color           portColor   = graphEditor.GetLinkColor(output.Item2);
                    List <NodeLink> connections = output.GetConnections();

                    for (int k = 0; k < connections.Count; k++)
                    {
                        NodeLink link = connections[k];
                        if (!link)
                        {
                            Debug.LogWarning("There was a null entry in a node's connected links list. Removing.");
                            output.VerifyConnections();
                            connections.RemoveAt(k);
                            k--;
                            continue;
                        }
                        NodeLinkPort input = link.GetToPort();

                        Gradient     noodleGradient  = graphEditor.GetNoodleGradient(output, input);
                        float        noodleThickness = graphEditor.GetNoodleThickness(link);
                        NoodlePath   noodlePath      = graphEditor.GetNoodlePath(output, input);
                        NoodleStroke noodleStroke    = graphEditor.GetNoodleStroke(output, input);

                        // Error handling
                        if (input == null)
                        {
                            continue;                //If a script has been updated and the port doesn't exist, it is removed and null is returned. If this happens, return.
                        }
                        //if (!input.IsConnectedTo(output)) input.Connect(output);
                        Rect toRect;
                        if (!linkConnectionPoints.TryGetValue(input, out toRect))
                        {
                            continue;
                        }

                        List <Vector2> reroutePoints = link.reroutePoints;

                        gridPoints.Clear();
                        gridPoints.Add(fromRect.center);
                        gridPoints.AddRange(reroutePoints);
                        gridPoints.Add(toRect.center);
                        DrawNoodle(noodleGradient, noodlePath, noodleStroke, noodleThickness, gridPoints, link);

                        // Loop through reroute points again and draw the points
                        for (int i = 0; i < reroutePoints.Count; i++)
                        {
                            //RerouteReference rerouteRef = new RerouteReference(output, k, i);
                            // Draw reroute point at position
                            Rect rect = new Rect(reroutePoints[i], new Vector2(12, 12));
                            rect.position = new Vector2(rect.position.x - 6, rect.position.y - 6);
                            rect          = GridToWindowRect(rect);

                            // TODO:
                            //// Draw selected reroute points with an outline
                            //if (selectedReroutes.Contains(rerouteRef)) {
                            //    GUI.color = NodeEditorPreferences.GetSettings().highlightColor;
                            //    GUI.DrawTexture(rect, NodeEditorResources.dotOuter);
                            //}

                            GUI.color = portColor;
                            GUI.DrawTexture(rect, NodeEditorResources.dot);
                            //if (rect.Overlaps(selectionBox)) selection.Add(rerouteRef);
                            //if (rect.Contains(mousePos)) hoveredReroute = rerouteRef;
                        }
                    }
                }
                GUI.color = col;
                if (Event.current.type != EventType.Layout && currentActivity == NodeActivity.DragGrid)
                {
                    selectedReroutes = selection;
                }
            }
        }
コード例 #7
0
ファイル: NodeEditorGUI.cs プロジェクト: Siccity/xNode
        /// <summary> Draws all connections </summary>
        public void DrawConnections()
        {
            Vector2 mousePos = Event.current.mousePosition;
            List <RerouteReference> selection = preBoxSelectionReroute != null ? new List <RerouteReference>(preBoxSelectionReroute) : new List <RerouteReference>();

            hoveredReroute = new RerouteReference();

            List <Vector2> gridPoints = new List <Vector2>(2);

            Color col = GUI.color;

            foreach (XNode.Node node in graph.nodes)
            {
                //If a null node is found, return. This can happen if the nodes associated script is deleted. It is currently not possible in Unity to delete a null asset.
                if (node == null)
                {
                    continue;
                }

                // Draw full connections and output > reroute
                foreach (XNode.NodePort output in node.Outputs)
                {
                    //Needs cleanup. Null checks are ugly
                    Rect fromRect;
                    if (!_portConnectionPoints.TryGetValue(output, out fromRect))
                    {
                        continue;
                    }

                    Color    portColor = graphEditor.GetPortColor(output);
                    GUIStyle portStyle = graphEditor.GetPortStyle(output);

                    for (int k = 0; k < output.ConnectionCount; k++)
                    {
                        XNode.NodePort input = output.GetConnection(k);

                        Gradient     noodleGradient  = graphEditor.GetNoodleGradient(output, input);
                        float        noodleThickness = graphEditor.GetNoodleThickness(output, input);
                        NoodlePath   noodlePath      = graphEditor.GetNoodlePath(output, input);
                        NoodleStroke noodleStroke    = graphEditor.GetNoodleStroke(output, input);

                        // Error handling
                        if (input == null)
                        {
                            continue;                //If a script has been updated and the port doesn't exist, it is removed and null is returned. If this happens, return.
                        }
                        if (!input.IsConnectedTo(output))
                        {
                            input.Connect(output);
                        }
                        Rect toRect;
                        if (!_portConnectionPoints.TryGetValue(input, out toRect))
                        {
                            continue;
                        }

                        List <Vector2> reroutePoints = output.GetReroutePoints(k);

                        gridPoints.Clear();
                        gridPoints.Add(fromRect.center);
                        gridPoints.AddRange(reroutePoints);
                        gridPoints.Add(toRect.center);
                        DrawNoodle(noodleGradient, noodlePath, noodleStroke, noodleThickness, gridPoints);

                        // Loop through reroute points again and draw the points
                        for (int i = 0; i < reroutePoints.Count; i++)
                        {
                            RerouteReference rerouteRef = new RerouteReference(output, k, i);
                            // Draw reroute point at position
                            Rect rect = new Rect(reroutePoints[i], new Vector2(12, 12));
                            rect.position = new Vector2(rect.position.x - 6, rect.position.y - 6);
                            rect          = GridToWindowRect(rect);

                            // Draw selected reroute points with an outline
                            if (selectedReroutes.Contains(rerouteRef))
                            {
                                GUI.color = NodeEditorPreferences.GetSettings().highlightColor;
                                GUI.DrawTexture(rect, portStyle.normal.background);
                            }

                            GUI.color = portColor;
                            GUI.DrawTexture(rect, portStyle.active.background);
                            if (rect.Overlaps(selectionBox))
                            {
                                selection.Add(rerouteRef);
                            }
                            if (rect.Contains(mousePos))
                            {
                                hoveredReroute = rerouteRef;
                            }
                        }
                    }
                }
            }
            GUI.color = col;
            if (Event.current.type != EventType.Layout && currentActivity == NodeActivity.DragGrid)
            {
                selectedReroutes = selection;
            }
        }
コード例 #8
0
        public void Controls()
        {
            wantsMouseMove = true;
            var e = Event.current;

            switch (e.type)
            {
            case EventType.MouseMove:
                break;

            case EventType.ScrollWheel:
                if (e.delta.y > 0)
                {
                    Zoom += 0.1f * Zoom;
                }
                else
                {
                    Zoom -= 0.1f * Zoom;
                }
                break;

            case EventType.MouseDrag:
                if (e.button == 0)
                {
                    if (IsDraggingPort)
                    {
                        if (IsHoveringPort && hoveredPort.Direction == PortIO.Input)
                        {
                            if (!draggedOutput.IsConnectedTo(hoveredPort))
                            {
                                draggedOutputTarget = hoveredPort;
                            }
                        }
                        else
                        {
                            draggedOutputTarget = null;
                        }

                        Repaint();
                    }
                    else if (currentActivity == NodeActivity.HoldNode)
                    {
                        RecalculateDragOffsets(e);
                        currentActivity = NodeActivity.DragNode;
                        Repaint();
                    }

                    if (currentActivity == NodeActivity.DragNode)
                    {
                        // Holding ctrl inverts grid snap
                        var gridSnap = this.GetSettings().gridSnap;
                        if (e.control)
                        {
                            gridSnap = !gridSnap;
                        }

                        var mousePos = WindowToGridPosition(e.mousePosition);
                        // Move selected nodes with offset
                        for (var i = 0; i < selection.Count; i++)
                        {
                            var node    = selection[i];
                            var initial = node.Position;
                            node.Position = mousePos + dragOffset[i];
                            if (gridSnap)
                            {
                                var newPosition = new Vector2(
                                    (Mathf.Round((node.Position.x + 8) / 16) * 16) - 8,
                                    (Mathf.Round((node.Position.y + 8) / 16) * 16) - 8);
                                node.Position = newPosition;
                            }

                            // Offset portConnectionPoints instantly if a node is dragged so they aren't delayed by a frame.
                            var offset = node.Position - initial;
                            if (!(offset.sqrMagnitude > 0))
                            {
                                continue;
                            }

                            // foreach (var output in node.Outputs) {
                            //     if (PortConnectionPoints.TryGetValue(output, out var rect)) {
                            //         rect.position                   += offset;
                            //         PortConnectionPoints[output] =  rect;
                            //     }
                            // }
                            //
                            // foreach (var input in node.Inputs) {
                            //     if (!PortConnectionPoints.TryGetValue(input, out var rect)) {
                            //         continue;
                            //     }
                            //
                            //     rect.position                  += offset;
                            //     PortConnectionPoints[input] =  rect;
                            // }
                        }

                        // Move selected reroutes with offset
                        for (var i = 0; i < selectedReroutes.Count; i++)
                        {
                            var pos = mousePos + dragOffset[selection.Count + i];
                            if (gridSnap)
                            {
                                pos.x = (Mathf.Round(pos.x / 16) * 16);
                                pos.y = (Mathf.Round(pos.y / 16) * 16);
                            }

                            selectedReroutes[i].SetPoint(pos);
                        }

                        Repaint();
                    }
                    else if (currentActivity == NodeActivity.HoldGrid)
                    {
                        currentActivity = NodeActivity.DragGrid;
                        preBoxSelection = selection.
                                          Select(x => x.Id).
                                          ToArray();

                        preBoxSelectionReroute = selectedReroutes.ToArray();
                        dragBoxStart           = WindowToGridPosition(e.mousePosition);
                        Repaint();
                    }
                    else if (currentActivity == NodeActivity.DragGrid)
                    {
                        var boxStartPos = GridToWindowPosition(dragBoxStart);
                        var boxSize     = e.mousePosition - boxStartPos;
                        if (boxSize.x < 0)
                        {
                            boxStartPos.x += boxSize.x;
                            boxSize.x      = Mathf.Abs(boxSize.x);
                        }

                        if (boxSize.y < 0)
                        {
                            boxStartPos.y += boxSize.y;
                            boxSize.y      = Mathf.Abs(boxSize.y);
                        }

                        selectionBox = new Rect(boxStartPos, boxSize);
                        Repaint();
                    }
                }
                else if (e.button == 1 || e.button == 2)
                {
                    var tempOffset = PanOffset;
                    tempOffset += e.delta * Zoom;
                    // Round value to increase crispyness of UI text
                    tempOffset.x = Mathf.Round(tempOffset.x);
                    tempOffset.y = Mathf.Round(tempOffset.y);
                    PanOffset    = tempOffset;
                    isPanning    = true;
                }

                break;

            case EventType.MouseDown:
                Repaint();
                if (e.button == 0)
                {
                    draggedOutputReroutes.Clear();

                    if (IsHoveringPort)
                    {
                        if (hoveredPort.IsOutput)
                        {
                            draggedOutput = hoveredPort;
                        }
                        else
                        {
                            hoveredPort.VerifyConnections();
                            if (hoveredPort.IsConnected)
                            {
                                var node   = hoveredPort.Node;
                                var output = hoveredPort.Connection as NodePort;
                                var outputConnectionIndex = output.GetConnectionIndex(hoveredPort);
                                draggedOutputReroutes = output.GetReroutePoints(outputConnectionIndex);
                                hoveredPort.Disconnect(output);
                                draggedOutput       = output;
                                draggedOutputTarget = hoveredPort;
                                if (NodeEditor.OnUpdateNode != null)
                                {
                                    NodeEditor.OnUpdateNode(node);
                                }
                            }
                        }
                    }
                    else if (IsHoveringNode && IsHoveringTitle(hoveredNode))
                    {
                        // If mousedown on node header, select or deselect
                        if (!IsSelected(hoveredNode))
                        {
                            Select(hoveredNode, e.control || e.shift);
                            if (!e.control && !e.shift)
                            {
                                selectedReroutes.Clear();
                            }
                        }
                        else if (e.control || e.shift)
                        {
                            Deselect(hoveredNode);
                        }

                        e.Use();
                        currentActivity = NodeActivity.HoldNode;
                    }
                    else if (IsHoveringReroute)
                    {
                        // If reroute isn't selected
                        if (!selectedReroutes.Contains(hoveredReroute))
                        {
                            // Add it
                            if (e.control || e.shift)
                            {
                                selectedReroutes.Add(hoveredReroute);
                            }
                            // Select it
                            else
                            {
                                selectedReroutes = new List <RerouteReference> {
                                    hoveredReroute
                                };
                                DeselectAll();
                            }
                        }
                        // Deselect
                        else if (e.control || e.shift)
                        {
                            selectedReroutes.Remove(hoveredReroute);
                        }

                        e.Use();
                        currentActivity = NodeActivity.HoldNode;
                    }
                    // If mousedown on grid background, deselect all
                    else if (!IsHoveringNode)
                    {
                        currentActivity = NodeActivity.HoldGrid;
                        if (!e.control && !e.shift)
                        {
                            selectedReroutes.Clear();
                            DeselectAll();
                        }
                    }
                }

                break;

            case EventType.MouseUp:
                if (e.button == 0)
                {
                    //Port drag release
                    if (IsDraggingPort)
                    {
                        //If connection is valid, save it
                        if (draggedOutputTarget != null)
                        {
                            var node = draggedOutputTarget.Node;
                            if (ActiveGraph.Nodes.Count != 0)
                            {
                                draggedOutput.Connect(draggedOutputTarget);
                            }

                            // ConnectionIndex can be -1 if the connection is removed instantly after creation
                            var connectionIndex = draggedOutput.GetConnectionIndex(draggedOutputTarget);
                            if (connectionIndex != -1)
                            {
                                draggedOutput.GetReroutePoints(connectionIndex).AddRange(draggedOutputReroutes);
                                if (NodeEditor.OnUpdateNode != null)
                                {
                                    NodeEditor.OnUpdateNode(node);
                                }
                                EditorUtility.SetDirty(ActiveGraph);
                            }
                        }

                        //Release dragged connection
                        draggedOutput       = null;
                        draggedOutputTarget = null;
                        EditorUtility.SetDirty(ActiveGraph);
                        if (this.GetSettings().autoSave)
                        {
                            AssetDatabase.SaveAssets();
                        }
                    }
                    else if (currentActivity == NodeActivity.DragNode)
                    {
                        var nodes = selection;
                        foreach (var node in nodes)
                        {
                            node.SetDirty();
                        }
                        if (this.GetSettings().autoSave)
                        {
                            AssetDatabase.SaveAssets();
                        }
                    }
                    else if (!IsHoveringNode)
                    {
                        // If click outside node, release field focus
                        if (!isPanning)
                        {
                            EditorGUI.FocusTextInControl(null);
                        }

                        if (this.GetSettings().autoSave)
                        {
                            AssetDatabase.SaveAssets();
                        }
                    }

                    // If click node header, select it.
                    if (currentActivity == NodeActivity.HoldNode && !(e.control || e.shift))
                    {
                        selectedReroutes.Clear();
                        Select(hoveredNode, false);
                    }

                    // If click reroute, select it.
                    if (IsHoveringReroute && !(e.control || e.shift))
                    {
                        selectedReroutes = new List <RerouteReference> {
                            hoveredReroute
                        };
                    }

                    Repaint();
                    currentActivity = NodeActivity.Idle;
                }
                else if (e.button == 1 || e.button == 2)
                {
                    if (!isPanning)
                    {
                        if (IsDraggingPort)
                        {
                            draggedOutputReroutes.Add(WindowToGridPosition(e.mousePosition));
                        }
                        else if (currentActivity == NodeActivity.DragNode &&
                                 selection.Count > 0 &&
                                 selectedReroutes.Count == 1)
                        {
                            selectedReroutes[0].InsertPoint(selectedReroutes[0].GetPoint());
                            selectedReroutes[0] = new RerouteReference(selectedReroutes[0].port,
                                                                       selectedReroutes[0].connectionIndex, selectedReroutes[0].pointIndex + 1);
                        }
                        else if (IsHoveringReroute)
                        {
                            ShowRerouteContextMenu(hoveredReroute);
                        }
                        else if (IsHoveringPort)
                        {
                            ShowPortContextMenu(hoveredPort);
                        }
                        else if (IsHoveringNode && IsHoveringTitle(hoveredNode))
                        {
                            if (!hoveredNode.IsSelected())
                            {
                                Select(hoveredNode, false);
                            }
                            ShowNodeContextMenu();
                        }
                        else if (!IsHoveringNode)
                        {
                            ShowGraphContextMenu();
                        }
                    }

                    isPanning = false;
                }

                break;

            case EventType.KeyDown:
                if (EditorGUIUtility.editingTextField)
                {
                    break;
                }
                else if (e.keyCode == KeyCode.F)
                {
                    Home();
                }
                if (SystemInfo.operatingSystemFamily == OperatingSystemFamily.MacOSX)
                {
                    if (e.keyCode == KeyCode.Return)
                    {
                        RenameSelectedNode();
                    }
                }
                else
                {
                    if (e.keyCode == KeyCode.F2)
                    {
                        RenameSelectedNode();
                    }
                }

                break;

            case EventType.ValidateCommand:
                if (e.commandName == "SoftDelete")
                {
                    RemoveSelectedNodes();
                }
                else if (SystemInfo.operatingSystemFamily == OperatingSystemFamily.MacOSX &&
                         e.commandName == "Delete")
                {
                    RemoveSelectedNodes();
                }
                else if (e.commandName == "Duplicate")
                {
                    DublicateSelectedNodes();
                }
                Repaint();
                break;

            case EventType.Ignore:
                // If release mouse outside window
                if (e.rawType == EventType.MouseUp && currentActivity == NodeActivity.DragGrid)
                {
                    Repaint();
                    currentActivity = NodeActivity.Idle;
                }

                break;
            }
        }
コード例 #9
0
        public void Controls()
        {
            wantsMouseMove = true;
            Event e = Event.current;

            switch (e.type)
            {
            case EventType.MouseMove:
                break;

            case EventType.ScrollWheel:
                if (e.delta.y > 0)
                {
                    zoom += 0.1f * zoom;
                }
                else
                {
                    zoom -= 0.1f * zoom;
                }
                break;

            case EventType.MouseDrag:
                if (e.button == 0)
                {
                    if (IsDraggingPort)
                    {
                        if (IsHoveringPort && hoveredPort.IsInput)
                        {
                            if (!draggedOutput.IsConnectedTo(hoveredPort))
                            {
                                draggedOutputTarget = hoveredPort;
                            }
                        }
                        else
                        {
                            draggedOutputTarget = null;
                        }
                        Repaint();
                    }
                    else if (currentActivity == NodeActivity.HoldNode)
                    {
                        RecalculateDragOffsets(e);
                        currentActivity = NodeActivity.DragNode;
                        Repaint();
                    }
                    if (currentActivity == NodeActivity.DragNode)
                    {
                        // Holding ctrl inverts grid snap
                        bool gridSnap = NodeEditorPreferences.GetSettings().gridSnap;
                        if (e.control)
                        {
                            gridSnap = !gridSnap;
                        }

                        Vector2 mousePos = WindowToGridPosition(e.mousePosition);
                        // Move selected nodes with offset
                        for (int i = 0; i < Selection.objects.Length; i++)
                        {
                            if (Selection.objects[i] is XNode.Node)
                            {
                                XNode.Node node = Selection.objects[i] as XNode.Node;
                                node.position = mousePos + dragOffset[i];
                                if (gridSnap)
                                {
                                    node.position.x = (Mathf.Round((node.position.x + 8) / 16) * 16) - 8;
                                    node.position.y = (Mathf.Round((node.position.y + 8) / 16) * 16) - 8;
                                }
                            }
                        }
                        // Move selected reroutes with offset
                        for (int i = 0; i < selectedReroutes.Count; i++)
                        {
                            Vector2 pos = mousePos + dragOffset[Selection.objects.Length + i];
                            pos.x -= 8;
                            pos.y -= 8;
                            if (gridSnap)
                            {
                                pos.x = (Mathf.Round((pos.x + 8) / 16) * 16);
                                pos.y = (Mathf.Round((pos.y + 8) / 16) * 16);
                            }
                            selectedReroutes[i].SetPoint(pos);
                        }
                        Repaint();
                    }
                    else if (currentActivity == NodeActivity.HoldGrid)
                    {
                        currentActivity        = NodeActivity.DragGrid;
                        preBoxSelection        = Selection.objects;
                        preBoxSelectionReroute = selectedReroutes.ToArray();
                        dragBoxStart           = WindowToGridPosition(e.mousePosition);
                        Repaint();
                    }
                    else if (currentActivity == NodeActivity.DragGrid)
                    {
                        Vector2 boxStartPos = GridToWindowPosition(dragBoxStart);
                        Vector2 boxSize     = e.mousePosition - boxStartPos;
                        if (boxSize.x < 0)
                        {
                            boxStartPos.x += boxSize.x; boxSize.x = Mathf.Abs(boxSize.x);
                        }
                        if (boxSize.y < 0)
                        {
                            boxStartPos.y += boxSize.y; boxSize.y = Mathf.Abs(boxSize.y);
                        }
                        selectionBox = new Rect(boxStartPos, boxSize);
                        Repaint();
                    }
                }
                else if (e.button == 1 || e.button == 2)
                {
                    Vector2 tempOffset = panOffset;
                    tempOffset += e.delta * zoom;
                    // Round value to increase crispyness of UI text
                    tempOffset.x = Mathf.Round(tempOffset.x);
                    tempOffset.y = Mathf.Round(tempOffset.y);
                    panOffset    = tempOffset;
                    isPanning    = true;
                }
                break;

            case EventType.MouseDown:
                Repaint();
                if (e.button == 0)
                {
                    draggedOutputReroutes.Clear();

                    if (IsHoveringPort)
                    {
                        if (hoveredPort.IsOutput)
                        {
                            draggedOutput = hoveredPort;
                        }
                        else
                        {
                            hoveredPort.VerifyConnections();
                            if (hoveredPort.IsConnected)
                            {
                                XNode.Node     node   = hoveredPort.node;
                                XNode.NodePort output = hoveredPort.Connection;
                                int            outputConnectionIndex = output.GetConnectionIndex(hoveredPort);
                                draggedOutputReroutes = output.GetReroutePoints(outputConnectionIndex);
                                hoveredPort.Disconnect(output);
                                draggedOutput       = output;
                                draggedOutputTarget = hoveredPort;
                                if (NodeEditor.onUpdateNode != null)
                                {
                                    NodeEditor.onUpdateNode(node);
                                }
                            }
                        }
                    }
                    else if (IsHoveringNode && IsHoveringTitle(hoveredNode))
                    {
                        // If mousedown on node header, select or deselect
                        if (!Selection.Contains(hoveredNode))
                        {
                            SelectNode(hoveredNode, e.control || e.shift);
                            if (!e.control && !e.shift)
                            {
                                selectedReroutes.Clear();
                            }
                        }
                        else if (e.control || e.shift)
                        {
                            DeselectNode(hoveredNode);
                        }
                        e.Use();
                        currentActivity = NodeActivity.HoldNode;
                    }
                    else if (IsHoveringReroute)
                    {
                        // If reroute isn't selected
                        if (!selectedReroutes.Contains(hoveredReroute))
                        {
                            // Add it
                            if (e.control || e.shift)
                            {
                                selectedReroutes.Add(hoveredReroute);
                            }
                            // Select it
                            else
                            {
                                selectedReroutes = new List <RerouteReference>()
                                {
                                    hoveredReroute
                                };
                                Selection.activeObject = null;
                            }
                        }
                        // Deselect
                        else if (e.control || e.shift)
                        {
                            selectedReroutes.Remove(hoveredReroute);
                        }
                        e.Use();
                        currentActivity = NodeActivity.HoldNode;
                    }
                    // If mousedown on grid background, deselect all
                    else if (!IsHoveringNode)
                    {
                        currentActivity = NodeActivity.HoldGrid;
                        if (!e.control && !e.shift)
                        {
                            selectedReroutes.Clear();
                            Selection.activeObject = null;
                        }
                    }
                }
                break;

            case EventType.MouseUp:
                if (e.button == 0)
                {
                    //Port drag release
                    if (IsDraggingPort)
                    {
                        //If connection is valid, save it
                        if (draggedOutputTarget != null)
                        {
                            XNode.Node node = draggedOutputTarget.node;
                            if (graph.nodes.Count != 0)
                            {
                                draggedOutput.Connect(draggedOutputTarget);
                            }

                            // ConnectionIndex can be -1 if the connection is removed instantly after creation
                            int connectionIndex = draggedOutput.GetConnectionIndex(draggedOutputTarget);
                            if (connectionIndex != -1)
                            {
                                draggedOutput.GetReroutePoints(connectionIndex).AddRange(draggedOutputReroutes);
                                if (NodeEditor.onUpdateNode != null)
                                {
                                    NodeEditor.onUpdateNode(node);
                                }
                                EditorUtility.SetDirty(graph);
                            }
                        }
                        //Release dragged connection
                        draggedOutput       = null;
                        draggedOutputTarget = null;
                        EditorUtility.SetDirty(graph);
                        AssetDatabase.SaveAssets();
                    }
                    else if (currentActivity == NodeActivity.DragNode)
                    {
                        AssetDatabase.SaveAssets();
                    }
                    else if (!IsHoveringNode)
                    {
                        // If click outside node, release field focus
                        if (!isPanning)
                        {
                            // I've got no idea which of these do what, so we'll just reset all of it.
                            GUIUtility.hotControl             = 0;
                            GUIUtility.keyboardControl        = 0;
                            EditorGUIUtility.editingTextField = false;
                            EditorGUIUtility.keyboardControl  = 0;
                            EditorGUIUtility.hotControl       = 0;
                        }
                        AssetDatabase.SaveAssets();
                    }

                    // If click node header, select it.
                    if (currentActivity == NodeActivity.HoldNode && !(e.control || e.shift))
                    {
                        selectedReroutes.Clear();
                        SelectNode(hoveredNode, false);
                    }

                    // If click reroute, select it.
                    if (IsHoveringReroute && !(e.control || e.shift))
                    {
                        selectedReroutes = new List <RerouteReference>()
                        {
                            hoveredReroute
                        };
                        Selection.activeObject = null;
                    }

                    Repaint();
                    currentActivity = NodeActivity.Idle;
                }
                else if (e.button == 1)
                {
                    if (!isPanning)
                    {
                        if (IsDraggingPort)
                        {
                            draggedOutputReroutes.Add(WindowToGridPosition(e.mousePosition));
                        }
                        else if (currentActivity == NodeActivity.DragNode && Selection.activeObject == null && selectedReroutes.Count == 1)
                        {
                            selectedReroutes[0].InsertPoint(selectedReroutes[0].GetPoint());
                            selectedReroutes[0] = new RerouteReference(selectedReroutes[0].port, selectedReroutes[0].connectionIndex, selectedReroutes[0].pointIndex + 1);
                        }
                        else if (IsHoveringReroute)
                        {
                            ShowRerouteContextMenu(hoveredReroute);
                        }
                        else if (IsHoveringPort)
                        {
                            ShowPortContextMenu(hoveredPort);
                        }
                        else if (IsHoveringNode && IsHoveringTitle(hoveredNode))
                        {
                            if (!Selection.Contains(hoveredNode))
                            {
                                SelectNode(hoveredNode, false);
                            }
                            ShowNodeContextMenu();
                        }
                        else if (!IsHoveringNode)
                        {
                            ShowGraphContextMenu();
                        }
                    }
                    isPanning = false;
                }
                break;

            case EventType.KeyDown:
                if (EditorGUIUtility.editingTextField)
                {
                    break;
                }
                else if (e.keyCode == KeyCode.F)
                {
                    Home();
                }
                break;

            case EventType.ValidateCommand:
                if (e.commandName == "SoftDelete")
                {
                    RemoveSelectedNodes();
                }
                else if (e.commandName == "Duplicate")
                {
                    DublicateSelectedNodes();
                }
                Repaint();
                break;

            case EventType.Ignore:
                // If release mouse outside window
                if (e.rawType == EventType.MouseUp && currentActivity == NodeActivity.DragGrid)
                {
                    Repaint();
                    currentActivity = NodeActivity.Idle;
                }
                break;
            }
        }
コード例 #10
0
ファイル: NodeEditorGUI.cs プロジェクト: liuruoyu1981/xNode
        /// <summary> Draws all connections </summary>
        public void DrawConnections()
        {
            Vector2 mousePos = Event.current.mousePosition;
            List <RerouteReference> selection = preBoxSelectionReroute != null ? new List <RerouteReference>(preBoxSelectionReroute) : new List <RerouteReference>();

            hoveredReroute = new RerouteReference();

            foreach (XNode.Node node in graph.nodes)
            {
                //If a null node is found, return. This can happen if the nodes associated script is deleted. It is currently not possible in Unity to delete a null asset.
                if (node == null)
                {
                    continue;
                }

                // Draw full connections and output > reroute
                foreach (XNode.NodePort output in node.Outputs)
                {
                    //Needs cleanup. Null checks are ugly
                    if (!portConnectionPoints.ContainsKey(output))
                    {
                        continue;
                    }

                    Color connectionColor = graphEditor.GetTypeColor(output.ValueType);

                    for (int k = 0; k < output.ConnectionCount; k++)
                    {
                        XNode.NodePort input = output.GetConnection(k);

                        // Error handling
                        if (input == null)
                        {
                            continue;                //If a script has been updated and the port doesn't exist, it is removed and null is returned. If this happens, return.
                        }
                        if (!input.IsConnectedTo(output))
                        {
                            input.Connect(output);
                        }
                        if (!_portConnectionPoints.ContainsKey(input))
                        {
                            continue;
                        }

                        Vector2        from          = _portConnectionPoints[output].center;
                        Vector2        to            = Vector2.zero;
                        List <Vector2> reroutePoints = output.GetReroutePoints(k);
                        // Loop through reroute points and draw the path
                        for (int i = 0; i < reroutePoints.Count; i++)
                        {
                            to = reroutePoints[i];
                            DrawConnection(from, to, connectionColor);
                            from = to;
                        }
                        to = _portConnectionPoints[input].center;
                        DrawConnection(from, to, connectionColor);

                        // Loop through reroute points again and draw the points
                        for (int i = 0; i < reroutePoints.Count; i++)
                        {
                            // Draw reroute point at position
                            Rect rect = new Rect(reroutePoints[i], new Vector2(16, 16));
                            rect.position = new Vector2(rect.position.x - 8, rect.position.y - 8);
                            rect          = GridToWindowRect(rect);
                            Color bgcol = new Color32(90, 97, 105, 255);;
                            if (selectedReroutes.Contains(new RerouteReference(output, k, i)))
                            {
                                bgcol = Color.yellow;
                            }
                            NodeEditorGUILayout.DrawPortHandle(rect, bgcol, connectionColor);

                            if (rect.Overlaps(selectionBox))
                            {
                                selection.Add(new RerouteReference(output, k, i));
                            }
                            if (rect.Contains(mousePos))
                            {
                                hoveredReroute = new RerouteReference(output, k, i);
                            }
                        }
                    }
                }
            }
            if (Event.current.type != EventType.Layout && currentActivity == NodeActivity.DragGrid)
            {
                selectedReroutes = selection;
            }
        }