From 0ed8ac6404890d0129f3c92c1bf93cfbc26de5f5 Mon Sep 17 00:00:00 2001 From: Thor Brigsted Date: Sun, 4 Aug 2019 23:07:55 +0200 Subject: [PATCH] Started working on node groups --- Scripts/Editor/NodeEditorGUI.cs | 14 ++- Scripts/Editor/NodeEditorResources.cs | 7 +- Scripts/Editor/NodeGraphEditor.cs | 14 +++ Scripts/Editor/Resources/xnode_group.png | Bin 0 -> 19936 bytes Scripts/Editor/Resources/xnode_group.png.meta | 99 ++++++++++++++++++ .../Editor/Resources/xnode_node_workfile.psd | Bin 33269 -> 33945 bytes Scripts/NodeGraph.cs | 2 + Scripts/NodeGroup.cs | 10 ++ Scripts/NodeGroup.cs.meta | 11 ++ 9 files changed, 153 insertions(+), 4 deletions(-) create mode 100644 Scripts/Editor/Resources/xnode_group.png create mode 100644 Scripts/Editor/Resources/xnode_group.png.meta create mode 100644 Scripts/NodeGroup.cs create mode 100644 Scripts/NodeGroup.cs.meta 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 0000000000000000000000000000000000000000..a07f90598b0ea1a861d368f7269118cbf136f81c GIT binary patch literal 19936 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 literal 0 HcmV?d00001 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 a578c46f72983f361977f536f07fe3642b1ad2eb..f41c333fa4ad18a764937b30264ba75be4206673 100644 GIT binary patch delta 5222 zcmc(g3rtg27{||j7Rq3yGz2G)UMTngW??9gOmGrW5LBR;8J3J9Iz@y9P}z(-#x2?A zHdL-U&9+RlEql75-77PTE=y)&VlrecbcNfBna&KTI6&H7dUtwhE3Juvw1azcAOG)u z=bZ0;_xqhQ_9}k*P5dYm&gZNyE+a|cIu;#!a>22Jg|dBR)xGUMDxOaNH+#7Agrn?i zJrSOro|&UjXXIt(=Bbyn`-ogW%g@AqRbAcI+}iCqE7H|D>WuUinOWNO+~wNL^lbI= z+T86=X|uA_nY!o5L2^c(Y(r>{?-K)m_*ag+oo$iB%aFhdWM|C%(S+S8J;3bn%8C{``B=dij&_ zp9=QhO-)uE|L4HhM>t;k{H~AgU&1d`6mRIfdgfIBgksY(@@S>{+q>_t4_Vp%<`Uue zQU21cxO@DU$-A}*Ky7{ZuPxPamX4Ff`B&PK&vT(m>e#`3hYqygEiT>ME{T}cZCeJU8y@78Up49CK= z^D=Xk-XGecdFwH;5?m<*;BEG+swYYs_cSy#)z&MK0bkR&yBXbGSw+VtZR?I{cj?}3 zTU(o&%d{=K8nwH(p*L>7(wCZ*NGaIZ?TbSIh;Kt@DN9%7g=jzydJ$=1*Hv-2bV9dy z^DUABl}$xE+2ra(_Px#d?1wcW>^s#d>B!G}tZi;o)-~;^^%~H_>IUTl8*8anV1>G| z>PdnEMa@OevXUCta7)?B8U<0@*uvJ=lq@Jb=pCT)Wu>yJv9%~^Q(MC-z+S6q(dBDj z!{i6o4YIa0xGp5*)ef?ou&L3EoC2q*8b8*PN$ z!8`4OT_BzO&`q)M;%{<&y#}LRV(9JT%!A|n zq`;$|!(5+1ucrl3S+uXWu*yf{6LqXLL5AuMs91n8SJ6QDh3@8WFLK@Kz8%BG4ZC&QzX^6WL9mD}= zIUW>d*&)dO5EbJ?88A;}#8Z0q0i;RJQ8&I*5C_083byZ2}M&K~hGVphyC<13MrwLLRF$ zGPE)-I*cYT9ykDw(XrhOnIMOu1U88b6cNj$6_y({lJdedMi~`KOadNtjbzfw^%}Z7 zjY*Kvm=oCuLkeTBN{pN$HNdBh`5cE`8mNSgI>|totqLetfix~%yU__`a pCO$FAq>>~h#>dD+!t8*?2wEB;i!{mUNLhqb1aSf=d}*Dc_&;vOchdj> delta 4591 zcmc&$3s4hR6n(o1Ap*e=7zeQxoPsSdD1`9sC=^=-W?EFVl|m~&0So91pDF6#PPJ8O z6(NfqsqG*&m9~l<8y(cPq82~=2?;2om}0?FAyFa5{Py)_6Qx)YEFybnXYYA$_rAOD zp0jsL3vks|yl4*RT3}ej+e{`f9?r${W)?@;bKP2A`*u!&t+Mc<-!$dd*_Gv44357S zKX3)#H`v=dSP(!GjG)Ix&NDW-3W5Rz$^0OJmrt@c-zz0ZAn;1`75I1s1q7@SBqk-U zN$~X*Co}t*C0-rOS;M&@o`dfw2zFnl2U!%>-;h)j81!?<(U^!RC{YDu z-PnD{BXV9(wX=MMaJewTwL~P0aC2Y!I|Llb|;1Vh5r zNq-aS1vh%%gFqyV&VTA;YL42!L4P~u5a*Nqnxi`_Zw&1vPi@ZM)v+%3v+YH^mJ7~< zhmu~Z?CzEpg#TF1ndUCOww#A?{Db*{E{~X{i~fQQ!0f%~%pm8k3}!FMqWZKFu z+}cqb{%$YR$~Jp_#@gh?Ycn!P#j0848?g@L%P|YdZ{peHzSz0mp%JhbJwzW%vevmI zug^^kO_p0f91F{EF^#3WFwdYt^7FV^Vw<=j2HPejDqm4{}+&10yOo zhfIr)B=^Nx+eUA6aap-8XYngb^D;uYWPNO$TIax{nne zyh!s<2Q3Y%o~9~MX-TKhvZPd0W#X$AvJC2exva6SvzArYC^NB|Fp>YBnf&)?@|(3` zQpn^AgcwsHlPeIysLe@H-S`ADtiR{ZwQ=#9c!A`9QbL6JQ}^iY|D%w}6$mk=LMB%r z#Kc?3gakrN4*AE^#%O^M6K^4psPiO#Jx;I3?;%F%OA`wE3^7sve?|p9Ux5%4Zy`?+ z2smpt4Y0t_k3H9}lV@SawP70}$7kTt(cM|2xFZlPy)=(SaGenvKY4&p 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: