diff --git a/Scripts/Editor/NodeEditor.cs b/Scripts/Editor/NodeEditor.cs
index 8b06c26..f38b510 100644
--- a/Scripts/Editor/NodeEditor.cs
+++ b/Scripts/Editor/NodeEditor.cs
@@ -81,6 +81,26 @@ namespace XNodeEditor {
return NodeEditorResources.styles.nodeBody;
}
+ /// Add items for the context menu when right-clicking this node. Override to add custom menu items.
+ public virtual void AddContextMenuItems(GenericMenu menu) {
+ // Actions if only one node is selected
+ if (Selection.objects.Length == 1 && Selection.activeObject is XNode.Node) {
+ XNode.Node node = Selection.activeObject as XNode.Node;
+ menu.AddItem(new GUIContent("Move To Top"), false, () => NodeEditorWindow.current.MoveNodeToTop(node));
+ menu.AddItem(new GUIContent("Rename"), false, NodeEditorWindow.current.RenameSelectedNode);
+ }
+
+ // Add actions to any number of selected nodes
+ menu.AddItem(new GUIContent("Duplicate"), false, NodeEditorWindow.current.DuplicateSelectedNodes);
+ menu.AddItem(new GUIContent("Remove"), false, NodeEditorWindow.current.RemoveSelectedNodes);
+
+ // Custom sctions if only one node is selected
+ if (Selection.objects.Length == 1 && Selection.activeObject is XNode.Node) {
+ XNode.Node node = Selection.activeObject as XNode.Node;
+ NodeEditorWindow.AddCustomContextMenuItems(menu, node);
+ }
+ }
+
public void InitiateRename() {
renaming = 1;
}
diff --git a/Scripts/Editor/NodeEditorAction.cs b/Scripts/Editor/NodeEditorAction.cs
index b5315f8..d8d36cb 100644
--- a/Scripts/Editor/NodeEditorAction.cs
+++ b/Scripts/Editor/NodeEditorAction.cs
@@ -260,9 +260,13 @@ namespace XNodeEditor {
ShowPortContextMenu(hoveredPort);
} else if (IsHoveringNode && IsHoveringTitle(hoveredNode)) {
if (!Selection.Contains(hoveredNode)) SelectNode(hoveredNode, false);
- ShowNodeContextMenu();
+ GenericMenu menu = new GenericMenu();
+ NodeEditor.GetEditor(hoveredNode).AddContextMenuItems(menu);
+ menu.DropDown(new Rect(Event.current.mousePosition, Vector2.zero));
} else if (!IsHoveringNode) {
- ShowGraphContextMenu();
+ GenericMenu menu = new GenericMenu();
+ graphEditor.AddContextMenuItems(menu);
+ menu.DropDown(new Rect(Event.current.mousePosition, Vector2.zero));
}
}
isPanning = false;
@@ -323,15 +327,6 @@ namespace XNodeEditor {
panOffset = Vector2.zero;
}
- public void CreateNode(Type type, Vector2 position) {
- XNode.Node node = graph.AddNode(type);
- node.position = position;
- node.name = UnityEditor.ObjectNames.NicifyVariableName(type.Name);
- AssetDatabase.AddObjectToAsset(node, graph);
- if (NodeEditorPreferences.GetSettings().autoSave) AssetDatabase.SaveAssets();
- Repaint();
- }
-
/// Remove nodes in the graph in Selection.objects
public void RemoveSelectedNodes() {
// We need to delete reroutes starting at the highest point index to avoid shifting indices
diff --git a/Scripts/Editor/NodeEditorGUI.cs b/Scripts/Editor/NodeEditorGUI.cs
index 8d7b95a..9f48f0e 100644
--- a/Scripts/Editor/NodeEditorGUI.cs
+++ b/Scripts/Editor/NodeEditorGUI.cs
@@ -116,60 +116,6 @@ namespace XNodeEditor {
if (NodeEditorPreferences.GetSettings().autoSave) AssetDatabase.SaveAssets();
}
- /// Show right-click context menu for selected nodes
- public void ShowNodeContextMenu() {
- GenericMenu contextMenu = new GenericMenu();
- // If only one node is selected
- if (Selection.objects.Length == 1 && Selection.activeObject is XNode.Node) {
- XNode.Node node = Selection.activeObject as XNode.Node;
- contextMenu.AddItem(new GUIContent("Move To Top"), false, () => MoveNodeToTop(node));
- contextMenu.AddItem(new GUIContent("Rename"), false, RenameSelectedNode);
- }
-
- contextMenu.AddItem(new GUIContent("Duplicate"), false, DuplicateSelectedNodes);
- contextMenu.AddItem(new GUIContent("Remove"), false, RemoveSelectedNodes);
-
- // If only one node is selected
- if (Selection.objects.Length == 1 && Selection.activeObject is XNode.Node) {
- XNode.Node node = Selection.activeObject as XNode.Node;
- AddCustomContextMenuItems(contextMenu, node);
- }
-
- contextMenu.DropDown(new Rect(Event.current.mousePosition, Vector2.zero));
- }
-
- /// Show right-click context menu for current graph
- void ShowGraphContextMenu() {
- GenericMenu contextMenu = new GenericMenu();
- Vector2 pos = WindowToGridPosition(Event.current.mousePosition);
- for (int i = 0; i < nodeTypes.Length; i++) {
- Type type = nodeTypes[i];
-
- //Get node context menu path
- string path = graphEditor.GetNodeMenuName(type);
- if (string.IsNullOrEmpty(path)) continue;
-
- contextMenu.AddItem(new GUIContent(path), 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));
- }
-
- void AddCustomContextMenuItems(GenericMenu contextMenu, object obj) {
- KeyValuePair[] items = GetContextMenuMethods(obj);
- if (items.Length != 0) {
- contextMenu.AddSeparator("");
- for (int i = 0; i < items.Length; i++) {
- KeyValuePair kvp = items[i];
- contextMenu.AddItem(new GUIContent(kvp.Key.menuItem), false, () => kvp.Value.Invoke(obj, null));
- }
- }
- }
-
/// Draw a bezier from startpoint to endpoint, both in grid coordinates
public void DrawConnection(Vector2 startPoint, Vector2 endPoint, Color col) {
startPoint = GridToWindowPosition(startPoint);
diff --git a/Scripts/Editor/NodeEditorReflection.cs b/Scripts/Editor/NodeEditorReflection.cs
index 42e583c..bfe8307 100644
--- a/Scripts/Editor/NodeEditorReflection.cs
+++ b/Scripts/Editor/NodeEditorReflection.cs
@@ -71,6 +71,17 @@ namespace XNodeEditor {
return types.ToArray();
}
+ public static void AddCustomContextMenuItems(GenericMenu contextMenu, object obj) {
+ KeyValuePair[] items = GetContextMenuMethods(obj);
+ if (items.Length != 0) {
+ contextMenu.AddSeparator("");
+ for (int i = 0; i < items.Length; i++) {
+ KeyValuePair kvp = items[i];
+ contextMenu.AddItem(new GUIContent(kvp.Key.menuItem), false, () => kvp.Value.Invoke(obj, null));
+ }
+ }
+ }
+
public static KeyValuePair[] GetContextMenuMethods(object obj) {
Type type = obj.GetType();
MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
diff --git a/Scripts/Editor/NodeGraphEditor.cs b/Scripts/Editor/NodeGraphEditor.cs
index 1c32a6e..20f5657 100644
--- a/Scripts/Editor/NodeGraphEditor.cs
+++ b/Scripts/Editor/NodeGraphEditor.cs
@@ -38,10 +38,39 @@ namespace XNodeEditor {
return ObjectNames.NicifyVariableName(type.ToString().Replace('.', '/'));
}
+ /// Add items for the context menu when right-clicking this node. Override to add custom menu items.
+ public virtual void AddContextMenuItems(GenericMenu menu) {
+ Vector2 pos = NodeEditorWindow.current.WindowToGridPosition(Event.current.mousePosition);
+ for (int i = 0; i < NodeEditorWindow.nodeTypes.Length; i++) {
+ Type type = NodeEditorWindow.nodeTypes[i];
+
+ //Get node context menu path
+ string path = GetNodeMenuName(type);
+ if (string.IsNullOrEmpty(path)) continue;
+
+ menu.AddItem(new GUIContent(path), false, () => {
+ CreateNode(type, pos);
+ });
+ }
+ menu.AddSeparator("");
+ menu.AddItem(new GUIContent("Preferences"), false, () => NodeEditorWindow.OpenPreferences());
+ NodeEditorWindow.AddCustomContextMenuItems(menu, target);
+ }
+
public virtual Color GetTypeColor(Type type) {
return NodeEditorPreferences.GetTypeColor(type);
}
+ /// Create a node and save it in the graph asset
+ public virtual void CreateNode(Type type, Vector2 position) {
+ XNode.Node node = target.AddNode(type);
+ node.position = position;
+ node.name = UnityEditor.ObjectNames.NicifyVariableName(type.Name);
+ AssetDatabase.AddObjectToAsset(node, target);
+ if (NodeEditorPreferences.GetSettings().autoSave) AssetDatabase.SaveAssets();
+ NodeEditorWindow.RepaintAll();
+ }
+
/// Creates a copy of the original node in the graph
public XNode.Node CopyNode(XNode.Node original) {
XNode.Node node = target.CopyNode(original);