Ejemplo n.º 1
0
 public void Save()
 {
     if (AssetDatabase.Contains(graph))
     {
         EditorUtility.SetDirty(graph);
         if (NodeEditorPreferences.GetSettings().autoSave)
         {
             AssetDatabase.SaveAssets();
         }
     }
     else
     {
         SaveAs();
     }
 }
Ejemplo n.º 2
0
 /// <summary> Draw a connection as we are dragging it </summary>
 public void DrawDraggedConnection()
 {
     if (IsDraggingPort)
     {
         if (!_portConnectionPoints.ContainsKey(draggedOutput))
         {
             return;
         }
         Vector2 from = _portConnectionPoints[draggedOutput].center;
         Vector2 to   = draggedOutputTarget != null ? portConnectionPoints[draggedOutputTarget].center : WindowToGridPosition(Event.current.mousePosition);
         Color   col  = NodeEditorPreferences.GetTypeColor(draggedOutput.ValueType);
         col.a = 0.6f;
         DrawConnection(from, to, col);
     }
 }
Ejemplo n.º 3
0
        /// <summary> Returns color for target node </summary>
        public virtual Color GetTint()
        {
            // Try get color from [NodeTint] attribute
            Type  type = target.GetType();
            Color color;

            if (type.TryGetAttributeTint(out color))
            {
                return(color);
            }
            // Return default color (grey)
            else
            {
                return(NodeEditorPreferences.GetSettings().tintColor);
            }
        }
Ejemplo n.º 4
0
 /// <summary> Create a node and save it in the graph asset </summary>
 public virtual XNode.Node CreateNode(Type type, Vector2 position)
 {
     XNode.Node node = target.AddNode(type);
     node.position = position;
     if (node.name == null || node.name.Trim() == "")
     {
         node.name = NodeEditorUtilities.NodeDefaultName(type);
     }
     AssetDatabase.AddObjectToAsset(node, target);
     if (NodeEditorPreferences.GetSettings().autoSave)
     {
         AssetDatabase.SaveAssets();
     }
     NodeEditorWindow.RepaintAll();
     return(node);
 }
Ejemplo n.º 5
0
 private void DrawTooltip()
 {
     if (hoveredPort != null && NodeEditorPreferences.GetSettings().portTooltips&& graphEditor != null)
     {
         string tooltip = graphEditor.GetPortTooltip(hoveredPort);
         if (string.IsNullOrEmpty(tooltip))
         {
             return;
         }
         GUIContent content = new GUIContent(tooltip);
         Vector2    size    = NodeEditorResources.styles.tooltip.CalcSize(content);
         Rect       rect    = new Rect(Event.current.mousePosition - (size), size);
         EditorGUI.LabelField(rect, content, NodeEditorResources.styles.tooltip);
         Repaint();
     }
 }
Ejemplo n.º 6
0
        void OnFocus()
        {
            current = this;
            ValidateGraphEditor();
            var set = NodeEditorPreferences.GetSettings();

            if (graphEditor != null && set != null && set.autoSave)
            {
                try
                {
                    AssetDatabase.SaveAssets();
                }catch (Exception ex)
                {
                    Debug.LogWarning(ex.Message);
                }
            }
        }
Ejemplo n.º 7
0
        /// <summary> Draw a connection as we are dragging it </summary>
        public void DrawDraggedConnection()
        {
            if (IsDraggingPort)
            {
                Color col = NodeEditorPreferences.GetTypeColor(draggedOutput.ValueType);
                col.a = draggedOutputTarget != null ? 1.0f : 0.6f;

                Rect fromRect;
                if (!_portConnectionPoints.TryGetValue(draggedOutput, out fromRect))
                {
                    return;
                }
                List <Vector2> gridPoints = new List <Vector2>();
                gridPoints.Add(fromRect.center);
                for (int i = 0; i < draggedOutputReroutes.Count; i++)
                {
                    gridPoints.Add(draggedOutputReroutes[i]);
                }
                if (draggedOutputTarget != null)
                {
                    gridPoints.Add(portConnectionPoints[draggedOutputTarget].center);
                }
                else
                {
                    gridPoints.Add(WindowToGridPosition(Event.current.mousePosition));
                }

                DrawNoodle(col, gridPoints);

                Color bgcol = Color.black;
                Color frcol = col;
                bgcol.a = 0.6f;
                frcol.a = 0.6f;

                // Loop through reroute points again and draw the points
                for (int i = 0; i < draggedOutputReroutes.Count; i++)
                {
                    // Draw reroute point at position
                    Rect rect = new Rect(draggedOutputReroutes[i], new Vector2(16, 16));
                    rect.position = new Vector2(rect.position.x - 8, rect.position.y - 8);
                    rect          = GridToWindowRect(rect);

                    NodeEditorGUILayout.DrawPortHandle(rect, bgcol, frcol);
                }
            }
        }
Ejemplo n.º 8
0
        /// <summary> Show right-click context menu for hovered port </summary>
        void ShowPortContextMenu(XNode.NodePort hoveredPort)
        {
            GenericMenu contextMenu = new GenericMenu();

            foreach (var port in hoveredPort.GetConnections())
            {
                var name  = port.node.name;
                var index = hoveredPort.GetConnectionIndex(port);
                contextMenu.AddItem(new GUIContent($"Disconnect({name})"), false, () => hoveredPort.Disconnect(index));
            }
            contextMenu.AddItem(new GUIContent("Clear Connections"), false, () => hoveredPort.ClearConnections());
            contextMenu.DropDown(new Rect(Event.current.mousePosition, Vector2.zero));
            if (NodeEditorPreferences.GetSettings().autoSave)
            {
                AssetDatabase.SaveAssets();
            }
        }
Ejemplo n.º 9
0
        /// <summary> Attempt to connect dragged output to target node </summary>
        public void AutoConnect(XNode.Node node)
        {
            if (autoConnectOutput != null)
            {
                // Find input port of same type
                XNode.NodePort inputPort = node.Ports.FirstOrDefault(x => x.IsInput && x.ValueType == autoConnectOutput.ValueType);
                // Fallback to input port
                if (inputPort == null)
                {
                    inputPort = node.Ports.FirstOrDefault(x => x.IsInput);
                }
                // Autoconnect
                if (inputPort != null)
                {
                    autoConnectOutput.Connect(inputPort);
                }

                // Save changes
                EditorUtility.SetDirty(graph);
                if (NodeEditorPreferences.GetSettings().autoSave)
                {
                    AssetDatabase.SaveAssets();
                }
                autoConnectOutput = null;
            }

            if (autoConnectOutputLink != null)
            {
                var linkType   = autoConnectOutputLink.Link.LinkType;
                var inputLinks = XNode.NodeDataCache.GetInputLinks(node.GetType());
                var inputPort  = inputLinks.FirstOrDefault(x => x.LinkType == linkType);
                inputPort = inputPort ?? inputLinks.FirstOrDefault(x => x.LinkType.IsAssignableFrom(linkType));
                if (inputPort != null)
                {
                    XNode.NodeLink link = autoConnectOutputLink.Connect(new XNode.NodeLinkPort(node, inputPort));
                    SelectObject(link, false);
                    EditorUtility.SetDirty(graph);
                    if (NodeEditorPreferences.GetSettings().autoSave)
                    {
                        AssetDatabase.SaveAssets();
                    }
                }
                autoConnectOutputLink = null;
            }
        }
Ejemplo n.º 10
0
 private void DrawTooltip()
 {
     if (hoveredPort != null && NodeEditorPreferences.GetSettings().portTooltips)
     {
         Type       type    = hoveredPort.ValueType;
         GUIContent content = new GUIContent();
         content.text = type.PrettyName();
         if (hoveredPort.IsOutput)
         {
             object obj = hoveredPort.node.GetValue(hoveredPort);
             content.text += " = " + (obj != null ? obj.ToString() : "null");
         }
         Vector2 size = NodeEditorResources.styles.tooltip.CalcSize(content);
         Rect    rect = new Rect(Event.current.mousePosition - (size), size);
         EditorGUI.LabelField(rect, content, NodeEditorResources.styles.tooltip);
         Repaint();
     }
 }
Ejemplo n.º 11
0
 /// <summary> Safely remove a node and all its connections. </summary>
 public virtual void RemoveNode(XNode.Node node)
 {
     Undo.RecordObject(node, "Delete Node");
     Undo.RecordObject(target, "Delete Node");
     foreach (var port in node.Ports)
     {
         foreach (var conn in port.GetConnections())
         {
             Undo.RecordObject(conn.node, "Delete Node");
         }
     }
     target.RemoveNode(node);
     Undo.DestroyObjectImmediate(node);
     if (NodeEditorPreferences.GetSettings().autoSave)
     {
         AssetDatabase.SaveAssets();
     }
 }
Ejemplo n.º 12
0
        public void CreateNode(Type type, Vector2 position)
        {
            XNode.Node node = graph.AddNode(type);
            node.position = position;
            node.name     = UnityEditor.ObjectNames.NicifyVariableName(type.Name);

            //PT
            if (node is PTNode)
            {
                (node as PTNode).UpdatePreview();
            }

            AssetDatabase.AddObjectToAsset(node, graph);
            if (NodeEditorPreferences.GetSettings().autoSave)
            {
                AssetDatabase.SaveAssets();
            }
            Repaint();
        }
Ejemplo n.º 13
0
        private void OnDisable()
        {
            if (NodeEditorPreferences.GetSettings().autoSave)
            {
                AutoSave();
            }
            // Cache portConnectionPoints before serialization starts
            int count = portConnectionPoints.Count;

            _references = new NodePortReference[count];
            _rects      = new Rect[count];
            int index = 0;

            foreach (var portConnectionPoint in portConnectionPoints)
            {
                _references[index] = new NodePortReference(portConnectionPoint.Key);
                _rects[index]      = portConnectionPoint.Value;
                index++;
            }
        }
Ejemplo n.º 14
0
 /// <summary> Create a node and save it in the graph asset </summary>
 public virtual XNode.Node CreateNode(Type type, Vector2 position)
 {
     Undo.RecordObject(target, "Create Node");
     XNode.Node node = target.AddNode(type);
     Undo.RegisterCreatedObjectUndo(node, "Create Node");
     node.position = position;
     if (node.name == null || node.name.Trim() == "")
     {
         node.name = NodeEditorUtilities.NodeDefaultName(type);
     }
     if (!string.IsNullOrEmpty(AssetDatabase.GetAssetPath(target)))
     {
         AssetDatabase.AddObjectToAsset(node, target);
     }
     if (NodeEditorPreferences.GetSettings().autoSave)
     {
         AssetDatabase.SaveAssets();
     }
     NodeEditorWindow.RepaintAll();
     return(node);
 }
Ejemplo n.º 15
0
 /// <summary> Create a node and save it in the graph asset </summary>
 public virtual void CreateNode(Type type, Vector2 position)
 {
     XNode.Node node = target.AddNode(type);
     node.position = position;
     if (string.IsNullOrEmpty(node.name))
     {
         // Automatically remove redundant 'Node' postfix
         string typeName = type.Name;
         if (typeName.EndsWith("Node"))
         {
             typeName = typeName.Substring(0, typeName.LastIndexOf("Node"));
         }
         node.name = UnityEditor.ObjectNames.NicifyVariableName(typeName);
     }
     AssetDatabase.AddObjectToAsset(node, target);
     if (NodeEditorPreferences.GetSettings().autoSave)
     {
         AssetDatabase.SaveAssets();
     }
     NodeEditorWindow.RepaintAll();
 }
Ejemplo n.º 16
0
        /// <summary> Draw a connection as we are dragging it </summary>
        public void DrawDraggedConnection()
        {
            if (IsDraggingPort)
            {
                Color col = NodeEditorPreferences.GetTypeColor(draggedOutput.ValueType);

                Rect fromRect;
                if (!_portConnectionPoints.TryGetValue(draggedOutput, out fromRect))
                {
                    return;
                }
                Vector2 from = fromRect.center;
                col.a = draggedOutputTarget != null ? 1.0f : 0.6f;
                Vector2 to = Vector2.zero;
                for (int i = 0; i < draggedOutputReroutes.Count; i++)
                {
                    to = draggedOutputReroutes[i];
                    DrawConnection(from, to, col);
                    from = to;
                }
                to = draggedOutputTarget != null ? portConnectionPoints[draggedOutputTarget].center : WindowToGridPosition(Event.current.mousePosition);
                DrawConnection(from, to, col);

                Color bgcol = Color.black;
                Color frcol = col;
                bgcol.a = 0.6f;
                frcol.a = 0.6f;

                // Loop through reroute points again and draw the points
                for (int i = 0; i < draggedOutputReroutes.Count; i++)
                {
                    // Draw reroute point at position
                    Rect rect = new Rect(draggedOutputReroutes[i], new Vector2(16, 16));
                    rect.position = new Vector2(rect.position.x - 8, rect.position.y - 8);
                    rect          = GridToWindowRect(rect);

                    NodeEditorGUILayout.DrawPortHandle(rect, bgcol, frcol);
                }
            }
        }
Ejemplo n.º 17
0
        /// <summary> Draws all connections </summary>
        public void DrawConnections()
        {
            foreach (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;
                }

                foreach (NodePort output in node.Outputs)
                {
                    //Needs cleanup. Null checks are ugly
                    if (!portConnectionPoints.ContainsKey(output))
                    {
                        continue;
                    }
                    Vector2 from = _portConnectionPoints[output].center;
                    for (int k = 0; k < output.ConnectionCount; k++)
                    {
                        NodePort input = output.GetConnection(k);
                        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 to = _portConnectionPoints[input].center;
                        DrawConnection(from, to, NodeEditorPreferences.GetTypeColor(output.ValueType));
                    }
                }
            }
        }
