diff --git a/Scripts/Editor/NodeEditorGUI.cs b/Scripts/Editor/NodeEditorGUI.cs index 3fc5f21..aa6919d 100644 --- a/Scripts/Editor/NodeEditorGUI.cs +++ b/Scripts/Editor/NodeEditorGUI.cs @@ -28,7 +28,10 @@ namespace XNodeEditor { DrawGrid(position, zoom, panOffset); DrawConnections(); DrawDraggedConnection(); + BeginZoomed(position, zoom, topPadding); + DrawGroups(); DrawNodes(); + EndZoomed(position, zoom, topPadding); DrawSelectionBox(); DrawTooltip(); DrawGraphOnGUI(); @@ -272,8 +275,6 @@ namespace XNodeEditor { if (onValidate != null) EditorGUI.BeginChangeCheck(); } - BeginZoomed(position, zoom, topPadding); - Vector2 mousePos = Event.current.mousePosition; if (e.type != EventType.Layout) { @@ -403,7 +404,6 @@ namespace XNodeEditor { } 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, @@ -411,6 +411,14 @@ namespace XNodeEditor { if (onValidate != null && EditorGUI.EndChangeCheck()) onValidate.Invoke(Selection.activeObject, null); } + private void DrawGroups() { + for (int i = 0; i < graph.groups.Count; i++) { + GUIStyle style = new GUIStyle(graphEditor.GetGroupStyle()); + Rect groupRect = GridToWindowRectNoClipped(graph.groups[i].position); + GUI.Box(groupRect, "", style); + } + } + private bool ShouldBeCulled(XNode.Node node) { Vector2 nodePos = GridToWindowPositionNoClipped(node.position); diff --git a/Scripts/Editor/NodeEditorResources.cs b/Scripts/Editor/NodeEditorResources.cs index 0a84e0a..1737991 100644 --- a/Scripts/Editor/NodeEditorResources.cs +++ b/Scripts/Editor/NodeEditorResources.cs @@ -12,13 +12,15 @@ namespace XNodeEditor { private static Texture2D _nodeBody; public static Texture2D nodeHighlight { get { return _nodeHighlight != null ? _nodeHighlight : _nodeHighlight = Resources.Load("xnode_node_highlight"); } } private static Texture2D _nodeHighlight; + public static Texture2D groupBody { get { return _groupBody != null ? _groupBody : _groupBody = Resources.Load("xnode_group"); } } + private static Texture2D _groupBody; // Styles public static Styles styles { get { return _styles != null ? _styles : _styles = new Styles(); } } public static Styles _styles = null; public static GUIStyle OutputPort { get { return new GUIStyle(EditorStyles.label) { alignment = TextAnchor.UpperRight }; } } public class Styles { - public GUIStyle inputPort, nodeHeader, nodeBody, tooltip, nodeHighlight; + public GUIStyle inputPort, nodeHeader, nodeBody, tooltip, nodeHighlight, group; public Styles() { GUIStyle baseStyle = new GUIStyle("Label"); @@ -38,6 +40,9 @@ namespace XNodeEditor { nodeBody.border = new RectOffset(32, 32, 32, 32); nodeBody.padding = new RectOffset(16, 16, 4, 16); + group = new GUIStyle(nodeBody); + group.normal.background = NodeEditorResources.groupBody; + nodeHighlight = new GUIStyle(); nodeHighlight.normal.background = NodeEditorResources.nodeHighlight; nodeHighlight.border = new RectOffset(32, 32, 32, 32); diff --git a/Scripts/Editor/NodeGraphEditor.cs b/Scripts/Editor/NodeGraphEditor.cs index 110c506..b002c1d 100644 --- a/Scripts/Editor/NodeGraphEditor.cs +++ b/Scripts/Editor/NodeGraphEditor.cs @@ -56,6 +56,7 @@ namespace XNodeEditor { }); } menu.AddSeparator(""); + menu.AddItem(new GUIContent("New Group"), false, () => AddNewGroup(pos)); 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()); @@ -70,6 +71,10 @@ namespace XNodeEditor { return NodeEditorPreferences.GetTypeColor(type); } + public virtual GUIStyle GetGroupStyle() { + return NodeEditorResources.styles.group; + } + public virtual string GetPortTooltip(XNode.NodePort port) { Type portType = port.ValueType; string tooltip = ""; @@ -112,6 +117,15 @@ namespace XNodeEditor { if (NodeEditorPreferences.GetSettings().autoSave) AssetDatabase.SaveAssets(); } + /// Add a new group and instantly start editing its title + public virtual void AddNewGroup(Vector2 position) { + XNode.NodeGroup group = new XNode.NodeGroup() { + name = "New Group", + position = new Rect(position, new Vector2(100, 100)) + }; + target.groups.Add(group); + } + [AttributeUsage(AttributeTargets.Class)] public class CustomNodeGraphEditorAttribute : Attribute, XNodeEditor.Internal.NodeEditorBase.INodeEditorAttrib { diff --git a/Scripts/Editor/Resources/xnode_group.png b/Scripts/Editor/Resources/xnode_group.png new file mode 100644 index 0000000..a07f905 Binary files /dev/null and b/Scripts/Editor/Resources/xnode_group.png differ diff --git a/Scripts/Editor/Resources/xnode_group.png.meta b/Scripts/Editor/Resources/xnode_group.png.meta new file mode 100644 index 0000000..1c4f73a --- /dev/null +++ b/Scripts/Editor/Resources/xnode_group.png.meta @@ -0,0 +1,99 @@ +fileFormatVersion: 2 +guid: 14772c8dd8fde6d4aa7e364285743b82 +TextureImporter: + fileIDToRecycleName: {} + externalObjects: {} + serializedVersion: 7 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 1 + mipBias: -100 + wrapU: 1 + wrapV: 1 + wrapW: -1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 2 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + vertices: [] + indices: + edges: [] + weights: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Editor/Resources/xnode_node_workfile.psd b/Scripts/Editor/Resources/xnode_node_workfile.psd index a578c46..f41c333 100644 Binary files a/Scripts/Editor/Resources/xnode_node_workfile.psd and b/Scripts/Editor/Resources/xnode_node_workfile.psd differ diff --git a/Scripts/NodeGraph.cs b/Scripts/NodeGraph.cs index 6a0cead..2ccbc38 100644 --- a/Scripts/NodeGraph.cs +++ b/Scripts/NodeGraph.cs @@ -10,6 +10,8 @@ namespace XNode { /// All nodes in the graph. /// See: [SerializeField] public List nodes = new List(); + /// All groups in the graph. + [SerializeField] public List groups = new List(); /// Add a node to the graph by type (convenience method - will call the System.Type version) public T AddNode() where T : Node { diff --git a/Scripts/NodeGroup.cs b/Scripts/NodeGroup.cs new file mode 100644 index 0000000..025bfc0 --- /dev/null +++ b/Scripts/NodeGroup.cs @@ -0,0 +1,10 @@ +using System; +using UnityEngine; + +namespace XNode { + [Serializable] + public class NodeGroup { + public string name; + public Rect position; + } +} \ No newline at end of file diff --git a/Scripts/NodeGroup.cs.meta b/Scripts/NodeGroup.cs.meta new file mode 100644 index 0000000..c202486 --- /dev/null +++ b/Scripts/NodeGroup.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7aa18e940963e0744bcfe540789d8e85 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: