Beispiel #1
0
        public static void ShowContextMenu(NodeEditorInputInfo inputInfo)
        {
            GenericMenu contextMenu = new GenericMenu();

            FillContextMenu(inputInfo, contextMenu, ContextType.Canvas);
            contextMenu.Show(inputInfo.inputPos);
        }
Beispiel #2
0
        [EventHandlerAttribute(EventType.MouseDown, 0)]          // One of the highest priorities after node selection
        private static void HandleContextClicks(NodeEditorInputInfo inputInfo)
        {
            if (Event.current.button == 1)
            {             // Handle context clicks on Node and canvas
                NodeEditorState state       = inputInfo.editorState;
                GenericMenu     contextMenu = new GenericMenu();
                if (inputInfo.editorState.focusedNode != null)            // Node Context Click
                {
                    if (!state.selectedNodes.Contains(state.focusedNode)) //&& state.focusedNode != state.selectedNode)
                    {
                        state.selectedNodes.Clear();
                        state.selectedNodes.Add(state.focusedNode);
                        state.selectedNode = state.focusedNode;
                    }

                    FillContextMenu(inputInfo, contextMenu, ContextType.Node);
                }
                else             // Editor Context Click
                {
                    FillContextMenu(inputInfo, contextMenu, ContextType.Canvas);
                }
                contextMenu.Show(inputInfo.inputPos);
                Event.current.Use();
            }
        }
        public void DrawToolbarGUI(Rect rect)
        {
            rect.height = toolbarHeight;
            GUILayout.BeginArea(rect, NodeEditorGUI.toolbar);
            GUILayout.BeginHorizontal();
            float curToolbarHeight = 0;


            if (GUILayout.Button("File", NodeEditorGUI.toolbarDropdown, GUILayout.Width(50)))
            {
                GenericMenu menu = new GenericMenu(!Application.isPlaying);

                // New Canvas filled with canvas types
                NodeCanvasManager.FillCanvasTypeMenu(ref menu, NewNodeCanvas, "新建画布/");
                // Load / Save
#if UNITY_EDITOR
                menu.AddItem(new GUIContent("重置画布"), false, ReloadCanvas);
                menu.AddSeparator("");
                if (canvasCache.nodeCanvas.allowSceneSaveOnly)
                {
                    menu.AddDisabledItem(new GUIContent("Save Canvas"));
                    menu.AddDisabledItem(new GUIContent("Save Canvas As"));
                }
                else
                {
                    menu.AddItem(new GUIContent("保存画布"), false, SaveCanvas);
                    menu.AddItem(new GUIContent("另存画布"), false, SaveCanvasAs);
                }
                menu.AddSeparator("");
#endif
                menu.AddItem(new GUIContent("导入数据[未完成!]"), false, Import);
                menu.AddItem(new GUIContent("导出数据[未完成!]"), false, Export);

                // Show dropdown
                menu.Show(new Vector2(5, toolbarHeight));
            }
            curToolbarHeight = Mathf.Max(curToolbarHeight, GUILayoutUtility.GetLastRect().yMax);

            GUILayout.Space(10);
            string fileName = Path.GetFileNameWithoutExtension(canvasCache.nodeCanvas.savePath);
            GUILayout.Button(new GUIContent(fileName, canvasCache.nodeCanvas.savePath), NodeEditorGUI.toolbarArrow);
            curToolbarHeight = Mathf.Max(curToolbarHeight, GUILayoutUtility.GetLastRect().yMax);

            GUILayout.EndHorizontal();
            GUILayout.EndArea();

            if (Event.current.type == EventType.Repaint)
            {
                toolbarHeight = curToolbarHeight;
            }
        }
