1
0
mirror of https://github.com/Siccity/xNode.git synced 2026-03-26 22:49:02 +08:00

Disable removal of a required node

This commit is contained in:
Thor Brigsted 2020-04-24 15:55:17 +02:00
parent 262efc6905
commit ea721c5e14
4 changed files with 48 additions and 16 deletions

View File

@ -106,17 +106,22 @@ namespace XNodeEditor {
/// <summary> Add items for the context menu when right-clicking this node. Override to add custom menu items. </summary> /// <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) { public virtual void AddContextMenuItems(GenericMenu menu) {
bool canRemove = true;
// Actions if only one node is selected // Actions if only one node is selected
if (Selection.objects.Length == 1 && Selection.activeObject is XNode.Node) { if (Selection.objects.Length == 1 && Selection.activeObject is XNode.Node) {
XNode.Node node = Selection.activeObject as 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("Move To Top"), false, () => NodeEditorWindow.current.MoveNodeToTop(node));
menu.AddItem(new GUIContent("Rename"), false, NodeEditorWindow.current.RenameSelectedNode); menu.AddItem(new GUIContent("Rename"), false, NodeEditorWindow.current.RenameSelectedNode);
canRemove = NodeGraphEditor.GetEditor(node.graph, NodeEditorWindow.current).CanRemove(node);
} }
// Add actions to any number of selected nodes // Add actions to any number of selected nodes
menu.AddItem(new GUIContent("Copy"), false, NodeEditorWindow.current.CopySelectedNodes); menu.AddItem(new GUIContent("Copy"), false, NodeEditorWindow.current.CopySelectedNodes);
menu.AddItem(new GUIContent("Duplicate"), false, NodeEditorWindow.current.DuplicateSelectedNodes); menu.AddItem(new GUIContent("Duplicate"), false, NodeEditorWindow.current.DuplicateSelectedNodes);
menu.AddItem(new GUIContent("Remove"), false, NodeEditorWindow.current.RemoveSelectedNodes);
if (canRemove) menu.AddItem(new GUIContent("Remove"), false, NodeEditorWindow.current.RemoveSelectedNodes);
else menu.AddItem(new GUIContent("Remove"), false, null);
// Custom sctions if only one node is selected // Custom sctions if only one node is selected
if (Selection.objects.Length == 1 && Selection.activeObject is XNode.Node) { if (Selection.objects.Length == 1 && Selection.activeObject is XNode.Node) {
@ -136,7 +141,6 @@ namespace XNodeEditor {
/// <summary> Called after this node's name has changed. </summary> /// <summary> Called after this node's name has changed. </summary>
public virtual void OnRename() { } public virtual void OnRename() { }
[AttributeUsage(AttributeTargets.Class)] [AttributeUsage(AttributeTargets.Class)]
public class CustomNodeEditorAttribute : Attribute, public class CustomNodeEditorAttribute : Attribute,
XNodeEditor.Internal.NodeEditorBase<NodeEditor, NodeEditor.CustomNodeEditorAttribute, XNode.Node>.INodeEditorAttrib { XNodeEditor.Internal.NodeEditorBase<NodeEditor, NodeEditor.CustomNodeEditorAttribute, XNode.Node>.INodeEditorAttrib {

View File

@ -181,8 +181,25 @@ namespace XNodeEditor {
return node; return node;
} }
/// <summary> Return false for nodes that can't be removed </summary>
public virtual bool CanRemove(XNode.Node node) {
// Check graph attributes to see if this node is required
Type graphType = target.GetType();
XNode.NodeGraph.RequireNodeAttribute[] attribs = Array.ConvertAll(
graphType.GetCustomAttributes(typeof(XNode.NodeGraph.RequireNodeAttribute), true), x => x as XNode.NodeGraph.RequireNodeAttribute);
if (attribs.Any(x => x.Requires(node.GetType()))) {
if (target.nodes.Count(x => x.GetType() == node.GetType()) <= 1) {
return false;
}
}
return true;
}
/// <summary> Safely remove a node and all its connections. </summary> /// <summary> Safely remove a node and all its connections. </summary>
public virtual void RemoveNode(XNode.Node node) { public virtual void RemoveNode(XNode.Node node) {
if (!CanRemove(node)) return;
// Remove the node
Undo.RecordObject(node, "Delete Node"); Undo.RecordObject(node, "Delete Node");
Undo.RecordObject(target, "Delete Node"); Undo.RecordObject(target, "Delete Node");
foreach (var port in node.Ports) foreach (var port in node.Ports)

View File

@ -23,20 +23,23 @@ namespace XNodeEditor {
NodeGraph.RequireNodeAttribute[] attribs = Array.ConvertAll( NodeGraph.RequireNodeAttribute[] attribs = Array.ConvertAll(
graphType.GetCustomAttributes(typeof(NodeGraph.RequireNodeAttribute), true), x => x as NodeGraph.RequireNodeAttribute); graphType.GetCustomAttributes(typeof(NodeGraph.RequireNodeAttribute), true), x => x as NodeGraph.RequireNodeAttribute);
Vector2 position = Vector2.zero; Vector2 position = Vector2.zero;
foreach (NodeGraph.RequireNodeAttribute attrib in attribs) { foreach (NodeGraph.RequireNodeAttribute attrib in attribs) {
if (attrib.type0 != null) { if (attrib.type0 != null) AddRequired(graph, attrib.type0, ref position);
if (!graph.nodes.Any(x => x.GetType() == attrib.type0)) { if (attrib.type1 != null) AddRequired(graph, attrib.type1, ref position);
XNode.Node node = graph.AddNode(attrib.type0); if (attrib.type2 != null) AddRequired(graph, attrib.type2, ref position);
node.position = position;
position.x += 200;
if (node.name == null || node.name.Trim() == "") node.name = NodeEditorUtilities.NodeDefaultName(attrib.type0);
if (!string.IsNullOrEmpty(AssetDatabase.GetAssetPath(graph))) AssetDatabase.AddObjectToAsset(node, graph);
}
}
} }
} }
} }
private static void AddRequired(NodeGraph graph, Type type, ref Vector2 position) {
if (!graph.nodes.Any(x => x.GetType() == type)) {
XNode.Node node = graph.AddNode(type);
node.position = position;
position.x += 200;
if (node.name == null || node.name.Trim() == "") node.name = NodeEditorUtilities.NodeDefaultName(type);
if (!string.IsNullOrEmpty(AssetDatabase.GetAssetPath(graph))) AssetDatabase.AddObjectToAsset(node, graph);
}
}
} }
} }

View File

@ -110,6 +110,14 @@ namespace XNode {
this.type1 = type2; this.type1 = type2;
this.type2 = type3; this.type2 = type3;
} }
public bool Requires(Type type) {
if (type == null) return false;
if (type == type0) return true;
else if (type == type1) return true;
else if (type == type2) return true;
return false;
}
} }
#endregion #endregion
} }