예제 #1
0
        /// <summary> Show right-click context menu </summary>
        public void ShowContextMenu()
        {
            GenericMenu contextMenu = new GenericMenu();
            Vector2     pos         = WindowToGridPosition(Event.current.mousePosition);

            if (hoveredNode != null)
            {
                Node node = hoveredNode;
                contextMenu.AddItem(new GUIContent("Remove"), false, () => graph.RemoveNode(node));
            }
            else
            {
                for (int i = 0; i < nodeTypes.Length; i++)
                {
                    Type type = nodeTypes[i];

                    string name = nodeTypes[i].ToString().Replace('.', '/');
                    Node.CreateNodeMenuAttribute attrib;
                    if (NodeEditorUtilities.GetAttrib(type, out attrib))
                    {
                        name = attrib.menuName;
                    }
                    contextMenu.AddItem(new GUIContent(name), false, () => {
                        CreateNode(type, pos);
                    });
                }
            }
            contextMenu.DropDown(new Rect(Event.current.mousePosition, Vector2.zero));
        }
예제 #2
0
 /// <summary> The order by which the menu items are displayed. </summary>
 public virtual int GetNodeMenuOrder(Type type) {
     //Check if type has the CreateNodeMenuAttribute
     XNode.Node.CreateNodeMenuAttribute attrib;
     if (NodeEditorUtilities.GetAttrib(type, out attrib)) // Return custom path
         return attrib.order;
     else
         return 0;
 }
예제 #3
0
 /// <summary> Returns context node menu path. Null or empty strings for hidden nodes. </summary>
 public virtual string GetNodeMenuName(Type type) {
     //Check if type has the CreateNodeMenuAttribute
     XNode.Node.CreateNodeMenuAttribute attrib;
     if (NodeEditorUtilities.GetAttrib(type, out attrib)) // Return custom path
         return attrib.menuName;
     else // Return generated path
         return NodeEditorUtilities.NodeDefaultPath(type);
 }
예제 #4
0
        /// <summary> Add items for the context menu when right-clicking this node. Override to add custom menu items. </summary>
        public virtual void AddContextMenuItems(GenericMenu menu)
        {
            Vector2 pos       = NodeEditorWindow.current.WindowToGridPosition(Event.current.mousePosition);
            var     nodeTypes = NodeEditorReflection.nodeTypes.OrderBy(type => GetNodeMenuOrder(type)).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;
                    }
                }
                if (window.graph is DialogGraph)
                {
                }

                // 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);
        }
예제 #5
0
 public virtual bool IsExcludeContextMenuNode(Type type)
 {
     //Check if type has the CreateNodeMenuAttribute
     XNode.Node.CreateNodeMenuAttribute attrib;
     if (NodeEditorUtilities.GetAttrib(type, out attrib))  // Return custom path
     {
         return(attrib.exclude);
     }
     return(false);
 }
 public static string[] GetNodeMenuTags(Type type)
 {
     //Check if type has the CreateNodeMenuAttribute
     XNode.CreateNodeMenuAttribute attrib;
     if (NodeEditorUtilities.GetAttrib(type, out attrib))  // Return custom path
     {
         return(attrib.Tags);
     }
     return(new string[0]);
 }
예제 #7
0
 /// <summary> Returns context node menu path. Null or empty strings for hidden nodes. </summary>
 public virtual string GetNodeMenuName(Type type)
 {
     //Check if type has the CreateNodeMenuAttribute
     XNode.Node.CreateNodeMenuAttribute attrib;
     if (NodeEditorUtilities.GetAttrib(type, out attrib)) // Return custom path
     {
         return(attrib.menuName);
     }
     else // Return generated path
     {
         return(ObjectNames.NicifyVariableName(type.ToString().Replace('.', '/')));
     }
 }