Beispiel #4
0
 protected override void FillContextMenuCanvas(
     Action <NodeEditorInputInfo, NodeEditorFramework.Utilities.GenericMenu, ContextType> orig,
     NodeEditorInputInfo inputInfo,
     NodeEditorFramework.Utilities.GenericMenu contextMenu,
     ContextType contextType)
 {
     foreach (var type in nodeTypes)
     {
         string text = GetTypeString(type, typeof(AINode));
         if (type.GetCustomAttributes(typeof(ContextClickOverrideAttribute), false).Length != 0)
         {
             ContextClickOverrideAttribute attr = type.GetCustomAttributes(typeof(ContextClickOverrideAttribute), false)[0] as ContextClickOverrideAttribute;
             text = attr.path;
         }
         contextMenu.AddItem(new GUIContent(text.Trim('/')), true, () => AddNode(type, inputInfo.inputPos));
     }
 }
 [EventHandlerAttribute(EventType.MouseDown, 0)]          // One of the highest priorities after node selection
 private static void HandleContextClicks(NodeEditorInputInfo inputInfo)
 {
     if (Event.current.button == 1)
     {                                                  // Handle context clicks on Node and canvas
         GenericMenu contextMenu = new GenericMenu();
         if (inputInfo.editorState.focusedNode != null) // Node Context Click
         {
             FillContextMenu(inputInfo, contextMenu, ContextType.Node);
         }
         else                 // Editor Context Click
         {
             FillContextMenu(inputInfo, contextMenu, ContextType.Canvas);
         }
         contextMenu.Show(inputInfo.inputPos);
         Event.current.Use();
     }
 }
