Наследование: NodeEditorBase, INodeEditorData
Пример #1
0
        private void DrawNodeArea(
            NodeEditor nodeEditor,
            EditorNode editorNode,
            Vector2 nodePos,
            Rect rectArea,
            NodeEditorGuiState state)
        {
            if (state.EventType == EventType.Ignore)
            {
                return;
            }

            GUILayout.BeginArea(rectArea);

            this.WrapDrawer(() => DrawNodeEditorArea(nodeEditor, editorNode, state), true);
            this.WrapDrawer(() => DrawNodePorts(editorNode.Node, nodePos, state), true);

            GUILayout.EndArea();
        }
Пример #2
0
        private void DrawNodeEditorArea(
            NodeEditor nodeEditor,
            EditorNode editorNode,
            NodeEditorGuiState state)
        {
            var eventType  = state.EventType;
            var stateEvent = state.Event;
            var node       = editorNode.Node;

            if (eventType == EventType.Ignore ||
                stateEvent.type == EventType.Ignore ||
                stateEvent.rawType == EventType.Ignore)
            {
                return;
            }

            var guiColor = GUI.color;

            var selected = IsSelected(node);

            if (selected)
            {
                var style          = new GUIStyle(nodeEditor.GetBodyStyle());
                var highlightStyle = new GUIStyle(NodeEditorResources.styles.nodeHighlight);
                highlightStyle.padding = style.padding;
                style.padding          = new RectOffset();
                GUI.color = nodeEditor.GetTint();
                GUILayout.BeginVertical(style);
                GUI.color = this.GetSettings().highlightColor;

                //TODO fix style
                GUILayout.BeginVertical(new GUIStyle(highlightStyle));
            }
            else
            {
                var style = new GUIStyle(nodeEditor.GetBodyStyle());
                GUI.color = nodeEditor.GetTint();
                GUILayout.BeginVertical(style);
            }

            GUI.color = guiColor;

            EditorGUI.BeginChangeCheck();

            //Draw node contents
            nodeEditor.OnHeaderGUI();
            nodeEditor.OnBodyGUI();

            //If user changed a value, notify other scripts through onUpdateNode
            if (EditorGUI.EndChangeCheck())
            {
                if (NodeEditor.OnUpdateNode != null)
                {
                    NodeEditor.OnUpdateNode(node);
                }
                node.SetDirty();
            }

            GUILayout.EndVertical();

            //Cache data about the node for next frame
            if (state.EventType == EventType.Repaint)
            {
                var size = GUILayoutUtility.GetLastRect().size;
                if (NodeSizes.ContainsKey(node))
                {
                    NodeSizes[node] = size;
                }
                else
                {
                    NodeSizes.Add(node, size);
                }

                foreach (var portPairs in NodeEditor.PortPositions)
                {
                    var id            = portPairs.Key;
                    var portHandlePos = portPairs.Value;
                    portHandlePos += node.Position;
                    var rect = new Rect(portHandlePos.x - 8, portHandlePos.y - 8, 16, 16);
                    PortConnectionPoints[id] = rect;
                }
            }

            if (selected)
            {
                GUILayout.EndVertical();
            }
        }
Пример #3
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;
            }
        }