예제 #8
0
        /// <summary> Show right-click context menu for current graph </summary>
        void ShowGraphContextMenu()
        {
            GenericMenu contextMenu = new GenericMenu();
            Vector2     pos         = WindowToGridPosition(Event.current.mousePosition);

            for (int i = 0; i < nodeTypes.Length; i++)
            {
                Type   type = nodeTypes[i];
                string name = nodeTypes[i].ToString().Replace('.', '/');
                Node.CreateNodeMenuAttribute attrib;
                if (NodeEditorUtilities.GetAttrib(type, out attrib))
                {
                    name = attrib.menuName;
                }
                contextMenu.AddItem(new GUIContent(name), false, () => {
                    CreateNode(type, pos);
                });
            }
            contextMenu.AddSeparator("");
            contextMenu.AddItem(new GUIContent("Preferences"), false, () => OpenPreferences());
            AddCustomContextMenuItems(contextMenu, graph);
            contextMenu.DropDown(new Rect(Event.current.mousePosition, Vector2.zero));
        }
예제 #9
0
        /// <summary> Make a field for a serialized property. Manual node port override. </summary>
        public static void PropertyField(SerializedProperty property, GUIContent label, Siccity.XNode.NodePort port, bool includeChildren = true, params GUILayoutOption[] options)
        {
            if (property == null)
            {
                throw new NullReferenceException();
            }

            // If property is not a port, display a regular property field
            if (port == null)
            {
                EditorGUILayout.PropertyField(property, label, includeChildren, GUILayout.MinWidth(30));
            }
            else
            {
                Rect rect = new Rect();

                // If property is an input, display a regular property field and put a port handle on the left side
                if (port.direction == Siccity.XNode.NodePort.IO.Input)
                {
                    // Get data from [Input] attribute
                    Siccity.XNode.Node.ShowBackingValue showBacking = Siccity.XNode.Node.ShowBackingValue.Unconnected;
                    Siccity.XNode.Node.InputAttribute   inputAttribute;
                    if (NodeEditorUtilities.GetAttrib(port.node.GetType(), property.name, out inputAttribute))
                    {
                        showBacking = inputAttribute.backingValue;
                    }

                    switch (showBacking)
                    {
                    case Siccity.XNode.Node.ShowBackingValue.Unconnected:
                        // Display a label if port is connected
                        if (port.IsConnected)
                        {
                            EditorGUILayout.LabelField(label != null ? label : new GUIContent(property.displayName));
                        }
                        // Display an editable property field if port is not connected
                        else
                        {
                            EditorGUILayout.PropertyField(property, label, includeChildren, GUILayout.MinWidth(30));
                        }
                        break;

                    case Siccity.XNode.Node.ShowBackingValue.Never:
                        // Display a label
                        EditorGUILayout.LabelField(label != null ? label : new GUIContent(property.displayName));
                        break;

                    case Siccity.XNode.Node.ShowBackingValue.Always:
                        // Display an editable property field
                        EditorGUILayout.PropertyField(property, label, includeChildren, GUILayout.MinWidth(30));
                        break;
                    }

                    rect          = GUILayoutUtility.GetLastRect();
                    rect.position = rect.position - new Vector2(16, 0);
                    // If property is an output, display a text label and put a port handle on the right side
                }
                else if (port.direction == Siccity.XNode.NodePort.IO.Output)
                {
                    // Get data from [Output] attribute
                    Siccity.XNode.Node.ShowBackingValue showBacking = Siccity.XNode.Node.ShowBackingValue.Unconnected;
                    Siccity.XNode.Node.OutputAttribute  outputAttribute;
                    if (NodeEditorUtilities.GetAttrib(port.node.GetType(), property.name, out outputAttribute))
                    {
                        showBacking = outputAttribute.backingValue;
                    }

                    switch (showBacking)
                    {
                    case Siccity.XNode.Node.ShowBackingValue.Unconnected:
                        // Display a label if port is connected
                        if (port.IsConnected)
                        {
                            EditorGUILayout.LabelField(label != null ? label : new GUIContent(property.displayName), NodeEditorResources.OutputPort, GUILayout.MinWidth(30));
                        }
                        // Display an editable property field if port is not connected
                        else
                        {
                            EditorGUILayout.PropertyField(property, label, includeChildren, GUILayout.MinWidth(30));
                        }
                        break;

                    case Siccity.XNode.Node.ShowBackingValue.Never:
                        // Display a label
                        EditorGUILayout.LabelField(label != null ? label : new GUIContent(property.displayName), NodeEditorResources.OutputPort, GUILayout.MinWidth(30));
                        break;

                    case Siccity.XNode.Node.ShowBackingValue.Always:
                        // Display an editable property field
                        EditorGUILayout.PropertyField(property, label, includeChildren, GUILayout.MinWidth(30));
                        break;
                    }

                    rect          = GUILayoutUtility.GetLastRect();
                    rect.position = rect.position + new Vector2(rect.width, 0);
                }

                rect.size = new Vector2(16, 16);

                Color backgroundColor = new Color32(90, 97, 105, 255);
                if (NodeEditorWindow.nodeTint.ContainsKey(port.node.GetType()))
                {
                    backgroundColor *= NodeEditorWindow.nodeTint[port.node.GetType()];
                }
                Color col = NodeEditorWindow.current.graphEditor.GetTypeColor(port.ValueType);
                DrawPortHandle(rect, backgroundColor, col);

                // Register the handle position
                Vector2 portPos = rect.center;
                if (NodeEditor.portPositions.ContainsKey(port))
                {
                    NodeEditor.portPositions[port] = portPos;
                }
                else
                {
                    NodeEditor.portPositions.Add(port, portPos);
                }
            }
        }