Beispiel #6
0
        /// <summary>
        /// Fills the contextMenu of the specified contextType with the inputInfo
        /// </summary>
        private static void FillContextMenu(NodeEditorInputInfo inputInfo, GenericMenu contextMenu, ContextType contextType)
        {
            foreach (KeyValuePair <ContextEntryAttribute, PopupMenu.MenuFunctionData> contextEntry in contextEntries)
            {             // Add all registered menu entries for the specified type to the contextMenu
                if (contextEntry.Key.contextType == contextType)
                {
                    contextMenu.AddItem(new GUIContent(contextEntry.Key.contextPath), false, contextEntry.Value, inputInfo);
                }
            }

            object[] fillerParams = new object[] { inputInfo, contextMenu };
            foreach (KeyValuePair <ContextFillerAttribute, Delegate> contextFiller in contextFillers)
            {             // Let all registered menu fillers for the specified type add their entries to the contextMenu
                if (contextFiller.Key.contextType == contextType)
                {
                    contextFiller.Value.DynamicInvoke(fillerParams);
                }
            }
        }
        private void DrawSideWindow()
        {
            GUILayout.Label(new GUIContent("Node Editor (" + canvasCache.nodeCanvas.name + ")", "Opened Canvas path: " + canvasCache.openedCanvasPath), NodeEditorGUI.nodeLabelBold);

            EditorGUILayout.ObjectField("Loaded Canvas", canvasCache.nodeCanvas, typeof(NodeCanvas), false);
            EditorGUILayout.ObjectField("Loaded State", canvasCache.editorState, typeof(NodeEditorState), false);

/*
 *                      if (GUILayout.Button(new GUIContent("New Canvas", "Loads an Specified Empty CanvasType")))
 *                      {
 *                              NodeEditorFramework.Utilities.GenericMenu menu = new NodeEditorFramework.Utilities.GenericMenu();
 *                              NodeCanvasManager.FillCanvasTypeMenu(ref menu, canvasCache.NewNodeCanvas);
 *                              menu.Show(createCanvasUIPos.position, createCanvasUIPos.width);
 *                      }
 */
            if (Event.current.type == EventType.Repaint)
            {
                Rect popupPos = GUILayoutUtility.GetLastRect();
                createCanvasUIPos = new Rect(popupPos.x + 2, popupPos.yMax + 2, popupPos.width - 4, 0);
            }

            GUILayout.Space(6);

            if (GUILayout.Button(new GUIContent("Save Canvas", "Saves the Canvas to a Canvas Save File in the Assets Folder")))
            {
                string path = EditorUtility.SaveFilePanelInProject("Save Node Canvas", "Node Canvas", "asset", "", NodeEditor.editorPath + "Resources/Saves/");
                if (!string.IsNullOrEmpty(path))
                {
                    canvasCache.SaveNodeCanvas(path);
                }
            }

            if (GUILayout.Button(new GUIContent("Load Canvas", "Loads the Canvas from a Canvas Save File in the Assets Folder")))
            {
                string path = EditorUtility.OpenFilePanel("Load Node Canvas", NodeEditor.editorPath + "Resources/Saves/", "asset");
                if (!path.Contains(Application.dataPath))
                {
                    if (!string.IsNullOrEmpty(path))
                    {
                        ShowNotification(new GUIContent("You should select an asset inside your project folder!"));
                    }
                }
                else
                {
                    canvasCache.LoadNodeCanvas(path);
                }
            }

            GUILayout.Space(6);

            GUILayout.BeginHorizontal();
            sceneCanvasName = GUILayout.TextField(sceneCanvasName, GUILayout.ExpandWidth(true));
            if (GUILayout.Button(new GUIContent("Save to Scene", "Saves the Canvas to the Scene"), GUILayout.ExpandWidth(false)))
            {
                canvasCache.SaveSceneNodeCanvas(sceneCanvasName);
            }
            GUILayout.EndHorizontal();

            if (GUILayout.Button(new GUIContent("Load from Scene", "Loads the Canvas from the Scene")))
            {
                NodeEditorFramework.Utilities.GenericMenu menu = new NodeEditorFramework.Utilities.GenericMenu();
                foreach (string sceneSave in NodeEditorSaveManager.GetSceneSaves())
                {
                    menu.AddItem(new GUIContent(sceneSave), false, LoadSceneCanvasCallback, (object)sceneSave);
                }
                menu.Show(loadSceneUIPos.position, loadSceneUIPos.width);
            }
            if (Event.current.type == EventType.Repaint)
            {
                Rect popupPos = GUILayoutUtility.GetLastRect();
                loadSceneUIPos = new Rect(popupPos.x + 2, popupPos.yMax + 2, popupPos.width - 4, 0);
            }

            GUILayout.Space(6);

            if (GUILayout.Button(new GUIContent("Recalculate All", "Initiates complete recalculate. Usually does not need to be triggered manually.")))
            {
                NodeEditor.RecalculateAll(canvasCache.nodeCanvas);
            }

            if (GUILayout.Button("Force Re-Init"))
            {
                NodeEditor.ReInit(true);
            }

            NodeEditorGUI.knobSize       = EditorGUILayout.IntSlider(new GUIContent("Handle Size", "The size of the Node Input/Output handles"), NodeEditorGUI.knobSize, 12, 20);
            canvasCache.editorState.zoom = EditorGUILayout.Slider(new GUIContent("Zoom", "Use the Mousewheel. Seriously."), canvasCache.editorState.zoom, 0.6f, 2);

            if (canvasCache.editorState.selectedNode != null && Event.current.type != EventType.Ignore)
            {
                canvasCache.editorState.selectedNode.DrawNodePropertyEditor();
            }
        }
		/// <summary>
		/// Processes input events
		/// </summary>
		public static void InputEvents ()
		{
			Event e = Event.current;
			mousePos = e.mousePosition;

			bool leftClick = e.button == 0, rightClick = e.button == 1,
				mouseDown = e.type == EventType.MouseDown, mousUp = e.type == EventType.MouseUp;

			if (ignoreInput (mousePos))
				return;

			#region Change Node selection and focus
			// Choose focused and selected Node, accounting for focus changes
			curEditorState.focusedNode = null;
			if (mouseDown || mousUp)
			{
				curEditorState.focusedNode = NodeEditor.NodeAtPosition (mousePos);
				if (curEditorState.focusedNode != curEditorState.selectedNode)
					unfocusControls = true;
				if (mouseDown && leftClick) 
				{
					curEditorState.selectedNode = curEditorState.focusedNode;
					RepaintClients ();
				}
			}
			// Perform above mentioned focus changes in Repaint, which is the only suitable time to do this
			if (unfocusControls && Event.current.type == EventType.Repaint) 
			{
				GUIUtility.hotControl = 0;
				GUIUtility.keyboardControl = 0;
				unfocusControls = false;
			}
		#if UNITY_EDITOR
			if (curEditorState.focusedNode != null)
				UnityEditor.Selection.activeObject = curEditorState.focusedNode;
		#endif
			#endregion

			switch (e.type) 
			{
			case EventType.MouseDown:

				curEditorState.dragNode = false;
				curEditorState.panWindow = false;
				
				if (curEditorState.focusedNode != null) 
				{ // Clicked a Node
					if (rightClick)
					{ // Node Context Click
						GenericMenu menu = new GenericMenu ();
						menu.AddItem (new GUIContent ("Delete Node"), false, ContextCallback, new NodeEditorMenuCallback ("deleteNode", curNodeCanvas, curEditorState));
						menu.AddItem (new GUIContent ("Duplicate Node"), false, ContextCallback, new NodeEditorMenuCallback ("duplicateNode", curNodeCanvas, curEditorState));
						if (curEditorState.focusedNode.AcceptsTranstitions)
						{
							menu.AddSeparator ("Seperator");
							menu.AddItem (new GUIContent ("Make Transition"), false, ContextCallback, new NodeEditorMenuCallback ("startTransition", curNodeCanvas, curEditorState));
						}
						menu.ShowAsContext ();
						e.Use ();
					}
					else if (leftClick)
					{ // Detect click on a connection knob
						if (!CanvasGUIToScreenRect (curEditorState.focusedNode.rect).Contains (mousePos))
						{ // Clicked NodeEdge, check Node Inputs and Outputs
							NodeOutput nodeOutput = curEditorState.focusedNode.GetOutputAtPos (e.mousePosition);
							if (nodeOutput != null)
							{ // Output clicked -> New Connection drawn from this
								curEditorState.connectOutput = nodeOutput;
								e.Use();
								return;
							}

							NodeInput nodeInput = curEditorState.focusedNode.GetInputAtPos (e.mousePosition);
							if (nodeInput != null && nodeInput.connection != null)
							{ // Input clicked -> Loose and edit Connection
								// TODO: Draw input from NodeInput
								curEditorState.connectOutput = nodeInput.connection;
								nodeInput.RemoveConnection ();
								e.Use();
							}
						}
					}
				}
				else
				{ // Clicked on canvas
					
					// NOTE: Panning is not done here but in LateEvents, so buttons on the canvas won't be blocked when clicking

					if (rightClick) 
					{ // Editor Context Click
						GenericMenu menu = new GenericMenu ();
						if (curEditorState.connectOutput != null) 
						{ // A connection is drawn, so provide a context menu with apropriate nodes to auto-connect
							foreach (Node node in NodeTypes.nodes.Keys)
							{ // Iterate through all nodes and check for compability
								foreach (NodeInput input in node.Inputs)
								{
									if (input.type == curEditorState.connectOutput.type)
									{
										menu.AddItem (new GUIContent ("Add " + NodeTypes.nodes[node].adress), false, ContextCallback, new NodeEditorMenuCallback (node.GetID, curNodeCanvas, curEditorState));
										break;
									}
								}
							}
						}
						else if (curEditorState.makeTransition != null && curEditorState.makeTransition.AcceptsTranstitions) 
						{ // A transition is drawn, so provide a context menu with nodes to auto-connect
							foreach (Node node in NodeTypes.nodes.Keys)
							{ // Iterate through all nodes and check for compability
								if (node.AcceptsTranstitions)
									menu.AddItem (new GUIContent ("Add " + NodeTypes.nodes[node].adress), false, ContextCallback, new NodeEditorMenuCallback (node.GetID, curNodeCanvas, curEditorState));
							}
						}
						else 
						{ // Ordinary context click, add all nodes to add
							foreach (Node node in NodeTypes.nodes.Keys)
								menu.AddItem (new GUIContent ("Add " + NodeTypes.nodes [node].adress), false, ContextCallback, new NodeEditorMenuCallback (node.GetID, curNodeCanvas, curEditorState));
						}
						menu.ShowAsContext ();
						e.Use ();
					}
				}
				
				break;
				
			case EventType.MouseUp:

				if (curEditorState.focusedNode != null && curEditorState.connectOutput != null) 
				{ // Apply Drawn connections on node if theres a clicked input
					if (!curEditorState.focusedNode.Outputs.Contains (curEditorState.connectOutput)) 
					{ // An input was clicked, it'll will now be connected
						NodeInput clickedInput = curEditorState.focusedNode.GetInputAtPos (e.mousePosition);
						if (clickedInput.CanApplyConnection (curEditorState.connectOutput)) 
						{ // It can connect (type is equals, it does not cause recursion, ...)
							clickedInput.ApplyConnection (curEditorState.connectOutput);
						}
					}
					e.Use ();
				}
				
				curEditorState.makeTransition = null;
				curEditorState.connectOutput = null;
				curEditorState.dragNode = false;
				curEditorState.panWindow = false;
				
				break;
				
			case EventType.ScrollWheel:

				// Apply Zoom
				curEditorState.zoom = (float)Math.Round (Math.Min (2.0f, Math.Max (0.6f, curEditorState.zoom + e.delta.y / 15)), 2);

				RepaintClients ();
				break;
				
			case EventType.KeyDown:

				// TODO: Node Editor: Shortcuts

				if (e.keyCode == KeyCode.N) // Start Navigating (curve to origin / active Node)
					curEditorState.navigate = true;
				
				if (e.keyCode == KeyCode.LeftControl && curEditorState.selectedNode != null)
				{ // Snap selected Node's position to multiples of 10
					Vector2 pos = curEditorState.selectedNode.rect.position;
					pos = (pos - curEditorState.panOffset) / 10;
					pos = new Vector2 (Mathf.RoundToInt (pos.x), Mathf.RoundToInt (pos.y));
					curEditorState.selectedNode.rect.position = pos * 10 + curEditorState.panOffset;
				}

				RepaintClients ();
				break;
				
			case EventType.KeyUp:
				
				if (e.keyCode == KeyCode.N) // Stop Navigating
					curEditorState.navigate = false;
				
				RepaintClients ();
				break;
			
			case EventType.MouseDrag:

				if (curEditorState.panWindow) 
				{ // Scroll everything with the current mouse delta
					curEditorState.panOffset += e.delta * curEditorState.zoom;
					foreach (Node node in curNodeCanvas.nodes)
						node.rect.position += e.delta * curEditorState.zoom;
					e.delta = Vector2.zero;
					RepaintClients ();
				}
				
				if (curEditorState.dragNode && curEditorState.selectedNode != null && GUIUtility.hotControl == 0) 
				{ // Drag the active node with the current mouse delta
					curEditorState.selectedNode.rect.position += e.delta * curEditorState.zoom;
					NodeEditorCallbacks.IssueOnMoveNode (curEditorState.selectedNode);
					e.delta = Vector2.zero;
					RepaintClients ();
				} 
				else
					curEditorState.dragNode = false;

				break;
			}
		}
