private void FileMenuSelect( object objProperty ) { if( objProperty.GetType() != typeof( FileMenuOptions ) ) { return; } var option = (FileMenuOptions)objProperty; switch( option ) { case FileMenuOptions.NewGraph: { if (EditorUtility.DisplayDialog("New Graph","Old graph will be lost, are you sure?","Confirm","Cancel")) { _nextGraph = new ShaderGraph(); _nextGraph.Initialize( new Rect( 0, 0, Screen.width, Screen.height ), true); _graphNeedsUpdate = true; _lastGraphPath = ""; _lastExportPath = ""; _undoChain = new GraphHistory( _serializableTypes ); _markDirtyOnLoad = true; } break; } case FileMenuOptions.ExportGraph: case FileMenuOptions.ExportAsGraph: { _shouldExportShader = true; if (!String.IsNullOrEmpty(_lastExportPath) && option == FileMenuOptions.ExportGraph) { _quickExport = true; } if (!String.IsNullOrEmpty(_lastGraphPath)) { _shouldSaveGraph = true; _quickSaving = true; } break; } case FileMenuOptions.SaveGraph: case FileMenuOptions.SaveAsGraph: { _shouldSaveGraph = true; if (!String.IsNullOrEmpty(_lastGraphPath) && option == FileMenuOptions.SaveGraph) { _quickSaving = true; } break; } case FileMenuOptions.LoadGraph: { _shouldLoadGraph = true; break; } } }
public void OnGUI() { if (!_isInstructionCountCached) CacheCount(); GUI.Label(new Rect(5,0,95,45),new GUIContent(_instructionCountDetails,_instructionCountTooltip)); _reservedArea.Clear(); _drawArea = new Rect( 0, 0, Screen.width-300, Screen.height-23 ); _detailsBox = new Rect(Screen.width - 300,0, 300, Screen.height - 40); _optionsBox = new Rect(Screen.width - 300,Screen.height - 40, 300 , 25); //Mouse clicks in the reserved area do not attemp to select on graph _reservedArea.Add( _detailsBox ); _reservedArea.Add( _optionsBox ); _currentMousePosition.x = Event.current.mousePosition.x; _currentMousePosition.y = Event.current.mousePosition.y; // Handle Minimap! (Texel) if (_middleMouseDrag) { var oldColor = GUI.color; var trans = GUI.color * new Vector4(1,1,1,0.3f); // Fairly transparent // First, draw the bounds of the graph. This requires min/maxing the graph var drawCenter = new Vector2((_drawArea.x + (_drawArea.width * 0.5f)),_drawArea.y + (_drawArea.height * 0.5f)); drawCenter.x -= _drawArea.width * 0.1f; drawCenter.y -= _drawArea.height * 0.1f; var redSize = new Vector2(_drawArea.width,_drawArea.height) * 0.2f; GUI.color = trans; GUI.Box(new Rect(drawCenter.x,drawCenter.y,redSize.x,redSize.y),""); GUI.color = oldColor; var oldBkg = GUI.backgroundColor; // Now we will draw the graph centered around the offset (Scaled down ten times) //Rect[] rects = _selectedGraph.CurrentSubGraph.nodePositions; foreach(Node node in _selectedGraph.CurrentSubGraph.Nodes) { var rect = node.NodePositionInGraph; var delta = new Vector2(rect.x,rect.y);// - offset; var size = new Vector2(rect.width,rect.height); delta *= 0.2f; size *= 0.2f; delta += drawCenter; switch (node.CurrentState) { case (NodeState.Valid): GUI.color = Color.white; break; case (NodeState.NotConnected): GUI.color = new Color (0.8f, 0.8f, 1f); break; case (NodeState.CircularReferenceInGraph): GUI.color = new Color (0.8f, 0.8f, 0f); break; case (NodeState.Error): GUI.color = Color.red; break; } if( node == _selectedNode ) GUI.backgroundColor = Color.Lerp(GUI.backgroundColor,Color.green,0.5f); GUI.Box(new Rect(delta.x,delta.y,size.x,size.y),""); GUI.color = oldColor; GUI.backgroundColor = oldBkg; } } HandleEvents(); //GUI fixup for changed focus GUI.SetNextControlName("FocusFixup"); EditorGUI.Toggle(new Rect(-100, -100, 1, 1), false); if (_focusChangedUpdate) { GUI.FocusControl("FocusFixup"); _focusChangedUpdate = false; } //Update each node and draw them _selectedGraph.UpdateErrorState(); GUILayout.BeginArea( _drawArea ); _selectedGraph.Draw( this, _showComments, _drawArea ); UpdateIOChannels(); DrawIOLines(_drawArea); GUILayout.EndArea( ); if( _doingSelectBox ) { var oldColor = GUI.color; var newColor = GUI.color; newColor.a = 0.4f; GUI.color = newColor; GUI.Box( GetSelectionArea(), "" ); GUI.color = oldColor; } DrawSettings(); //Handle node delete / undo and redo if( !GUI.changed && Event.current.type == EventType.KeyDown ) { if (Event.current.keyCode == KeyCode.Z && ( Event.current.modifiers == EventModifiers.Alt ) ) { var graph = _undoChain.Undo(); if( graph != null ) { _nextGraph = graph; _nextGraph.Initialize( new Rect( 0, 0, Screen.width, Screen.height ), false); _graphNeedsUpdate = true; NextSelectedNode = _nextGraph.FirstSelected; _updateSelection = true; Event.current.Use(); } return; } if (Event.current.keyCode == KeyCode.Z && ( Event.current.modifiers == (EventModifiers.Alt | EventModifiers.Shift ) ) ) { var graph = _undoChain.Redo(); if( graph != null ) { _nextGraph = graph; _nextGraph.Initialize( new Rect( 0, 0, Screen.width, Screen.height ), false); _graphNeedsUpdate = true; NextSelectedNode = _nextGraph.FirstSelected; _updateSelection = true; Event.current.Use(); } return; } if (Event.current.keyCode == KeyCode.Delete || Event.current.keyCode == KeyCode.Backspace) { _selectedGraph.CurrentSubGraph.DeleteSelected(); NextSelectedNode = null; _graphNeedsUpdate = true; _updateSelection = true; SelectedInputChannel = null; SelectedOutputChannel = null; MarkDirty(); Event.current.Use(); } } //Draw the current subgraph type var oldFontSize = GUI.skin.label.fontSize; var oldFontStyle = GUI.skin.label.fontStyle; GUI.skin.label.fontSize = 30; GUI.skin.label.fontStyle = FontStyle.BoldAndItalic; GUILayout.BeginArea( _drawArea ); GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); GUILayout.Label( _currentSubGraphType.DisplayName(), GUI.skin.label ); GUILayout.Space( 10 ); GUILayout.EndHorizontal(); GUILayout.EndArea(); GUI.skin.label.fontSize = oldFontSize; GUI.skin.label.fontStyle = oldFontStyle; DrawOptions(); }
//Load the last 'autosave' graph private void LoadLastGraph() { var fi = new FileInfo(_autosavePath); if (fi.Exists) { try{ var fs = fi.OpenRead(); var reader = XmlDictionaryReader.CreateTextReader(fs, new XmlDictionaryReaderQuotas()); var ser = new DataContractSerializer(typeof(AutoSaveGraph), _serializableTypes, int.MaxValue, false, false, null); var loaded = ser.ReadObject(reader, true) as AutoSaveGraph; if (loaded != null) { _nextGraph = loaded.Graph; if( !string.IsNullOrEmpty( loaded.ExportPath ) && File.Exists( loaded.ExportPath ) ) _lastExportPath = loaded.ExportPath; if( !string.IsNullOrEmpty( loaded.SavePath ) && File.Exists( loaded.SavePath ) ) _lastGraphPath = loaded.SavePath; _nextGraph.Initialize( new Rect( 0, 0, Screen.width, Screen.height ), true); _markDirtyOnLoad = true; } reader.Close(); fs.Close(); } catch( Exception e ) { Debug.Log( e ); EditorUtility.DisplayDialog("Load Shader Error", "Could not load shader", "Ok"); } } }
protected NodeEditor( ) { _shaderEditorResourceDir = Application.dataPath + Path.DirectorySeparatorChar + "StrumpyShaderEditor" + Path.DirectorySeparatorChar + "Editor" + Path.DirectorySeparatorChar + "Resources" + Path.DirectorySeparatorChar; _internalTempDir = "Internal" + Path.DirectorySeparatorChar + "Temp" + Path.DirectorySeparatorChar; _internalTempUnityPath = "Internal/Temp/"; _autosavePath = _shaderEditorResourceDir + _internalTempDir + "autosave.sgraph"; _tempShaderPathFull = _shaderEditorResourceDir + _internalTempDir + TempShaderName + ".shader"; _shaderTemplatePath = _shaderEditorResourceDir + "Internal" + Path.DirectorySeparatorChar + "ShaderTemplate.template"; _graphsDir = _shaderEditorResourceDir + "Public" + Path.DirectorySeparatorChar + "Graphs"; _selectedGraph = new ShaderGraph(); _popupMenu = new PopupMenu( ); //Find all the nodes that exist in the assembly (for submission to popup menu) var types = AppDomain.CurrentDomain.GetAssemblies().ToList().SelectMany(s => s.GetTypes()); foreach (var type in types) { foreach (var attribute in Attribute.GetCustomAttributes(type).OfType<NodeMetaData>()) { NodeMetaData attribute2 = attribute; _popupMenu.AddItem( new ExecutableMenuItem( attribute.Category, attribute.DisplayName, delegate( Vector2 location ){ var toAdd = Activator.CreateInstance(attribute2.NodeType) as Node; if (toAdd == null) { return; } _selectedGraph.CurrentSubGraph.AddNode(toAdd); toAdd.NodePositionInGraph = new EditorRect( location.x, location.y, 10f, 10f); MarkDirty(); }, String.IsNullOrEmpty(attribute.Descriptor) ? "" : attribute.Descriptor ) ); } } _popupMenu.SortMenu(); //Find all the serializable types _serializableTypes.Clear(); foreach (var type in types) { var typeAttributes = Attribute.GetCustomAttributes(type); foreach (var attribute in typeAttributes) { if (attribute is DataContractAttribute) { _serializableTypes.Add(type); } } } //Finally load the last graph LoadLastGraph(); _selectedGraph.Initialize( new Rect( 0,0, Screen.width, Screen.height ), true ); _undoChain = new GraphHistory( _serializableTypes ); _shouldOpenPreviewWindow = true; }
public void Update() { wantsMouseMove = true; //Need to force recreate the preview window if transitioning from //game to editor or back if( _isPlayingInEditor != EditorApplication.isPlaying ) { DisablePreview(); _shouldOpenPreviewWindow = true; _isPlayingInEditor = EditorApplication.isPlaying; } if( _shouldOpenPreviewWindow && PreviewSupported() ) { //Find the preview window var types = AppDomain.CurrentDomain.GetAssemblies().ToList().SelectMany(s => s.GetTypes()); var previewWindowType = types.FirstOrDefault( x => x.FullName == "StrumpyPreviewWindow" ); if( previewWindowType != null ) { _previewWindow = GetWindow( previewWindowType, true, "Preview" ) as PreviewWindowInternal; if (_previewWindow != null) { _previewWindow.Initialize(this); _previewWindow.wantsMouseMove = true; _previewWindow.ShouldUpdate = true; _shouldOpenPreviewWindow = false; } } } //Update preview if (_shouldUpdateShader) { if (_selectedGraph.IsGraphValid()) { File.WriteAllText(_tempShaderPathFull, _selectedGraph.GetShader(_shaderTemplatePath, true)); var currentShader = Resources.Load(_internalTempUnityPath + TempShaderName) as Shader; var path = AssetDatabase.GetAssetPath(currentShader); AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate); if( _previewWindow != null ) _previewWindow.PreviewMaterial = new Material(currentShader); _graphNeedsUpdate = false; InstructionCounter.CountInstructions(); // Update the instruction count CacheCount(); // Solve the tooltip (Cached) } else { EditorUtility.DisplayDialog("Save Shader Error", "Cannot update shader, there are errors in the graph", "Ok"); } _shouldUpdateShader = false; } //Save graph if (_shouldSaveGraph) { var path = _quickSaving ? _lastGraphPath : EditorUtility.SaveFilePanel("Save shader graph to file...", _graphsDir, "shader.sgraph", "sgraph"); if (!string.IsNullOrEmpty(path)) { var writer = new FileStream(path, FileMode.Create); var ser = new DataContractSerializer(typeof (ShaderGraph), _serializableTypes, int.MaxValue, false, false, null); ser.WriteObject(writer, _selectedGraph); writer.Close(); _lastGraphPath = path; } _shouldSaveGraph = false; _quickSaving = false; } //Load graph if( _shouldLoadGraph ) { var loadDir = _graphsDir; if(!String.IsNullOrEmpty(_lastGraphPath)) loadDir = _lastGraphPath; var path = string.IsNullOrEmpty(_overrideLoadPath) ? EditorUtility.OpenFilePanel("Load shader graph...", loadDir, "sgraph") : _overrideLoadPath; bool didLoad = false; if (!string.IsNullOrEmpty(path)) { try { using( var fs = new FileStream(path, FileMode.Open) ) { using( var reader = XmlDictionaryReader.CreateTextReader(fs, new XmlDictionaryReaderQuotas()) ) { var ser = new DataContractSerializer(typeof (ShaderGraph), _serializableTypes, int.MaxValue, false, false, null); var loaded = ser.ReadObject(reader, true) as ShaderGraph; if (loaded != null) { _undoChain = new GraphHistory( _serializableTypes ); _nextGraph = loaded; loaded.Initialize( new Rect(0, 0, Screen.width, Screen.height), true); _lastGraphPath = path; _lastExportPath = ""; didLoad = true; } } } } catch( Exception e ){ Debug.Log( e ); } //Try loading autosave graph (it's in a differnt xml format) try { if( !didLoad ) { using( var fs = new FileStream(path, FileMode.Open) ) { using( var reader = XmlDictionaryReader.CreateTextReader(fs, new XmlDictionaryReaderQuotas()) ) { var ser = new DataContractSerializer(typeof(AutoSaveGraph), _serializableTypes, int.MaxValue, false, false, null); var loaded = ser.ReadObject(reader, true) as AutoSaveGraph; if (loaded != null) { _undoChain = new GraphHistory( _serializableTypes ); _nextGraph = loaded.Graph; _nextGraph.Initialize( new Rect(0, 0, Screen.width, Screen.height), true); _lastGraphPath = ""; _lastExportPath = ""; didLoad = true; } } } } } catch( Exception e) { Debug.Log(e); } if( !didLoad ) { EditorUtility.DisplayDialog("Load Shader Error", "Could not load shader", "Ok"); } } _shouldLoadGraph = false; _shouldUpdateShader = true; _overrideLoadPath = ""; } //Export the shader to a .shader file if (_shouldExportShader) { if (_selectedGraph.IsGraphValid()) { var path = _quickExport ? _lastExportPath : EditorUtility.SaveFilePanel("Export shader to file...", Application.dataPath, "shader.shader", "shader"); _lastExportPath = path; // For quick exporting - Texel if (!string.IsNullOrEmpty(path)) { File.WriteAllText(path, _selectedGraph.GetShader(_shaderTemplatePath, false)); AssetDatabase.Refresh(); // Investigate if this is optimal } InstructionCounter.CountInstructions(); // Update the instruction count CacheCount(); // Solve the tooltip (Cached) } else { EditorUtility.DisplayDialog("Export Shader Error", "Cannot export shader, there are errors in the graph", "Ok"); } _shouldExportShader = false; _quickExport = false; } Repaint(); }