/// <summary> Find methods marked with the [ContextMenu] attribute and add them to the context menu </summary> public static void AddCustomContextMenuItems(this GenericMenu contextMenu, object obj) { KeyValuePair <ContextMenu, MethodInfo>[] items = GetContextMenuMethods(obj); if (items.Length != 0) { contextMenu.AddSeparator(""); List <string> invalidatedEntries = new List <string>(); foreach (KeyValuePair <ContextMenu, MethodInfo> checkValidate in items) { if (checkValidate.Key.validate && !(bool)checkValidate.Value.Invoke(obj, null)) { invalidatedEntries.Add(checkValidate.Key.menuItem); } } for (int i = 0; i < items.Length; i++) { KeyValuePair <ContextMenu, MethodInfo> kvp = items[i]; if (invalidatedEntries.Contains(kvp.Key.menuItem)) { contextMenu.AddDisabledItem(new GUIContent(kvp.Key.menuItem)); } else { contextMenu.AddItem(new GUIContent(kvp.Key.menuItem), false, () => kvp.Value.Invoke(obj, null)); } } } }
/// <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; if (compatibleType != null && NodeEditorPreferences.GetSettings().createFilter) { nodeTypes = NodeEditorUtilities.GetCompatibleNodesTypes(NodeEditorReflection.nodeTypes, compatibleType, direction).OrderBy(GetNodeMenuOrder).ToArray(); } else { nodeTypes = NodeEditorReflection.nodeTypes.OrderBy(GetNodeMenuOrder).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); }