Ejemplo n.º 18
0
        /// <summary>
        /// Add items for the context menu when right-clicking this node.
        /// Override to add custom menu items.
        /// </summary>
        /// <param name="menu"></param>
        /// <param name="compatibleType">Use it to filter only nodes with ports value type, compatible with this type</param>
        /// <param name="direction">Direction of the compatiblity</param>
        public virtual void AddContextMenuItems(GenericMenu menu, Type compatibleType = null, XNode.NodePort.IO direction = XNode.NodePort.IO.Input) {
            Vector2 pos = NodeEditorWindow.current.WindowToGridPosition(Event.current.mousePosition);

            Type[] nodeTypes = NodeEditorReflection.nodeTypes.OrderBy(type => GetNodeMenuOrder(type)).ToArray();

            if (compatibleType != null && NodeEditorPreferences.GetSettings().createFilter) {
                nodeTypes = NodeEditorUtilities.GetCompatibleNodesTypes(NodeEditorReflection.nodeTypes, compatibleType, direction).ToArray();
            }

            for (int i = 0; i < nodeTypes.Length; i++) {

                Type type = nodeTypes[i];

                //Get node context menu path
                string path = GetNodeMenuName(type);
                if (string.IsNullOrEmpty(path)) continue;

                // Check if user is allowed to add more of given node type
                XNode.Node.DisallowMultipleNodesAttribute disallowAttrib;
                bool disallowed = false;
                if (NodeEditorUtilities.GetAttrib(type, out disallowAttrib)) {
                    int typeCount = target.nodes.Count(x => x.GetType() == type);
                    if (typeCount >= disallowAttrib.max) disallowed = true;
                }

                // Add node entry to context menu
                if (disallowed) menu.AddItem(new GUIContent(path), false, null);
                else menu.AddItem(new GUIContent(path), false, () => {
                    XNode.Node node = CreateNode(type, pos);
                    NodeEditorWindow.current.AutoConnect(node);
                });
            }
            menu.AddSeparator("");
            if (NodeEditorWindow.copyBuffer != null && NodeEditorWindow.copyBuffer.Length > 0) menu.AddItem(new GUIContent("Paste"), false, () => NodeEditorWindow.current.PasteNodes(pos));
            else menu.AddDisabledItem(new GUIContent("Paste"));
            menu.AddItem(new GUIContent("Preferences"), false, () => NodeEditorReflection.OpenPreferences());
            menu.AddCustomContextMenuItems(target);
        }
Ejemplo n.º 19
0
        public void SaveAs()
        {
            string path = EditorUtility.SaveFilePanelInProject("Save NodeGraph", "NewNodeGraph", "asset", "");

            if (string.IsNullOrEmpty(path))
            {
                return;
            }
            else
            {
                XNode.NodeGraph existingGraph = AssetDatabase.LoadAssetAtPath <XNode.NodeGraph>(path);
                if (existingGraph != null)
                {
                    AssetDatabase.DeleteAsset(path);
                }
                AssetDatabase.CreateAsset(graph, path);
                EditorUtility.SetDirty(graph);
                if (NodeEditorPreferences.GetSettings().autoSave)
                {
                    AssetDatabase.SaveAssets();
                }
            }
        }
Ejemplo n.º 20
0
        private void OnDisable()
        {
            // Cache portConnectionPoints before serialization starts
            int count = portConnectionPoints.Count;

            _references = new NodePortReference[count];
            _rects      = new Rect[count];
            int index = 0;

            foreach (var portConnectionPoint in portConnectionPoints)
            {
                _references[index] = new NodePortReference(portConnectionPoint.Key);
                _rects[index]      = portConnectionPoint.Value;
                index++;
            }

            if (!NodeEditorPreferences.GetSettings().autoSave)
            {
                if (EditorUtility.DisplayDialog("Save?", "Save asset?", "Save"))
                {
                    AssetDatabase.SaveAssets();
                }
            }
        }
        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;
            }
        }