예제 #10
0
        private void InsertDuplicateNodes(XNode.Node[] nodes, Vector2 topLeft)
        {
            if (nodes == null || nodes.Length == 0)
            {
                return;
            }

            // Get top-left node
            Vector2 topLeftNode = nodes.Select(x => x.position).Aggregate((x, y) => new Vector2(Mathf.Min(x.x, y.x), Mathf.Min(x.y, y.y)));
            Vector2 offset      = topLeft - topLeftNode;

            UnityEngine.Object[] newNodes = new UnityEngine.Object[nodes.Length];
            Dictionary <XNode.Node, XNode.Node> substitutes = new Dictionary <XNode.Node, XNode.Node>();

            for (int i = 0; i < nodes.Length; i++)
            {
                XNode.Node srcNode = nodes[i];
                if (srcNode == null)
                {
                    continue;
                }

                // Check if user is allowed to add more of given node type
                XNode.Node.DisallowMultipleNodesAttribute disallowAttrib;
                Type nodeType = srcNode.GetType();
                if (NodeEditorUtilities.GetAttrib(nodeType, out disallowAttrib))
                {
                    int typeCount = graph.nodes.Count(x => x.GetType() == nodeType);
                    if (typeCount >= disallowAttrib.max)
                    {
                        continue;
                    }
                }

                XNode.Node newNode = graphEditor.CopyNode(srcNode);
                substitutes.Add(srcNode, newNode);
                newNode.position = srcNode.position + offset;
                newNodes[i]      = newNode;
            }

            // Walk through the selected nodes again, recreate connections, using the new nodes
            for (int i = 0; i < nodes.Length; i++)
            {
                XNode.Node srcNode = nodes[i];
                if (srcNode == null)
                {
                    continue;
                }
                foreach (XNode.NodePort port in srcNode.Ports)
                {
                    for (int c = 0; c < port.ConnectionCount; c++)
                    {
                        XNode.NodePort inputPort  = port.direction == XNode.NodePort.IO.Input ? port : port.GetConnection(c);
                        XNode.NodePort outputPort = port.direction == XNode.NodePort.IO.Output ? port : port.GetConnection(c);

                        XNode.Node newNodeIn, newNodeOut;
                        if (substitutes.TryGetValue(inputPort.node, out newNodeIn) && substitutes.TryGetValue(outputPort.node, out newNodeOut))
                        {
                            newNodeIn.UpdatePorts();
                            newNodeOut.UpdatePorts();
                            inputPort  = newNodeIn.GetInputPort(inputPort.fieldName);
                            outputPort = newNodeOut.GetOutputPort(outputPort.fieldName);
                        }
                        if (!inputPort.IsConnectedTo(outputPort))
                        {
                            inputPort.Connect(outputPort);
                        }
                    }
                }
            }
            // Select the new nodes
            Selection.objects = newNodes;
        }