Beispiel #9
0
        public void SideGUI()
        {
            GUILayout.Label(new GUIContent("Node Editor (" + canvas.name + ")", "The currently opened canvas in the Node Editor"));
            screenSize = GUILayout.Toggle(screenSize, "Adapt to Screen");
            GUILayout.Label("FPS: " + FPSCounter.currentFPS);

            GUILayout.Label(new GUIContent("Node Editor (" + canvas.name + ")"), NodeEditorGUI.nodeLabelBold);

            if (GUILayout.Button(new GUIContent("New Canvas", "Loads an empty Canvas")))
            {
                NewNodeCanvas();
            }

            GUILayout.Space(6);

                #if UNITY_EDITOR
            if (GUILayout.Button(new GUIContent("Save Canvas", "Saves the Canvas to a Canvas Save File in the Assets Folder")))
            {
                string path = UnityEditor.EditorUtility.SaveFilePanelInProject("Save Node Canvas", "Node Canvas", "asset", "", NodeEditor.editorPath + "Resources/Saves/");
                if (!string.IsNullOrEmpty(path))
                {
                    NodeEditorSaveManager.SaveNodeCanvas(path, canvas, true);
                }
            }

            if (GUILayout.Button(new GUIContent("Load Canvas", "Loads the Canvas from a Canvas Save File in the Assets Folder")))
            {
                string path = UnityEditor.EditorUtility.OpenFilePanel("Load Node Canvas", NodeEditor.editorPath + "Resources/Saves/", "asset");
                if (!path.Contains(Application.dataPath))
                {
                    if (!string.IsNullOrEmpty(path))
                    {
                        Debug.LogWarning("You should select an asset inside your project folder!");
                    }
                }
                else
                {
                    path = path.Replace(Application.dataPath, "Assets");
                    LoadNodeCanvas(path);
                }
            }
            GUILayout.Space(6);
                #endif

            GUILayout.BeginHorizontal();
            sceneCanvasName = GUILayout.TextField(sceneCanvasName, GUILayout.ExpandWidth(true));
            if (GUILayout.Button(new GUIContent("Save to Scene", "Saves the Canvas to the Scene"), GUILayout.ExpandWidth(false)))
            {
                SaveSceneNodeCanvas(sceneCanvasName);
            }
            GUILayout.EndHorizontal();

            if (GUILayout.Button(new GUIContent("Load from Scene", "Loads the Canvas from the Scene")))
            {
                NodeEditorFramework.Utilities.GenericMenu menu = new NodeEditorFramework.Utilities.GenericMenu();
                foreach (string sceneSave in NodeEditorSaveManager.GetSceneSaves())
                {
                    menu.AddItem(new GUIContent(sceneSave), false, LoadSceneCanvasCallback, (object)sceneSave);
                }
                menu.Show(loadScenePos);
            }
            if (Event.current.type == EventType.Repaint)
            {
                Rect popupPos = GUILayoutUtility.GetLastRect();
                loadScenePos = new Vector2(popupPos.x + 2, popupPos.yMax + 2);
            }

            GUILayout.Space(6);

            if (GUILayout.Button(new GUIContent("Recalculate All", "Initiates complete recalculate. Usually does not need to be triggered manually.")))
            {
                NodeEditor.RecalculateAll(canvas);
            }

            if (GUILayout.Button("Force Re-Init"))
            {
                NodeEditor.ReInit(true);
            }

            NodeEditorGUI.knobSize = RTEditorGUI.IntSlider(new GUIContent("Handle Size", "The size of the Node Input/Output handles"), NodeEditorGUI.knobSize, 12, 20);
            state.zoom             = RTEditorGUI.Slider(new GUIContent("Zoom", "Use the Mousewheel. Seriously."), state.zoom, 0.6f, 2);
        }
        public void SideGUI()
        {
            GUILayout.Label(new GUIContent("" + cache.nodeCanvas.saveName + " (" + (cache.nodeCanvas.livesInScene? "Scene Save" : "Asset Save") + ")", "Opened Canvas path: " + cache.nodeCanvas.savePath), NodeEditorGUI.nodeLabelBold);
            GUILayout.Label("Type: " + cache.typeData.DisplayString + "/" + cache.nodeCanvas.GetType().Name + "");



            if (GUILayout.Button(new GUIContent("New Canvas", "Loads an Specified Empty CanvasType")))
            {
                NodeEditorFramework.Utilities.GenericMenu menu = new NodeEditorFramework.Utilities.GenericMenu();
                NodeCanvasManager.FillCanvasTypeMenu(ref menu, cache.NewNodeCanvas);
                menu.Show(createCanvasUIPos.position, createCanvasUIPos.width);
            }
            if (Event.current.type == EventType.Repaint)
            {
                Rect popupPos = GUILayoutUtility.GetLastRect();
                createCanvasUIPos = new Rect(popupPos.x + 2, popupPos.yMax + 2, popupPos.width - 4, 0);
            }
            if (cache.nodeCanvas.GetType() == typeof(NodeCanvas) && GUILayout.Button(new GUIContent("Convert Canvas", "Converts the current canvas to a new type.")))
            {
                NodeEditorFramework.Utilities.GenericMenu menu = new NodeEditorFramework.Utilities.GenericMenu();
                NodeCanvasManager.FillCanvasTypeMenu(ref menu, cache.ConvertCanvasType);
                menu.Show(convertCanvasUIPos.position, convertCanvasUIPos.width);
            }
            if (Event.current.type == EventType.Repaint)
            {
                Rect popupPos = GUILayoutUtility.GetLastRect();
                convertCanvasUIPos = new Rect(popupPos.x + 2, popupPos.yMax + 2, popupPos.width - 4, 0);
            }

            if (GUILayout.Button(new GUIContent("Save Canvas", "Save the Canvas to the load location")))
            {
                string path = cache.nodeCanvas.savePath;
                if (!string.IsNullOrEmpty(path))
                {
                    if (path.StartsWith("SCENE/"))
                    {
                        cache.SaveSceneNodeCanvas(path.Substring(6));
                    }
                    else
                    {
                        cache.SaveNodeCanvas(path);
                    }
                }
            }



                #if UNITY_EDITOR
            GUILayout.Label("Asset Saving", NodeEditorGUI.nodeLabel);

            if (GUILayout.Button(new GUIContent("Save Canvas As", "Save the canvas as an asset")))
            {
                string panelPath = NodeEditor.editorPath + "Resources/Saves/";
                if (cache.nodeCanvas != null && !string.IsNullOrEmpty(cache.nodeCanvas.savePath))
                {
                    panelPath = cache.nodeCanvas.savePath;
                }
                string path = UnityEditor.EditorUtility.SaveFilePanelInProject("Save Node Canvas", "Node Canvas", "asset", "", panelPath);
                if (!string.IsNullOrEmpty(path))
                {
                    cache.SaveNodeCanvas(path);
                }
            }

            if (GUILayout.Button(new GUIContent("Load Canvas", "Load the Canvas from an asset")))
            {
                string panelPath = NodeEditor.editorPath + "Resources/Saves/";
                if (cache.nodeCanvas != null && !string.IsNullOrEmpty(cache.nodeCanvas.savePath))
                {
                    panelPath = cache.nodeCanvas.savePath;
                }
                string path = UnityEditor.EditorUtility.OpenFilePanel("Load Node Canvas", panelPath, "asset");
                if (!path.Contains(Application.dataPath))
                {
                    if (!string.IsNullOrEmpty(path))
                    {
                        Debug.LogWarning(new GUIContent("You should select an asset inside your project folder!"));
                    }
                }
                else
                {
                    cache.LoadNodeCanvas(path);
                }
                if (cache.nodeCanvas.GetType() == typeof(NodeCanvas))
                {
                    Debug.LogWarning(new GUIContent("The Canvas has no specific type. Please use the convert button to assign a type and re-save the canvas!"));
                }
            }
                #endif

            GUILayout.Label("Scene Saving", NodeEditorGUI.nodeLabel);

            GUILayout.BeginHorizontal();
            sceneCanvasName = GUILayout.TextField(sceneCanvasName, GUILayout.ExpandWidth(true));
            if (GUILayout.Button(new GUIContent("Save to Scene", "Save the canvas to the Scene"), GUILayout.ExpandWidth(false)))
            {
                cache.SaveSceneNodeCanvas(sceneCanvasName);
            }
            GUILayout.EndHorizontal();

            if (GUILayout.Button(new GUIContent("Load from Scene", "Load the canvas from the Scene")))
            {
                NodeEditorFramework.Utilities.GenericMenu menu = new NodeEditorFramework.Utilities.GenericMenu();
                foreach (string sceneSave in NodeEditorSaveManager.GetSceneSaves())
                {
                    menu.AddItem(new GUIContent(sceneSave), false, LoadSceneCanvasCallback, (object)sceneSave);
                }
                menu.Show(loadSceneUIPos.position, loadSceneUIPos.width);
            }
            if (Event.current.type == EventType.Repaint)
            {
                Rect popupPos = GUILayoutUtility.GetLastRect();
                loadSceneUIPos = new Rect(popupPos.x + 2, popupPos.yMax + 2, popupPos.width - 4, 0);
            }



            GUILayout.Label("Utility/Debug", NodeEditorGUI.nodeLabel);

            if (GUILayout.Button(new GUIContent("Recalculate All", "Initiates complete recalculate. Usually does not need to be triggered manually.")))
            {
                cache.nodeCanvas.TraverseAll();
            }

            if (GUILayout.Button("Force Re-Init"))
            {
                NodeEditor.ReInit(true);
            }

            NodeEditorGUI.knobSize = RTEditorGUI.IntSlider(new GUIContent("Handle Size", "The size of the Node Input/Output handles"), NodeEditorGUI.knobSize, 12, 20);
            //cache.editorState.zoom = EditorGUILayout.Slider (new GUIContent ("Zoom", "Use the Mousewheel. Seriously."), cache.editorState.zoom, 0.6f, 4);
            NodeEditorUserCache.cacheIntervalSec = RTEditorGUI.IntSlider(new GUIContent("Cache Interval (Sec)", "The interval in seconds the canvas is temporarily saved into the cache as a precaution for crashes."), NodeEditorUserCache.cacheIntervalSec, 30, 300);

            screenSize = GUILayout.Toggle(screenSize, "Adapt to Screen");
            GUILayout.Label("FPS: " + FPSCounter.currentFPS);



            if (cache.editorState.selectedNode != null && Event.current.type != EventType.Ignore)
            {
                cache.editorState.selectedNode.DrawNodePropertyEditor();
            }
        }
        public void DrawToolbarGUI(Rect rect)
        {
            rect.height = toolbarHeight;
            GUILayout.BeginArea(rect, NodeEditorGUI.toolbar);
            GUILayout.BeginHorizontal();
            float curToolbarHeight = 0;

            if (GUILayout.Button("File", NodeEditorGUI.toolbarDropdown, GUILayout.Width(50)))
            {
                GenericMenu menu = new GenericMenu(!Application.isPlaying);

                // New Canvas filled with canvas types
                NodeCanvasManager.FillCanvasTypeMenu(ref menu, NewNodeCanvas, "New Canvas/");
                menu.AddSeparator("");

                // Load / Save
#if UNITY_EDITOR
                menu.AddItem(new GUIContent("Load Canvas"), false, LoadCanvas);
                menu.AddItem(new GUIContent("Reload Canvas"), false, ReloadCanvas);
                menu.AddSeparator("");
                menu.AddItem(new GUIContent("Save Canvas"), false, SaveCanvas);
                menu.AddItem(new GUIContent("Save Canvas As"), false, SaveCanvasAs);
                menu.AddSeparator("");
                foreach (var kv in ActionMenuTools.GetInstance().Getfolderdict())
                {
                    menu.AddItem(new GUIContent(kv.Key), false, kv.Value);
                }
                menu.AddSeparator("");
#endif

                // Import / Export filled with import/export types
                ImportExportManager.FillImportFormatMenu(ref menu, ImportCanvasCallback, "Import/");
                ImportExportManager.FillExportFormatMenu(ref menu, ExportCanvasCallback, "Export/");
                menu.AddSeparator("");

                // Scene Saving
                string[] sceneSaves = NodeEditorSaveManager.GetSceneSaves();
                if (sceneSaves.Length <= 0)                 // Display disabled item
                {
                    menu.AddItem(new GUIContent("Load Canvas from Scene"), false, null);
                }
                else
                {
                    foreach (string sceneSave in sceneSaves)                  // Display scene saves to load
                    {
                        menu.AddItem(new GUIContent("Load Canvas from Scene/" + sceneSave), false, LoadSceneCanvasCallback, sceneSave);
                    }
                }
                menu.AddItem(new GUIContent("Save Canvas to Scene"), false, SaveSceneCanvasCallback);

                // Show dropdown
                menu.Show(new Vector2(5, toolbarHeight));
            }
            curToolbarHeight = Mathf.Max(curToolbarHeight, GUILayoutUtility.GetLastRect().yMax);

            GUILayout.Space(10);
            GUILayout.FlexibleSpace();

            GUILayout.Label(new GUIContent("" + canvasCache.nodeCanvas.saveName + " (" + (canvasCache.nodeCanvas.livesInScene ? "Scene Save" : "Asset Save") + ")",
                                           "Opened Canvas path: " + canvasCache.nodeCanvas.savePath), NodeEditorGUI.toolbarLabel);
            GUILayout.Label("Type: " + canvasCache.typeData.DisplayString, NodeEditorGUI.toolbarLabel);
            curToolbarHeight = Mathf.Max(curToolbarHeight, GUILayoutUtility.GetLastRect().yMax);

            GUI.backgroundColor = new Color(1, 0.3f, 0.3f, 1);
            if (GUILayout.Button("Force Re-init", NodeEditorGUI.toolbarButton, GUILayout.Width(100)))
            {
                NodeEditor.ReInit(true);
                canvasCache.nodeCanvas.Validate();
            }
#if !UNITY_EDITOR
            GUILayout.Space(5);
            if (GUILayout.Button("Quit", NodeEditorGUI.toolbarButton, GUILayout.Width(100)))
            {
                Application.Quit();
            }
#endif
            curToolbarHeight    = Mathf.Max(curToolbarHeight, GUILayoutUtility.GetLastRect().yMax);
            GUI.backgroundColor = Color.white;

            GUILayout.EndHorizontal();
            GUILayout.EndArea();
            if (Event.current.type == EventType.Repaint)
            {
                toolbarHeight = curToolbarHeight;
            }
        }