Ejemplo n.º 22
0
        private void DrawNodes()
        {
            Event e = Event.current;

            if (e.type == EventType.Layout)
            {
                selectionCache = new List <UnityEngine.Object>(Selection.objects);
            }
            if (e.type == EventType.Repaint)
            {
                portConnectionPoints.Clear();
                nodeWidths.Clear();
            }

            //Active node is hashed before and after node GUI to detect changes
            int nodeHash = 0;

            System.Reflection.MethodInfo onValidate = null;
            if (Selection.activeObject != null && Selection.activeObject is Siccity.XNode.Node)
            {
                onValidate = Selection.activeObject.GetType().GetMethod("OnValidate");
                if (onValidate != null)
                {
                    nodeHash = Selection.activeObject.GetHashCode();
                }
            }

            BeginZoomed(position, zoom);

            Vector2 mousePos = Event.current.mousePosition;

            if (e.type != EventType.Layout)
            {
                hoveredNode = null;
                hoveredPort = null;
            }

            List <UnityEngine.Object> preSelection = preBoxSelection != null ? new List <UnityEngine.Object>(preBoxSelection) : new List <UnityEngine.Object>();

            //Save guiColor so we can revert it
            Color guiColor = GUI.color;

            for (int n = 0; n < graph.nodes.Count; n++)
            {
                // Skip null nodes. The user could be in the process of renaming scripts, so removing them at this point is not advisable.
                if (graph.nodes[n] == null)
                {
                    continue;
                }
                if (n >= graph.nodes.Count)
                {
                    return;
                }
                Siccity.XNode.Node node = graph.nodes[n];

                NodeEditor nodeEditor = NodeEditor.GetEditor(node);
                NodeEditor.portPositions = new Dictionary <Siccity.XNode.NodePort, Vector2>();

                //Get node position
                Vector2 nodePos = GridToWindowPositionNoClipped(node.position);

                GUILayout.BeginArea(new Rect(nodePos, new Vector2(nodeEditor.GetWidth(), 4000)));

                bool selected = selectionCache.Contains(graph.nodes[n]);

                if (selected)
                {
                    GUIStyle style          = new GUIStyle(NodeEditorResources.styles.nodeBody);
                    GUIStyle highlightStyle = new GUIStyle(NodeEditorResources.styles.nodeHighlight);
                    highlightStyle.padding = style.padding;
                    style.padding          = new RectOffset();
                    GUI.color = nodeEditor.GetTint();
                    GUILayout.BeginVertical(new GUIStyle(style));
                    GUI.color = NodeEditorPreferences.GetSettings().highlightColor;
                    GUILayout.BeginVertical(new GUIStyle(highlightStyle));
                }
                else
                {
                    GUIStyle style = NodeEditorResources.styles.nodeBody;
                    GUI.color = nodeEditor.GetTint();
                    GUILayout.BeginVertical(new GUIStyle(style));
                }

                GUI.color = guiColor;
                EditorGUI.BeginChangeCheck();

                //Draw node contents
                nodeEditor.OnNodeGUI();

                //Apply
                nodeEditor.serializedObject.ApplyModifiedProperties();

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

                if (e.type == EventType.Repaint)
                {
                    nodeWidths.Add(node, nodeEditor.GetWidth());

                    foreach (var kvp in NodeEditor.portPositions)
                    {
                        Vector2 portHandlePos = kvp.Value;
                        portHandlePos += node.position;
                        Rect rect = new Rect(portHandlePos.x - 8, portHandlePos.y - 8, 16, 16);
                        portConnectionPoints.Add(kvp.Key, rect);
                    }
                }

                GUILayout.EndVertical();
                if (selected)
                {
                    GUILayout.EndVertical();
                }

                if (e.type != EventType.Layout)
                {
                    //Check if we are hovering this node
                    Vector2 nodeSize   = GUILayoutUtility.GetLastRect().size;
                    Rect    windowRect = new Rect(nodePos, nodeSize);
                    if (windowRect.Contains(mousePos))
                    {
                        hoveredNode = node;
                    }

                    //If dragging a selection box, add nodes inside to selection
                    if (currentActivity == NodeActivity.DragGrid)
                    {
                        Vector2 startPos = GridToWindowPositionNoClipped(dragBoxStart);
                        Vector2 size     = mousePos - startPos;
                        if (size.x < 0)
                        {
                            startPos.x += size.x; size.x = Mathf.Abs(size.x);
                        }
                        if (size.y < 0)
                        {
                            startPos.y += size.y; size.y = Mathf.Abs(size.y);
                        }
                        Rect r = new Rect(startPos, size);
                        if (windowRect.Overlaps(r))
                        {
                            preSelection.Add(node);
                        }
                    }

                    //Check if we are hovering any of this nodes ports
                    //Check input ports
                    foreach (Siccity.XNode.NodePort input in node.Inputs)
                    {
                        //Check if port rect is available
                        if (!portConnectionPoints.ContainsKey(input))
                        {
                            continue;
                        }
                        Rect r = GridToWindowRect(portConnectionPoints[input]);
                        if (r.Contains(mousePos))
                        {
                            hoveredPort = input;
                        }
                    }
                    //Check all output ports
                    foreach (Siccity.XNode.NodePort output in node.Outputs)
                    {
                        //Check if port rect is available
                        if (!portConnectionPoints.ContainsKey(output))
                        {
                            continue;
                        }
                        Rect r = GridToWindowRect(portConnectionPoints[output]);
                        if (r.Contains(mousePos))
                        {
                            hoveredPort = output;
                        }
                    }
                }

                GUILayout.EndArea();
            }

            if (e.type != EventType.Layout && currentActivity == NodeActivity.DragGrid)
            {
                Selection.objects = preSelection.ToArray();
            }
            EndZoomed(position, zoom);

            //If a change in hash is detected in the selected node, call OnValidate method.
            //This is done through reflection because OnValidate is only relevant in editor,
            //and thus, the code should not be included in build.
            if (nodeHash != 0)
            {
                if (onValidate != null && nodeHash != Selection.activeObject.GetHashCode())
                {
                    onValidate.Invoke(Selection.activeObject, null);
                }
            }
        }
Ejemplo n.º 23
0
        /// <summary> Draw a bezier from startpoint to endpoint, both in grid coordinates </summary>
        public void DrawConnection(Vector2 startPoint, Vector2 endPoint, Color col)
        {
            startPoint = GridToWindowPosition(startPoint);
            endPoint   = GridToWindowPosition(endPoint);

            switch (NodeEditorPreferences.GetSettings().noodleType)
            {
            case NodeEditorPreferences.NoodleType.Curve:
                Vector2 startTangent = startPoint;
                if (startPoint.x < endPoint.x)
                {
                    startTangent.x = Mathf.LerpUnclamped(startPoint.x, endPoint.x, 0.7f);
                }
                else
                {
                    startTangent.x = Mathf.LerpUnclamped(startPoint.x, endPoint.x, -0.7f);
                }

                Vector2 endTangent = endPoint;
                if (startPoint.x > endPoint.x)
                {
                    endTangent.x = Mathf.LerpUnclamped(endPoint.x, startPoint.x, -0.7f);
                }
                else
                {
                    endTangent.x = Mathf.LerpUnclamped(endPoint.x, startPoint.x, 0.7f);
                }
                Handles.DrawBezier(startPoint, endPoint, startTangent, endTangent, col, null, 4);
                break;

            case NodeEditorPreferences.NoodleType.Line:
                Handles.color = col;
                Handles.DrawAAPolyLine(5, startPoint, endPoint);
                break;

            case NodeEditorPreferences.NoodleType.Angled:
                Handles.color = col;
                if (startPoint.x <= endPoint.x - (50 / zoom))
                {
                    float   midpoint = (startPoint.x + endPoint.x) * 0.5f;
                    Vector2 start_1  = startPoint;
                    Vector2 end_1    = endPoint;
                    start_1.x = midpoint;
                    end_1.x   = midpoint;
                    Handles.DrawAAPolyLine(5, startPoint, start_1);
                    Handles.DrawAAPolyLine(5, start_1, end_1);
                    Handles.DrawAAPolyLine(5, end_1, endPoint);
                }
                else
                {
                    float   midpoint = (startPoint.y + endPoint.y) * 0.5f;
                    Vector2 start_1  = startPoint;
                    Vector2 end_1    = endPoint;
                    start_1.x += 25 / zoom;
                    end_1.x   -= 25 / zoom;
                    Vector2 start_2 = start_1;
                    Vector2 end_2   = end_1;
                    start_2.y = midpoint;
                    end_2.y   = midpoint;
                    Handles.DrawAAPolyLine(5, startPoint, start_1);
                    Handles.DrawAAPolyLine(5, start_1, start_2);
                    Handles.DrawAAPolyLine(5, start_2, end_2);
                    Handles.DrawAAPolyLine(5, end_2, end_1);
                    Handles.DrawAAPolyLine(5, end_1, endPoint);
                }
                break;
            }
        }
Ejemplo n.º 24
0
        /// <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;
            }
        }
Ejemplo n.º 25
0
        private void DrawNodes()
        {
            Event e = Event.current;

            if (e.type == EventType.Layout)
            {
                selectionCache = new List <UnityEngine.Object>(Selection.objects);
            }

            System.Reflection.MethodInfo onValidate = null;
            if (Selection.activeObject != null && Selection.activeObject is XNode.Node)
            {
                onValidate = Selection.activeObject.GetType().GetMethod("OnValidate");
                if (onValidate != null)
                {
                    EditorGUI.BeginChangeCheck();
                }
            }

            BeginZoomed(position, zoom, topPadding);

            Vector2 mousePos = Event.current.mousePosition;

            if (e.type != EventType.Layout)
            {
                hoveredNode = null;
                hoveredPort = null;
            }

            List <UnityEngine.Object> preSelection = preBoxSelection != null ? new List <UnityEngine.Object>(preBoxSelection) : new List <UnityEngine.Object>();

            // Selection box stuff
            Vector2 boxStartPos = GridToWindowPositionNoClipped(dragBoxStart);
            Vector2 boxSize     = mousePos - 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);
            }
            Rect selectionBox = new Rect(boxStartPos, boxSize);

            //Save guiColor so we can revert it
            Color guiColor = GUI.color;

            List <XNode.NodePort> removeEntries = new List <XNode.NodePort>();

            if (e.type == EventType.Layout)
            {
                culledNodes = new List <XNode.Node>();
            }
            for (int n = 0; n < graph.nodes.Count; n++)
            {
                // Skip null nodes. The user could be in the process of renaming scripts, so removing them at this point is not advisable.
                if (graph.nodes[n] == null)
                {
                    continue;
                }
                if (n >= graph.nodes.Count)
                {
                    return;
                }
                XNode.Node node = graph.nodes[n];

                // Culling
                if (e.type == EventType.Layout)
                {
                    // Cull unselected nodes outside view
                    if (!Selection.Contains(node) && ShouldBeCulled(node))
                    {
                        culledNodes.Add(node);
                        continue;
                    }
                }
                else if (culledNodes.Contains(node))
                {
                    continue;
                }

                if (e.type == EventType.Repaint)
                {
                    removeEntries.Clear();
                    foreach (var kvp in _portConnectionPoints)
                    {
                        if (kvp.Key.node == node)
                        {
                            removeEntries.Add(kvp.Key);
                        }
                    }
                    foreach (var k in removeEntries)
                    {
                        _portConnectionPoints.Remove(k);
                    }
                }

                NodeEditor nodeEditor = NodeEditor.GetEditor(node, this);

                NodeEditor.portPositions.Clear();

                // Set default label width. This is potentially overridden in OnBodyGUI
                EditorGUIUtility.labelWidth = 84;

                //Get node position
                Vector2 nodePos = GridToWindowPositionNoClipped(node.position);

                GUILayout.BeginArea(new Rect(nodePos, new Vector2(nodeEditor.GetWidth(), 4000)));

                bool selected = selectionCache.Contains(graph.nodes[n]);

                if (selected)
                {
                    GUIStyle style          = new GUIStyle(nodeEditor.GetBodyStyle());
                    GUIStyle highlightStyle = new GUIStyle(nodeEditor.GetBodyHighlightStyle());
                    highlightStyle.padding = style.padding;
                    style.padding          = new RectOffset();
                    GUI.color = nodeEditor.GetTint();
                    GUILayout.BeginVertical(style);
                    GUI.color = NodeEditorPreferences.GetSettings().highlightColor;
                    GUILayout.BeginVertical(new GUIStyle(highlightStyle));
                }
                else
                {
                    GUIStyle style = new GUIStyle(nodeEditor.GetBodyStyle());
                    GUI.color = nodeEditor.GetTint();
                    GUILayout.BeginVertical(style);
                }

                GUI.color = guiColor;
                EditorGUI.BeginChangeCheck();

                //Draw node contents
                nodeEditor.OnHeaderGUI();

                //if (zoom < 2)
                //{
                nodeEditor.OnBodyGUI();

                //}



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

                GUILayout.EndVertical();

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

                    foreach (var kvp in NodeEditor.portPositions)
                    {
                        Vector2 portHandlePos = kvp.Value;
                        portHandlePos += node.position;
                        Rect rect = new Rect(portHandlePos.x - 8, portHandlePos.y - 8, 16, 16);
                        portConnectionPoints[kvp.Key] = rect;
                    }
                }

                if (selected)
                {
                    GUILayout.EndVertical();
                }

                if (e.type != EventType.Layout)
                {
                    //Check if we are hovering this node
                    Vector2 nodeSize   = GUILayoutUtility.GetLastRect().size;
                    Rect    windowRect = new Rect(nodePos, nodeSize);
                    if (windowRect.Contains(mousePos))
                    {
                        hoveredNode = node;
                    }

                    //If dragging a selection box, add nodes inside to selection
                    if (currentActivity == NodeActivity.DragGrid)
                    {
                        if (windowRect.Overlaps(selectionBox))
                        {
                            preSelection.Add(node);
                        }
                    }

                    //Check if we are hovering any of this nodes ports
                    //Check input ports
                    foreach (XNode.NodePort input in node.Inputs)
                    {
                        //Check if port rect is available
                        if (!portConnectionPoints.ContainsKey(input))
                        {
                            continue;
                        }
                        Rect r = GridToWindowRectNoClipped(portConnectionPoints[input]);
                        if (r.Contains(mousePos))
                        {
                            hoveredPort = input;
                        }
                    }
                    //Check all output ports
                    foreach (XNode.NodePort output in node.Outputs)
                    {
                        //Check if port rect is available
                        if (!portConnectionPoints.ContainsKey(output))
                        {
                            continue;
                        }
                        Rect r = GridToWindowRectNoClipped(portConnectionPoints[output]);
                        if (r.Contains(mousePos))
                        {
                            hoveredPort = output;
                        }
                    }
                }

                GUILayout.EndArea();
            }

            if (e.type != EventType.Layout && currentActivity == NodeActivity.DragGrid)
            {
                Selection.objects = preSelection.ToArray();
            }
            EndZoomed(position, zoom, topPadding);

            //If a change in is detected in the selected node, call OnValidate method.
            //This is done through reflection because OnValidate is only relevant in editor,
            //and thus, the code should not be included in build.
            if (onValidate != null && EditorGUI.EndChangeCheck())
            {
                onValidate.Invoke(Selection.activeObject, null);
            }
        }
Ejemplo n.º 26
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.HoldHeader || currentActivity == NodeActivity.DragHeader)
                    {
                        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 = WindowToGridPosition(e.mousePosition) + dragOffset[i];
                                bool gridSnap = NodeEditorPreferences.GetSettings().gridSnap;
                                if (e.control)
                                {
                                    gridSnap = !gridSnap;
                                }
                                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;
                                }
                            }
                        }
                        currentActivity = NodeActivity.DragHeader;
                        Repaint();
                    }
                    else if (currentActivity == NodeActivity.HoldGrid)
                    {
                        currentActivity = NodeActivity.DragGrid;
                        preBoxSelection = Selection.objects;
                        dragBoxStart    = WindowToGridPosition(e.mousePosition);
                        Repaint();
                    }
                    else if (currentActivity == NodeActivity.DragGrid)
                    {
                        foreach (XNode.Node node in graph.nodes)
                        {
                        }
                        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)
                {
                    if (IsHoveringPort)
                    {
                        if (hoveredPort.IsOutput)
                        {
                            draggedOutput = hoveredPort;
                        }
                        else
                        {
                            hoveredPort.VerifyConnections();
                            if (hoveredPort.IsConnected)
                            {
                                XNode.Node     node   = hoveredPort.node;
                                XNode.NodePort output = hoveredPort.Connection;
                                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);
                        }
                        else if (e.control || e.shift)
                        {
                            DeselectNode(hoveredNode);
                        }
                        e.Use();
                        currentActivity = NodeActivity.HoldHeader;
                        dragOffset      = new Vector2[Selection.objects.Length];
                        for (int i = 0; i < dragOffset.Length; i++)
                        {
                            if (Selection.objects[i] is XNode.Node)
                            {
                                XNode.Node node = Selection.objects[i] as XNode.Node;
                                dragOffset[i] = node.position - WindowToGridPosition(e.mousePosition);
                            }
                        }
                    }
                    // If mousedown on grid background, deselect all
                    else if (!IsHoveringNode)
                    {
                        currentActivity = NodeActivity.HoldGrid;
                        if (!e.control && !e.shift)
                        {
                            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);
                            }
                            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.DragHeader)
                    {
                        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 single node.
                    if (currentActivity == NodeActivity.HoldHeader && !(e.control || e.shift))
                    {
                        SelectNode(hoveredNode, false);
                    }

                    Repaint();
                    currentActivity = NodeActivity.Idle;
                }
                else if (e.button == 1)
                {
                    if (!isPanning)
                    {
                        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;
            }
        }
Ejemplo n.º 27
0
 public virtual Color GetTypeColor(Type type)
 {
     return(NodeEditorPreferences.GetTypeColor(type));
 }
Ejemplo n.º 28
0
 public virtual Texture2D GetSecondaryGridTexture()
 {
     return(NodeEditorPreferences.GetSettings().crossTexture);
 }
Ejemplo n.º 29
0
 public virtual Texture2D GetGridTexture()
 {
     return(NodeEditorPreferences.GetSettings().gridTexture);
 }
Ejemplo n.º 30
0
 public virtual NoodleStroke GetNoodleStroke(XNode.NodePort output, XNode.NodePort input)
 {
     return(NodeEditorPreferences.GetSettings().noodleStroke);
 }