diff options
author | chai <chaifix@163.com> | 2020-10-23 13:08:43 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2020-10-23 13:08:43 +0800 |
commit | b82da95b5181ac8bbae38efb13e950d5e88a4caa (patch) | |
tree | 48a6f3269276484bbc7cfc95f0651f40a2176aa1 /Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu | |
parent | 917e9e0b320775634dc2e710f7deac74fd0822f0 (diff) |
*移动amplify shader editor到third party目录
Diffstat (limited to 'Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu')
58 files changed, 12148 insertions, 0 deletions
diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/AmplifyShaderEditorWindow.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/AmplifyShaderEditorWindow.cs new file mode 100644 index 00000000..8cbfafaf --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/AmplifyShaderEditorWindow.cs @@ -0,0 +1,5945 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using UnityEngine; +using UnityEditor; +using UnityEditor.Callbacks; +using System; +using System.Collections; +using System.Threading; +using System.Globalization; +using System.Collections.Generic; +using UnityEngine.Networking; + +namespace AmplifyShaderEditor +{ + // Disabling Substance Deprecated warning + + public class AmplifyShaderEditorWindow : SearchableEditorWindow, ISerializationCallbackReceiver + { + public const string PreviewSizeGlobalVariable = "_ASEPreviewSize"; + + public const double InactivitySaveTime = 1.0; + + public const string CopyCommand = "Copy"; + public const string PasteCommand = "Paste"; + public const string SelectAll = "SelectAll"; + public const string Duplicate = "Duplicate"; + public const string ObjectSelectorClosed = "ObjectSelectorClosed"; + public const string LiveShaderError = "Live Shader only works with an assigned Master Node on the graph"; + + //public Texture2D MasterNodeOnTexture = null; + //public Texture2D MasterNodeOffTexture = null; + + //public Texture2D GPUInstancedOnTexture = null; + //public Texture2D GPUInstancedOffTexture = null; + + private bool m_initialized = false; + private bool m_checkInvalidConnections = false; + private bool m_afterDeserializeFlag = true; + + + [SerializeField] + private ParentGraph m_customGraph = null; + + // UI + private Rect m_graphArea; + private Texture2D m_graphBgTexture; + private Texture2D m_graphFgTexture; + private GUIStyle m_graphFontStyle; + //private GUIStyle _borderStyle; + private Texture2D m_wireTexture; + + [SerializeField] + TemplatesManager m_templatesManager; + + [SerializeField] + private InnerWindowEditorVariables m_innerEditorVariables; + + [SerializeField] + private string m_lastpath; + + [SerializeField] + private ASESelectionMode m_selectionMode = ASESelectionMode.Shader; + + [SerializeField] + private DuplicatePreventionBuffer m_duplicatePreventionBuffer; + + [SerializeField] + private double m_inactivityTime = 0; + + // Prevent save ops every tick when on live mode + [SerializeField] + private double m_lastTimeSaved = 0; + + [SerializeField] + private bool m_cacheSaveOp = false; + private const double SaveTime = 1; + + private bool m_markedToSave = false; + + // Graph logic + [SerializeField] + private ParentGraph m_mainGraphInstance; + + // Camera control + [SerializeField] + private Vector2 m_cameraOffset; + + private float m_cameraSpeed = 1; + + private Rect m_cameraInfo; + + [SerializeField] + private float m_cameraZoom; + + [SerializeField] + private Vector2 m_minNodePos; + + [SerializeField] + private Vector2 m_maxNodePos; + + [SerializeField] + private bool m_isDirty; + + [SerializeField] + private bool m_saveIsDirty; + + [SerializeField] + private bool m_repaintIsDirty; + + [SerializeField] + private bool m_liveShaderEditing = false; + + [SerializeField] + private bool m_shaderIsModified = false; + + [SerializeField] + private string m_lastOpenedLocation = string.Empty; + + [SerializeField] + private bool m_zoomChanged = true; + + [SerializeField] + private float m_lastWindowWidth = 0; + + [SerializeField] + private int m_graphCount = 0; + + [SerializeField] + private double m_currentInactiveTime = 0; + + private bool m_ctrlSCallback = false; + + private bool m_altBoxSelection = false; + private bool m_altDragStarted = false; + private bool m_altPressDown = false; + private bool m_altAvailable = true; + + // Events + private Vector3 m_currentMousePos; + private Vector2 m_keyEvtMousePos2D; + private Vector2 m_currentMousePos2D; + private Event m_currentEvent; + private string m_currentCommandName = string.Empty; + private bool m_insideEditorWindow; + + private bool m_lostFocus = false; + // Selection box for multiple node selection + private bool m_multipleSelectionActive = false; + private bool m_lmbPressed = false; + private Vector2 m_multipleSelectionStart; + private Rect m_multipleSelectionArea = new Rect( 0, 0, 0, 0 ); + private bool m_autoPanDirActive = false; + private bool m_forceAutoPanDir = false; + private bool m_refreshOnUndo = false; + private bool m_loadShaderOnSelection = false; + private bool m_refreshAvailableNodes = false; + private double m_time; + + //Context Menu + private Vector2 m_rmbStartPos; + private Vector2 m_altKeyStartPos; + private GraphContextMenu m_contextMenu; + private ShortcutsManager m_shortcutManager; + + [SerializeField] + private NodeAvailability m_currentNodeAvailability = NodeAvailability.SurfaceShader; + //Clipboard + private Clipboard m_clipboard; + + //Node Parameters Window + [SerializeField] + private bool m_nodeParametersWindowMaximized = true; + private NodeParametersWindow m_nodeParametersWindow; + + // Tools Window + private ToolsWindow m_toolsWindow; + + private ConsoleLogWindow m_consoleLogWindow; + + //Editor Options + private OptionsWindow m_optionsWindow; + + // Mode Window + private ShaderEditorModeWindow m_modeWindow; + + // Tools Window + private TipsWindow m_tipsWindow; + + //Palette Window + [SerializeField] + private bool m_paletteWindowMaximized = true; + private PaletteWindow m_paletteWindow; + + private ContextPalette m_contextPalette; + private PalettePopUp m_palettePopup; + private System.Type m_paletteChosenType; + private AmplifyShaderFunction m_paletteChosenFunction; + + // In-Editor Message System + GenericMessageUI m_genericMessageUI; + private GUIContent m_genericMessageContent; + + // Drag&Drop Tool + private DragAndDropTool m_dragAndDropTool; + + //Custom Styles + //private CustomStylesContainer m_customStyles; + + private AmplifyShaderFunction m_previousShaderFunction; + + private List<MenuParent> m_registeredMenus; + + private PreMadeShaders m_preMadeShaders; + + private AutoPanData[] m_autoPanArea; + + private DrawInfo m_drawInfo; + private KeyCode m_lastKeyPressed = KeyCode.None; + private System.Type m_commentaryTypeNode; + + private int m_onLoadDone = 0; + + private float m_copyPasteDeltaMul = 0; + private Vector2 m_copyPasteInitialPos = Vector2.zero; + private Vector2 m_copyPasteDeltaPos = Vector2.zero; + + private int m_repaintCount = 0; + private bool m_forceUpdateFromMaterialFlag = false; + + private UnityEngine.Object m_delayedLoadObject = null; + private double m_focusOnSelectionTimestamp; + private double m_focusOnMasterNodeTimestamp; + private double m_wiredDoubleTapTimestamp; + + private bool m_globalPreview = false; + private bool m_globalShowInternalData = true; + + private const double AutoZoomTime = 0.25; + private const double ToggleTime = 0.25; + private const double WiredDoubleTapTime = 0.25; + private const double DoubleClickTime = 0.25; + + private Material m_delayedMaterialSet = null; + + private bool m_mouseDownOnValidArea = false; + + private bool m_removedKeyboardFocus = false; + + private int m_lastHotControl = -1; + + [SerializeField] + private bool m_isShaderFunctionWindow = false; + + private string m_currentTitle = string.Empty; + private bool m_currentTitleMod = false; + + //private Material m_maskingMaterial = null; + //private int m_cachedProjectInLinearId = -1; + private int m_cachedEditorTimeId = -1; + private int m_cachedEditorDeltaTimeId = -1; + //private float m_repaintFrequency = 15; + //private double m_repaintTimestamp = 0; + + // Smooth Zoom + private bool m_smoothZoom = false; + private float m_targetZoom; + private double m_zoomTime; + private Vector2 m_zoomPivot; + private float m_targetZoomIncrement; + private float m_zoomVelocity = 0; + + // Smooth Pan + private bool m_smoothOffset = false; + private double m_offsetTime; + private Vector2 m_targetOffset; + private Vector2 m_camVelocity = Vector2.zero; + + // Auto-Compile samples + private bool m_forcingMaterialUpdateFlag = false; + private bool m_forcingMaterialUpdateOp = false; + private List<Material> m_materialsToUpdate = new List<Material>(); + + private NodeExporterUtils m_nodeExporterUtils; + private bool m_performFullUndoRegister = true; + + [SerializeField] + private AmplifyShaderFunction m_openedShaderFunction; + + [SerializeField] + private bool m_openedAssetFromNode = false; + + private bool m_nodesLoadedCorrectly = false; + private GUIContent NodesExceptionMessage = new GUIContent( "ASE is unable to load correctly due to some faulty other classes/plugin in your project. We advise to review all your imported plugins." ); + + + private bool m_outdatedShaderFromTemplateLoaded = false; + private bool m_replaceMasterNode = false; + private AvailableShaderTypes m_replaceMasterNodeType; + private string m_replaceMasterNodeData; + private bool m_replaceMasterNodeDataFromCache; + private NodeWireReferencesUtils m_wireReferenceUtils = new NodeWireReferencesUtils(); + + private ParentNode m_nodeToFocus = null; + private float m_zoomToFocus = 1.0f; + private bool m_selectNodeToFocus = true; + + [NonSerialized] + public Dictionary<string, bool> VisitedChanged = new Dictionary<string, bool>(); + + [SerializeField] + private List<Toast> m_messages = new List<Toast>(); + + [SerializeField] + private float m_maxMsgWidth = 100; + + [SerializeField] + private bool m_maximizeMessages = false; + + [NonSerialized] + private Dictionary<string, OutputPort> m_savedList = new Dictionary<string, OutputPort>(); + + public int m_frameCounter = 0; + public double m_fpsTime = 0; + public string m_fpsDisplay = string.Empty; + +#if UNITY_EDITOR_WIN + // ScreenShot vars + IntPtr m_aseHandle; + private Rect m_prevWindowRect; + private Vector2 m_prevCameraOffset; + private float m_prevCameraZoom; + private bool m_openSavedFolder = false; + private bool m_takeScreenShot = false; +#endif + public bool CheckFunctions = false; + + // Unity Menu item + [MenuItem( "Window/Amplify Shader Editor/Open Canvas", false, 1000 )] + static void OpenMainShaderGraph() + { + if( IOUtils.AllOpenedWindows.Count > 0 ) + { + AmplifyShaderEditorWindow currentWindow = CreateTab( "Empty", UIUtils.ShaderIcon ); + UIUtils.CurrentWindow = currentWindow; + currentWindow.CreateNewGraph( "Empty" ); + currentWindow.Show(); + } + else + { + AmplifyShaderEditorWindow currentWindow = OpenWindow( "Empty", UIUtils.ShaderIcon ); + currentWindow.CreateNewGraph( "Empty" ); + //currentWindow.Show(); + } + } + + public static string GenerateTabTitle( string original, bool modified = false ) + { + GUIContent content = new GUIContent( original ); + GUIStyle tabStyle = new GUIStyle( (GUIStyle)"dragtabdropwindow" );// GUI.skin.FindStyle( "dragtabdropwindow" ); + string finalTitle = string.Empty; + bool addEllipsis = false; + for( int i = 1; i <= original.Length; i++ ) + { + content.text = original.Substring( 0, i ); + Vector2 titleSize = tabStyle.CalcSize( content ); + int maxSize = modified ? 62 : 69; + if( titleSize.x > maxSize ) + { + addEllipsis = true; + break; + } + else + { + finalTitle = content.text; + } + } + if( addEllipsis ) + finalTitle += ".."; + if( modified ) + finalTitle += "*"; + return finalTitle; + } + + public static void ConvertShaderToASE( Shader shader ) + { + if( UIUtils.IsUnityNativeShader( shader ) ) + { + Debug.LogWarningFormat( "Action not allowed. Attempting to load the native {0} shader into Amplify Shader Editor", shader.name ); + return; + } + + string guid = AssetDatabase.AssetPathToGUID( AssetDatabase.GetAssetPath( shader ) ); + if( IOUtils.AllOpenedWindows.Count > 0 ) + { + AmplifyShaderEditorWindow openedTab = null; + for( int i = 0; i < IOUtils.AllOpenedWindows.Count; i++ ) + { + //if( AssetDatabase.GetAssetPath( shader ).Equals( IOUtils.AllOpenedWindows[ i ].LastOpenedLocation ) ) + if( guid.Equals( IOUtils.AllOpenedWindows[ i ].GUID ) ) + { + openedTab = IOUtils.AllOpenedWindows[ i ]; + break; + } + } + + if( openedTab != null ) + { + openedTab.wantsMouseMove = true; + openedTab.ShowTab(); + UIUtils.CurrentWindow = openedTab; + } + else + { + EditorWindow openedWindow = AmplifyShaderEditorWindow.GetWindow<AmplifyShaderEditorWindow>(); + AmplifyShaderEditorWindow currentWindow = CreateTab(); + WindowHelper.AddTab( openedWindow, currentWindow ); + UIUtils.CurrentWindow = currentWindow; + } + } + else + { + AmplifyShaderEditorWindow currentWindow = OpenWindow( shader.name, UIUtils.ShaderIcon ); + UIUtils.CurrentWindow = currentWindow; + } + + if( IOUtils.IsASEShader( shader ) ) + { + UIUtils.CurrentWindow.LoadProjectSelected( shader ); + } + else + { + UIUtils.CreateEmptyFromInvalid( shader ); + UIUtils.ShowMessage( "Trying to open shader not created on ASE!\nBEWARE, old data will be lost if saving it here!", MessageSeverity.Warning ); + if( UIUtils.CurrentWindow.LiveShaderEditing ) + { + UIUtils.ShowMessage( "Disabling Live Shader Editing. Must manually re-enable it.", MessageSeverity.Warning ); + UIUtils.CurrentWindow.LiveShaderEditing = false; + } + } + } + + public static void LoadMaterialToASE( Material material ) + { + string guid = AssetDatabase.AssetPathToGUID( AssetDatabase.GetAssetPath( material.shader ) ); + + if( IOUtils.AllOpenedWindows.Count > 0 ) + { + AmplifyShaderEditorWindow openedTab = null; + for( int i = 0; i < IOUtils.AllOpenedWindows.Count; i++ ) + { + //if( AssetDatabase.GetAssetPath( material.shader ).Equals( IOUtils.AllOpenedWindows[ i ].LastOpenedLocation ) ) + if( guid.Equals( IOUtils.AllOpenedWindows[ i ].GUID ) ) + { + openedTab = IOUtils.AllOpenedWindows[ i ]; + break; + } + } + + if( openedTab != null ) + { + openedTab.wantsMouseMove = true; + openedTab.ShowTab(); + UIUtils.CurrentWindow = openedTab; + } + else + { + EditorWindow openedWindow = AmplifyShaderEditorWindow.GetWindow<AmplifyShaderEditorWindow>(); + AmplifyShaderEditorWindow currentWindow = CreateTab(); + WindowHelper.AddTab( openedWindow, currentWindow ); + UIUtils.CurrentWindow = currentWindow; + } + } + else + { + AmplifyShaderEditorWindow currentWindow = OpenWindow( material.name, UIUtils.MaterialIcon ); + UIUtils.CurrentWindow = currentWindow; + } + + if( IOUtils.IsASEShader( material.shader ) ) + { + UIUtils.CurrentWindow.LoadProjectSelected( material ); + } + else + { + UIUtils.CreateEmptyFromInvalid( material.shader ); + UIUtils.SetDelayedMaterialMode( material ); + } + } + + public static void LoadShaderFunctionToASE( AmplifyShaderFunction shaderFunction, bool openedAssetFromNode ) + { + string guid = AssetDatabase.AssetPathToGUID( AssetDatabase.GetAssetPath( shaderFunction ) ); + + if( IOUtils.AllOpenedWindows.Count > 0 ) + { + AmplifyShaderEditorWindow openedTab = null; + for( int i = 0; i < IOUtils.AllOpenedWindows.Count; i++ ) + { + //if( AssetDatabase.GetAssetPath( shaderFunction ).Equals( IOUtils.AllOpenedWindows[ i ].LastOpenedLocation ) ) + if( guid.Equals( IOUtils.AllOpenedWindows[ i ].GUID ) ) + { + openedTab = IOUtils.AllOpenedWindows[ i ]; + break; + } + } + + if( openedTab != null ) + { + openedTab.wantsMouseMove = true; + openedTab.ShowTab(); + UIUtils.CurrentWindow = openedTab; + } + else + { + EditorWindow openedWindow = AmplifyShaderEditorWindow.GetWindow<AmplifyShaderEditorWindow>(); + AmplifyShaderEditorWindow currentWindow = CreateTab(); + WindowHelper.AddTab( openedWindow, currentWindow ); + UIUtils.CurrentWindow = currentWindow; + } + } + else + { + AmplifyShaderEditorWindow currentWindow = OpenWindow( shaderFunction.FunctionName, UIUtils.ShaderFunctionIcon ); + UIUtils.CurrentWindow = currentWindow; + } + + UIUtils.CurrentWindow.OpenedAssetFromNode = openedAssetFromNode; + if( IOUtils.IsShaderFunction( shaderFunction.FunctionInfo ) ) + { + UIUtils.CurrentWindow.LoadProjectSelected( shaderFunction ); + } + else + { + UIUtils.CurrentWindow.titleContent.text = GenerateTabTitle( shaderFunction.FunctionName ); + UIUtils.CurrentWindow.titleContent.image = UIUtils.ShaderFunctionIcon; + UIUtils.CreateEmptyFunction( shaderFunction ); + } + } + + public static AmplifyShaderEditorWindow OpenWindow( string title = null, Texture icon = null ) + { + AmplifyShaderEditorWindow currentWindow = (AmplifyShaderEditorWindow)AmplifyShaderEditorWindow.GetWindow( typeof( AmplifyShaderEditorWindow ), false ); + currentWindow.minSize = new Vector2( ( Constants.MINIMIZE_WINDOW_LOCK_SIZE - 150 ), 270 ); + currentWindow.wantsMouseMove = true; + if( title != null ) + currentWindow.titleContent.text = GenerateTabTitle( title ); + if( icon != null ) + currentWindow.titleContent.image = icon; + return currentWindow; + } + + public static AmplifyShaderEditorWindow CreateTab( string title = null, Texture icon = null ) + { + AmplifyShaderEditorWindow currentWindow = EditorWindow.CreateInstance<AmplifyShaderEditorWindow>(); + currentWindow.minSize = new Vector2( ( Constants.MINIMIZE_WINDOW_LOCK_SIZE - 150 ), 270 ); + currentWindow.wantsMouseMove = true; + if( title != null ) + currentWindow.titleContent.text = GenerateTabTitle( title ); + if( icon != null ) + currentWindow.titleContent.image = icon; + return currentWindow; + } + + public double CalculateInactivityTime() + { + double currTime = EditorApplication.timeSinceStartup; + switch( Event.current.type ) + { + case EventType.MouseDown: + case EventType.MouseUp: + //case EventType.MouseMove: + case EventType.MouseDrag: + case EventType.KeyDown: + case EventType.KeyUp: + case EventType.ScrollWheel: + case EventType.DragUpdated: + case EventType.DragPerform: + case EventType.DragExited: + case EventType.ValidateCommand: + case EventType.ExecuteCommand: + { + m_inactivityTime = currTime; + return 0; + } + } + return currTime - m_inactivityTime; + } + + + // Shader Graph window + public override void OnEnable() + { + base.OnEnable(); + + Preferences.LoadDefaults(); + +#if UNITY_2018_3_OR_NEWER + ASEPackageManagerHelper.RequestInfo(); + ASEPackageManagerHelper.Update(); +#endif + + Shader.SetGlobalVector( PreviewSizeGlobalVariable, new Vector4( ParentNode.PreviewWidth, ParentNode.PreviewHeight, 0, 0 ) ); + + if( m_templatesManager == null ) + { + m_templatesManager = IOUtils.FirstValidTemplatesManager; + if( m_templatesManager == null ) + { + m_templatesManager = ScriptableObject.CreateInstance<TemplatesManager>(); + m_templatesManager.Init(); + if( TemplatesManager.ShowDebugMessages ) + Debug.Log( "Creating Manager" ); + } + else + { + if( TemplatesManager.ShowDebugMessages ) + Debug.Log( "Assigning Manager" ); + } + } + else if( !m_templatesManager.Initialized ) + { + if( TemplatesManager.ShowDebugMessages ) + Debug.Log( "Re-Initializing Manager" ); + m_templatesManager.Init(); + } + TemplatePostProcessor.Destroy(); + if( m_innerEditorVariables == null ) + { + m_innerEditorVariables = new InnerWindowEditorVariables(); + m_innerEditorVariables.Initialize(); + } + + if( m_mainGraphInstance == null ) + { + m_mainGraphInstance = CreateInstance<ParentGraph>(); + m_mainGraphInstance.Init(); + m_mainGraphInstance.ParentWindow = this; + m_mainGraphInstance.SetGraphId( 0 ); + } + m_mainGraphInstance.ResetEvents(); + m_mainGraphInstance.OnNodeEvent += OnNodeStoppedMovingEvent; + m_mainGraphInstance.OnMaterialUpdatedEvent += OnMaterialUpdated; + m_mainGraphInstance.OnShaderUpdatedEvent += OnShaderUpdated; + m_mainGraphInstance.OnEmptyGraphDetectedEvt += OnEmptyGraphDetected; + m_mainGraphInstance.OnNodeRemovedEvent += m_toolsWindow.OnNodeRemovedFromGraph; + GraphCount = 1; + + IOUtils.Init(); + IOUtils.AllOpenedWindows.Add( this ); + + // Only runs once for multiple windows + EditorApplication.update -= IOUtils.UpdateIO; + EditorApplication.update += IOUtils.UpdateIO; + + //EditorApplication.update -= UpdateTime; + EditorApplication.update -= UpdateNodePreviewListAndTime; + //EditorApplication.update += UpdateTime; + + EditorApplication.update += UpdateNodePreviewListAndTime; + + + if( CurrentSelection == ASESelectionMode.ShaderFunction ) + { + IsShaderFunctionWindow = true; + } + else + { + IsShaderFunctionWindow = false; + } + + m_optionsWindow = new OptionsWindow( this ); + m_optionsWindow.Init(); + + m_contextMenu = new GraphContextMenu( m_mainGraphInstance ); + m_nodesLoadedCorrectly = m_contextMenu.CorrectlyLoaded; + + m_paletteWindow = new PaletteWindow( this ) + { + Resizable = true + }; + m_paletteWindow.OnPaletteNodeCreateEvt += OnPaletteNodeCreate; + m_registeredMenus.Add( m_paletteWindow ); + + m_contextPalette = new ContextPalette( this ); + m_contextPalette.OnPaletteNodeCreateEvt += OnContextPaletteNodeCreate; + m_registeredMenus.Add( m_contextPalette ); + + m_genericMessageUI = new GenericMessageUI(); + m_genericMessageUI.OnMessageDisplayEvent += ShowMessageImmediately; + + Selection.selectionChanged += OnProjectSelectionChanged; +#if UNITY_2018_1_OR_NEWER + EditorApplication.projectChanged += OnProjectWindowChanged; +#else + EditorApplication.projectWindowChanged += OnProjectWindowChanged; +#endif + m_focusOnSelectionTimestamp = EditorApplication.timeSinceStartup; + m_focusOnMasterNodeTimestamp = EditorApplication.timeSinceStartup; + + m_nodeParametersWindow.IsMaximized = m_innerEditorVariables.NodeParametersMaximized; + if( DebugConsoleWindow.UseShaderPanelsInfo ) + m_nodeParametersWindow.IsMaximized = m_nodeParametersWindowMaximized; + + m_paletteWindow.IsMaximized = m_innerEditorVariables.NodePaletteMaximized; + if( DebugConsoleWindow.UseShaderPanelsInfo ) + m_paletteWindow.IsMaximized = m_paletteWindowMaximized; + + m_shortcutManager = new ShortcutsManager(); + // REGISTER NODE SHORTCUTS + foreach( KeyValuePair<KeyCode, ShortcutKeyData> kvp in m_contextMenu.NodeShortcuts ) + { + m_shortcutManager.RegisterNodesShortcuts( kvp.Key, kvp.Value.Name ); + } + + // REGISTER EDITOR SHORTCUTS + + m_shortcutManager.RegisterEditorShortcut( true, EventModifiers.FunctionKey, KeyCode.F1, "Open Selected Node Wiki page", () => + { + List<ParentNode> selectedNodes = m_mainGraphInstance.SelectedNodes; + if( selectedNodes != null && selectedNodes.Count == 1 ) + { + Application.OpenURL( selectedNodes[ 0 ].Attributes.NodeUrl ); + } + } ); + + + m_shortcutManager.RegisterEditorShortcut( true, KeyCode.C, "Create Commentary", () => + { + // Create commentary + ParentNode[] selectedNodes = m_mainGraphInstance.SelectedNodes.ToArray(); + UIUtils.MarkUndoAction(); + Undo.RegisterCompleteObjectUndo( this, "Adding Commentary Node" ); + CommentaryNode node = m_mainGraphInstance.CreateNode( m_commentaryTypeNode, true, -1, false ) as CommentaryNode; + node.CreateFromSelectedNodes( TranformedMousePos, selectedNodes ); + node.Focus(); + m_mainGraphInstance.DeSelectAll(); + m_mainGraphInstance.SelectNode( node, false, false ); + SetSaveIsDirty(); + ForceRepaint(); + } ); + + + m_shortcutManager.RegisterEditorShortcut( true, KeyCode.F, "Focus On Selection", () => + { + OnToolButtonPressed( ToolButtonType.FocusOnSelection ); + ForceRepaint(); + } ); + + //m_shortcutManager.RegisterEditorShortcut( true, EventModifiers.None, KeyCode.B, "New Master Node", () => + //{ + // OnToolButtonPressed( ToolButtonType.MasterNode ); + // ForceRepaint(); + //} ); + + m_shortcutManager.RegisterEditorShortcut( true, EventModifiers.None, KeyCode.Space, "Open Node Palette", null, () => + { + m_contextPalette.Show( m_currentMousePos2D, m_cameraInfo ); + } ); + + + m_shortcutManager.RegisterEditorShortcut( true, KeyCode.W, "Toggle Colored Line Mode", () => + { + m_optionsWindow.ColoredPorts = !m_optionsWindow.ColoredPorts; + ForceRepaint(); + + } ); + + m_shortcutManager.RegisterEditorShortcut( true, EventModifiers.Control, KeyCode.W, "Toggle Multi-Line Mode", () => + { + m_optionsWindow.MultiLinePorts = !m_optionsWindow.MultiLinePorts; + ForceRepaint(); + } ); + + m_shortcutManager.RegisterEditorShortcut( true, KeyCode.P, "Global Preview", () => + { + GlobalPreview = !GlobalPreview; + EditorPrefs.SetBool( "GlobalPreview", GlobalPreview ); + + ForceRepaint(); + } ); + + GlobalShowInternalData = EditorPrefs.GetBool( "ASEGlobalShowInternalData", true ); + m_shortcutManager.RegisterEditorShortcut( true, KeyCode.I, "Global Show Internal Data", () => + { + GlobalShowInternalData = !GlobalShowInternalData; + EditorPrefs.SetBool( "ASEGlobalShowInternalData", GlobalShowInternalData ); + ForceRepaint(); + } ); + + m_shortcutManager.RegisterEditorShortcut( true, EventModifiers.FunctionKey, KeyCode.Delete, "Delete selected nodes", DeleteSelectedNodeWithRepaint ); + m_shortcutManager.RegisterEditorShortcut( true, EventModifiers.FunctionKey, KeyCode.Backspace, "Delete selected nodes", DeleteSelectedNodeWithRepaint ); + + m_liveShaderEditing = m_innerEditorVariables.LiveMode; + + UpdateLiveUI(); + } + + + public AmplifyShaderEditorWindow() + { + m_minNodePos = new Vector2( float.MaxValue, float.MaxValue ); + m_maxNodePos = new Vector2( float.MinValue, float.MinValue ); + + m_duplicatePreventionBuffer = new DuplicatePreventionBuffer(); + m_commentaryTypeNode = typeof( CommentaryNode ); + titleContent = new GUIContent( "Shader Editor" ); + autoRepaintOnSceneChange = true; + + m_currentMousePos = new Vector3( 0, 0, 0 ); + m_keyEvtMousePos2D = new Vector2( 0, 0 ); + m_multipleSelectionStart = new Vector2( 0, 0 ); + m_initialized = false; + m_graphBgTexture = null; + m_graphFgTexture = null; + + m_cameraOffset = new Vector2( 0, 0 ); + CameraZoom = 1; + + m_registeredMenus = new List<MenuParent>(); + + m_nodeParametersWindow = new NodeParametersWindow( this ) + { + Resizable = true + }; + m_registeredMenus.Add( m_nodeParametersWindow ); + + m_modeWindow = new ShaderEditorModeWindow( this ); + //_registeredMenus.Add( _modeWindow ); + + m_toolsWindow = new ToolsWindow( this ); + m_toolsWindow.ToolButtonPressedEvt += OnToolButtonPressed; + + m_consoleLogWindow = new ConsoleLogWindow( this ); + + m_tipsWindow = new TipsWindow( this ); + + m_registeredMenus.Add( m_toolsWindow ); + //m_registeredMenus.Add( m_consoleLogWindow ); + + m_palettePopup = new PalettePopUp(); + + m_clipboard = new Clipboard(); + + m_genericMessageContent = new GUIContent(); + m_dragAndDropTool = new DragAndDropTool(); + m_dragAndDropTool.OnValidDropObjectEvt += OnValidObjectsDropped; + + //_confirmationWindow = new ConfirmationWindow( 100, 100, 300, 100 ); + + m_saveIsDirty = false; + + m_preMadeShaders = new PreMadeShaders(); + + Undo.undoRedoPerformed += UndoRedoPerformed; + + float autoPanSpeed = 2; + m_autoPanArea = new AutoPanData[ 4 ]; + m_autoPanArea[ 0 ] = new AutoPanData( AutoPanLocation.TOP, 25, autoPanSpeed * Vector2.up ); + m_autoPanArea[ 1 ] = new AutoPanData( AutoPanLocation.BOTTOM, 25, autoPanSpeed * Vector2.down ); + m_autoPanArea[ 2 ] = new AutoPanData( AutoPanLocation.LEFT, 25, autoPanSpeed * Vector2.right ); + m_autoPanArea[ 3 ] = new AutoPanData( AutoPanLocation.RIGHT, 25, autoPanSpeed * Vector2.left ); + + m_drawInfo = new DrawInfo(); + UIUtils.CurrentWindow = this; + + m_nodeExporterUtils = new NodeExporterUtils( this ); + m_repaintIsDirty = false; + m_initialized = false; + } + + public void SetStandardShader() + { + m_mainGraphInstance.ReplaceMasterNode( AvailableShaderTypes.SurfaceShader ); + m_mainGraphInstance.FireMasterNodeReplacedEvent(); + } + + public void SetTemplateShader( string templateName, bool writeDefaultData ) + { + TemplateDataParent templateData = m_templatesManager.GetTemplate( ( string.IsNullOrEmpty( templateName ) ? "6e114a916ca3e4b4bb51972669d463bf" : templateName ) ); + m_mainGraphInstance.ReplaceMasterNode( AvailableShaderTypes.Template, writeDefaultData, templateData ); + } + + public void DeleteSelectedNodeWithRepaint() + { + DeleteSelectedNodes(); + SetSaveIsDirty(); + } + + + void UndoRedoPerformed() + { + m_repaintIsDirty = true; + m_saveIsDirty = true; + m_removedKeyboardFocus = true; + m_refreshOnUndo = true; + } + + void Destroy() + { + Undo.ClearUndo( this ); + + m_initialized = false; + + m_nodeExporterUtils.Destroy(); + m_nodeExporterUtils = null; + + m_delayedMaterialSet = null; + + m_materialsToUpdate.Clear(); + m_materialsToUpdate = null; + + GLDraw.Destroy(); + + UIUtils.Destroy(); + m_preMadeShaders.Destroy(); + m_preMadeShaders = null; + + m_registeredMenus.Clear(); + m_registeredMenus = null; + + m_mainGraphInstance.Destroy(); + ScriptableObject.DestroyImmediate( m_mainGraphInstance ); + m_mainGraphInstance = null; + + Resources.UnloadAsset( m_graphBgTexture ); + m_graphBgTexture = null; + + Resources.UnloadAsset( m_graphFgTexture ); + m_graphFgTexture = null; + + Resources.UnloadAsset( m_wireTexture ); + m_wireTexture = null; + + m_contextMenu.Destroy(); + m_contextMenu = null; + + m_shortcutManager.Destroy(); + m_shortcutManager = null; + + m_nodeParametersWindow.Destroy(); + m_nodeParametersWindow = null; + + + m_modeWindow.Destroy(); + m_modeWindow = null; + + m_toolsWindow.Destroy(); + m_toolsWindow = null; + + m_consoleLogWindow.Destroy(); + m_consoleLogWindow = null; + + m_tipsWindow.Destroy(); + m_tipsWindow = null; + + m_optionsWindow.Destroy(); + m_optionsWindow = null; + + m_paletteWindow.Destroy(); + m_paletteWindow = null; + + m_palettePopup.Destroy(); + m_palettePopup = null; + + m_contextPalette.Destroy(); + m_contextPalette = null; + + m_clipboard.ClearClipboard(); + m_clipboard = null; + + m_genericMessageUI.Destroy(); + m_genericMessageUI = null; + m_genericMessageContent = null; + + m_dragAndDropTool.Destroy(); + m_dragAndDropTool = null; + + m_openedShaderFunction = null; + + UIUtils.CurrentWindow = null; + m_duplicatePreventionBuffer.ReleaseAllData(); + m_duplicatePreventionBuffer = null; +#if UNITY_2018_1_OR_NEWER + EditorApplication.projectChanged -= OnProjectWindowChanged; +#else + EditorApplication.projectWindowChanged -= OnProjectWindowChanged; +#endif + Selection.selectionChanged -= OnProjectSelectionChanged; + + IOUtils.AllOpenedWindows.Remove( this ); + + if( IOUtils.AllOpenedWindows.Count == 0 ) + { + m_templatesManager.Destroy(); + ScriptableObject.DestroyImmediate( m_templatesManager ); + } + m_templatesManager = null; + + IOUtils.Destroy(); + + Resources.UnloadUnusedAssets(); + GC.Collect(); + } + + void Init() + { + // = AssetDatabase.LoadAssetAtPath( Constants.ASEPath + "", typeof( Texture2D ) ) as Texture2D; + m_graphBgTexture = AssetDatabase.LoadAssetAtPath( AssetDatabase.GUIDToAssetPath( IOUtils.GraphBgTextureGUID ), typeof( Texture2D ) ) as Texture2D; + if( m_graphBgTexture != null ) + { + m_graphFgTexture = AssetDatabase.LoadAssetAtPath( AssetDatabase.GUIDToAssetPath( IOUtils.GraphFgTextureGUID ), typeof( Texture2D ) ) as Texture2D; + + //Setup usable area + m_cameraInfo = position; + m_graphArea = new Rect( 0, 0, m_cameraInfo.width, m_cameraInfo.height ); + + // Creating style state to show current selected object + m_graphFontStyle = new GUIStyle() + { + fontSize = 32, + alignment = TextAnchor.MiddleCenter, + fixedWidth = m_cameraInfo.width, + fixedHeight = 50, + stretchWidth = true, + stretchHeight = true + }; + m_graphFontStyle.normal.textColor = Color.white; + + m_wireTexture = AssetDatabase.LoadAssetAtPath( AssetDatabase.GUIDToAssetPath( IOUtils.WireTextureGUID ), typeof( Texture2D ) ) as Texture2D; + + m_initialized = m_graphBgTexture != null && + m_graphFgTexture != null && + m_wireTexture != null; + } + } +#if UNITY_2018_3_OR_NEWER + + +#endif + [OnOpenAssetAttribute()] + static bool OnOpenAsset( int instanceID, int line ) + { + if( line > -1 ) + { + return false; + } + Preferences.LoadDefaults(); +#if UNITY_2018_3_OR_NEWER + ASEPackageManagerHelper.RequestInfo(); + ASEPackageManagerHelper.Update(); + if( ASEPackageManagerHelper.IsProcessing ) + { + Shader selectedShader = Selection.activeObject as Shader; + if( selectedShader != null ) + { + if( IOUtils.IsASEShader( selectedShader ) ) + { + ASEPackageManagerHelper.SetupLateShader( selectedShader ); + return true; + } + } + else + { + Material mat = Selection.activeObject as Material; + if( mat != null ) + { + if( IOUtils.IsASEShader( mat.shader ) ) + { + ASEPackageManagerHelper.SetupLateMaterial( mat ); + return true; + } + } + else + { + AmplifyShaderFunction shaderFunction = Selection.activeObject as AmplifyShaderFunction; + if( shaderFunction != null ) + { + if( IOUtils.IsShaderFunction( shaderFunction.FunctionInfo ) ) + { + ASEPackageManagerHelper.SetupLateShaderFunction( shaderFunction ); + return true; + } + } + } + } + } + else +#endif + { + Shader selectedShader = Selection.activeObject as Shader; + if( selectedShader != null ) + { + if( IOUtils.IsASEShader( selectedShader ) ) + { + ConvertShaderToASE( selectedShader ); + return true; + } + } + else + { + Material mat = Selection.activeObject as Material; + if( mat != null ) + { + if( IOUtils.IsASEShader( mat.shader ) ) + { + LoadMaterialToASE( mat ); + return true; + } + } + else + { + AmplifyShaderFunction shaderFunction = Selection.activeObject as AmplifyShaderFunction; + if( shaderFunction != null ) + { + if( IOUtils.IsShaderFunction( shaderFunction.FunctionInfo ) ) + { + LoadShaderFunctionToASE( shaderFunction, false ); + return true; + } + } + } + } + } + + return false; + } + + [MenuItem( "Assets/Create/Amplify Shader/Surface", false, 84 )] + [MenuItem( "Assets/Create/Shader/Amplify Surface Shader" )] + static void CreateConfirmationStandardShader() + { + string path = AssetDatabase.GetAssetPath( Selection.activeObject ); + if( path == "" ) + { + path = "Assets"; + } + else if( System.IO.Path.GetExtension( path ) != "" ) + { + path = path.Replace( System.IO.Path.GetFileName( AssetDatabase.GetAssetPath( Selection.activeObject ) ), "" ); + } + + string assetPathAndName = AssetDatabase.GenerateUniqueAssetPath( path + "/New Amplify Shader.shader" ); + var endNameEditAction = ScriptableObject.CreateInstance<DoCreateStandardShader>(); + ProjectWindowUtil.StartNameEditingIfProjectWindowExists( 0, endNameEditAction, assetPathAndName, AssetPreview.GetMiniTypeThumbnail( typeof( Shader ) ), null ); + } + //static void CreateNewShader( ) + //{ + // CreateNewShader( null, null ); + //} + + static void CreateNewShader( string customPath , string customShaderName ) + { + + string path = string.Empty; + if( string.IsNullOrEmpty( customPath ) ) + { + if( Selection.activeObject != null ) + { + path = ( IOUtils.dataPath + AssetDatabase.GetAssetPath( Selection.activeObject ) ); + } + else + { + UnityEngine.Object[] selection = Selection.GetFiltered( typeof( UnityEngine.Object ), SelectionMode.DeepAssets ); + if( selection.Length > 0 && selection[ 0 ] != null ) + { + path = ( IOUtils.dataPath + AssetDatabase.GetAssetPath( selection[ 0 ] ) ); + } + else + { + path = Application.dataPath; + } + + } + + if( path.IndexOf( '.' ) > -1 ) + { + path = path.Substring( 0, path.LastIndexOf( '/' ) ); + } + path += "/"; + } + else + { + path = customPath; + } + + if( IOUtils.AllOpenedWindows.Count > 0 ) + { + EditorWindow openedWindow = AmplifyShaderEditorWindow.GetWindow<AmplifyShaderEditorWindow>(); + AmplifyShaderEditorWindow currentWindow = CreateTab(); + WindowHelper.AddTab( openedWindow, currentWindow ); + UIUtils.CurrentWindow = currentWindow; + Shader shader = UIUtils.CreateNewEmpty( path, customShaderName ); + Selection.activeObject = shader; + } + else + { + AmplifyShaderEditorWindow currentWindow = OpenWindow(); + UIUtils.CurrentWindow = currentWindow; + Shader shader = UIUtils.CreateNewEmpty( path, customShaderName ); + Selection.activeObject = shader; + } + //Selection.objects = new UnityEngine.Object[] { shader }; + } + + public static void CreateConfirmationTemplateShader( string templateGuid ) + { + UIUtils.NewTemplateGUID = templateGuid; + string path = AssetDatabase.GetAssetPath( Selection.activeObject ); + if( path == "" ) + { + path = "Assets"; + } + else if( System.IO.Path.GetExtension( path ) != "" ) + { + path = path.Replace( System.IO.Path.GetFileName( AssetDatabase.GetAssetPath( Selection.activeObject ) ), "" ); + } + + string assetPathAndName = AssetDatabase.GenerateUniqueAssetPath( path + "/New Amplify Shader.shader" ); + var endNameEditAction = ScriptableObject.CreateInstance<DoCreateTemplateShader>(); + ProjectWindowUtil.StartNameEditingIfProjectWindowExists( 0, endNameEditAction, assetPathAndName, AssetPreview.GetMiniTypeThumbnail( typeof( Shader ) ), null ); + } + + public static Shader CreateNewTemplateShader( string templateGUID , string customPath = null, string customShaderName = null ) + { + string path = string.Empty; + if( string.IsNullOrEmpty( customPath ) ) + { + path = Selection.activeObject == null ? Application.dataPath : ( IOUtils.dataPath + AssetDatabase.GetAssetPath( Selection.activeObject ) ); + if( path.IndexOf( '.' ) > -1 ) + { + path = path.Substring( 0, path.LastIndexOf( '/' ) ); + } + path += "/"; + } + else + { + path = customPath; + } + Shader shader = null; + if( IOUtils.AllOpenedWindows.Count > 0 ) + { + EditorWindow openedWindow = AmplifyShaderEditorWindow.GetWindow<AmplifyShaderEditorWindow>(); + AmplifyShaderEditorWindow currentWindow = CreateTab(); + WindowHelper.AddTab( openedWindow, currentWindow ); + UIUtils.CurrentWindow = currentWindow; + shader = UIUtils.CreateNewEmptyTemplate( templateGUID, path, customShaderName ); + Selection.activeObject = shader; + } + else + { + AmplifyShaderEditorWindow currentWindow = OpenWindow(); + UIUtils.CurrentWindow = currentWindow; + shader = UIUtils.CreateNewEmptyTemplate( templateGUID, path, customShaderName ); + Selection.activeObject = shader; + } + + //Selection.objects = new UnityEngine.Object[] { shader }; + return shader; + } + + [MenuItem( "Assets/Create/Amplify Shader Function", false, 84 )] + [MenuItem( "Assets/Create/Shader/Amplify Shader Function" )] + static void CreateNewShaderFunction() + { + AmplifyShaderFunction asset = ScriptableObject.CreateInstance<AmplifyShaderFunction>(); + + string path = AssetDatabase.GetAssetPath( Selection.activeObject ); + if( path == "" ) + { + path = "Assets"; + } + else if( System.IO.Path.GetExtension( path ) != "" ) + { + path = path.Replace( System.IO.Path.GetFileName( AssetDatabase.GetAssetPath( Selection.activeObject ) ), "" ); + } + + string assetPathAndName = AssetDatabase.GenerateUniqueAssetPath( path + "/New ShaderFunction.asset" ); + + var endNameEditAction = ScriptableObject.CreateInstance<DoCreateFunction>(); + ProjectWindowUtil.StartNameEditingIfProjectWindowExists( asset.GetInstanceID(), endNameEditAction, assetPathAndName, AssetPreview.GetMiniThumbnail( asset ), null ); + } + + public void UpdateTabTitle( string newTitle, bool modified ) + { + string[] titleArray = newTitle.Split( '/' ); + newTitle = titleArray[ titleArray.Length - 1 ]; + + if( !( m_currentTitle.Equals( newTitle ) && m_currentTitleMod == modified ) ) + { + this.titleContent.text = GenerateTabTitle( newTitle, modified ); + } + m_currentTitle = newTitle; + m_currentTitleMod = modified; + } + + public void OnProjectWindowChanged() + { + Shader selectedShader = Selection.activeObject as Shader; + if( selectedShader != null ) + { + if( m_mainGraphInstance != null && m_mainGraphInstance.CurrentMasterNode != null && selectedShader == m_mainGraphInstance.CurrentMasterNode.CurrentShader ) + { + m_lastOpenedLocation = AssetDatabase.GetAssetPath( selectedShader ); + } + } + } + + public void LoadProjectSelected( UnityEngine.Object selectedObject = null ) + { + bool hasFocus = true; + if( EditorWindow.focusedWindow != this ) + { + hasFocus = false; + } + + if( hasFocus && m_mainGraphInstance != null && m_mainGraphInstance.CurrentMasterNode != null ) + { + LoadObject( selectedObject ?? Selection.activeObject ); + } + else + { + m_delayedLoadObject = selectedObject ?? Selection.activeObject; + } + + if( !hasFocus ) + Focus(); + } + + public void LoadObject( UnityEngine.Object objToLoad ) + { + Shader selectedShader = objToLoad as Shader; + Material selectedMaterial = objToLoad as Material; + AmplifyShaderFunction selectedFunction = objToLoad as AmplifyShaderFunction; + + if( selectedFunction != null ) + { + IsShaderFunctionWindow = true; + m_mainGraphInstance.CurrentCanvasMode = NodeAvailability.ShaderFunction; + } + else + { + IsShaderFunctionWindow = false; + } + + ASESelectionMode selectedFileType = ASESelectionMode.Shader; + if( selectedShader != null ) + { + selectedFileType = ASESelectionMode.Shader; + } + else if( selectedMaterial != null ) + { + selectedFileType = ASESelectionMode.Material; + } + else if( selectedFunction != null ) + { + selectedFileType = ASESelectionMode.ShaderFunction; + } + + + switch( CurrentSelection ) + { + case ASESelectionMode.Shader: + { + if( ShaderIsModified ) + { + Shader currShader = m_mainGraphInstance.CurrentMasterNode.CurrentShader; + bool savePrevious = UIUtils.DisplayDialog( AssetDatabase.GetAssetPath( currShader ) ); + OnSaveShader( savePrevious, currShader, null, null ); + } + } + break; + case ASESelectionMode.Material: + { + if( ShaderIsModified ) + { + Shader currShader = m_mainGraphInstance.CurrentMasterNode.CurrentShader; + bool savePrevious = UIUtils.DisplayDialog( AssetDatabase.GetAssetPath( currShader ) ); + OnSaveShader( savePrevious, currShader, m_mainGraphInstance.CurrentMasterNode.CurrentMaterial, null ); + } + } + break; + case ASESelectionMode.ShaderFunction: + { + if( ShaderIsModified ) + { + bool savePrevious = UIUtils.DisplayDialog( AssetDatabase.GetAssetPath( m_openedShaderFunction ) ); + OnSaveShader( savePrevious, null, null, selectedFunction ); + } + } + break; + } + + switch( selectedFileType ) + { + case ASESelectionMode.Shader: + { + LoadDroppedObject( true, selectedShader, null ); + } + break; + case ASESelectionMode.Material: + { + LoadDroppedObject( true, selectedMaterial.shader, selectedMaterial ); + } + break; + case ASESelectionMode.ShaderFunction: + { + LoadDroppedObject( true, null, null, selectedFunction ); + } + break; + } + + m_openedShaderFunction = m_mainGraphInstance.CurrentShaderFunction; + + //Need to force one graph draw because it wont call OnGui propertly since its focuses somewhere else + // Focus() doesn't fix this since it only changes keyboard focus + m_drawInfo.InvertedZoom = 1 / m_cameraZoom; + m_mainGraphInstance.Draw( m_drawInfo ); + + ShaderIsModified = false; + Focus(); + Repaint(); + } + + public void OnProjectSelectionChanged() + { + if( m_loadShaderOnSelection ) + { + LoadProjectSelected(); + } + } + + ShaderLoadResult OnSaveShader( bool value, Shader shader, Material material, AmplifyShaderFunction function ) + { + if( value ) + { + SaveToDisk( false ); + } + + return value ? ShaderLoadResult.LOADED : ShaderLoadResult.FILE_NOT_FOUND; + } + + public void ResetCameraSettings() + { + m_cameraInfo = position; + m_cameraOffset = new Vector2( m_cameraInfo.width * 0.5f, m_cameraInfo.height * 0.5f ); + CameraZoom = 1; + } + + public void Reset() + { + if( m_mainGraphInstance == null ) + { + m_mainGraphInstance = CreateInstance<ParentGraph>(); + m_mainGraphInstance.Init(); + m_mainGraphInstance.ParentWindow = this; + m_mainGraphInstance.SetGraphId( 0 ); + } + m_mainGraphInstance.ResetEvents(); + m_mainGraphInstance.OnNodeEvent += OnNodeStoppedMovingEvent; + m_mainGraphInstance.OnMaterialUpdatedEvent += OnMaterialUpdated; + m_mainGraphInstance.OnShaderUpdatedEvent += OnShaderUpdated; + m_mainGraphInstance.OnEmptyGraphDetectedEvt += OnEmptyGraphDetected; + m_mainGraphInstance.OnNodeRemovedEvent += m_toolsWindow.OnNodeRemovedFromGraph; + m_outdatedShaderFromTemplateLoaded = false; + GraphCount = 1; + + FullCleanUndoStack(); + m_performFullUndoRegister = true; + m_toolsWindow.BorderStyle = null; + m_selectionMode = ASESelectionMode.Shader; + ResetCameraSettings(); + UIUtils.ResetMainSkin(); + m_duplicatePreventionBuffer.ReleaseAllData(); + if( m_genericMessageUI != null ) + m_genericMessageUI.CleanUpMessageStack(); + } + + + public Shader CreateNewGraph( string name ) + { + Reset(); + UIUtils.DirtyMask = false; + m_mainGraphInstance.CreateNewEmpty( name ); + m_lastOpenedLocation = string.Empty; + UIUtils.DirtyMask = true; + return m_mainGraphInstance.CurrentMasterNode.CurrentShader; + } + + public Shader CreateNewTemplateGraph( string templateGUID ) + { + Reset(); + UIUtils.DirtyMask = false; + m_mainGraphInstance.CreateNewEmptyTemplate( templateGUID ); + m_lastOpenedLocation = string.Empty; + UIUtils.DirtyMask = true; + return m_mainGraphInstance.CurrentMasterNode.CurrentShader; + } + + public Shader CreateNewGraph( Shader shader ) + { + Reset(); + UIUtils.DirtyMask = false; + m_mainGraphInstance.CreateNewEmpty( shader.name ); + m_mainGraphInstance.CurrentMasterNode.CurrentShader = shader; + + m_lastOpenedLocation = string.Empty; + UIUtils.DirtyMask = true; + return m_mainGraphInstance.CurrentMasterNode.CurrentShader; + } + + public void CreateNewFunctionGraph( AmplifyShaderFunction shaderFunction ) + { + Reset(); + UIUtils.DirtyMask = false; + m_mainGraphInstance.CreateNewEmptyFunction( shaderFunction ); + m_mainGraphInstance.CurrentShaderFunction = shaderFunction; + + m_lastOpenedLocation = AssetDatabase.GetAssetPath( shaderFunction ); //string.Empty; + UIUtils.DirtyMask = true; + //return m_mainGraphInstance.CurrentMasterNode.CurrentShader; + } + + public bool SaveToDisk( bool checkTimestamp ) + { + if( checkTimestamp ) + { + if( !m_cacheSaveOp ) + { + m_lastTimeSaved = EditorApplication.timeSinceStartup; + m_cacheSaveOp = true; + } + return false; + } + + + System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.InvariantCulture; + + m_customGraph = null; + m_cacheSaveOp = false; + ShaderIsModified = false; + m_mainGraphInstance.LoadedShaderVersion = VersionInfo.FullNumber; + m_lastTimeSaved = EditorApplication.timeSinceStartup; + + if( m_mainGraphInstance.CurrentMasterNodeId == Constants.INVALID_NODE_ID ) + { + Shader currentShader = m_mainGraphInstance.CurrentMasterNode != null ? m_mainGraphInstance.CurrentMasterNode.CurrentShader : null; + string newShader; + if( !String.IsNullOrEmpty( m_lastOpenedLocation ) ) + { + newShader = m_lastOpenedLocation; + } + else if( currentShader != null ) + { + newShader = AssetDatabase.GetAssetPath( currentShader ); + } + else + { + newShader = EditorUtility.SaveFilePanel( "Select Shader to save", Application.dataPath, "MyShader", "shader" ); + } + + if( !String.IsNullOrEmpty( newShader ) ) + { + ShowMessage( "No Master node assigned.\nShader file will only have node info" ); + IOUtils.StartSaveThread( GenerateGraphInfo(), newShader ); + AssetDatabase.Refresh(); + LoadFromDisk( newShader ); + System.Threading.Thread.CurrentThread.CurrentCulture = System.Threading.Thread.CurrentThread.CurrentUICulture; + return true; + } + } + else if( m_mainGraphInstance.CurrentMasterNode != null ) + { + //m_mainGraphInstance.CurrentStandardSurface.ForceReordering(); + Shader currShader = m_mainGraphInstance.CurrentMasterNode.CurrentShader; + if( currShader != null ) + { + m_mainGraphInstance.FireMasterNode( currShader ); + Material material = m_mainGraphInstance.CurrentMaterial; + m_lastpath = ( material != null ) ? AssetDatabase.GetAssetPath( material ) : AssetDatabase.GetAssetPath( currShader ); + EditorPrefs.SetString( IOUtils.LAST_OPENED_OBJ_ID, m_lastpath ); + System.Threading.Thread.CurrentThread.CurrentCulture = System.Threading.Thread.CurrentThread.CurrentUICulture; + if( IOUtils.OnShaderSavedEvent != null ) + { + string info = string.Empty; + if( !m_mainGraphInstance.IsStandardSurface ) + { + TemplateMultiPassMasterNode masterNode = m_mainGraphInstance.GetMainMasterNodeOfLOD( -1 ); + if( masterNode != null ) + { + info = masterNode.CurrentTemplate.GUID; + } + } + IOUtils.OnShaderSavedEvent( currShader, !m_mainGraphInstance.IsStandardSurface, info ); + } + return true; + } + else + { + + string shaderName; + string pathName; + IOUtils.GetShaderName( out shaderName, out pathName, Constants.DefaultShaderName, UIUtils.LatestOpenedFolder ); + if( !String.IsNullOrEmpty( pathName ) ) + { + UIUtils.CurrentWindow.CurrentGraph.CurrentMasterNode.SetName( shaderName ); + m_mainGraphInstance.FireMasterNode( pathName, true ); + m_lastpath = pathName; + EditorPrefs.SetString( IOUtils.LAST_OPENED_OBJ_ID, pathName ); + System.Threading.Thread.CurrentThread.CurrentCulture = System.Threading.Thread.CurrentThread.CurrentUICulture; + return true; + } + } + } + else + { + //m_nodeParametersWindow.ForceReordering(); + m_mainGraphInstance.ResetNodesLocalVariables(); + + List<FunctionInput> functionInputNodes = UIUtils.FunctionInputList(); + functionInputNodes.Sort( ( x, y ) => { return x.OrderIndex.CompareTo( y.OrderIndex ); } ); + for( int i = 0; i < functionInputNodes.Count; i++ ) + { + functionInputNodes[ i ].OrderIndex = i; + } + + List<FunctionOutput> functionOutputNodes = UIUtils.FunctionOutputList(); + functionOutputNodes.Sort( ( x, y ) => { return x.OrderIndex.CompareTo( y.OrderIndex ); } ); + for( int i = 0; i < functionOutputNodes.Count; i++ ) + { + functionOutputNodes[ i ].OrderIndex = i; + } + + m_mainGraphInstance.CurrentShaderFunction.AdditionalDirectives.UpdateSaveItemsFromDirectives(); + m_mainGraphInstance.CurrentShaderFunction.FunctionInfo = GenerateGraphInfo(); + m_mainGraphInstance.CurrentShaderFunction.FunctionInfo = IOUtils.AddAdditionalInfo( m_mainGraphInstance.CurrentShaderFunction.FunctionInfo ); + + if( AssetDatabase.IsMainAsset( m_mainGraphInstance.CurrentShaderFunction ) ) + { + EditorUtility.SetDirty( m_mainGraphInstance.CurrentShaderFunction ); + } + else + { + //Debug.Log( LastOpenedLocation ); + //AssetDatabase.CreateAsset( m_mainGraphInstance.CurrentShaderFunction, LastOpenedLocation ); + } + + AssetDatabase.SaveAssets(); + AssetDatabase.Refresh(); + m_mainGraphInstance.CurrentShaderFunction.AdditionalDirectives.UpdateDirectivesFromSaveItems(); + IOUtils.FunctionNodeChanged = true; + m_lastpath = AssetDatabase.GetAssetPath( m_mainGraphInstance.CurrentShaderFunction ); + System.Threading.Thread.CurrentThread.CurrentCulture = System.Threading.Thread.CurrentThread.CurrentUICulture; + //EditorPrefs.SetString( IOUtils.LAST_OPENED_OBJ_ID, AssetDatabase.GetAssetPath( m_mainGraphInstance.CurrentShaderFunction ) ); + return true; + } + System.Threading.Thread.CurrentThread.CurrentCulture = System.Threading.Thread.CurrentThread.CurrentUICulture; + return false; + } + + public void OnToolButtonPressed( ToolButtonType type ) + { + switch( type ) + { + case ToolButtonType.New: + { + UIUtils.CreateNewEmpty(); + } + break; + case ToolButtonType.Open: + { + UIUtils.OpenFile(); + } + break; + case ToolButtonType.Save: + { + SaveToDisk( false ); + } + break; + case ToolButtonType.Library: + { + ShowShaderLibrary(); + } + break; + case ToolButtonType.Options: { } break; + case ToolButtonType.Update: + { + SaveToDisk( false ); + } + break; + case ToolButtonType.Live: + { + m_liveShaderEditing = !m_liveShaderEditing; + m_innerEditorVariables.LiveMode = m_liveShaderEditing; + // 0 off + // 1 on + // 2 pending + if( m_liveShaderEditing && m_mainGraphInstance.CurrentMasterNode != null && m_mainGraphInstance.CurrentMasterNode.CurrentShader == null ) + { + m_liveShaderEditing = false; + m_innerEditorVariables.LiveMode = false; + } + + UpdateLiveUI(); + + if( m_liveShaderEditing ) + { + SaveToDisk( false ); + } + } + break; + case ToolButtonType.OpenSourceCode: + { + AssetDatabase.OpenAsset( m_mainGraphInstance.CurrentMasterNode.CurrentShader, 1 ); + } + break; + case ToolButtonType.MasterNode: + { + m_mainGraphInstance.AssignMasterNode(); + } + break; + + case ToolButtonType.FocusOnMasterNode: + { + double currTime = EditorApplication.timeSinceStartup; + bool autoZoom = ( currTime - m_focusOnMasterNodeTimestamp ) < AutoZoomTime; + m_focusOnMasterNodeTimestamp = currTime; + FocusOnNode( m_mainGraphInstance.CurrentMasterNode, autoZoom ? 1 : m_cameraZoom, true ); + } + break; + + case ToolButtonType.FocusOnSelection: + { + FocusZoom( false, true, true ); + } + break; + case ToolButtonType.ShowInfoWindow: + { + PortLegendInfo.OpenWindow(); + } + break; + case ToolButtonType.ShowTipsWindow: + { + TipsWindow.ShowWindow( true ); + } + break; + case ToolButtonType.ShowConsole: + { + m_consoleLogWindow.Toggle(); + } + break; + case ToolButtonType.Share: + { + List<ParentNode> selectedNodes = m_mainGraphInstance.SelectedNodes; + if( selectedNodes.Count > 0 ) + { + CopyToClipboard(); + StartPasteRequest(); + } + else + { + ShowMessage( "No nodes selected to share" ); + } + } + break; + case ToolButtonType.TakeScreenshot: + { +#if UNITY_EDITOR_WIN + this.Focus(); + m_aseHandle = WindowsUtil.GetActiveWindow(); + //m_aseHandle = FindASEWindowHandle(); + + bool takeit = EditorUtility.DisplayDialog( "Take Screenshot", "This is a work in progress feature that will undock itself if needed, increase the window outside of your screen resolution to take the shot, if something fails (ie: graph too big) you may need to restart Unity, do you wish to continue?", "Yes", "Cancel" ); + if( !takeit ) + break; + + if( this.IsDocked() ) + { + this.Undock(); + this.Focus(); + m_aseHandle = WindowsUtil.GetActiveWindow(); + } + + int windowLong = WindowsUtil.GetWindowLong( m_aseHandle, WindowsUtil.GWL_STYLE ); + + List<ParentNode> selectedNodes = m_mainGraphInstance.AllNodes; + + Vector2 minPos = new Vector2( float.MaxValue, float.MaxValue ); + Vector2 maxPos = new Vector2( float.MinValue, float.MinValue ); + Vector2 centroid = Vector2.zero; + + for( int i = 0; i < selectedNodes.Count; i++ ) + { + Rect currPos = selectedNodes[ i ].TruePosition; + minPos.x = ( currPos.x < minPos.x ) ? currPos.x : minPos.x; + minPos.y = ( currPos.y < minPos.y ) ? currPos.y : minPos.y; + + maxPos.x = ( ( currPos.x + currPos.width ) > maxPos.x ) ? ( currPos.x + currPos.width ) : maxPos.x; + maxPos.y = ( ( currPos.y + currPos.height ) > maxPos.y ) ? ( currPos.y + currPos.height ) : maxPos.y; + } + + centroid = ( maxPos - minPos ); + + m_prevCameraOffset = m_cameraOffset; + m_prevCameraZoom = CameraZoom; + + WindowsUtil.SetWindowLong( m_aseHandle, WindowsUtil.GWL_STYLE, (int)( windowLong & ~( WindowsUtil.WS_SIZEBOX ) ) ); + var rect = new WindowsUtil.Rect(); + WindowsUtil.GetWindowRect( m_aseHandle, ref rect ); + m_prevWindowRect = new Rect( rect.Left, rect.Top, rect.Width, rect.Height ); + + WindowsUtil.SetWindowPos( m_aseHandle, 0, (int)m_prevWindowRect.xMin, (int)m_prevWindowRect.yMin, (int)centroid.x, (int)centroid.y, 0x0040 ); + WindowsUtil.SetWindowLong( m_aseHandle, WindowsUtil.GWL_STYLE, (int)( windowLong ) ); + + m_takeScreenShot = true; +#else + EditorUtility.DisplayDialog( "Take Screenshot", "This is a work in progress feature that only works in Windows environment", "Ok" ); +#endif + } + break; + case ToolButtonType.CleanUnusedNodes: + { + m_mainGraphInstance.CleanUnusedNodes(); + } + break; + case ToolButtonType.Help: + { + Application.OpenURL( Constants.HelpURL ); + } + break; + } + } + +#if UNITY_EDITOR_WIN + IntPtr FindASEWindowHandle() + { + System.Diagnostics.Process process = System.Diagnostics.Process.GetCurrentProcess(); + + IntPtr[] winPtrs = WindowsUtil.GetProcessWindows( process.Id ); + m_aseHandle = IntPtr.Zero; + bool found = false; + for( int i = 0; i < winPtrs.Length; i++ ) + { + WindowsUtil.EnumChildWindows( winPtrs[ i ], delegate ( System.IntPtr hwnd, System.IntPtr param ) + { + System.Text.StringBuilder Title = new System.Text.StringBuilder( 256 ); + WindowsUtil.GetWindowText( hwnd, Title, Title.Capacity ); + + if( Title.ToString().Contains( "AmplifyShaderEditor.AmplifyShaderEditorWindow" ) ) + { + if( !found ) + { + m_aseHandle = winPtrs[ i ]; + found = true; + } + } + + return true; + }, System.IntPtr.Zero ); + } + + return m_aseHandle; + } + + void OpenSavedFolder() + { + m_openSavedFolder = false; + + var path = System.IO.Path.GetFullPath( Application.dataPath + "\\..\\ScreenshotASE.png" ); + EditorUtility.RevealInFinder( path ); + GUIUtility.ExitGUI(); + } + + void TakeScreenShot() + { + m_takeScreenShot = false; + + var cacher = RenderTexture.active; + RenderTexture.active = null; + + Texture2D m_screenshotTex2D = new Texture2D( (int)position.width, (int)position.height, TextureFormat.RGB24, false ); + m_screenshotTex2D.ReadPixels( new Rect( 0, 0, m_screenshotTex2D.width, m_screenshotTex2D.height ), 0, 0 ); + m_screenshotTex2D.Apply(); + + byte[] bytes = m_screenshotTex2D.EncodeToPNG(); + + var path = System.IO.Path.GetFullPath( Application.dataPath + "\\..\\ScreenshotASE.png" ); + System.IO.File.WriteAllBytes( path, bytes ); + + RenderTexture.active = cacher; + + ShowMessage( "[AmplifyShaderEditor] Screenshot successfully taken and saved at: " + path, consoleLog:true ); + + WindowsUtil.SetWindowPos( m_aseHandle, 0, (int)m_prevWindowRect.xMin, (int)m_prevWindowRect.yMin, (int)m_prevWindowRect.width, (int)m_prevWindowRect.height, 0x0040 ); + m_cameraOffset = m_prevCameraOffset; + CameraZoom = m_prevCameraZoom; + + m_openSavedFolder = true; + } +#endif + + + void UpdateLiveUI() + { + if( m_toolsWindow != null ) + { + m_toolsWindow.SetStateOnButton( ToolButtonType.Live, ( m_liveShaderEditing ) ? 1 : 0 ); + } + } + + void FocusZoom( bool forceAllNodes, bool doubleTap, bool smooth = true ) + { + List<ParentNode> selectedNodes = ( m_mainGraphInstance.SelectedNodes.Count > 0 ) && !forceAllNodes ? m_mainGraphInstance.SelectedNodes : m_mainGraphInstance.AllNodes; + + Vector2 minPos = new Vector2( float.MaxValue, float.MaxValue ); + Vector2 maxPos = new Vector2( float.MinValue, float.MinValue ); + Vector2 centroid = Vector2.zero; + + for( int i = 0; i < selectedNodes.Count; i++ ) + { + Rect currPos = selectedNodes[ i ].TruePosition; + + minPos.x = ( currPos.x < minPos.x ) ? currPos.x : minPos.x; + minPos.y = ( currPos.y < minPos.y ) ? currPos.y : minPos.y; + + maxPos.x = ( ( currPos.x + currPos.width ) > maxPos.x ) ? ( currPos.x + currPos.width ) : maxPos.x; + maxPos.y = ( ( currPos.y + currPos.height ) > maxPos.y ) ? ( currPos.y + currPos.height ) : maxPos.y; + + } + + centroid = ( maxPos - minPos ); + + double currTime = EditorApplication.timeSinceStartup; + bool autoZoom = ( currTime - m_focusOnSelectionTimestamp ) < AutoZoomTime; + if( !doubleTap ) + autoZoom = true; + m_focusOnSelectionTimestamp = currTime; + + float zoom = m_cameraZoom; + if( autoZoom ) + { + zoom = 1f; + float canvasWidth = m_cameraInfo.width; + if( m_nodeParametersWindow.IsMaximized ) + canvasWidth -= m_nodeParametersWindow.RealWidth; + if( m_paletteWindow.IsMaximized ) + canvasWidth -= m_paletteWindow.RealWidth; + canvasWidth -= 40; + //float canvasWidth = AvailableCanvasWidth;// - 20; + float canvasHeight = AvailableCanvasHeight - 60; + if( centroid.x > canvasWidth || + centroid.y > canvasHeight ) + { + float hZoom = float.MinValue; + float vZoom = float.MinValue; + if( centroid.x > canvasWidth ) + { + hZoom = ( centroid.x ) / canvasWidth; + } + + if( centroid.y > canvasHeight ) + { + vZoom = ( centroid.y ) / canvasHeight; + } + zoom = ( hZoom > vZoom ) ? hZoom : vZoom; + } + } + + minPos.y -= 20 * zoom; + if( m_nodeParametersWindow.IsMaximized ) + minPos.x -= m_nodeParametersWindow.RealWidth * 0.5f * zoom; + if( m_paletteWindow.IsMaximized ) + minPos.x += m_paletteWindow.RealWidth * 0.5f * zoom; + + FocusOnPoint( minPos + centroid * 0.5f, zoom, smooth ); + } + + public void FocusOnNode( int nodeId, float zoom, bool selectNode, bool late = false ) + { + ParentNode node = m_mainGraphInstance.GetNode( nodeId ); + if( node != null ) + { + FocusOnNode( node, zoom, selectNode, late ); + } + } + + public void FocusOnNode( ParentNode node, float zoom, bool selectNode, bool late = false ) + { + if( late ) + { + m_nodeToFocus = node; + m_zoomToFocus = zoom; + m_selectNodeToFocus = selectNode; + return; + } + + if( selectNode ) + { + m_mainGraphInstance.SelectNode( node, false, false ); + } + + Vector2 nodePoint = node.CenterPosition; + nodePoint.x = nodePoint.x - ( m_nodeParametersWindow.RealWidth * 0.5f + m_paletteWindow.RealWidth * 0.5f ) * ( zoom > 0.999f ? zoom : CameraZoom ); + FocusOnPoint( nodePoint, zoom ); + } + + public void FocusOnPoint( Vector2 point, float zoom, bool smooth = true ) + { + if( zoom > 0.999f ) + { + if( smooth ) + SmoothZoom( zoom ); + else + CameraZoom = zoom; + } + + if( smooth ) + SmoothCameraOffset( -point + new Vector2( ( m_cameraInfo.width ) * 0.5f, m_cameraInfo.height * 0.5f ) * CameraZoom ); + else + m_cameraOffset = -point + new Vector2( ( m_cameraInfo.width ) * 0.5f, m_cameraInfo.height * 0.5f ) * CameraZoom; + } + + void SmoothZoom( float newZoom ) + { + m_smoothZoom = true; + m_zoomTime = 0; + m_targetZoom = newZoom; + m_zoomPivot = m_graphArea.center; + } + + void SmoothCameraOffset( Vector2 newOffset ) + { + m_smoothOffset = true; + m_offsetTime = 0; + m_targetOffset = newOffset; + } + + void PreTestLeftMouseDown() + { + if( m_currentEvent.type == EventType.MouseDown && m_currentEvent.button == ButtonClickId.LeftMouseButton ) + { + ParentNode node = m_mainGraphInstance.CheckNodeAt( m_currentMousePos ); + if( node != null ) + { + m_mainGraphInstance.NodeClicked = node.UniqueId; + return; + } + } + + m_mainGraphInstance.NodeClicked = -1; + } + + + + void OnLeftMouseDown() + { + Focus(); + + if( m_lastKeyPressed == KeyCode.Q ) + { + m_rmbStartPos = m_currentMousePos2D; + UseCurrentEvent(); + return; + } + + m_mouseDownOnValidArea = true; + m_lmbPressed = true; + if( m_currentEvent.alt ) + { + m_altBoxSelection = true; + } + + UIUtils.ShowContextOnPick = true; + ParentNode node = ( m_mainGraphInstance.NodeClicked < 0 ) ? m_mainGraphInstance.CheckNodeAt( m_currentMousePos ) : m_mainGraphInstance.GetClickedNode(); + if( node != null ) + { + m_mainGraphInstance.NodeClicked = node.UniqueId; + m_altBoxSelection = false; + + if( m_contextMenu.CheckShortcutKey() ) + { + if( node.ConnStatus == NodeConnectionStatus.Island ) + { + if( !m_multipleSelectionActive ) + { + ParentNode newNode = m_contextMenu.CreateNodeFromShortcutKey(); + if( newNode != null ) + { + newNode.ContainerGraph = m_mainGraphInstance; + newNode.Vec2Position = TranformedMousePos; + m_mainGraphInstance.AddNode( newNode, true ); + m_mainGraphInstance.SelectNode( newNode, false, false ); + ForceRepaint(); + } + ( node as CommentaryNode ).AddNodeToCommentary( newNode ); + } + } + } + else + { + if( node.OnClick( m_currentMousePos2D ) ) + { + if( !node.Selected ) + { + m_mainGraphInstance.SelectNode( node, ( m_currentEvent.modifiers == EventModifiers.Shift || m_currentEvent.modifiers == EventModifiers.Control ), true ); + } + else if( m_currentEvent.modifiers == EventModifiers.Shift || m_currentEvent.modifiers == EventModifiers.Control ) + { + m_mainGraphInstance.DeselectNode( node ); + } + + if( m_currentEvent.alt ) + { + int conn = 0; + for( int i = 0; i < node.InputPorts.Count; i++ ) + { + if( node.InputPorts[ i ].IsConnected ) + conn++; + } + + if( node.InputPorts.Count > 0 && node.OutputPorts.Count > 0 && conn > 0 && node.OutputPorts[ 0 ].IsConnected ) + { + m_altDragStarted = true; + } + } + + } + + if( m_currentEvent.alt ) + { + if( node.InputPorts.Count > 0 && node.OutputPorts.Count > 0 && node.InputPorts[ 0 ].IsConnected && node.OutputPorts[ 0 ].IsConnected ) + { + m_altDragStarted = true; + } + } + + return; + } + } + else if( !m_multipleSelectionActive ) + { + ParentNode newNode = m_contextMenu.CreateNodeFromShortcutKey(); + if( newNode != null ) + { + newNode.ContainerGraph = m_mainGraphInstance; + newNode.Vec2Position = TranformedMousePos; + m_mainGraphInstance.AddNode( newNode, true ); + m_mainGraphInstance.SelectNode( newNode, false, false ); + SetSaveIsDirty(); + ForceRepaint(); + } + else + { + List<WireBezierReference> wireRefs = m_mainGraphInstance.GetWireBezierListInPos( m_currentMousePos2D ); + if( wireRefs != null && wireRefs.Count > 0 ) + { + for( int i = 0; i < wireRefs.Count; i++ ) + { + // Place wire code here + ParentNode outNode = m_mainGraphInstance.GetNode( wireRefs[ i ].OutNodeId ); + ParentNode inNode = m_mainGraphInstance.GetNode( wireRefs[ i ].InNodeId ); + + OutputPort outputPort = outNode.GetOutputPortByUniqueId( wireRefs[ i ].OutPortId ); + InputPort inputPort = inNode.GetInputPortByUniqueId( wireRefs[ i ].InPortId ); + + // Calculate the 4 points for bezier taking into account wire nodes and their automatic tangents + Vector3 endPos = new Vector3( inputPort.Position.x, inputPort.Position.y ); + Vector3 startPos = new Vector3( outputPort.Position.x, outputPort.Position.y ); + + float mag = ( endPos - startPos ).magnitude; + float resizedMag = Mathf.Min( mag, Constants.HORIZONTAL_TANGENT_SIZE * m_drawInfo.InvertedZoom ); + + Vector3 startTangent = new Vector3( startPos.x + resizedMag, startPos.y ); + Vector3 endTangent = new Vector3( endPos.x - resizedMag, endPos.y ); + + if( inNode != null && inNode.GetType() == typeof( WireNode ) ) + endTangent = endPos + ( ( inNode as WireNode ).TangentDirection ) * mag * 0.33f; + + if( outNode != null && outNode.GetType() == typeof( WireNode ) ) + startTangent = startPos - ( ( outNode as WireNode ).TangentDirection ) * mag * 0.33f; + + float dist = HandleUtility.DistancePointBezier( m_currentMousePos, startPos, endPos, startTangent, endTangent ); + if( dist < 10 ) + { + double doubleTapTime = EditorApplication.timeSinceStartup; + bool doubleTap = ( doubleTapTime - m_wiredDoubleTapTimestamp ) < WiredDoubleTapTime; + m_wiredDoubleTapTimestamp = doubleTapTime; + + if( doubleTap ) + { + Undo.RegisterCompleteObjectUndo( this, Constants.UndoCreateConnectionId ); + Undo.RegisterCompleteObjectUndo( m_mainGraphInstance, Constants.UndoCreateConnectionId ); + Undo.RecordObject( outNode, Constants.UndoCreateConnectionId ); + Undo.RecordObject( inNode, Constants.UndoCreateConnectionId ); + + ParentNode wireNode = m_mainGraphInstance.CreateNode( typeof( WireNode ), true ); + if( wireNode != null ) + { + wireNode.Vec2Position = TranformedMousePos; + + m_mainGraphInstance.CreateConnection( wireNode.InputPorts[ 0 ].NodeId, wireNode.InputPorts[ 0 ].PortId, outputPort.NodeId, outputPort.PortId ); + m_mainGraphInstance.CreateConnection( inputPort.NodeId, inputPort.PortId, wireNode.OutputPorts[ 0 ].NodeId, wireNode.OutputPorts[ 0 ].PortId ); + + SetSaveIsDirty(); + ForceRepaint(); + Undo.IncrementCurrentGroup(); + } + } + + break; + } + } + } + //Reset focus from any textfield which may be selected at this time + GUIUtility.keyboardControl = 0; + } + } + + if( m_currentEvent.modifiers != EventModifiers.Shift && m_currentEvent.modifiers != EventModifiers.Control && !m_altBoxSelection ) + m_mainGraphInstance.DeSelectAll(); + + if( m_wireReferenceUtils.ValidReferences() ) + { + m_wireReferenceUtils.InvalidateReferences(); + return; + } + + if( !m_contextMenu.CheckShortcutKey() && m_currentEvent.modifiers != EventModifiers.Shift && m_currentEvent.modifiers != EventModifiers.Control || m_altBoxSelection ) + { + // Only activate multiple selection if no node is selected and shift key not pressed + m_multipleSelectionActive = true; + + m_multipleSelectionStart = TranformedMousePos; + m_multipleSelectionArea.position = m_multipleSelectionStart; + m_multipleSelectionArea.size = Vector2.zero; + } + + UseCurrentEvent(); + } + + void OnLeftMouseDrag() + { + if( m_lostFocus ) + { + m_lostFocus = false; + return; + } + + if( m_lastKeyPressed == KeyCode.Q ) + { + if( m_currentEvent.alt ) + { + ModifyZoom( Constants.ALT_CAMERA_ZOOM_SPEED * ( m_currentEvent.delta.x + m_currentEvent.delta.y ), m_altKeyStartPos ); + } + else + { + m_cameraOffset += m_cameraZoom * m_currentEvent.delta; + } + UseCurrentEvent(); + return; + } + + if( m_altDragStarted ) + { + m_altDragStarted = false; + + if( m_currentEvent.modifiers == EventModifiers.Alt && CurrentGraph.SelectedNodes.Count == 1 ) + { + ParentNode node = CurrentGraph.SelectedNodes[ 0 ]; + int lastId = 0; + int conn = 0; + for( int i = 0; i < node.InputPorts.Count; i++ ) + { + if( node.InputPorts[ i ].IsConnected ) + { + conn++; + lastId = i; + } + } + + if( conn > 1 ) + lastId = 0; + + + + OutputPort outputPort = node.InputPorts[ lastId ].GetOutputConnection( 0 ); + ParentNode outputNode = m_mainGraphInstance.GetNode( outputPort.NodeId ); + bool outputIsWireNode = outputNode is WireNode; + + Undo.RegisterCompleteObjectUndo( this, Constants.UndoCreateConnectionId ); + node.RecordObject( Constants.UndoCreateConnectionId ); + outputNode.RecordObject( Constants.UndoCreateConnectionId ); + + List<InputPort> inputPorts = new List<InputPort>(); + for( int i = 0; i < node.OutputPorts[ 0 ].ConnectionCount; i++ ) + { + InputPort inputPort = node.OutputPorts[ 0 ].GetInputConnection( i ); + ParentNode inputNode = m_mainGraphInstance.GetNode( inputPort.NodeId ); + inputNode.RecordObject( Constants.UndoCreateConnectionId ); + inputPorts.Add( inputPort ); + } + + for( int i = 0; i < inputPorts.Count; i++ ) + { + if( outputIsWireNode ) + { + if( i == 0 ) + { + m_mainGraphInstance.CreateConnection( inputPorts[ i ].NodeId, inputPorts[ i ].PortId, outputPort.NodeId, outputPort.PortId ); + } + else + { + UIUtils.DeleteConnection( true, inputPorts[ i ].NodeId, inputPorts[ i ].PortId, false, true ); + } + } + else + { + m_mainGraphInstance.CreateConnection( inputPorts[ i ].NodeId, inputPorts[ i ].PortId, outputPort.NodeId, outputPort.PortId ); + } + } + + UIUtils.DeleteConnection( true, node.UniqueId, node.InputPorts[ lastId ].PortId, false, true ); + + SetSaveIsDirty(); + ForceRepaint(); + } + } + + if( !m_wireReferenceUtils.ValidReferences() && !m_altBoxSelection ) + { + if( m_mouseDownOnValidArea && m_insideEditorWindow ) + { + if( m_currentEvent.control ) + { + m_mainGraphInstance.MoveSelectedNodes( m_cameraZoom * m_currentEvent.delta, true ); + } + else + { + m_mainGraphInstance.MoveSelectedNodes( m_cameraZoom * m_currentEvent.delta ); + } + //m_mainGraphInstance.MoveSelectedNodes( m_cameraZoom * m_currentEvent.delta ); + m_autoPanDirActive = true; + } + } + else + { + List<ParentNode> nodes = m_mainGraphInstance.GetNodesInGrid( m_drawInfo.TransformedMousePos ); + if( nodes != null && nodes.Count > 0 ) + { + Vector2 currentPortPos = new Vector2(); + Vector2 mousePos = TranformedMousePos; + + if( m_wireReferenceUtils.InputPortReference.IsValid ) + { + OutputPort currentPort = null; + float smallestDistance = float.MaxValue; + Vector2 smallestPosition = Vector2.zero; + for( int nodeIdx = 0; nodeIdx < nodes.Count; nodeIdx++ ) + { + List<OutputPort> outputPorts = nodes[ nodeIdx ].OutputPorts; + if( outputPorts != null ) + { + for( int o = 0; o < outputPorts.Count; o++ ) + { + if( outputPorts[ o ].Available ) + { + currentPortPos.x = outputPorts[ o ].Position.x; + currentPortPos.y = outputPorts[ o ].Position.y; + + currentPortPos = currentPortPos * m_cameraZoom - m_cameraOffset; + float dist = ( mousePos - currentPortPos ).sqrMagnitude; + if( dist < smallestDistance ) + { + smallestDistance = dist; + smallestPosition = currentPortPos; + currentPort = outputPorts[ o ]; + } + } + } + } + } + + if( currentPort != null && currentPort.Available && ( smallestDistance < Constants.SNAP_SQR_DIST || currentPort.InsideActiveArea( ( mousePos + m_cameraOffset ) / m_cameraZoom ) ) ) + { + m_wireReferenceUtils.ActivateSnap( smallestPosition, currentPort ); + } + else + { + m_wireReferenceUtils.DeactivateSnap(); + } + } + + if( m_wireReferenceUtils.OutputPortReference.IsValid ) + { + InputPort currentPort = null; + float smallestDistance = float.MaxValue; + Vector2 smallestPosition = Vector2.zero; + for( int nodeIdx = 0; nodeIdx < nodes.Count; nodeIdx++ ) + { + List<InputPort> inputPorts = nodes[ nodeIdx ].InputPorts; + if( inputPorts != null ) + { + for( int i = 0; i < inputPorts.Count; i++ ) + { + if( inputPorts[ i ].Available ) + { + currentPortPos.x = inputPorts[ i ].Position.x; + currentPortPos.y = inputPorts[ i ].Position.y; + + currentPortPos = currentPortPos * m_cameraZoom - m_cameraOffset; + float dist = ( mousePos - currentPortPos ).sqrMagnitude; + if( dist < smallestDistance ) + { + smallestDistance = dist; + smallestPosition = currentPortPos; + currentPort = inputPorts[ i ]; + } + } + } + } + } + if( currentPort != null && currentPort.Available && ( smallestDistance < Constants.SNAP_SQR_DIST || currentPort.InsideActiveArea( ( mousePos + m_cameraOffset ) / m_cameraZoom ) ) ) + { + m_wireReferenceUtils.ActivateSnap( smallestPosition, currentPort ); + } + else + { + m_wireReferenceUtils.DeactivateSnap(); + } + } + } + else if( m_wireReferenceUtils.SnapEnabled ) + { + m_wireReferenceUtils.DeactivateSnap(); + } + } + UseCurrentEvent(); + } + + public void OnLeftMouseUp() + { + m_lmbPressed = false; + if( m_multipleSelectionActive ) + { + //m_multipleSelectionActive = false; + UpdateSelectionArea(); + //m_mainGraphInstance.MultipleSelection( m_multipleSelectionArea, ( m_currentEvent.modifiers == EventModifiers.Shift || m_currentEvent.modifiers == EventModifiers.Control ), true ); + if( m_currentEvent.alt && m_altBoxSelection ) + { + m_mainGraphInstance.MultipleSelection( m_multipleSelectionArea, !m_currentEvent.shift ); + } + else + { + m_mainGraphInstance.DeSelectAll(); + m_mainGraphInstance.MultipleSelection( m_multipleSelectionArea ); + } + } + + if( m_wireReferenceUtils.ValidReferences() ) + { + //Check if there is some kind of port beneath the mouse ... if so connect to it + ParentNode targetNode = m_wireReferenceUtils.SnapEnabled ? m_mainGraphInstance.GetNode( m_wireReferenceUtils.SnapPort.NodeId ) : m_mainGraphInstance.CheckNodeAt( m_currentMousePos ); + if( targetNode != null && targetNode.ConnStatus != NodeConnectionStatus.Island ) + { + if( m_wireReferenceUtils.InputPortReference.IsValid && m_wireReferenceUtils.InputPortReference.NodeId != targetNode.UniqueId ) + { + OutputPort outputPort = m_wireReferenceUtils.SnapEnabled ? targetNode.GetOutputPortByUniqueId( m_wireReferenceUtils.SnapPort.PortId ) : targetNode.CheckOutputPortAt( m_currentMousePos ); + if( outputPort != null && !outputPort.Locked && ( !m_wireReferenceUtils.InputPortReference.TypeLocked || + m_wireReferenceUtils.InputPortReference.DataType == WirePortDataType.OBJECT || + ( m_wireReferenceUtils.InputPortReference.TypeLocked && outputPort.DataType == m_wireReferenceUtils.InputPortReference.DataType ) ) ) + { + + ParentNode originNode = m_mainGraphInstance.GetNode( m_wireReferenceUtils.InputPortReference.NodeId ); + InputPort inputPort = originNode.GetInputPortByUniqueId( m_wireReferenceUtils.InputPortReference.PortId ); + UIUtils.MarkUndoAction(); + Undo.RegisterCompleteObjectUndo( this, Constants.UndoCreateConnectionId ); + originNode.RecordObject( Constants.UndoCreateConnectionId ); + targetNode.RecordObject( Constants.UndoCreateConnectionId ); + + if( !inputPort.CheckValidType( outputPort.DataType ) ) + { + UIUtils.ShowIncompatiblePortMessage( true, originNode, inputPort, targetNode, outputPort ); + m_wireReferenceUtils.InvalidateReferences(); + UseCurrentEvent(); + return; + } + + if( !outputPort.CheckValidType( inputPort.DataType ) ) + { + UIUtils.ShowIncompatiblePortMessage( false, targetNode, outputPort, originNode, inputPort ); + m_wireReferenceUtils.InvalidateReferences(); + UseCurrentEvent(); + return; + } + + inputPort.DummyAdd( outputPort.NodeId, outputPort.PortId ); + outputPort.DummyAdd( m_wireReferenceUtils.InputPortReference.NodeId, m_wireReferenceUtils.InputPortReference.PortId ); + + if( UIUtils.DetectNodeLoopsFrom( originNode, new Dictionary<int, int>() ) ) + { + inputPort.DummyRemove(); + outputPort.DummyRemove(); + m_wireReferenceUtils.InvalidateReferences(); + ShowMessage( "Infinite Loop detected" ); + UseCurrentEvent(); + return; + } + + inputPort.DummyRemove(); + outputPort.DummyRemove(); + + if( inputPort.IsConnected ) + { + DeleteConnection( true, m_wireReferenceUtils.InputPortReference.NodeId, m_wireReferenceUtils.InputPortReference.PortId, true, false ); + } + + //link output to input + if( outputPort.ConnectTo( m_wireReferenceUtils.InputPortReference.NodeId, m_wireReferenceUtils.InputPortReference.PortId, m_wireReferenceUtils.InputPortReference.DataType, m_wireReferenceUtils.InputPortReference.TypeLocked ) ) + targetNode.OnOutputPortConnected( outputPort.PortId, m_wireReferenceUtils.InputPortReference.NodeId, m_wireReferenceUtils.InputPortReference.PortId ); + + //link input to output + if( inputPort.ConnectTo( outputPort.NodeId, outputPort.PortId, outputPort.DataType, m_wireReferenceUtils.InputPortReference.TypeLocked ) ) + originNode.OnInputPortConnected( m_wireReferenceUtils.InputPortReference.PortId, targetNode.UniqueId, outputPort.PortId ); + m_mainGraphInstance.MarkWireHighlights(); + } + else if( outputPort != null && m_wireReferenceUtils.InputPortReference.TypeLocked && m_wireReferenceUtils.InputPortReference.DataType != outputPort.DataType ) + { + ShowMessage( "Attempting to connect a port locked to type " + m_wireReferenceUtils.InputPortReference.DataType + " into a port of type " + outputPort.DataType ); + } + ShaderIsModified = true; + SetSaveIsDirty(); + } + + if( m_wireReferenceUtils.OutputPortReference.IsValid && m_wireReferenceUtils.OutputPortReference.NodeId != targetNode.UniqueId ) + { + InputPort inputPort = m_wireReferenceUtils.SnapEnabled ? targetNode.GetInputPortByUniqueId( m_wireReferenceUtils.SnapPort.PortId ) : targetNode.CheckInputPortAt( m_currentMousePos ); + if( inputPort != null && !inputPort.Locked && ( !inputPort.TypeLocked || + inputPort.DataType == WirePortDataType.OBJECT || + ( inputPort.TypeLocked && inputPort.DataType == m_wireReferenceUtils.OutputPortReference.DataType ) ) ) + { + ParentNode originNode = m_mainGraphInstance.GetNode( m_wireReferenceUtils.OutputPortReference.NodeId ); + OutputPort outputPort = originNode.GetOutputPortByUniqueId( m_wireReferenceUtils.OutputPortReference.PortId ); + + UIUtils.MarkUndoAction(); + Undo.RegisterCompleteObjectUndo( this, Constants.UndoCreateConnectionId ); + originNode.RecordObject( Constants.UndoCreateConnectionId ); + targetNode.RecordObject( Constants.UndoCreateConnectionId ); + + if( !inputPort.CheckValidType( outputPort.DataType ) ) + { + UIUtils.ShowIncompatiblePortMessage( true, targetNode, inputPort, originNode, outputPort ); + m_wireReferenceUtils.InvalidateReferences(); + UseCurrentEvent(); + return; + } + + if( !outputPort.CheckValidType( inputPort.DataType ) ) + { + UIUtils.ShowIncompatiblePortMessage( false, originNode, outputPort, targetNode, inputPort ); + m_wireReferenceUtils.InvalidateReferences(); + UseCurrentEvent(); + return; + } + + inputPort.DummyAdd( m_wireReferenceUtils.OutputPortReference.NodeId, m_wireReferenceUtils.OutputPortReference.PortId ); + outputPort.DummyAdd( inputPort.NodeId, inputPort.PortId ); + if( UIUtils.DetectNodeLoopsFrom( targetNode, new Dictionary<int, int>() ) ) + { + inputPort.DummyRemove(); + outputPort.DummyRemove(); + m_wireReferenceUtils.InvalidateReferences(); + ShowMessage( "Infinite Loop detected" ); + UseCurrentEvent(); + return; + } + + inputPort.DummyRemove(); + outputPort.DummyRemove(); + + if( inputPort.IsConnected ) + { + if( m_currentEvent.control && m_wireReferenceUtils.SwitchPortReference.IsValid ) + { + ParentNode oldOutputNode = UIUtils.GetNode( inputPort.GetConnection( 0 ).NodeId ); + OutputPort oldOutputPort = oldOutputNode.GetOutputPortByUniqueId( inputPort.GetConnection( 0 ).PortId ); + + ParentNode switchNode = UIUtils.GetNode( m_wireReferenceUtils.SwitchPortReference.NodeId ); + InputPort switchPort = switchNode.GetInputPortByUniqueId( m_wireReferenceUtils.SwitchPortReference.PortId ); + + switchPort.DummyAdd( oldOutputPort.NodeId, oldOutputPort.PortId ); + oldOutputPort.DummyAdd( switchPort.NodeId, switchPort.PortId ); + if( UIUtils.DetectNodeLoopsFrom( switchNode, new Dictionary<int, int>() ) ) + { + switchPort.DummyRemove(); + oldOutputPort.DummyRemove(); + m_wireReferenceUtils.InvalidateReferences(); + ShowMessage( "Infinite Loop detected" ); + UseCurrentEvent(); + return; + } + + switchPort.DummyRemove(); + oldOutputPort.DummyRemove(); + + DeleteConnection( true, inputPort.NodeId, inputPort.PortId, true, false ); + ConnectInputToOutput( switchPort.NodeId, switchPort.PortId, oldOutputPort.NodeId, oldOutputPort.PortId ); + } + else + { + DeleteConnection( true, inputPort.NodeId, inputPort.PortId, true, false ); + } + } + inputPort.InvalidateAllConnections(); + + + //link input to output + if( inputPort.ConnectTo( m_wireReferenceUtils.OutputPortReference.NodeId, m_wireReferenceUtils.OutputPortReference.PortId, m_wireReferenceUtils.OutputPortReference.DataType, inputPort.TypeLocked ) ) + targetNode.OnInputPortConnected( inputPort.PortId, m_wireReferenceUtils.OutputPortReference.NodeId, m_wireReferenceUtils.OutputPortReference.PortId ); + //link output to input + + if( outputPort.ConnectTo( inputPort.NodeId, inputPort.PortId, inputPort.DataType, inputPort.TypeLocked ) ) + originNode.OnOutputPortConnected( m_wireReferenceUtils.OutputPortReference.PortId, targetNode.UniqueId, inputPort.PortId ); + m_mainGraphInstance.MarkWireHighlights(); + } + else if( inputPort != null && inputPort.TypeLocked && inputPort.DataType != m_wireReferenceUtils.OutputPortReference.DataType ) + { + ShowMessage( "Attempting to connect a " + m_wireReferenceUtils.OutputPortReference.DataType + " to a port locked to type " + inputPort.DataType ); + } + ShaderIsModified = true; + SetSaveIsDirty(); + } + m_wireReferenceUtils.InvalidateReferences(); + } + else + { + if( UIUtils.ShowContextOnPick ) + m_contextPalette.Show( m_currentMousePos2D, m_cameraInfo ); + else + m_wireReferenceUtils.InvalidateReferences(); + } + } + else if( m_currentEvent.modifiers == EventModifiers.Alt && m_altAvailable && CurrentGraph.SelectedNodes.Count == 1 && !m_altBoxSelection && !m_multipleSelectionActive ) + { + List<WireBezierReference> wireRefs = m_mainGraphInstance.GetWireBezierListInPos( m_currentMousePos2D ); + if( wireRefs != null && wireRefs.Count > 0 ) + { + float closestDist = 50; + int closestId = 0; + + for( int i = 0; i < wireRefs.Count; i++ ) + { + ParentNode outNode = m_mainGraphInstance.GetNode( wireRefs[ i ].OutNodeId ); + ParentNode inNode = m_mainGraphInstance.GetNode( wireRefs[ i ].InNodeId ); + + if( outNode == CurrentGraph.SelectedNodes[ 0 ] || inNode == CurrentGraph.SelectedNodes[ 0 ] ) + continue; + + OutputPort outputPort = outNode.GetOutputPortByUniqueId( wireRefs[ i ].OutPortId ); + InputPort inputPort = inNode.GetInputPortByUniqueId( wireRefs[ i ].InPortId ); + + // Calculate the 4 points for bezier taking into account wire nodes and their automatic tangents + Vector3 endPos = new Vector3( inputPort.Position.x, inputPort.Position.y ); + Vector3 startPos = new Vector3( outputPort.Position.x, outputPort.Position.y ); + + float mag = ( endPos - startPos ).magnitude; + float resizedMag = Mathf.Min( mag, Constants.HORIZONTAL_TANGENT_SIZE * m_drawInfo.InvertedZoom ); + + Vector3 startTangent = new Vector3( startPos.x + resizedMag, startPos.y ); + Vector3 endTangent = new Vector3( endPos.x - resizedMag, endPos.y ); + + if( inNode != null && inNode.GetType() == typeof( WireNode ) ) + endTangent = endPos + ( ( inNode as WireNode ).TangentDirection ) * mag * 0.33f; + + if( outNode != null && outNode.GetType() == typeof( WireNode ) ) + startTangent = startPos - ( ( outNode as WireNode ).TangentDirection ) * mag * 0.33f; + + //Vector2 pos = ( CurrentGraph.SelectedNodes[0].CenterPosition + m_cameraOffset ) / m_cameraZoom; + + float dist = HandleUtility.DistancePointBezier( /*pos*/ m_currentMousePos, startPos, endPos, startTangent, endTangent ); + if( dist < 40 ) + { + if( dist < closestDist ) + { + closestDist = dist; + closestId = i; + } + } + } + + if( closestDist < 40 ) + { + ParentNode outNode = m_mainGraphInstance.GetNode( wireRefs[ closestId ].OutNodeId ); + ParentNode inNode = m_mainGraphInstance.GetNode( wireRefs[ closestId ].InNodeId ); + + OutputPort outputPort = outNode.GetOutputPortByUniqueId( wireRefs[ closestId ].OutPortId ); + InputPort inputPort = inNode.GetInputPortByUniqueId( wireRefs[ closestId ].InPortId ); + + ParentNode selectedNode = CurrentGraph.SelectedNodes[ 0 ]; + if( selectedNode.InputPorts.Count > 0 && selectedNode.OutputPorts.Count > 0 ) + { + Undo.RegisterCompleteObjectUndo( this, Constants.UndoCreateConnectionId ); + selectedNode.RecordObject( Constants.UndoCreateConnectionId ); + inNode.RecordObject( Constants.UndoCreateConnectionId ); + outNode.RecordObject( Constants.UndoCreateConnectionId ); + + m_mainGraphInstance.CreateConnection( selectedNode.UniqueId, selectedNode.InputPorts[ 0 ].PortId, outputPort.NodeId, outputPort.PortId ); + m_mainGraphInstance.CreateConnection( inputPort.NodeId, inputPort.PortId, selectedNode.UniqueId, selectedNode.OutputPorts[ 0 ].PortId ); + } + + SetSaveIsDirty(); + ForceRepaint(); + } + } + } + UIUtils.ShowContextOnPick = true; + m_altBoxSelection = false; + m_multipleSelectionActive = false; + UseCurrentEvent(); + } + + public void ConnectInputToOutput( int inNodeId, int inPortId, int outNodeId, int outPortId, bool registerUndo = true ) + { + ParentNode inNode = m_mainGraphInstance.GetNode( inNodeId ); + ParentNode outNode = m_mainGraphInstance.GetNode( outNodeId ); + if( inNode != null && outNode != null ) + { + InputPort inPort = inNode.GetInputPortByUniqueId( inPortId ); + OutputPort outPort = outNode.GetOutputPortByUniqueId( outPortId ); + if( inPort != null && outPort != null ) + { + if( registerUndo ) + { + Undo.RegisterCompleteObjectUndo( this, Constants.UndoCreateConnectionId ); + inNode.RecordObject( Constants.UndoCreateConnectionId ); + outNode.RecordObject( Constants.UndoCreateConnectionId ); + } + + if( inPort.ConnectTo( outNodeId, outPortId, outPort.DataType, inPort.TypeLocked ) ) + { + inNode.OnInputPortConnected( inPortId, outNodeId, outPortId ); + } + + if( outPort.ConnectTo( inNodeId, inPortId, inPort.DataType, inPort.TypeLocked ) ) + { + outNode.OnOutputPortConnected( outPortId, inNodeId, inPortId ); + } + } + m_mainGraphInstance.MarkWireHighlights(); + ShaderIsModified = true; + } + } + + void OnRightMouseDown() + { + Focus(); + m_rmbStartPos = m_currentMousePos2D; + UseCurrentEvent(); + } + + void OnRightMouseDrag() + { + // We look at the control to detect when user hits a tooltip ( which has a hot control of 0 ) + // This needs to be checked because on this first "frame" of hitting a tooltip because it generates incorrect mouse delta values + if( GUIUtility.hotControl == 0 && m_lastHotControl != 0 ) + { + m_lastHotControl = GUIUtility.hotControl; + return; + } + + m_lastHotControl = GUIUtility.hotControl; + if( m_currentEvent.alt ) + { + ModifyZoom( Constants.ALT_CAMERA_ZOOM_SPEED * ( m_currentEvent.delta.x + m_currentEvent.delta.y ), m_altKeyStartPos ); + } + else + { + m_cameraOffset += m_cameraZoom * m_currentEvent.delta; + } + UseCurrentEvent(); + } + + void OnRightMouseUp() + { + //Resetting the hot control test variable so it can be used again on right mouse drag detection ( if we did not do this then m_lastHotControl could be left with a a value of 0 and wouldn't be able to be correctly used on rthe drag ) + m_lastHotControl = -1; + + if( ( m_rmbStartPos - m_currentMousePos2D ).sqrMagnitude < Constants.RMB_SCREEN_DIST ) + { + ParentNode node = m_mainGraphInstance.CheckNodeAt( m_currentMousePos, true ); + if( node == null ) + { + m_contextPalette.Show( m_currentMousePos2D, m_cameraInfo ); + } + } + UseCurrentEvent(); + } + + void UpdateSelectionArea() + { + m_multipleSelectionArea.size = TranformedMousePos - m_multipleSelectionStart; + } + + public void OnValidObjectsDropped( UnityEngine.Object[] droppedObjs ) + { + bool propagateDraggedObjsToNode = true; + // Only supporting single drag&drop object selection + if( droppedObjs.Length == 1 ) + { + ShaderIsModified = true; + SetSaveIsDirty(); + // Check if its a shader, material or game object and if so load the shader graph code from it + Shader newShader = droppedObjs[ 0 ] as Shader; + Material newMaterial = null; + if( newShader == null ) + { + newMaterial = droppedObjs[ 0 ] as Material; +#if UNITY_2018_1_OR_NEWER + bool isProcedural = ( newMaterial != null ); +#else + // Disabling Substance Deprecated warning +#pragma warning disable 0618 + bool isProcedural = ( newMaterial != null && newMaterial is ProceduralMaterial ); +#pragma warning restore 0618 +#endif + if( newMaterial != null && !isProcedural ) + { + if( UIUtils.IsUnityNativeShader( AssetDatabase.GetAssetPath( newMaterial.shader ) ) ) + { + return; + } + //newShader = newMaterial.shader; + LoadMaterialToASE( newMaterial ); + //m_mainGraphInstance.UpdateMaterialOnMasterNode( newMaterial ); + } + else + { + GameObject go = droppedObjs[ 0 ] as GameObject; + if( go != null ) + { + Renderer renderer = go.GetComponent<Renderer>(); + if( renderer ) + { + newMaterial = renderer.sharedMaterial; + newShader = newMaterial.shader; + } + } + } + } + + if( newShader != null ) + { + ConvertShaderToASE( newShader ); + + propagateDraggedObjsToNode = false; + } + + // if not shader loading then propagate the seletion to whats below the mouse + if( propagateDraggedObjsToNode ) + { + ParentNode node = m_mainGraphInstance.CheckNodeAt( m_currentMousePos ); + if( node != null ) + { + // if there's a node then pass the object into it to see if there's a setup with it + node.OnObjectDropped( droppedObjs[ 0 ] ); + } + else + { + // If not then check if there's a node that can be created through the dropped object + ParentNode newNode = m_contextMenu.CreateNodeFromCastType( droppedObjs[ 0 ].GetType() ); + if( newNode ) + { + newNode.ContainerGraph = m_mainGraphInstance; + newNode.Vec2Position = TranformedMousePos; + m_mainGraphInstance.AddNode( newNode, true ); + newNode.SetupFromCastObject( droppedObjs[ 0 ] ); + m_mainGraphInstance.SelectNode( newNode, false, false ); + ForceRepaint(); + bool find = false; + if( newNode is FunctionNode && CurrentGraph.CurrentShaderFunction != null ) + find = SearchFunctionNodeRecursively( CurrentGraph.CurrentShaderFunction ); + + if( find ) + { + DestroyNode( newNode, false ); + ShowMessage( "Shader Function loop detected, new node was removed to prevent errors." ); + } + } + } + } + } + } + + public bool SearchFunctionNodeRecursively( AmplifyShaderFunction function ) + { + List<FunctionNode> graphList = UIUtils.FunctionList(); + + bool nodeFind = false; + + for( int i = 0; i < graphList.Count; i++ ) + { + ParentGraph temp = CustomGraph; + CustomGraph = graphList[ i ].FunctionGraph; + nodeFind = SearchFunctionNodeRecursively( function ); + CustomGraph = temp; + + //Debug.Log( "tested = " + node.Function.FunctionName + " : " + function.FunctionName ); + + if( graphList[ i ].Function == function ) + return true; + } + + return nodeFind; + } + + public void SetDelayedMaterialMode( Material material ) + { + if( material == null ) + return; + m_delayedMaterialSet = material; + } + + public ShaderLoadResult LoadDroppedObject( bool value, Shader shader, Material material, AmplifyShaderFunction shaderFunction = null ) + { + UIUtils.CurrentWindow = this; + ShaderLoadResult result; + if( shaderFunction != null ) + { + string assetDatapath = AssetDatabase.GetAssetPath( shaderFunction ); + string latestOpenedFolder = Application.dataPath + assetDatapath.Substring( 6 ); + UIUtils.LatestOpenedFolder = latestOpenedFolder.Substring( 0, latestOpenedFolder.LastIndexOf( '/' ) + 1 ); + result = LoadFromDisk( assetDatapath, shaderFunction ); + CurrentSelection = ASESelectionMode.ShaderFunction; + IsShaderFunctionWindow = true; + titleContent.text = GenerateTabTitle( shaderFunction.FunctionName ); + titleContent.image = UIUtils.ShaderFunctionIcon; + m_lastpath = assetDatapath; + m_nodeParametersWindow.OnShaderFunctionLoad(); + //EditorPrefs.SetString( IOUtils.LAST_OPENED_OBJ_ID, assetDatapath ); + } + else if( value && shader != null ) + { + string assetDatapath = AssetDatabase.GetAssetPath( shader ); + string latestOpenedFolder = Application.dataPath + assetDatapath.Substring( 6 ); + UIUtils.LatestOpenedFolder = latestOpenedFolder.Substring( 0, latestOpenedFolder.LastIndexOf( '/' ) + 1 ); + result = LoadFromDisk( assetDatapath ); + switch( result ) + { + case ShaderLoadResult.LOADED: + { + m_mainGraphInstance.UpdateShaderOnMasterNode( shader ); + } + break; + case ShaderLoadResult.ASE_INFO_NOT_FOUND: + { + ShowMessage( "Loaded shader wasn't created with ASE. Saving it will remove previous data." ); + UIUtils.CreateEmptyFromInvalid( shader ); + } + break; + case ShaderLoadResult.FILE_NOT_FOUND: + case ShaderLoadResult.UNITY_NATIVE_PATHS: + { + UIUtils.CreateEmptyFromInvalid( shader ); + } + break; + } + + m_mainGraphInstance.UpdateMaterialOnMasterNode( material ); + m_mainGraphInstance.SetMaterialModeOnGraph( material ); + + if( material != null ) + { + CurrentSelection = ASESelectionMode.Material; + IsShaderFunctionWindow = false; + titleContent.text = GenerateTabTitle( material.name ); + titleContent.image = UIUtils.MaterialIcon; + if( material.HasProperty( IOUtils.DefaultASEDirtyCheckId ) ) + { + material.SetInt( IOUtils.DefaultASEDirtyCheckId, 1 ); + } + m_lastpath = AssetDatabase.GetAssetPath( material ); + EditorPrefs.SetString( IOUtils.LAST_OPENED_OBJ_ID, m_lastpath ); + } + else + { + CurrentSelection = ASESelectionMode.Shader; + IsShaderFunctionWindow = false; + titleContent.text = GenerateTabTitle( shader.name ); + titleContent.image = UIUtils.ShaderIcon; + m_lastpath = AssetDatabase.GetAssetPath( shader ); + EditorPrefs.SetString( IOUtils.LAST_OPENED_OBJ_ID, m_lastpath ); + } + } + else + { + result = ShaderLoadResult.FILE_NOT_FOUND; + } + return result; + } + + bool InsideMenus( Vector2 position ) + { + for( int i = 0; i < m_registeredMenus.Count; i++ ) + { + if( m_registeredMenus[ i ].IsInside( position ) ) + { + return true; + } + } + return false; + } + + void HandleGUIEvents() + { + if( m_currentEvent.type == EventType.KeyDown ) + { + m_contextMenu.UpdateKeyPress( m_currentEvent.keyCode ); + } + else if( m_currentEvent.type == EventType.KeyUp ) + { + m_contextMenu.UpdateKeyReleased( m_currentEvent.keyCode ); + } + + if( InsideMenus( m_currentMousePos2D ) ) + { + if( m_currentEvent.type == EventType.Used ) + m_mouseDownOnValidArea = false; + + if( m_currentEvent.type == EventType.MouseDown ) + { + m_mouseDownOnValidArea = false; + UseCurrentEvent(); + } + return; + } + else if( m_nodeParametersWindow.IsResizing || m_paletteWindow.IsResizing ) + { + m_mouseDownOnValidArea = false; + } + + int controlID = GUIUtility.GetControlID( FocusType.Passive ); + switch( m_currentEvent.GetTypeForControl( controlID ) ) + { + case EventType.MouseDown: + { + GUIUtility.hotControl = controlID; + switch( m_currentEvent.button ) + { + case ButtonClickId.LeftMouseButton: + { + OnLeftMouseDown(); + } + break; + case ButtonClickId.RightMouseButton: + case ButtonClickId.MiddleMouseButton: + { + OnRightMouseDown(); + } + break; + } + } + break; + case EventType.MouseMove: + { + m_keyEvtMousePos2D = m_currentEvent.mousePosition; + } + break; + case EventType.MouseUp: + { + GUIUtility.hotControl = 0; + switch( m_currentEvent.button ) + { + case ButtonClickId.LeftMouseButton: + { + OnLeftMouseUp(); + } + break; + case ButtonClickId.MiddleMouseButton: break; + case ButtonClickId.RightMouseButton: + { + OnRightMouseUp(); + } + break; + } + } + break; + case EventType.MouseDrag: + { + switch( m_currentEvent.button ) + { + case ButtonClickId.LeftMouseButton: + { + OnLeftMouseDrag(); + } + break; + case ButtonClickId.MiddleMouseButton: + case ButtonClickId.RightMouseButton: + { + OnRightMouseDrag(); + } + break; + } + } + break; + case EventType.ScrollWheel: + { + OnScrollWheel(); + } + break; + case EventType.KeyDown: + { + OnKeyboardDown(); + } + break; + case EventType.KeyUp: + { + OnKeyboardUp(); + } + break; + case EventType.ValidateCommand: + { + switch( m_currentEvent.commandName ) + { + case CopyCommand: + case PasteCommand: + case SelectAll: + case Duplicate: + { + m_currentEvent.Use(); + } + break; + case ObjectSelectorClosed: + { + m_mouseDownOnValidArea = false; + } + break; + } + } + break; + case EventType.ExecuteCommand: + { + m_currentEvent.Use(); + switch( m_currentEvent.commandName ) + { + case CopyCommand: + { + CopyToClipboard(); + } + break; + case PasteCommand: + { + PasteFromClipboard( true ); + } + break; + case SelectAll: + { + m_mainGraphInstance.SelectAll(); + ForceRepaint(); + } + break; + case Duplicate: + { + CopyToClipboard(); + PasteFromClipboard( true ); + } + break; + case ObjectSelectorClosed: + { + m_mouseDownOnValidArea = false; + } + break; + } + } + break; + case EventType.Repaint: + { + } + break; + } + + m_dragAndDropTool.TestDragAndDrop( m_graphArea ); + + } + + public void DeleteConnection( bool isInput, int nodeId, int portId, bool registerOnLog, bool propagateCallback ) + { + m_mainGraphInstance.DeleteConnection( isInput, nodeId, portId, registerOnLog, propagateCallback ); + } + + void DeleteSelectedNodes() + { + if( m_mainGraphInstance.SelectedNodes.Count == 0 ) + return; + + UIUtils.ClearUndoHelper(); + ParentNode[] selectedNodes = new ParentNode[ m_mainGraphInstance.SelectedNodes.Count ]; + for( int i = 0; i < selectedNodes.Length; i++ ) + { + selectedNodes[ i ] = m_mainGraphInstance.SelectedNodes[ i ]; + selectedNodes[ i ].Rewire(); + UIUtils.CheckUndoNode( selectedNodes[ i ] ); + } + + //Check nodes connected to deleted nodes to preserve connections on undo + List<ParentNode> extraNodes = new List<ParentNode>(); + for( int selectedNodeIdx = 0; selectedNodeIdx < selectedNodes.Length; selectedNodeIdx++ ) + { + // Check inputs + { + int inputIdxCount = selectedNodes[ selectedNodeIdx ].InputPorts.Count; + if( inputIdxCount > 0 ) + { + for( int inputIdx = 0; inputIdx < inputIdxCount; inputIdx++ ) + { + if( selectedNodes[ selectedNodeIdx ].InputPorts[ inputIdx ].IsConnected ) + { + int nodeIdx = selectedNodes[ selectedNodeIdx ].InputPorts[ inputIdx ].ExternalReferences[ 0 ].NodeId; + if( nodeIdx > -1 ) + { + ParentNode node = m_mainGraphInstance.GetNode( nodeIdx ); + if( node != null && UIUtils.CheckUndoNode( node ) ) + { + extraNodes.Add( node ); + } + } + } + } + } + } + + // Check outputs + int outputIdxCount = selectedNodes[ selectedNodeIdx ].OutputPorts.Count; + if( outputIdxCount > 0 ) + { + for( int outputIdx = 0; outputIdx < outputIdxCount; outputIdx++ ) + { + int inputIdxCount = selectedNodes[ selectedNodeIdx ].OutputPorts[ outputIdx ].ExternalReferences.Count; + if( inputIdxCount > 0 ) + { + for( int inputIdx = 0; inputIdx < inputIdxCount; inputIdx++ ) + { + int nodeIdx = selectedNodes[ selectedNodeIdx ].OutputPorts[ outputIdx ].ExternalReferences[ inputIdx ].NodeId; + if( nodeIdx > -1 ) + { + ParentNode node = m_mainGraphInstance.GetNode( nodeIdx ); + if( UIUtils.CheckUndoNode( node ) ) + { + extraNodes.Add( node ); + } + } + } + } + } + } + } + + UIUtils.ClearUndoHelper(); + //Undo.IncrementCurrentGroup(); + //Record deleted nodes + UIUtils.MarkUndoAction(); + Undo.RegisterCompleteObjectUndo( this, Constants.UndoDeleteNodeId ); + Undo.RegisterCompleteObjectUndo( m_mainGraphInstance, Constants.UndoDeleteNodeId ); + Undo.RecordObjects( selectedNodes, Constants.UndoDeleteNodeId ); + Undo.RecordObjects( extraNodes.ToArray(), Constants.UndoDeleteNodeId ); + + //Record deleting connections + for( int i = 0; i < selectedNodes.Length; i++ ) + { + selectedNodes[ i ].Alive = false; + m_mainGraphInstance.DeleteAllConnectionFromNode( selectedNodes[ i ], false, true, true ); + } + //Delete + m_mainGraphInstance.DeleteNodesOnArray( ref selectedNodes ); + + + //Undo.IncrementCurrentGroup(); + extraNodes.Clear(); + extraNodes = null; + + EditorUtility.SetDirty( this ); + + ForceRepaint(); + } + + void OnKeyboardUp() + { + CheckKeyboardCameraUp(); + + if( m_altPressDown ) + { + m_altPressDown = false; + } + + if( m_shortcutManager.ActivateShortcut( m_currentEvent.modifiers, m_lastKeyPressed, false ) ) + { + ForceRepaint(); + } + m_lastKeyPressed = KeyCode.None; + } + + bool OnKeyboardPress( KeyCode code ) + { + return ( m_currentEvent.keyCode == code && m_lastKeyPressed == KeyCode.None ); + } + + void CheckKeyboardCameraDown() + { + if( m_contextPalette.IsActive ) + return; + if( m_currentEvent.alt ) + { + bool foundKey = false; + float dir = 0; + switch( m_currentEvent.keyCode ) + { + case KeyCode.UpArrow: foundKey = true; dir = 1; break; + case KeyCode.DownArrow: foundKey = true; dir = -1; break; + case KeyCode.LeftArrow: foundKey = true; dir = 1; break; + case KeyCode.RightArrow: foundKey = true; dir = -1; break; + } + if( foundKey ) + { + ModifyZoom( Constants.ALT_CAMERA_ZOOM_SPEED * dir * m_cameraSpeed, new Vector2( m_cameraInfo.width * 0.5f, m_cameraInfo.height * 0.5f ) ); + if( m_cameraSpeed < 15 ) + m_cameraSpeed += 0.2f; + UseCurrentEvent(); + } + + + } + else + { + bool foundKey = false; + Vector2 dir = Vector2.zero; + switch( m_currentEvent.keyCode ) + { + case KeyCode.UpArrow: foundKey = true; dir = Vector2.up; break; + case KeyCode.DownArrow: foundKey = true; dir = Vector2.down; break; + case KeyCode.LeftArrow: foundKey = true; dir = Vector2.right; break; + case KeyCode.RightArrow: foundKey = true; dir = Vector2.left; break; + } + if( foundKey ) + { + m_cameraOffset += m_cameraZoom * m_cameraSpeed * dir; + if( m_cameraSpeed < 15 ) + m_cameraSpeed += 0.2f; + + UseCurrentEvent(); + } + } + } + + void CheckKeyboardCameraUp() + { + switch( m_currentEvent.keyCode ) + { + case KeyCode.UpArrow: + case KeyCode.DownArrow: + case KeyCode.LeftArrow: + case KeyCode.RightArrow: m_cameraSpeed = 1; break; + } + } + + void OnKeyboardDown() + { + //if( DebugConsoleWindow.DeveloperMode ) + //{ + // if( OnKeyboardPress( KeyCode.F8 ) ) + // { + // Shader currShader = CurrentGraph.CurrentShader; + // ShaderUtilEx.OpenCompiledShader( currShader, ShaderInspectorPlatformsPopupEx.GetCurrentMode(), ShaderInspectorPlatformsPopupEx.GetCurrentPlatformMask(), ShaderInspectorPlatformsPopupEx.GetCurrentVariantStripping() == 0 ); + + // string filename = Application.dataPath; + // filename = filename.Replace( "Assets", "Temp/Compiled-" ); + // string shaderFilename = AssetDatabase.GetAssetPath( currShader ); + // int lastIndex = shaderFilename.LastIndexOf( '/' ) + 1; + // filename = filename + shaderFilename.Substring( lastIndex ); + + // string compiledContents = IOUtils.LoadTextFileFromDisk( filename ); + // Debug.Log( compiledContents ); + // } + + // if( OnKeyboardPress( KeyCode.F9 ) ) + // { + // m_nodeExporterUtils.CalculateShaderInstructions( CurrentGraph.CurrentShader ); + // } + //} + + CheckKeyboardCameraDown(); + + if( m_lastKeyPressed == KeyCode.None ) + { + m_shortcutManager.ActivateShortcut( m_currentEvent.modifiers, m_currentEvent.keyCode, true ); + } + + if( m_currentEvent.control && m_currentEvent.shift && m_currentEvent.keyCode == KeyCode.V ) + { + PasteFromClipboard( false ); + } + + if( !m_altPressDown && ( OnKeyboardPress( KeyCode.LeftAlt ) || OnKeyboardPress( KeyCode.RightAlt ) || OnKeyboardPress( KeyCode.AltGr ) ) ) + { + m_altPressDown = true; + m_altAvailable = true; + m_altKeyStartPos = m_currentMousePos2D; + } + + if( m_currentEvent.keyCode != KeyCode.None && m_currentEvent.modifiers == EventModifiers.None ) + { + m_lastKeyPressed = m_currentEvent.keyCode; + } + } + + IEnumerator m_coroutine; + + private void StartPasteRequest() + { + m_coroutine = SendPostCoroutine( "http://paste.amplify.pt/api/create" ); + EditorApplication.update += PasteRequest; + } + + IEnumerator SendPostCoroutine( string url ) + { + WWWForm form = new WWWForm(); + form.AddField( "text", Clipboard.ClipboardId + ";" + EditorPrefs.GetString( Clipboard.ClipboardId, string.Empty ) ); + form.AddField( "title", "ASE Copy" ); + form.AddField( "name", "ASE" ); + form.AddField( "private", "1" ); + form.AddField( "lang", "text" ); + form.AddField( "expire", "0" ); + + UnityWebRequest www = UnityWebRequest.Post( url, form ); +#if UNITY_2017_2_OR_NEWER + www.SendWebRequest(); +#else + www.Send(); +#endif + + yield return www; + } + + public void PasteRequest() + { + UnityWebRequest www = (UnityWebRequest)m_coroutine.Current; + if( !m_coroutine.MoveNext() ) + { + if( !www.isDone ) + { + m_coroutine.MoveNext(); + } + else + { +#if UNITY_2020_1_OR_NEWER + if( www.result == UnityWebRequest.Result.ConnectionError ) +#elif UNITY_2017_2_OR_NEWER + if( www.isNetworkError ) +#else + if( www.isError ) +#endif + { + Debug.Log( "[AmplifyShaderEditor]\n" + www.error ); + } + else + { + // Print Body + string finalURL = www.downloadHandler.text; + + if( finalURL.IndexOf( "paste.amplify.pt/view/" ) > -1 ) + { + System.Text.RegularExpressions.Regex parser = new System.Text.RegularExpressions.Regex( @".*(http:\/\/paste.amplify.pt\/view\/)([0-9a-z]*).*", System.Text.RegularExpressions.RegexOptions.Singleline ); + finalURL = parser.Replace( finalURL, "$1raw/$2" ); + + ShowMessage( "Link copied to clipboard\n"+ finalURL, consoleLog:false ); + Debug.Log( "[AmplifyShaderEditor] Link copied to clipboard\n"+ finalURL+"\n" ); + // Copy Paste to clipboard + EditorGUIUtility.systemCopyBuffer = finalURL; + } + else + { + Debug.Log( "[AmplifyShaderEditor] Failed to generate paste:\n" + finalURL ); + } + } + EditorApplication.update -= PasteRequest; + } + } + } + + void OnScrollWheel() + { + ModifyZoomSmooth( m_currentEvent.delta.y, m_currentMousePos2D ); + UseCurrentEvent(); + } + + void ModifyZoom( float zoomIncrement, Vector2 pivot ) + { + float minCam = Mathf.Min( ( m_cameraInfo.width - ( m_nodeParametersWindow.RealWidth + m_paletteWindow.RealWidth ) ), ( m_cameraInfo.height - ( m_toolsWindow.Height ) ) ); + if( minCam < 1 ) + minCam = 1; + + float dynamicMaxZoom = m_mainGraphInstance.MaxNodeDist / minCam; + + Vector2 canvasPos = TranformPosition( pivot ); + if( zoomIncrement < 0 ) + CameraZoom = Mathf.Max( m_cameraZoom + zoomIncrement * Constants.CAMERA_ZOOM_SPEED, Constants.CAMERA_MIN_ZOOM ); + else if( CameraZoom < Mathf.Max( Constants.CAMERA_MAX_ZOOM, dynamicMaxZoom ) ) + CameraZoom = m_cameraZoom + zoomIncrement * Constants.CAMERA_ZOOM_SPEED;// Mathf.Min( m_cameraZoom + zoomIncrement * Constants.CAMERA_ZOOM_SPEED, Mathf.Max( Constants.CAMERA_MAX_ZOOM, dynamicMaxZoom ) ); + m_cameraOffset.x = pivot.x * m_cameraZoom - canvasPos.x; + m_cameraOffset.y = pivot.y * m_cameraZoom - canvasPos.y; + } + + void ModifyZoomSmooth( float zoomIncrement, Vector2 pivot ) + { + if( m_smoothZoom && Mathf.Sign( m_targetZoomIncrement * zoomIncrement ) >= 0 ) + m_targetZoomIncrement += zoomIncrement; + else + m_targetZoomIncrement = zoomIncrement; + + m_smoothZoom = true; + m_zoomTime = 0; + + float minCam = Mathf.Min( ( m_cameraInfo.width - ( m_nodeParametersWindow.RealWidth + m_paletteWindow.RealWidth ) ), ( m_cameraInfo.height - ( m_toolsWindow.Height ) ) ); + if( minCam < 1 ) + minCam = 1; + + float dynamicMaxZoom = m_mainGraphInstance.MaxNodeDist / minCam; + if( m_targetZoomIncrement < 0 ) + m_targetZoom = Mathf.Max( m_cameraZoom + m_targetZoomIncrement * Constants.CAMERA_ZOOM_SPEED, Constants.CAMERA_MIN_ZOOM ); + else if( CameraZoom < Mathf.Max( Constants.CAMERA_MAX_ZOOM, dynamicMaxZoom ) ) + m_targetZoom = m_cameraZoom + m_targetZoomIncrement * Constants.CAMERA_ZOOM_SPEED;// Mathf.Min( m_cameraZoom + zoomIncrement * Constants.CAMERA_ZOOM_SPEED, Mathf.Max( Constants.CAMERA_MAX_ZOOM, dynamicMaxZoom ) ); + + m_zoomPivot = pivot; + } + + void OnSelectionChange() + { + ForceRepaint(); + } + + private void OnFocus() + { + EditorGUI.FocusTextInControl( null ); +#if UNITY_2019_1_OR_NEWER + m_fixOnFocus = true; +#endif + } + + void OnLostFocus() + { + m_lostFocus = true; + m_multipleSelectionActive = false; + m_wireReferenceUtils.InvalidateReferences(); + if( m_genericMessageUI != null ) + m_genericMessageUI.CleanUpMessageStack(); + m_nodeParametersWindow.OnLostFocus(); + m_paletteWindow.OnLostFocus(); + m_contextMenu.ResetShortcutKeyStates(); + } + + void CopyToClipboard() + { + m_copyPasteDeltaMul = 0; + m_copyPasteDeltaPos = new Vector2( float.MaxValue, float.MaxValue ); + m_clipboard.ClearClipboard(); + m_copyPasteInitialPos = m_mainGraphInstance.SelectedNodesCentroid; + m_clipboard.AddToClipboard( m_mainGraphInstance.SelectedNodes, m_copyPasteInitialPos, m_mainGraphInstance ); + } + + ParentNode CreateNodeFromClipboardData( int clipId ) + { + string[] parameters = m_clipboard.CurrentClipboardStrData[ clipId ].Data.Split( IOUtils.FIELD_SEPARATOR ); + System.Type nodeType = System.Type.GetType( parameters[ IOUtils.NodeTypeId ] ); + NodeAttributes attributes = m_contextMenu.GetNodeAttributesForType( nodeType ); + if( attributes != null && !UIUtils.GetNodeAvailabilityInBitArray( attributes.NodeAvailabilityFlags, m_mainGraphInstance.CurrentCanvasMode ) && !UIUtils.GetNodeAvailabilityInBitArray( attributes.NodeAvailabilityFlags, m_currentNodeAvailability ) ) + return null; + + ParentNode newNode = (ParentNode)ScriptableObject.CreateInstance( nodeType ); + newNode.IsNodeBeingCopied = true; + if( newNode != null ) + { + newNode.ContainerGraph = m_mainGraphInstance; + newNode.ClipboardFullReadFromString( ref parameters ); + m_mainGraphInstance.AddNode( newNode, true, true, true, false ); + newNode.IsNodeBeingCopied = false; + m_clipboard.CurrentClipboardStrData[ clipId ].NewNodeId = newNode.UniqueId; + return newNode; + } + return null; + } + + void CreateConnectionsFromClipboardData( int clipId ) + { + if( String.IsNullOrEmpty( m_clipboard.CurrentClipboardStrData[ clipId ].Connections ) ) + return; + string[] lines = m_clipboard.CurrentClipboardStrData[ clipId ].Connections.Split( IOUtils.LINE_TERMINATOR ); + + for( int lineIdx = 0; lineIdx < lines.Length; lineIdx++ ) + { + string[] parameters = lines[ lineIdx ].Split( IOUtils.FIELD_SEPARATOR ); + + int InNodeId = 0; + int InPortId = 0; + int OutNodeId = 0; + int OutPortId = 0; + + try + { + InNodeId = Convert.ToInt32( parameters[ IOUtils.InNodeId ] ); + InPortId = Convert.ToInt32( parameters[ IOUtils.InPortId ] ); + + OutNodeId = Convert.ToInt32( parameters[ IOUtils.OutNodeId ] ); + OutPortId = Convert.ToInt32( parameters[ IOUtils.OutPortId ] ); + } + catch( Exception e ) + { + Debug.LogException( e ); + } + + + int newInNodeId = m_clipboard.GeNewNodeId( InNodeId ); + int newOutNodeId = m_clipboard.GeNewNodeId( OutNodeId ); + + if( newInNodeId > -1 && newOutNodeId > -1 ) + { + ParentNode inNode = m_mainGraphInstance.GetNode( newInNodeId ); + ParentNode outNode = m_mainGraphInstance.GetNode( newOutNodeId ); + + InputPort inputPort = null; + OutputPort outputPort = null; + + if( inNode != null && outNode != null ) + { + inNode.IsNodeBeingCopied = true; + outNode.IsNodeBeingCopied = true; + inputPort = inNode.GetInputPortByUniqueId( InPortId ); + outputPort = outNode.GetOutputPortByUniqueId( OutPortId ); + if( inputPort != null && outputPort != null ) + { + inputPort.ConnectTo( newOutNodeId, OutPortId, outputPort.DataType, false ); + outputPort.ConnectTo( newInNodeId, InPortId, inputPort.DataType, inputPort.TypeLocked ); + + inNode.OnInputPortConnected( InPortId, newOutNodeId, OutPortId ); + outNode.OnOutputPortConnected( OutPortId, newInNodeId, InPortId ); + } + + inNode.IsNodeBeingCopied = false; + outNode.IsNodeBeingCopied = false; + } + } + } + } + + private void StartGetRequest( string url ) + { + m_coroutine = SendGetCoroutine( url ); + EditorApplication.update += GetRequest; + } + + IEnumerator SendGetCoroutine( string url ) + { + UnityWebRequest www = UnityWebRequest.Get( url ); +#if UNITY_2017_2_OR_NEWER + www.SendWebRequest(); +#else + www.Send(); +#endif + + yield return www; + } + + public void GetRequest() + { + UnityWebRequest www = (UnityWebRequest)m_coroutine.Current; + if( !m_coroutine.MoveNext() ) + { + if( !www.isDone ) + { + m_coroutine.MoveNext(); + } + else + { +#if UNITY_2020_1_OR_NEWER + if( www.result == UnityWebRequest.Result.ConnectionError ) +#elif UNITY_2017_2_OR_NEWER + if( www.isNetworkError ) +#else + if( www.isError ) +#endif + { + Debug.Log( "[AmplifyShaderEditor]\n" + www.error ); + } + else + { + string data = www.downloadHandler.text; + if( data.IndexOf( Clipboard.ClipboardId + ";" ) > -1 ) + { + data = www.downloadHandler.text.Replace( Clipboard.ClipboardId + ";", "" ); + if( data.IndexOf( "<div " ) > -1 ) + { + System.Text.RegularExpressions.Regex parser = new System.Text.RegularExpressions.Regex( @"(.*)<div .*", System.Text.RegularExpressions.RegexOptions.Singleline ); + data = parser.Replace( data, "$1" ); + } + EditorGUIUtility.systemCopyBuffer = string.Empty; + Debug.Log( "[AmplifyShaderEditor] Successfully downloaded snippet!" ); + EditorPrefs.SetString( Clipboard.ClipboardId, data ); + try + { + // send paste event instead to make sure it runs properly + Event e = new Event(); + e.type = EventType.ExecuteCommand; + e.commandName = PasteCommand; + this.SendEvent( e ); + } + catch( Exception ) + { + EditorGUIUtility.systemCopyBuffer = string.Empty; + EditorApplication.update -= GetRequest; + throw; + } + } + else + { + Debug.Log( "[AmplifyShaderEditor] Error downloading, snippet might not exist anymore, clearing clipboard..." ); + EditorGUIUtility.systemCopyBuffer = string.Empty; + } + } + EditorApplication.update -= GetRequest; + } + } + } + + void PasteFromClipboard( bool copyConnections ) + { + string result = EditorGUIUtility.systemCopyBuffer; + if( result.IndexOf( "http://paste.amplify.pt/view/raw/" ) > -1 ) + { + StartGetRequest( result ); + return; + } + + if( result.IndexOf( Clipboard.ClipboardId + ";" ) > -1 ) + { + result = result.Replace( Clipboard.ClipboardId + ";", "" ); + EditorPrefs.SetString( Clipboard.ClipboardId, result ); + } + + m_mainGraphInstance.IsDuplicating = true; + m_copyPasteInitialPos = m_clipboard.GetDataFromEditorPrefs(); + if( m_clipboard.CurrentClipboardStrData.Count == 0 ) + { + return; + } + + Vector2 deltaPos = TranformedKeyEvtMousePos - m_copyPasteInitialPos; + if( ( m_copyPasteDeltaPos - deltaPos ).magnitude > 5.0f ) + { + m_copyPasteDeltaMul = 0; + } + else + { + m_copyPasteDeltaMul += 1; + } + m_copyPasteDeltaPos = deltaPos; + + m_mainGraphInstance.DeSelectAll(); + UIUtils.InhibitMessages = true; + + if( m_clipboard.CurrentClipboardStrData.Count > 0 ) + { + UIUtils.MarkUndoAction(); + Undo.RegisterCompleteObjectUndo( this, Constants.UndoPasteNodeId ); + } + + List<ParentNode> createdNodes = new List<ParentNode>(); + for( int i = 0; i < m_clipboard.CurrentClipboardStrData.Count; i++ ) + { + ParentNode node = CreateNodeFromClipboardData( i ); + if( node != null ) + { + m_clipboard.CurrentClipboardStrData[ i ].NewNodeId = node.UniqueId; + Vector2 pos = node.Vec2Position; + node.Vec2Position = pos + deltaPos + m_copyPasteDeltaMul * Constants.CopyPasteDeltaPos; + //node.RefreshExternalReferences(); + node.AfterDuplication(); + createdNodes.Add( node ); + m_mainGraphInstance.SelectNode( node, true, false ); + } + } + + if( copyConnections ) + { + for( int i = 0; i < m_clipboard.CurrentClipboardStrData.Count; i++ ) + { + CreateConnectionsFromClipboardData( i ); + } + } + + // Refresh external references must always be called after all nodes are created + for( int i = 0; i < createdNodes.Count; i++ ) + { + createdNodes[ i ].RefreshExternalReferences(); + } + createdNodes.Clear(); + createdNodes = null; + //Need to force increment on Undo because if not Undo may incorrectly group consecutive pastes + Undo.IncrementCurrentGroup(); + + UIUtils.InhibitMessages = false; + ShaderIsModified = true; + SetSaveIsDirty(); + ForceRepaint(); + m_mainGraphInstance.IsDuplicating = false; + } + + public string GenerateGraphInfo() + { + string graphInfo = IOUtils.ShaderBodyBegin + '\n'; + string nodesInfo = ""; + string connectionsInfo = ""; + graphInfo += VersionInfo.FullLabel + '\n'; + graphInfo += ( + m_cameraInfo.x.ToString() + IOUtils.FIELD_SEPARATOR + + m_cameraInfo.y.ToString() + IOUtils.FIELD_SEPARATOR + + m_cameraInfo.width.ToString() + IOUtils.FIELD_SEPARATOR + + m_cameraInfo.height.ToString() + IOUtils.FIELD_SEPARATOR + + m_cameraOffset.x.ToString() + IOUtils.FIELD_SEPARATOR + + m_cameraOffset.y.ToString() + IOUtils.FIELD_SEPARATOR + + m_cameraZoom.ToString() + IOUtils.FIELD_SEPARATOR + + m_nodeParametersWindow.IsMaximized + IOUtils.FIELD_SEPARATOR + + m_paletteWindow.IsMaximized + '\n' + ); + m_mainGraphInstance.OrderNodesByGraphDepth(); + m_mainGraphInstance.WriteToString( ref nodesInfo, ref connectionsInfo ); + graphInfo += nodesInfo; + graphInfo += connectionsInfo; + graphInfo += IOUtils.ShaderBodyEnd + '\n'; + + return graphInfo; + } + + // TODO: this need to be fused to the main load function somehow + public static void LoadFromMeta( ref ParentGraph graph, GraphContextMenu contextMenu, string meta ) + { + graph.IsLoading = true; + graph.CleanNodes(); + + int checksumId = meta.IndexOf( IOUtils.CHECKSUM ); + if( checksumId > -1 ) + { + string checkSumStoredValue = meta.Substring( checksumId ); + string trimmedBuffer = meta.Remove( checksumId ); + + string[] typeValuePair = checkSumStoredValue.Split( IOUtils.VALUE_SEPARATOR ); + if( typeValuePair != null && typeValuePair.Length == 2 ) + { + // Check read checksum and compare with the actual shader body to detect external changes + string currentChecksumValue = IOUtils.CreateChecksum( trimmedBuffer ); + if( DebugConsoleWindow.DeveloperMode && !currentChecksumValue.Equals( typeValuePair[ 1 ] ) ) + { + //ShowMessage( "Wrong checksum" ); + } + + trimmedBuffer = trimmedBuffer.Replace( "\r", string.Empty ); + // find node info body + int shaderBodyId = trimmedBuffer.IndexOf( IOUtils.ShaderBodyBegin ); + if( shaderBodyId > -1 ) + { + trimmedBuffer = trimmedBuffer.Substring( shaderBodyId ); + //Find set of instructions + string[] instructions = trimmedBuffer.Split( IOUtils.LINE_TERMINATOR ); + // First line is to be ignored and second line contains version + string[] versionParams = instructions[ 1 ].Split( IOUtils.VALUE_SEPARATOR ); + if( versionParams.Length == 2 ) + { + int version = 0; + try + { + version = Convert.ToInt32( versionParams[ 1 ] ); + } + catch( Exception e ) + { + Debug.LogException( e ); + } + + //if( version > versionInfo.FullNumber ) + //{ + //ShowMessage( "This shader was created on a new ASE version\nPlease install v." + version ); + //} + + if( DebugConsoleWindow.DeveloperMode ) + { + //if( version < versionInfo.FullNumber ) + //{ + //ShowMessage( "This shader was created on a older ASE version\nSaving will update it to the new one." ); + //} + } + + graph.LoadedShaderVersion = version; + } + else + { + //ShowMessage( "Corrupted version" ); + } + + // Dummy values,camera values can only be applied after node loading is complete + Rect dummyCameraInfo = new Rect(); + Vector2 dummyCameraOffset = new Vector2(); + //float dummyCameraZoom = 0; + //bool applyDummy = false; + //bool dummyNodeParametersWindowMaximized = false; + //bool dummyPaletteWindowMaximized = false; + + //Second line contains camera information ( position, size, offset and zoom ) + string[] cameraParams = instructions[ 2 ].Split( IOUtils.FIELD_SEPARATOR ); + if( cameraParams.Length == 9 ) + { + //applyDummy = true; + try + { + dummyCameraInfo.x = Convert.ToSingle( cameraParams[ 0 ] ); + dummyCameraInfo.y = Convert.ToSingle( cameraParams[ 1 ] ); + dummyCameraInfo.width = Convert.ToSingle( cameraParams[ 2 ] ); + dummyCameraInfo.height = Convert.ToSingle( cameraParams[ 3 ] ); + dummyCameraOffset.x = Convert.ToSingle( cameraParams[ 4 ] ); + dummyCameraOffset.y = Convert.ToSingle( cameraParams[ 5 ] ); + + //dummyCameraZoom = Convert.ToSingle( cameraParams[ 6 ] ); + //dummyNodeParametersWindowMaximized = Convert.ToBoolean( cameraParams[ 7 ] ); + //dummyPaletteWindowMaximized = Convert.ToBoolean( cameraParams[ 8 ] ); + } + catch( Exception e ) + { + Debug.LogException( e ); + } + } + else + { + //ShowMessage( "Camera parameters are corrupted" ); + } + + // valid instructions are only between the line after version and the line before the last one ( which contains ShaderBodyEnd ) + for( int instructionIdx = 3; instructionIdx < instructions.Length - 1; instructionIdx++ ) + { + //TODO: After all is working, convert string parameters to ints in order to speed up reading + string[] parameters = instructions[ instructionIdx ].Split( IOUtils.FIELD_SEPARATOR ); + + // All nodes must be created before wiring the connections ... + // Since all nodes on the save op are written before the wires, we can safely create them + // If that order is not maintained the it's because of external editing and its the users responsability + switch( parameters[ 0 ] ) + { + case IOUtils.NodeParam: + { + string typeStr = parameters[ IOUtils.NodeTypeId ]; + //System.Type type = System.Type.GetType( parameters[ IOUtils.NodeTypeId ] ); + System.Type type = System.Type.GetType( IOUtils.NodeTypeReplacer.ContainsKey( typeStr ) ? IOUtils.NodeTypeReplacer[ typeStr ] : typeStr ); + if( type != null ) + { + System.Type oldType = type; + NodeAttributes attribs = contextMenu.GetNodeAttributesForType( type ); + if( attribs == null ) + { + attribs = contextMenu.GetDeprecatedNodeAttributesForType( type ); + if( attribs != null ) + { + if( attribs.Deprecated && attribs.DeprecatedAlternativeType != null ) + { + type = attribs.DeprecatedAlternativeType; + //ShowMessage( string.Format( "Node {0} is deprecated and was replaced by {1} ", attribs.Name, attribs.DeprecatedAlternative ) ); + } + } + } + + ParentNode newNode = (ParentNode)ScriptableObject.CreateInstance( type ); + if( newNode != null ) + { + try + { + newNode.ContainerGraph = graph; + if( oldType != type ) + { + newNode.ParentReadFromString( ref parameters ); + newNode.ReadFromDeprecated( ref parameters, oldType ); + } + else + newNode.ReadFromString( ref parameters ); + + + if( oldType == type ) + { + newNode.ReadInputDataFromString( ref parameters ); + if( UIUtils.CurrentShaderVersion() > 5107 ) + { + newNode.ReadOutputDataFromString( ref parameters ); + } + } + } + catch( Exception e ) + { + Debug.LogException( e, newNode ); + } + graph.AddNode( newNode, false, true, false ); + } + } + else + { + UIUtils.ShowMessage( string.Format( "{0} is not a valid ASE node ", parameters[ IOUtils.NodeTypeId ] ), MessageSeverity.Error ); + } + } + break; + case IOUtils.WireConnectionParam: + { + int InNodeId = 0; + int InPortId = 0; + int OutNodeId = 0; + int OutPortId = 0; + + try + { + InNodeId = Convert.ToInt32( parameters[ IOUtils.InNodeId ] ); + InPortId = Convert.ToInt32( parameters[ IOUtils.InPortId ] ); + OutNodeId = Convert.ToInt32( parameters[ IOUtils.OutNodeId ] ); + OutPortId = Convert.ToInt32( parameters[ IOUtils.OutPortId ] ); + } + catch( Exception e ) + { + Debug.LogException( e ); + } + + ParentNode inNode = graph.GetNode( InNodeId ); + ParentNode outNode = graph.GetNode( OutNodeId ); + + //if ( UIUtils.CurrentShaderVersion() < 5002 ) + //{ + // InPortId = inNode.VersionConvertInputPortId( InPortId ); + // OutPortId = outNode.VersionConvertOutputPortId( OutPortId ); + //} + + InputPort inputPort = null; + OutputPort outputPort = null; + if( inNode != null && outNode != null ) + { + + if( UIUtils.CurrentShaderVersion() < 5002 ) + { + InPortId = inNode.VersionConvertInputPortId( InPortId ); + OutPortId = outNode.VersionConvertOutputPortId( OutPortId ); + + inputPort = inNode.GetInputPortByArrayId( InPortId ); + outputPort = outNode.GetOutputPortByArrayId( OutPortId ); + } + else + { + inputPort = inNode.GetInputPortByUniqueId( InPortId ); + outputPort = outNode.GetOutputPortByUniqueId( OutPortId ); + } + + if( inputPort != null && outputPort != null ) + { + bool inputCompatible = inputPort.CheckValidType( outputPort.DataType ); + bool outputCompatible = outputPort.CheckValidType( inputPort.DataType ); + if( inputCompatible && outputCompatible ) + { + inputPort.ConnectTo( OutNodeId, OutPortId, outputPort.DataType, false ); + outputPort.ConnectTo( InNodeId, InPortId, inputPort.DataType, inputPort.TypeLocked ); + + inNode.OnInputPortConnected( InPortId, OutNodeId, OutPortId, false ); + outNode.OnOutputPortConnected( OutPortId, InNodeId, InPortId ); + } + else if( DebugConsoleWindow.DeveloperMode ) + { + if( !inputCompatible ) + UIUtils.ShowIncompatiblePortMessage( true, inNode, inputPort, outNode, outputPort ); + + if( !outputCompatible ) + UIUtils.ShowIncompatiblePortMessage( true, outNode, outputPort, inNode, inputPort ); + } + } + else if( DebugConsoleWindow.DeveloperMode ) + { + if( inputPort == null ) + { + UIUtils.ShowMessage( "Input Port " + InPortId + " doesn't exist on node " + InNodeId, MessageSeverity.Error ); + } + else + { + UIUtils.ShowMessage( "Output Port " + OutPortId + " doesn't exist on node " + OutNodeId, MessageSeverity.Error ); + } + } + } + else if( DebugConsoleWindow.DeveloperMode ) + { + if( inNode == null ) + { + UIUtils.ShowMessage( "Input node " + InNodeId + " doesn't exist", MessageSeverity.Error ); + } + else + { + UIUtils.ShowMessage( "Output node " + OutNodeId + " doesn't exist", MessageSeverity.Error ); + } + } + } + break; + } + } + } + } + } + + graph.CheckForDuplicates(); + graph.UpdateRegisters(); + graph.RefreshExternalReferences(); + graph.ForceSignalPropagationOnMasterNode(); + graph.LoadedShaderVersion = VersionInfo.FullNumber; + //Reset(); + graph.IsLoading = false; + } + + public ShaderLoadResult LoadFromDisk( string pathname, AmplifyShaderFunction shaderFunction = null ) + { + m_mainGraphInstance.IsLoading = true; + System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.InvariantCulture; + + FullCleanUndoStack(); + m_performFullUndoRegister = true; + + UIUtils.DirtyMask = false; + if( UIUtils.IsUnityNativeShader( pathname ) ) + { + ShowMessage( "Cannot edit native unity shaders.\nReplacing by a new one." ); + return ShaderLoadResult.UNITY_NATIVE_PATHS; + } + + m_lastOpenedLocation = pathname; + Lastpath = pathname; + + string buffer = string.Empty; + if( shaderFunction == null ) + buffer = IOUtils.LoadTextFileFromDisk( pathname ); + else + buffer = shaderFunction.FunctionInfo; + + if( String.IsNullOrEmpty( buffer ) ) + { + ShowMessage( "Could not open file " + pathname ); + return ShaderLoadResult.FILE_NOT_FOUND; + } + + if( !IOUtils.HasValidShaderBody( ref buffer ) ) + { + return ShaderLoadResult.ASE_INFO_NOT_FOUND; + } + + m_mainGraphInstance.CleanNodes(); + Reset(); + + Shader shader = null; + ShaderLoadResult loadResult = ShaderLoadResult.LOADED; + // Find checksum value on body + int checksumId = buffer.IndexOf( IOUtils.CHECKSUM ); + if( checksumId > -1 ) + { + string checkSumStoredValue = buffer.Substring( checksumId ); + string trimmedBuffer = buffer.Remove( checksumId ); + + string[] typeValuePair = checkSumStoredValue.Split( IOUtils.VALUE_SEPARATOR ); + if( typeValuePair != null && typeValuePair.Length == 2 ) + { + // Check read checksum and compare with the actual shader body to detect external changes + string currentChecksumValue = IOUtils.CreateChecksum( trimmedBuffer ); + if( DebugConsoleWindow.DeveloperMode && !currentChecksumValue.Equals( typeValuePair[ 1 ] ) ) + { + ShowMessage( "Wrong checksum" ); + } + + trimmedBuffer = trimmedBuffer.Replace( "\r", string.Empty ); + // find node info body + int shaderBodyId = trimmedBuffer.IndexOf( IOUtils.ShaderBodyBegin ); + if( shaderBodyId > -1 ) + { + trimmedBuffer = trimmedBuffer.Substring( shaderBodyId ); + //Find set of instructions + string[] instructions = trimmedBuffer.Split( IOUtils.LINE_TERMINATOR ); + // First line is to be ignored and second line contains version + string[] versionParams = instructions[ 1 ].Split( IOUtils.VALUE_SEPARATOR ); + if( versionParams.Length == 2 ) + { + int version = 0; + try + { + version = Convert.ToInt32( versionParams[ 1 ] ); + } + catch( Exception e ) + { + Debug.LogException( e ); + } + + if( version > VersionInfo.FullNumber ) + { + ShowMessage( "This shader was created on a new ASE version\nPlease install v." + version ); + } + + if( DebugConsoleWindow.DeveloperMode ) + { + if( version < VersionInfo.FullNumber ) + { + ShowMessage( "This shader was created on a older ASE version\nSaving will update it to the new one." ); + } + } + + m_mainGraphInstance.LoadedShaderVersion = version; + } + else + { + ShowMessage( "Corrupted version" ); + } + + // Dummy values,camera values can only be applied after node loading is complete + Rect dummyCameraInfo = new Rect(); + Vector2 dummyCameraOffset = new Vector2(); + float dummyCameraZoom = 0; + bool applyDummy = false; + bool dummyNodeParametersWindowMaximized = false; + bool dummyPaletteWindowMaximized = false; + + //Second line contains camera information ( position, size, offset and zoom ) + string[] cameraParams = instructions[ 2 ].Split( IOUtils.FIELD_SEPARATOR ); + if( cameraParams.Length == 9 ) + { + applyDummy = true; + try + { + dummyCameraInfo.x = Convert.ToSingle( cameraParams[ 0 ] ); + dummyCameraInfo.y = Convert.ToSingle( cameraParams[ 1 ] ); + dummyCameraInfo.width = Convert.ToSingle( cameraParams[ 2 ] ); + dummyCameraInfo.height = Convert.ToSingle( cameraParams[ 3 ] ); + dummyCameraOffset.x = Convert.ToSingle( cameraParams[ 4 ] ); + dummyCameraOffset.y = Convert.ToSingle( cameraParams[ 5 ] ); + dummyCameraZoom = Convert.ToSingle( cameraParams[ 6 ] ); + + float centerWidth = ( this.position.width - dummyCameraInfo.width ) * 0.5f * dummyCameraZoom; + float centerHeight = ( this.position.height - dummyCameraInfo.height ) * 0.5f * dummyCameraZoom; + + dummyCameraInfo.x += centerWidth; + dummyCameraOffset.x += centerWidth; + dummyCameraInfo.y += centerHeight; + dummyCameraOffset.y += centerHeight; + dummyNodeParametersWindowMaximized = Convert.ToBoolean( cameraParams[ 7 ] ); + dummyPaletteWindowMaximized = Convert.ToBoolean( cameraParams[ 8 ] ); + } + catch( Exception e ) + { + Debug.LogException( e ); + } + } + else + { + ShowMessage( "Camera parameters are corrupted" ); + } + + // valid instructions are only between the line after version and the line before the last one ( which contains ShaderBodyEnd ) + for( int instructionIdx = 3; instructionIdx < instructions.Length - 1; instructionIdx++ ) + { + //TODO: After all is working, convert string parameters to ints in order to speed up reading + string[] parameters = instructions[ instructionIdx ].Split( IOUtils.FIELD_SEPARATOR ); + + // All nodes must be created before wiring the connections ... + // Since all nodes on the save op are written before the wires, we can safely create them + // If that order is not maintained the it's because of external editing and its the users responsability + switch( parameters[ 0 ] ) + { + case IOUtils.NodeParam: + { + string typeStr = parameters[ IOUtils.NodeTypeId ]; + System.Type type = System.Type.GetType( IOUtils.NodeTypeReplacer.ContainsKey( typeStr ) ? IOUtils.NodeTypeReplacer[ typeStr ] : typeStr ); + if( type != null ) + { + System.Type oldType = type; + NodeAttributes attribs = m_contextMenu.GetNodeAttributesForType( type ); + if( attribs == null ) + { + attribs = m_contextMenu.GetDeprecatedNodeAttributesForType( type ); + if( attribs != null ) + { + if( attribs.Deprecated ) + { + if( attribs.DeprecatedAlternativeType != null ) + { + type = attribs.DeprecatedAlternativeType; + ShowMessage( string.Format( "Node {0} is deprecated and was replaced by {1} ", attribs.Name, attribs.DeprecatedAlternative ) ); + } + else + { + if( string.IsNullOrEmpty( attribs.DeprecatedAlternative ) ) + ShowMessage( string.Format( Constants.DeprecatedNoAlternativeMessageStr, attribs.Name, attribs.DeprecatedAlternative ), MessageSeverity.Normal, false ); + else + ShowMessage( string.Format( Constants.DeprecatedMessageStr, attribs.Name, attribs.DeprecatedAlternative ), MessageSeverity.Normal, false ); + } + } + } + } + + ParentNode newNode = (ParentNode)ScriptableObject.CreateInstance( type ); + if( newNode != null ) + { + try + { + newNode.ContainerGraph = m_mainGraphInstance; + if( oldType != type ) + { + newNode.ParentReadFromString( ref parameters ); + newNode.ReadFromDeprecated( ref parameters, oldType ); + } + else + newNode.ReadFromString( ref parameters ); + + + if( oldType == type ) + { + newNode.ReadInputDataFromString( ref parameters ); + if( UIUtils.CurrentShaderVersion() > 5107 ) + { + newNode.ReadOutputDataFromString( ref parameters ); + } + } + } + catch( Exception e ) + { + Debug.LogException( e, newNode ); + } + m_mainGraphInstance.AddNode( newNode, false, true, false ); + } + } + else + { + ShowMessage( string.Format( "{0} is not a valid ASE node ", parameters[ IOUtils.NodeTypeId ] ), MessageSeverity.Error ); + } + } + break; + case IOUtils.WireConnectionParam: + { + int InNodeId = 0; + int InPortId = 0; + int OutNodeId = 0; + int OutPortId = 0; + + try + { + InNodeId = Convert.ToInt32( parameters[ IOUtils.InNodeId ] ); + InPortId = Convert.ToInt32( parameters[ IOUtils.InPortId ] ); + OutNodeId = Convert.ToInt32( parameters[ IOUtils.OutNodeId ] ); + OutPortId = Convert.ToInt32( parameters[ IOUtils.OutPortId ] ); + } + catch( Exception e ) + { + Debug.LogException( e ); + } + + ParentNode inNode = m_mainGraphInstance.GetNode( InNodeId ); + ParentNode outNode = m_mainGraphInstance.GetNode( OutNodeId ); + + //if ( UIUtils.CurrentShaderVersion() < 5002 ) + //{ + // InPortId = inNode.VersionConvertInputPortId( InPortId ); + // OutPortId = outNode.VersionConvertOutputPortId( OutPortId ); + //} + + InputPort inputPort = null; + OutputPort outputPort = null; + if( inNode != null && outNode != null ) + { + + if( UIUtils.CurrentShaderVersion() < 5002 ) + { + InPortId = inNode.VersionConvertInputPortId( InPortId ); + OutPortId = outNode.VersionConvertOutputPortId( OutPortId ); + + inputPort = inNode.GetInputPortByArrayId( InPortId ); + outputPort = outNode.GetOutputPortByArrayId( OutPortId ); + } + else + { + inputPort = inNode.GetInputPortByUniqueId( InPortId ); + outputPort = outNode.GetOutputPortByUniqueId( OutPortId ); + } + + if( inputPort != null && outputPort != null ) + { + bool inputCompatible = inputPort.CheckValidType( outputPort.DataType ); + bool outputCompatible = outputPort.CheckValidType( inputPort.DataType ); + if( inputCompatible && outputCompatible ) + { + inputPort.ConnectTo( OutNodeId, OutPortId, outputPort.DataType, false ); + outputPort.ConnectTo( InNodeId, InPortId, inputPort.DataType, inputPort.TypeLocked ); + + inNode.OnInputPortConnected( InPortId, OutNodeId, OutPortId, false ); + outNode.OnOutputPortConnected( OutPortId, InNodeId, InPortId ); + } + else if( DebugConsoleWindow.DeveloperMode ) + { + if( !inputCompatible ) + UIUtils.ShowIncompatiblePortMessage( true, inNode, inputPort, outNode, outputPort ); + + if( !outputCompatible ) + UIUtils.ShowIncompatiblePortMessage( true, outNode, outputPort, inNode, inputPort ); + } + } + else if( DebugConsoleWindow.DeveloperMode ) + { + if( inputPort == null ) + { + UIUtils.ShowMessage( "Input Port " + InPortId + " doesn't exist on node " + InNodeId, MessageSeverity.Error ); + } + else + { + UIUtils.ShowMessage( "Output Port " + OutPortId + " doesn't exist on node " + OutNodeId, MessageSeverity.Error ); + } + } + } + else if( DebugConsoleWindow.DeveloperMode ) + { + if( inNode == null ) + { + UIUtils.ShowMessage( "Input node " + InNodeId + " doesn't exist", MessageSeverity.Error ); + } + else + { + UIUtils.ShowMessage( "Output node " + OutNodeId + " doesn't exist", MessageSeverity.Error ); + } + } + } + break; + } + } + + if( shaderFunction != null ) + { + m_onLoadDone = 2; + if( applyDummy ) + { + m_cameraInfo = dummyCameraInfo; + m_cameraOffset = dummyCameraOffset; + CameraZoom = dummyCameraZoom; + if( DebugConsoleWindow.UseShaderPanelsInfo ) + { + m_nodeParametersWindowMaximized = m_nodeParametersWindow.IsMaximized = dummyNodeParametersWindowMaximized; + m_paletteWindowMaximized = m_paletteWindow.IsMaximized = dummyPaletteWindowMaximized; + } + } + + } + else + { + shader = AssetDatabase.LoadAssetAtPath<Shader>( pathname ); + if( shader ) + { + + m_onLoadDone = 2; + if( applyDummy ) + { + m_cameraInfo = dummyCameraInfo; + m_cameraOffset = dummyCameraOffset; + CameraZoom = dummyCameraZoom; + if( DebugConsoleWindow.UseShaderPanelsInfo ) + { + m_nodeParametersWindowMaximized = m_nodeParametersWindow.IsMaximized = dummyNodeParametersWindowMaximized; + m_paletteWindowMaximized = m_paletteWindow.IsMaximized = dummyPaletteWindowMaximized; + } + } + } + else + { + ShowMessage( "Could not load shader asset" ); + } + } + } + else + { + ShowMessage( "Graph info not found" ); + } + } + else + { + ShowMessage( "Corrupted checksum" ); + } + } + else + { + ShowMessage( "Checksum not found" ); + } + + //m_mainGraphInstance.LoadedShaderVersion = m_versionInfo.FullNumber; + if( UIUtils.CurrentMasterNode() ) + UIUtils.CurrentMasterNode().ForcePortType(); + + UIUtils.DirtyMask = true; + m_checkInvalidConnections = true; + + m_mainGraphInstance.CheckForDuplicates(); + m_mainGraphInstance.UpdateRegisters(); + m_mainGraphInstance.RefreshExternalReferences(); + m_mainGraphInstance.ForceSignalPropagationOnMasterNode(); + + if( shaderFunction != null ) + { + //if( CurrentGraph.CurrentFunctionOutput == null ) + //{ + // //Fix in case a function output node is not marked as main node + // CurrentGraph.AssignMasterNode( UIUtils.FunctionOutputList()[ 0 ], false ); + //} + shaderFunction.ResetDirectivesOrigin(); + CurrentGraph.CurrentShaderFunction = shaderFunction; + } + else + { + if( shader != null ) + { + m_mainGraphInstance.UpdateShaderOnMasterNode( shader ); + if( m_mainGraphInstance.CurrentCanvasMode == NodeAvailability.TemplateShader ) + { + m_mainGraphInstance.RefreshLinkedMasterNodes( false ); + m_mainGraphInstance.OnRefreshLinkedPortsComplete(); + //m_mainGraphInstance.SetLateOptionsRefresh(); + } + } + } + + + m_mainGraphInstance.LoadedShaderVersion = VersionInfo.FullNumber; + + System.Threading.Thread.CurrentThread.CurrentCulture = System.Threading.Thread.CurrentThread.CurrentUICulture; + + m_mainGraphInstance.IsLoading = false; + //Remove focus from UI elements so no UI is incorrectly selected from previous loads + //Shader Name textfield was sometimes incorrectly selected + GUI.FocusControl( null ); + return loadResult; + } + + public void FullCleanUndoStack() + { + Undo.ClearUndo( this ); + m_mainGraphInstance.FullCleanUndoStack(); + } + + public void FullRegisterOnUndoStack() + { + Undo.RegisterCompleteObjectUndo( this, Constants.UndoRegisterFullGrapId ); + m_mainGraphInstance.FullRegisterOnUndoStack(); + } + + public void ShowPortInfo() + { + GetWindow<PortLegendInfo>(); + } + + public void ShowShaderLibrary() + { + GetWindow<ShaderLibrary>(); + } + + public void ShowMessage( string message, MessageSeverity severity = MessageSeverity.Normal, bool registerTimestamp = true, bool consoleLog = false ) + { + ShowMessage( -1, message, severity, registerTimestamp, consoleLog ); + } + + public void ShowMessage( int messageOwner, string message, MessageSeverity severity = MessageSeverity.Normal, bool registerTimestamp = true, bool consoleLog = false ) + { + if( UIUtils.InhibitMessages || m_genericMessageUI == null ) + return; + + m_consoleLogWindow.AddMessage( severity, message , messageOwner); + + MarkToRepaint(); + + if( consoleLog ) + { + switch( severity ) + { + case MessageSeverity.Normal: + { + Debug.Log( message ); + } + break; + case MessageSeverity.Warning: + { + Debug.LogWarning( message ); + } + break; + case MessageSeverity.Error: + { + Debug.LogError( message ); + } + break; + } + } + } + + // NOTE: this can probably be removed safely + public void ShowMessageImmediately( string message, MessageSeverity severity = MessageSeverity.Normal, bool consoleLog = true ) + { + if( UIUtils.InhibitMessages ) + return; + + switch( severity ) + { + case MessageSeverity.Normal: + { + m_genericMessageContent.text = message; + if( consoleLog ) + { + Debug.Log( message ); + } + } + break; + case MessageSeverity.Warning: + { + m_genericMessageContent.text = "Warning!\n" + message; + if( consoleLog ) + { + Debug.LogWarning( message ); + } + } + break; + case MessageSeverity.Error: + { + m_genericMessageContent.text = "Error!!!\n" + message; + if( consoleLog ) + { + Debug.LogError( message ); + } + } + break; + } + + try + { + ShowNotification( m_genericMessageContent ); + } + catch( Exception e ) + { + Debug.LogException( e ); + } + } + + public bool MouseInteracted = false; + +#if UNITY_2019_1_OR_NEWER + private bool m_fixOnFocus = false; + private bool m_fixFocusRepaint = false; +#endif + void OnGUI() + { +#if UNITY_2019_1_OR_NEWER + // hack fix for mouse selecting text fields when window is opening or window not focused? + if( m_fixFocusRepaint && Event.current.type == EventType.Repaint ) + { + // hack over hack: makes texture fields selectable again when window is not focused + if( ( EditorGUIUtility.editingTextField && EditorGUIUtility.hotControl != 0 ) || + !( EditorGUIUtility.editingTextField && EditorGUIUtility.hotControl == EditorGUIUtility.keyboardControl && EditorGUIUtility.keyboardControl != 0 ) + ) + { + EditorGUI.FocusTextInControl( null ); + GUIUtility.keyboardControl = 0; + } + + m_fixOnFocus = false; + m_fixFocusRepaint = false; + } + + if( m_fixOnFocus && ( Event.current.type == EventType.Used || Event.current.type == EventType.MouseDown ) ) + { + m_fixFocusRepaint = true; + } +#endif + + +#if UNITY_2018_3_OR_NEWER + if( ASEPackageManagerHelper.CheckImporter ) + return; +#endif + +#if UNITY_EDITOR_WIN + if( m_openSavedFolder && Event.current.type == EventType.Repaint ) + { + OpenSavedFolder(); + return; + } +#endif + AmplifyShaderEditorWindow cacheWindow = UIUtils.CurrentWindow; + UIUtils.CurrentWindow = this; + + if( !m_initialized || (object)UIUtils.MainSkin == null || !UIUtils.Initialized ) + { + UIUtils.InitMainSkin(); + Init(); + } + + m_currentEvent = Event.current; + if( m_currentEvent.type == EventType.ExecuteCommand || m_currentEvent.type == EventType.ValidateCommand ) + m_currentCommandName = m_currentEvent.commandName; + else + m_currentCommandName = string.Empty; + + System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.InvariantCulture; + + MouseInteracted = false; + + if( m_refreshOnUndo ) + { + m_refreshOnUndo = false; + m_mainGraphInstance.RefreshOnUndo(); + } + + if( m_refreshAvailableNodes ) + { + RefreshAvaibleNodes(); + } + + if( m_previousShaderFunction != CurrentGraph.CurrentShaderFunction ) + { + m_nodeParametersWindow.ForceUpdate = true; + m_previousShaderFunction = CurrentGraph.CurrentShaderFunction; + } + + if( m_nodeToFocus != null && m_currentEvent.type == EventType.Layout ) + { + FocusOnNode( m_nodeToFocus, m_zoomToFocus, m_selectNodeToFocus ); + m_nodeToFocus = null; + } + + m_mainGraphInstance.OnDuplicateEventWrapper(); + + m_currentInactiveTime = CalculateInactivityTime(); + + if( m_nodeParametersWindow != null && m_innerEditorVariables.NodeParametersMaximized != m_nodeParametersWindow.IsMaximized ) + m_innerEditorVariables.NodeParametersMaximized = m_nodeParametersWindow.IsMaximized; + if( m_paletteWindow != null && m_innerEditorVariables.NodePaletteMaximized != m_paletteWindow.IsMaximized ) + m_innerEditorVariables.NodePaletteMaximized = m_paletteWindow.IsMaximized; + + if( m_checkInvalidConnections ) + { + m_checkInvalidConnections = false; + m_mainGraphInstance.DeleteInvalidConnections(); + } + + //if ( m_repaintIsDirty ) + //{ + // m_repaintIsDirty = false; + // ForceRepaint(); + //} + + if( m_forcingMaterialUpdateFlag ) + { + Focus(); + if( m_materialsToUpdate.Count > 0 ) + { + float percentage = 100.0f * (float)( UIUtils.TotalExampleMaterials - m_materialsToUpdate.Count ) / (float)UIUtils.TotalExampleMaterials; + if( m_forcingMaterialUpdateOp ) // Read + { + Debug.Log( percentage + "% Recompiling " + m_materialsToUpdate[ 0 ].name ); + LoadDroppedObject( true, m_materialsToUpdate[ 0 ].shader, m_materialsToUpdate[ 0 ] ); + } + else // Write + { + Debug.Log( percentage + "% Saving " + m_materialsToUpdate[ 0 ].name ); + SaveToDisk( false ); + m_materialsToUpdate.RemoveAt( 0 ); + } + m_forcingMaterialUpdateOp = !m_forcingMaterialUpdateOp; + } + else + { + Debug.Log( "100% - All Materials compiled " ); + m_forcingMaterialUpdateFlag = false; + } + } + + + if( m_removedKeyboardFocus ) + { + m_removedKeyboardFocus = false; + GUIUtility.keyboardControl = 0; + } + + + Vector2 pos = m_currentEvent.mousePosition; + pos.x += position.x; + pos.y += position.y; + m_insideEditorWindow = position.Contains( pos ); + + if( m_delayedLoadObject != null && m_mainGraphInstance.CurrentMasterNode != null ) + { + m_mainGraphInstance.SetLateOptionsRefresh(); + LoadObject( m_delayedLoadObject ); + m_delayedLoadObject = null; + } + else if( m_delayedLoadObject != null && m_mainGraphInstance.CurrentOutputNode != null ) + { + m_mainGraphInstance.SetLateOptionsRefresh(); + LoadObject( m_delayedLoadObject ); + m_delayedLoadObject = null; + } + + if( m_delayedMaterialSet != null && m_mainGraphInstance.CurrentMasterNode != null ) + { + m_mainGraphInstance.UpdateMaterialOnMasterNode( m_delayedMaterialSet ); + m_mainGraphInstance.SetMaterialModeOnGraph( m_delayedMaterialSet ); + CurrentSelection = ASESelectionMode.Material; + IsShaderFunctionWindow = false; + m_delayedMaterialSet = null; + } + + Material currentMaterial = m_mainGraphInstance.CurrentMaterial; + if( m_forceUpdateFromMaterialFlag ) + { + Focus(); + m_forceUpdateFromMaterialFlag = false; + if( currentMaterial != null ) + { + m_mainGraphInstance.CopyValuesFromMaterial( currentMaterial ); + m_repaintIsDirty = true; + } + } + + m_repaintCount = 0; + m_cameraInfo = position; + + //if( m_currentEvent.type == EventType.keyDown ) + if( m_currentEvent.type == EventType.Repaint ) + m_keyEvtMousePos2D = m_currentEvent.mousePosition; + + m_currentMousePos2D = m_currentEvent.mousePosition; + m_currentMousePos.x = m_currentMousePos2D.x; + m_currentMousePos.y = m_currentMousePos2D.y; + + m_graphArea.width = m_cameraInfo.width; + m_graphArea.height = m_cameraInfo.height; + + m_autoPanDirActive = m_lmbPressed || m_forceAutoPanDir || m_multipleSelectionActive || m_wireReferenceUtils.ValidReferences(); + + + // Need to use it in order to prevent Mismatched LayoutGroup on ValidateCommand when rendering nodes + //if( Event.current.type == EventType.ValidateCommand ) + //{ + // Event.current.Use(); + //} + + // Nodes Graph background area + //GUILayout.BeginArea( m_graphArea, "Nodes" ); + { + // Camera movement is simulated by grabing the current camera offset, transforming it into texture space and manipulating the tiled texture uv coords + GUI.DrawTextureWithTexCoords( m_graphArea, m_graphBgTexture, + new Rect( ( -m_cameraOffset.x / m_graphBgTexture.width ), + ( m_cameraOffset.y / m_graphBgTexture.height ) - m_cameraZoom * m_cameraInfo.height / m_graphBgTexture.height, + m_cameraZoom * m_cameraInfo.width / m_graphBgTexture.width, + m_cameraZoom * m_cameraInfo.height / m_graphBgTexture.height ) ); + + Color col = GUI.color; + GUI.color = new Color( 1, 1, 1, 0.7f ); + GUI.DrawTexture( m_graphArea, m_graphFgTexture, ScaleMode.StretchToFill, true ); + GUI.color = col; + } + //GUILayout.EndArea(); + + if( DebugConsoleWindow.DeveloperMode && m_currentEvent.type == EventType.Repaint ) + { + GUI.Label( new Rect(Screen.width - 60, 40, 60, 50), m_fpsDisplay ); + } + + bool restoreMouse = false; + if( InsideMenus( m_currentMousePos2D ) /*|| _confirmationWindow.IsActive*/ ) + { + if( Event.current.type == EventType.MouseDown ) + { + restoreMouse = true; + Event.current.type = EventType.Ignore; + } + + // Must guarantee that mouse up ops on menus will reset auto pan if it is set + if( m_currentEvent.type == EventType.MouseUp && m_currentEvent.button == ButtonClickId.LeftMouseButton ) + { + m_lmbPressed = false; + } + + } + // Nodes + //GUILayout.BeginArea( m_graphArea ); + { + m_drawInfo.CameraArea = m_cameraInfo; + m_drawInfo.TransformedCameraArea = m_graphArea; + + m_drawInfo.MousePosition = m_currentMousePos2D; + m_drawInfo.CameraOffset = m_cameraOffset; + m_drawInfo.InvertedZoom = 1 / m_cameraZoom; + m_drawInfo.LeftMouseButtonPressed = m_currentEvent.button == ButtonClickId.LeftMouseButton; + m_drawInfo.CurrentEventType = m_currentEvent.type; + m_drawInfo.ZoomChanged = m_zoomChanged; + + m_drawInfo.TransformedMousePos = m_currentMousePos2D * m_cameraZoom - m_cameraOffset; + + if( m_drawInfo.CurrentEventType == EventType.Repaint ) + UIUtils.UpdateMainSkin( m_drawInfo ); + + // Draw mode indicator + m_modeWindow.Draw( m_graphArea, m_currentMousePos2D, m_mainGraphInstance.CurrentShader, currentMaterial, + 0.5f * ( m_graphArea.width - m_paletteWindow.RealWidth - m_nodeParametersWindow.RealWidth ), + ( m_nodeParametersWindow.IsMaximized ? m_nodeParametersWindow.RealWidth : 0 ), + ( m_paletteWindow.IsMaximized ? m_paletteWindow.RealWidth : 0 )/*, m_openedAssetFromNode*/ ); + + PreTestLeftMouseDown(); + //m_consoleLogWindow.Draw( m_graphArea, m_currentMousePos2D, m_currentEvent.button, false, m_paletteWindow.IsMaximized ? m_paletteWindow.RealWidth : 0 ); + //m_mainGraphInstance.DrawBezierBoundingBox(); + //CheckNodeReplacement(); + + // Main Graph Draw + m_repaintIsDirty = m_mainGraphInstance.Draw( m_drawInfo ) || m_repaintIsDirty; + + m_mainGraphInstance.DrawGrid( m_drawInfo ); + bool hasUnusedConnNodes = m_mainGraphInstance.HasUnConnectedNodes; + m_toolsWindow.SetStateOnButton( ToolButtonType.CleanUnusedNodes, hasUnusedConnNodes ? 1 : 0 ); + + m_zoomChanged = false; + + MasterNode masterNode = m_mainGraphInstance.CurrentMasterNode; + if( masterNode != null ) + { + m_toolsWindow.DrawShaderTitle( m_nodeParametersWindow, m_paletteWindow, AvailableCanvasWidth, m_graphArea.height, masterNode.CroppedShaderName ); + } + else if( m_mainGraphInstance.CurrentOutputNode != null ) + { + string functionName = string.Empty; + + if( m_mainGraphInstance.CurrentShaderFunction != null ) + functionName = m_mainGraphInstance.CurrentShaderFunction.FunctionName; + m_toolsWindow.DrawShaderTitle( m_nodeParametersWindow, m_paletteWindow, AvailableCanvasWidth, m_graphArea.height, functionName ); + } + } + //m_consoleLogWindow.Draw( m_graphArea, m_currentMousePos2D, m_currentEvent.button, false, m_paletteWindow.IsMaximized ? m_paletteWindow.RealWidth : 0 ); + //GUILayout.EndArea(); + + if( restoreMouse ) + { + Event.current.type = EventType.MouseDown; + m_drawInfo.CurrentEventType = EventType.MouseDown; + } + + m_toolsWindow.InitialX = m_nodeParametersWindow.RealWidth; + m_toolsWindow.Width = m_cameraInfo.width - ( m_nodeParametersWindow.RealWidth + m_paletteWindow.RealWidth ); + m_toolsWindow.Draw( m_cameraInfo, m_currentMousePos2D, m_currentEvent.button, false ); + + m_tipsWindow.Draw( m_cameraInfo, m_currentMousePos2D, m_currentEvent.button, false ); + + bool autoMinimize = false; + if( position.width < m_lastWindowWidth && position.width < Constants.MINIMIZE_WINDOW_LOCK_SIZE ) + { + autoMinimize = true; + } + + if( autoMinimize ) + m_nodeParametersWindow.IsMaximized = false; + + ParentNode selectedNode = ( m_mainGraphInstance.SelectedNodes.Count == 1 ) ? m_mainGraphInstance.SelectedNodes[ 0 ] : m_mainGraphInstance.CurrentMasterNode; + m_repaintIsDirty = m_nodeParametersWindow.Draw( m_cameraInfo, selectedNode, m_currentMousePos2D, m_currentEvent.button, false ) || m_repaintIsDirty; //TODO: If multiple nodes from the same type are selected also show a parameters window which modifies all of them + if( m_nodeParametersWindow.IsResizing ) + m_repaintIsDirty = true; + + // Test to ignore mouse on main palette when inside context palette ... IsInside also takes active state into account + bool ignoreMouseForPalette = m_contextPalette.IsInside( m_currentMousePos2D ); + if( ignoreMouseForPalette && Event.current.type == EventType.MouseDown ) + { + Event.current.type = EventType.Ignore; + m_drawInfo.CurrentEventType = EventType.Ignore; + } + if( autoMinimize ) + m_paletteWindow.IsMaximized = false; + + m_paletteWindow.Draw( m_cameraInfo, m_currentMousePos2D, m_currentEvent.button, !m_contextPalette.IsActive ); + if( m_paletteWindow.IsResizing ) + { + m_repaintIsDirty = true; + } + + if( ignoreMouseForPalette ) + { + if( restoreMouse ) + { + Event.current.type = EventType.MouseDown; + m_drawInfo.CurrentEventType = EventType.MouseDown; + } + } + + m_consoleLogWindow.Draw( m_graphArea, m_currentMousePos2D, m_currentEvent.button, false, m_paletteWindow.IsMaximized ? m_paletteWindow.RealWidth : 0 ); + + if( m_contextPalette.IsActive ) + { + m_contextPalette.Draw( m_cameraInfo, m_currentMousePos2D, m_currentEvent.button, m_contextPalette.IsActive ); + } + + if( m_palettePopup.IsActive ) + { + m_palettePopup.Draw( m_currentMousePos2D ); + m_repaintIsDirty = true; + int controlID = GUIUtility.GetControlID( FocusType.Passive ); + if( m_currentEvent.GetTypeForControl( controlID ) == EventType.MouseUp ) + { + if( m_currentEvent.button == ButtonClickId.LeftMouseButton ) + { + m_palettePopup.Deactivate(); + if( !InsideMenus( m_currentMousePos2D ) ) + { + ParentNode newNode = CreateNode( m_paletteChosenType, TranformedMousePos, m_paletteChosenFunction ); + //Debug.Log("created menu"); + m_mainGraphInstance.SelectNode( newNode, false, false ); + + bool find = false; + if( newNode is FunctionNode && CurrentGraph.CurrentShaderFunction != null ) + find = SearchFunctionNodeRecursively( CurrentGraph.CurrentShaderFunction ); + + if( find ) + { + DestroyNode( newNode, false ); + ShowMessage( "Shader Function loop detected, new node was removed to prevent errors." ); + } + else + { + newNode.RefreshExternalReferences(); + } + } + } + } + } + + // Handle all events ( mouse interaction + others ) + if( !MouseInteracted ) + HandleGUIEvents(); + + if( m_currentEvent.type == EventType.Repaint ) + { + m_mainGraphInstance.UpdateMarkForDeletion(); + } + // UI Overlay + // Selection Box + if( m_multipleSelectionActive ) + { + UpdateSelectionArea(); + Rect transformedArea = m_multipleSelectionArea; + transformedArea.position = ( transformedArea.position + m_cameraOffset ) / m_cameraZoom; + transformedArea.size /= m_cameraZoom; + + if( transformedArea.width < 0 ) + { + transformedArea.width = -transformedArea.width; + transformedArea.x -= transformedArea.width; + } + + if( transformedArea.height < 0 ) + { + transformedArea.height = -transformedArea.height; + transformedArea.y -= transformedArea.height; + } + Color original = GUI.color; + GUI.color = Constants.BoxSelectionColor; + GUI.Label( transformedArea, "", UIUtils.Box ); + GUI.color = original; + //GUI.backgroundColor = original; + } + + bool isResizing = m_nodeParametersWindow.IsResizing || m_paletteWindow.IsResizing; + //Test boundaries for auto-pan + if( !isResizing && m_autoPanDirActive ) + { + m_autoPanArea[ (int)AutoPanLocation.LEFT ].AdjustInitialX = m_nodeParametersWindow.IsMaximized ? m_nodeParametersWindow.RealWidth : 0; + m_autoPanArea[ (int)AutoPanLocation.RIGHT ].AdjustInitialX = m_paletteWindow.IsMaximized ? -m_paletteWindow.RealWidth : 0; + Vector2 autoPanDir = Vector2.zero; + for( int i = 0; i < m_autoPanArea.Length; i++ ) + { + if( m_autoPanArea[ i ].CheckArea( m_currentMousePos2D, m_cameraInfo, false ) ) + { + autoPanDir += m_autoPanArea[ i ].Velocity; + } + } + m_cameraOffset += autoPanDir; + if( !m_wireReferenceUtils.ValidReferences() && m_insideEditorWindow && !m_altBoxSelection ) + { + m_mainGraphInstance.MoveSelectedNodes( -autoPanDir ); + } + + m_repaintIsDirty = true; + } + + m_isDirty = m_isDirty || m_mainGraphInstance.IsDirty; + if( m_isDirty ) + { + m_isDirty = false; + //ShaderIsModified = true; + EditorUtility.SetDirty( this ); + } + + m_saveIsDirty = m_saveIsDirty || m_mainGraphInstance.SaveIsDirty; + if( m_liveShaderEditing ) + { + if( m_saveIsDirty ) + { + if( focusedWindow == this && m_currentInactiveTime > InactivitySaveTime ) + { + m_saveIsDirty = false; + if( m_mainGraphInstance.CurrentMasterNodeId != Constants.INVALID_NODE_ID ) + { + SaveToDisk( true ); + } + else + { + ShowMessage( LiveShaderError ); + } + } + } + } + else if( m_saveIsDirty ) + { + ShaderIsModified = true; + m_saveIsDirty = false; + } + + if( m_onLoadDone > 0 ) + { + m_onLoadDone--; + if( m_onLoadDone == 0 ) + { + ShaderIsModified = false; + } + } + + if( m_cacheSaveOp ) + { + if( ( EditorApplication.timeSinceStartup - m_lastTimeSaved ) > SaveTime ) + { + SaveToDisk( false ); + } + } + m_genericMessageUI.CheckForMessages(); + + if( m_ctrlSCallback ) + { + m_ctrlSCallback = false; + OnToolButtonPressed( ToolButtonType.Update ); + } + + m_lastWindowWidth = position.width; + m_nodeExporterUtils.Update(); + + if( m_markedToSave ) + { + m_markedToSave = false; + SaveToDisk( false ); + } + if( m_performFullUndoRegister ) + { + m_performFullUndoRegister = false; + FullRegisterOnUndoStack(); + } + + if( CheckFunctions ) + CheckFunctions = false; + + System.Threading.Thread.CurrentThread.CurrentCulture = System.Threading.Thread.CurrentThread.CurrentUICulture; + + UIUtils.CurrentWindow = cacheWindow; + if( !m_nodesLoadedCorrectly ) + { + try + { + ShowNotification( NodesExceptionMessage ); + } + catch( Exception e ) + { + Debug.LogException( e ); + } + } + + CheckNodeReplacement(); +#if UNITY_EDITOR_WIN + if( m_takeScreenShot ) + FocusZoom( true, false, false ); + + if( m_takeScreenShot && Event.current.type == EventType.Repaint ) + TakeScreenShot(); +#endif + } + + void OnInspectorUpdate() + { + Preferences.LoadDefaults(); +#if UNITY_2018_3_OR_NEWER + ASEPackageManagerHelper.Update(); +#endif + + if( m_afterDeserializeFlag ) + { + m_afterDeserializeFlag = false; + //m_mainGraphInstance.ParentWindow = this; + } + + if( IsShaderFunctionWindow && CurrentGraph.CurrentShaderFunction == null ) + { + Close(); + } + } + + public void SetCtrlSCallback( bool imediate ) + { + //MasterNode node = _mainGraphInstance.CurrentMasterNode; + if( /*node != null && node.CurrentShader != null && */m_shaderIsModified ) + { + if( imediate ) + { + OnToolButtonPressed( ToolButtonType.Update ); + } + else + { + m_ctrlSCallback = true; + } + } + } + + public void SetSaveIsDirty() + { + m_saveIsDirty = true && UIUtils.DirtyMask; + } + + public void OnPaletteNodeCreate( System.Type type, string name, AmplifyShaderFunction function ) + { + m_mainGraphInstance.DeSelectAll(); + m_paletteChosenType = type; + m_paletteChosenFunction = function; + m_palettePopup.Activate( name ); + } + + public void OnContextPaletteNodeCreate( System.Type type, string name, AmplifyShaderFunction function ) + { + m_mainGraphInstance.DeSelectAll(); + ParentNode newNode = CreateNode( type, m_contextPalette.StartDropPosition * m_cameraZoom - m_cameraOffset, function ); + //Debug.Log( "created context" ); + m_mainGraphInstance.SelectNode( newNode, false, false ); + bool find = false; + if( newNode is FunctionNode && CurrentGraph.CurrentShaderFunction != null ) + find = SearchFunctionNodeRecursively( CurrentGraph.CurrentShaderFunction ); + + if( find ) + { + DestroyNode( newNode, false ); + ShowMessage( "Shader Function loop detected, new node was removed to prevent errors." ); + } + else + { + newNode.RefreshExternalReferences(); + } + } + + void OnNodeStoppedMovingEvent( ParentNode node ) + { + CheckZoomBoundaries( node.Vec2Position ); + //ShaderIsModified = true; + } + + void OnRefreshFunctionNodeEvent( FunctionNode node ) + { + Debug.Log( node ); + } + + void OnMaterialUpdated( MasterNode masterNode ) + { + if( masterNode != null ) + { + if( masterNode.CurrentMaterial ) + { + m_toolsWindow.SetStateOnButton( ToolButtonType.Update, ShaderIsModified ? 0 : 2, ShaderIsModified ? "Click to update Shader preview." : "Preview up-to-date." ); + } + else + { + m_toolsWindow.SetStateOnButton( ToolButtonType.Update, 1, "Set an active Material in the Master Node." ); + } + UpdateLiveUI(); + } + else + { + m_toolsWindow.SetStateOnButton( ToolButtonType.Update, 1, "Set an active Material in the Master Node." ); + } + } + + void OnShaderUpdated( MasterNode masterNode ) + { + m_toolsWindow.SetStateOnButton( ToolButtonType.OpenSourceCode, masterNode.CurrentShader != null ? 1 : 0 ); + } + + public void CheckZoomBoundaries( Vector2 newPosition ) + { + if( newPosition.x < m_minNodePos.x ) + { + m_minNodePos.x = newPosition.x; + } + else if( newPosition.x > m_maxNodePos.x ) + { + m_maxNodePos.x = newPosition.x; + } + + if( newPosition.y < m_minNodePos.y ) + { + m_minNodePos.y = newPosition.y; + } + else if( newPosition.y > m_maxNodePos.y ) + { + m_maxNodePos.y = newPosition.y; + } + } + public void DestroyNode( ParentNode node, bool registerUndo = true ) { m_mainGraphInstance.DestroyNode( node, registerUndo ); } + public ParentNode CreateNode( System.Type type, Vector2 position, AmplifyShaderFunction function = null, bool selectNode = true ) + { + ParentNode node; + if( function == null ) + node = m_mainGraphInstance.CreateNode( type, true ); + else + node = m_mainGraphInstance.CreateNode( function, true ); + + Vector2 newPosition = position; + node.Vec2Position = newPosition; + CheckZoomBoundaries( newPosition ); + + // Connect node if a wire is active + if( m_wireReferenceUtils.ValidReferences() ) + { + if( m_wireReferenceUtils.InputPortReference.IsValid ) + { + ParentNode originNode = m_mainGraphInstance.GetNode( m_wireReferenceUtils.InputPortReference.NodeId ); + InputPort originPort = originNode.GetInputPortByUniqueId( m_wireReferenceUtils.InputPortReference.PortId ); + OutputPort outputPort = node.GetFirstOutputPortOfType( m_wireReferenceUtils.InputPortReference.DataType, true ); + if( outputPort != null && originPort.CheckValidType( outputPort.DataType ) && ( !m_wireReferenceUtils.InputPortReference.TypeLocked || + m_wireReferenceUtils.InputPortReference.DataType == WirePortDataType.OBJECT || + ( m_wireReferenceUtils.InputPortReference.TypeLocked && outputPort.DataType == m_wireReferenceUtils.InputPortReference.DataType ) ) ) + { + + //link output to input + if( outputPort.ConnectTo( m_wireReferenceUtils.InputPortReference.NodeId, m_wireReferenceUtils.InputPortReference.PortId, m_wireReferenceUtils.InputPortReference.DataType, m_wireReferenceUtils.InputPortReference.TypeLocked ) ) + node.OnOutputPortConnected( outputPort.PortId, m_wireReferenceUtils.InputPortReference.NodeId, m_wireReferenceUtils.InputPortReference.PortId ); + + //link input to output + if( originPort.ConnectTo( outputPort.NodeId, outputPort.PortId, outputPort.DataType, m_wireReferenceUtils.InputPortReference.TypeLocked ) ) + originNode.OnInputPortConnected( m_wireReferenceUtils.InputPortReference.PortId, node.UniqueId, outputPort.PortId ); + } + } + + if( m_wireReferenceUtils.OutputPortReference.IsValid ) + { + ParentNode originNode = m_mainGraphInstance.GetNode( m_wireReferenceUtils.OutputPortReference.NodeId ); + InputPort inputPort = node.GetFirstInputPortOfType( m_wireReferenceUtils.OutputPortReference.DataType, true ); + + if( inputPort != null && ( !inputPort.TypeLocked || + inputPort.DataType == WirePortDataType.OBJECT || + ( inputPort.TypeLocked && inputPort.DataType == m_wireReferenceUtils.OutputPortReference.DataType ) ) ) + { + + inputPort.InvalidateAllConnections(); + //link input to output + if( inputPort.ConnectTo( m_wireReferenceUtils.OutputPortReference.NodeId, m_wireReferenceUtils.OutputPortReference.PortId, m_wireReferenceUtils.OutputPortReference.DataType, inputPort.TypeLocked ) ) + node.OnInputPortConnected( inputPort.PortId, m_wireReferenceUtils.OutputPortReference.NodeId, m_wireReferenceUtils.OutputPortReference.PortId ); + //link output to input + + if( originNode.GetOutputPortByUniqueId( m_wireReferenceUtils.OutputPortReference.PortId ).ConnectTo( inputPort.NodeId, inputPort.PortId, m_wireReferenceUtils.OutputPortReference.DataType, inputPort.TypeLocked ) ) + originNode.OnOutputPortConnected( m_wireReferenceUtils.OutputPortReference.PortId, node.UniqueId, inputPort.PortId ); + } + } + m_wireReferenceUtils.InvalidateReferences(); + + //for ( int i = 0; i < m_mainGraphInstance.VisibleNodes.Count; i++ ) + //{ + // m_mainGraphInstance.VisibleNodes[ i ].OnNodeInteraction( node ); + //} + } + + if( selectNode ) + m_mainGraphInstance.SelectNode( node, false, false ); + //_repaintIsDirty = true + + SetSaveIsDirty(); + ForceRepaint(); + return node; + } + + public void UpdateNodePreviewListAndTime() + { + if( UIUtils.CurrentWindow != this ) + return; + + double deltaTime = Time.realtimeSinceStartup - m_time; + m_time = Time.realtimeSinceStartup; + + if( DebugConsoleWindow.DeveloperMode ) + { + m_frameCounter++; + if( m_frameCounter >= 60 ) + { + m_fpsDisplay = ( 60 / ( Time.realtimeSinceStartup - m_fpsTime ) ).ToString( "N2" ); + m_fpsTime = Time.realtimeSinceStartup; + m_frameCounter = 0; + } + } + + if( m_smoothZoom ) + { + m_repaintIsDirty = true; + if( Mathf.Abs( m_targetZoom - m_cameraZoom ) < 0.001f ) + { + m_smoothZoom = false; + m_cameraZoom = m_targetZoom; + m_zoomTime = 0; + } + else + { + m_zoomTime += deltaTime; + Vector2 canvasPos = m_zoomPivot * m_cameraZoom; + m_cameraZoom = Mathf.SmoothDamp( m_cameraZoom, m_targetZoom, ref m_zoomVelocity, 0.1f, 10000, (float)deltaTime * 1.5f ); + canvasPos = canvasPos - m_zoomPivot * m_cameraZoom; + m_cameraOffset = m_cameraOffset - canvasPos; + m_targetOffset = m_targetOffset - canvasPos; + } + + } + + if( m_smoothOffset ) + { + m_repaintIsDirty = true; + if( ( m_targetOffset - m_cameraOffset ).SqrMagnitude() < 1f ) + { + m_smoothOffset = false; + m_offsetTime = 0; + } + else + { + m_offsetTime += deltaTime; + m_cameraOffset = Vector2.SmoothDamp( m_cameraOffset, m_targetOffset, ref m_camVelocity, 0.1f, 100000, (float)deltaTime * 1.5f ); + } + } + + if( m_cachedEditorTimeId == -1 ) + m_cachedEditorTimeId = Shader.PropertyToID( "_EditorTime" ); + + if( m_cachedEditorDeltaTimeId == -1 ) + m_cachedEditorDeltaTimeId = Shader.PropertyToID( "_EditorDeltaTime" ); + + //Update Game View? + //Shader.SetGlobalVector( "_Time", new Vector4( Time.realtimeSinceStartup / 20, Time.realtimeSinceStartup, Time.realtimeSinceStartup * 2, Time.realtimeSinceStartup * 3 ) ); + + //System.Type T = System.Type.GetType( "UnityEditor.GameView,UnityEditor" ); + //UnityEngine.Object[] array = Resources.FindObjectsOfTypeAll( T ); + //EditorWindow gameView = ( array.Length <= 0 ) ? null : ( ( EditorWindow ) array[ 0 ] ); + //gameView.Repaint(); + + if( RenderSettings.sun != null ) + { + Vector3 lightdir = -RenderSettings.sun.transform.forward;//.rotation.eulerAngles; + + Shader.SetGlobalVector( "_EditorWorldLightPos", new Vector4( lightdir.x, lightdir.y, lightdir.z, 0 ) ); + Shader.SetGlobalColor( "_EditorLightColor", RenderSettings.sun.color.linear ); + } + Shader.SetGlobalFloat( "_EditorTime", (float)m_time ); + Shader.SetGlobalFloat( "_EditorDeltaTime", (float)deltaTime ); + + /////////// UPDATE PREVIEWS ////////////// + UIUtils.CheckNullMaterials(); + //CurrentGraph.AllNodes.Sort( ( x, y ) => { return x.Depth.CompareTo( y.Depth ); } ); + int nodeCount = CurrentGraph.AllNodes.Count; + for( int i = nodeCount - 1; i >= 0; i-- ) + { + ParentNode node = CurrentGraph.AllNodes[ i ]; + if( node != null && !VisitedChanged.ContainsKey( node.OutputId ) ) + { + bool result = node.RecursivePreviewUpdate(); + if( result ) + m_repaintIsDirty = true; + } + } + + VisitedChanged.Clear(); + if( m_repaintIsDirty ) + { + m_repaintIsDirty = false; + Repaint(); + } + } + + public void ForceRepaint() + { + m_repaintCount += 1; + m_repaintIsDirty = true; + //Repaint(); + } + + public void ForceUpdateFromMaterial() { m_forceUpdateFromMaterialFlag = true; } + void UseCurrentEvent() + { + m_currentEvent.Use(); + } + + + + public void OnBeforeSerialize() + { + //if ( !UIUtils.SerializeFromUndo() ) + //{ + // m_mainGraphInstance.DeSelectAll(); + //} + + if( DebugConsoleWindow.UseShaderPanelsInfo ) + { + if( m_nodeParametersWindow != null ) + m_nodeParametersWindowMaximized = m_nodeParametersWindow.IsMaximized; + + if( m_paletteWindow != null ) + m_paletteWindowMaximized = m_paletteWindow.IsMaximized; + } + } + + public void OnAfterDeserialize() + { + m_afterDeserializeFlag = true; + + //m_customGraph = null; + if( DebugConsoleWindow.UseShaderPanelsInfo ) + { + if( m_nodeParametersWindow != null ) + m_nodeParametersWindow.IsMaximized = m_nodeParametersWindowMaximized; + + if( m_paletteWindow != null ) + m_paletteWindow.IsMaximized = m_paletteWindowMaximized; + } + } + + void OnDestroy() + { + m_ctrlSCallback = false; + Destroy(); + } + + public override void OnDisable() + { + base.OnDisable(); + m_ctrlSCallback = false; + //EditorApplication.update -= UpdateTime; + EditorApplication.update -= UpdateNodePreviewListAndTime; + + EditorApplication.update -= IOUtils.UpdateIO; + + for( int i = 0; i < IOUtils.AllOpenedWindows.Count; i++ ) + { + if( IOUtils.AllOpenedWindows[ i ] != this ) + { + EditorApplication.update += IOUtils.UpdateIO; + break; + } + } + } + + void OnEmptyGraphDetected( ParentGraph graph ) + { + if( m_delayedLoadObject != null ) + { + LoadObject( m_delayedLoadObject ); + m_delayedLoadObject = null; + Repaint(); + } + else + { + if( !string.IsNullOrEmpty( Lastpath ) ) + { + Shader shader = AssetDatabase.LoadAssetAtPath<Shader>( Lastpath ); + if( shader == null ) + { + Material material = AssetDatabase.LoadAssetAtPath<Material>( Lastpath ); + if( material != null ) + { + LoadDroppedObject( true, material.shader, material, null ); + } + else + { + AmplifyShaderFunction function = AssetDatabase.LoadAssetAtPath<AmplifyShaderFunction>( Lastpath ); + if( function != null ) + { + LoadDroppedObject( true, null, null, function ); + } + } + } + else + { + LoadDroppedObject( true, shader, null, null ); + } + Repaint(); + } + } + } + + + public void ForceMaterialsToUpdate( ref Dictionary<string, string> availableMaterials ) + { + m_forcingMaterialUpdateOp = true; + m_forcingMaterialUpdateFlag = true; + m_materialsToUpdate.Clear(); + foreach( KeyValuePair<string, string> kvp in availableMaterials ) + { + Material material = AssetDatabase.LoadAssetAtPath<Material>( AssetDatabase.GUIDToAssetPath( kvp.Value ) ); + if( material != null ) + { + m_materialsToUpdate.Add( material ); + } + } + } + + public void SetOutdatedShaderFromTemplate() + { + m_outdatedShaderFromTemplateLoaded = true; + } + + public void ReplaceMasterNode( MasterNodeCategoriesData data, bool cacheMasterNodes ) + { + // save connection list before switching + m_savedList.Clear(); + int count = m_mainGraphInstance.CurrentMasterNode.InputPorts.Count; + for( int i = 0; i < count; i++ ) + { + if( m_mainGraphInstance.CurrentMasterNode.InputPorts[ i ].IsConnected ) + { + string name = m_mainGraphInstance.CurrentMasterNode.InputPorts[ i ].Name; + OutputPort op = m_mainGraphInstance.CurrentMasterNode.InputPorts[ i ].GetOutputConnection(); + if( !m_savedList.ContainsKey( name ) ) + { + m_savedList.Add( name, op ); + } + } + } + + m_replaceMasterNodeType = data.Category; + m_replaceMasterNode = true; + m_replaceMasterNodeData = data.Name; + m_replaceMasterNodeDataFromCache = cacheMasterNodes; + if( cacheMasterNodes ) + { + m_clipboard.AddMultiPassNodesToClipboard( m_mainGraphInstance.MultiPassMasterNodes.NodesList ); + } + } + + void CheckNodeReplacement() + { + if( m_replaceMasterNode ) + { + m_replaceMasterNode = false; + switch( m_replaceMasterNodeType ) + { + default: + case AvailableShaderTypes.SurfaceShader: + { + SetStandardShader(); + if( IOUtils.OnShaderTypeChangedEvent != null ) + { + IOUtils.OnShaderTypeChangedEvent( m_mainGraphInstance.CurrentShader, false, string.Empty ); + } + } + break; + case AvailableShaderTypes.Template: + { + + TemplateDataParent templateData = m_templatesManager.GetTemplate( m_replaceMasterNodeData ); + if( m_replaceMasterNodeDataFromCache ) + { + m_mainGraphInstance.CrossCheckTemplateNodes( templateData ); + m_clipboard.GetMultiPassNodesFromClipboard( m_mainGraphInstance.MultiPassMasterNodes.NodesList ); + } + else + { + SetTemplateShader( m_replaceMasterNodeData, false ); + } + + if( IOUtils.OnShaderTypeChangedEvent != null ) + { + IOUtils.OnShaderTypeChangedEvent( m_mainGraphInstance.CurrentShader, true, templateData.GUID ); + } + } + break; + } + } + else if( m_outdatedShaderFromTemplateLoaded ) + { + m_outdatedShaderFromTemplateLoaded = false; + TemplateMultiPassMasterNode masterNode = m_mainGraphInstance.CurrentMasterNode as TemplateMultiPassMasterNode; + if( masterNode != null ) + { + ReplaceMasterNode( masterNode.CurrentCategoriesData, true ); + } + } + + // restore possible connections by name + if( m_savedList.Count > 0 ) + { + foreach( var item in m_savedList ) + { + string name = item.Key; + OutputPort op = item.Value; + InputPort ip = m_mainGraphInstance.CurrentMasterNode.InputPorts.Find( x => x.Name == name ); + + if( op != null && ip != null && ip.Visible ) + { + var iNode = UIUtils.GetNode( ip.NodeId ); + var oNode = UIUtils.GetNode( op.NodeId ); + ip.ConnectTo( oNode.UniqueId, op.PortId, op.DataType, false ); + op.ConnectTo( iNode.UniqueId, ip.PortId, ip.DataType, ip.TypeLocked ); + + iNode.OnInputPortConnected( ip.PortId, oNode.UniqueId, op.PortId ); + oNode.OnOutputPortConnected( op.PortId, iNode.UniqueId, ip.PortId ); + } + } + } + m_savedList.Clear(); + } + + public Vector2 TranformPosition( Vector2 pos ) + { + return pos * m_cameraZoom - m_cameraOffset; + } + + public void UpdateTabTitle() + { + if( m_isShaderFunctionWindow ) + { + if( m_openedShaderFunction != null ) + { + this.titleContent.text = GenerateTabTitle( m_openedShaderFunction.FunctionName ); + } + } + else + { + if( m_selectionMode == ASESelectionMode.Material ) + { + this.titleContent.text = GenerateTabTitle( m_mainGraphInstance.CurrentMaterial.name ); + } + else + { + this.titleContent.text = GenerateTabTitle( m_mainGraphInstance.CurrentShader.name ); + } + } + } + + public ParentGraph CustomGraph + { + get { return m_customGraph; } + set { m_customGraph = value; } + } + + public ParentGraph CurrentGraph + { + get + { + if( m_customGraph != null ) + return m_customGraph; + + return m_mainGraphInstance; + } + } + + public void RefreshAvaibleNodes() + { + if( m_contextMenu != null && m_mainGraphInstance != null ) + { + m_contextMenu.RefreshNodes( m_mainGraphInstance ); + m_paletteWindow.ForceUpdate = true; + m_contextPalette.ForceUpdate = true; + m_refreshAvailableNodes = false; + } + } + + public void LateRefreshAvailableNodes() + { + m_refreshAvailableNodes = true; + } + + public ParentGraph OutsideGraph { get { return m_mainGraphInstance; } } + + public bool ShaderIsModified + { + get { return m_shaderIsModified; } + set + { + m_shaderIsModified = value && UIUtils.DirtyMask; + + m_toolsWindow.SetStateOnButton( ToolButtonType.Save, m_shaderIsModified ? 1 : 0 ); + if( !IsShaderFunctionWindow ) + { + MasterNode masterNode = m_mainGraphInstance.CurrentMasterNode; + if( masterNode != null && masterNode.CurrentShader != null ) + { + m_toolsWindow.SetStateOnButton( ToolButtonType.Update, m_shaderIsModified ? 0 : 2 ); + UpdateTabTitle( masterNode.ShaderName, m_shaderIsModified ); + } + else + { + m_toolsWindow.SetStateOnButton( ToolButtonType.Update, 1 ); + } + + //if( m_mainGraphInstance.CurrentStandardSurface != null ) + // UpdateTabTitle( m_mainGraphInstance.CurrentStandardSurface.ShaderName, m_shaderIsModified ); + } + else + { + m_toolsWindow.SetStateOnButton( ToolButtonType.Update, m_shaderIsModified ? 0 : 2 ); + if( m_mainGraphInstance.CurrentShaderFunction != null ) + UpdateTabTitle( m_mainGraphInstance.CurrentShaderFunction.FunctionName, m_shaderIsModified ); + } + + } + } + public void MarkToRepaint() { m_repaintIsDirty = true; } + public void RequestSave() { m_markedToSave = true; } + public void RequestRepaint() { m_repaintIsDirty = true; } + public OptionsWindow Options { get { return m_optionsWindow; } } + public GraphContextMenu ContextMenuInstance { get { return m_contextMenu; } set { m_contextMenu = value; } } + public ShortcutsManager ShortcutManagerInstance { get { return m_shortcutManager; } } + + public bool GlobalPreview + { + get { return m_globalPreview; } + set { m_globalPreview = value; } + } + + public bool GlobalShowInternalData + { + get { return m_globalShowInternalData; } + set { m_globalShowInternalData = value; } + } + + public double EditorTime + { + get { return m_time; } + set { m_time = value; } + } + + public ASESelectionMode CurrentSelection + { + get { return m_selectionMode; } + set + { + m_selectionMode = value; + switch( m_selectionMode ) + { + default: + case ASESelectionMode.Shader: + { + m_toolsWindow.BorderStyle = UIUtils.GetCustomStyle( CustomStyle.ShaderBorder ); + } + break; + case ASESelectionMode.Material: + { + m_toolsWindow.BorderStyle = UIUtils.GetCustomStyle( CustomStyle.MaterialBorder ); + } + break; + case ASESelectionMode.ShaderFunction: + { + m_toolsWindow.BorderStyle = UIUtils.GetCustomStyle( CustomStyle.ShaderFunctionBorder ); + } + break; + } + } + } + + public bool LiveShaderEditing + { + get { return m_liveShaderEditing; } + set + { + m_liveShaderEditing = value; + m_innerEditorVariables.LiveMode = m_liveShaderEditing; + UpdateLiveUI(); + } + } + + public NodeAvailability CurrentNodeAvailability + { + get { return m_currentNodeAvailability; } + set + { + NodeAvailability cache = m_currentNodeAvailability; + m_currentNodeAvailability = value; + + if( cache != value ) + RefreshAvaibleNodes(); + } + } + public string GUID + { + get + { + if( m_isShaderFunctionWindow ) + { + return m_openedShaderFunction != null ? AssetDatabase.AssetPathToGUID( AssetDatabase.GetAssetPath( m_openedShaderFunction ) ) : string.Empty; + } + else + { + return m_mainGraphInstance.CurrentShader != null ? AssetDatabase.AssetPathToGUID( AssetDatabase.GetAssetPath( m_mainGraphInstance.CurrentShader ) ) : string.Empty; + } + } + } + public List<Toast> Messages { get { return m_messages; } set { m_messages = value; } } + public float MaxMsgWidth { get { return m_maxMsgWidth; } set { m_maxMsgWidth = value; } } + public bool MaximizeMessages { get { return m_maximizeMessages; } set { m_maximizeMessages = value; } } + public void InvalidateAlt() { m_altAvailable = false; } + public PaletteWindow CurrentPaletteWindow { get { return m_paletteWindow; } } + public PreMadeShaders PreMadeShadersInstance { get { return m_preMadeShaders; } } + public Rect CameraInfo { get { return m_cameraInfo; } } + public Vector2 TranformedMousePos { get { return m_currentMousePos2D * m_cameraZoom - m_cameraOffset; } } + public Vector2 TranformedKeyEvtMousePos { get { return m_keyEvtMousePos2D * m_cameraZoom - m_cameraOffset; } } + public PalettePopUp PalettePopUpInstance { get { return m_palettePopup; } } + public DuplicatePreventionBuffer DuplicatePrevBufferInstance { get { return m_duplicatePreventionBuffer; } } + public NodeParametersWindow ParametersWindow { get { return m_nodeParametersWindow; } } + public NodeExporterUtils CurrentNodeExporterUtils { get { return m_nodeExporterUtils; } } + public AmplifyShaderFunction OpenedShaderFunction { get { return m_openedShaderFunction; } } + public DrawInfo CameraDrawInfo { get { return m_drawInfo; } } + public string Lastpath { get { return m_lastpath; } set { m_lastpath = value; } } + public string LastOpenedLocation { get { return m_lastOpenedLocation; } set { m_lastOpenedLocation = value; } } + public float AvailableCanvasWidth { get { return ( m_cameraInfo.width - m_paletteWindow.RealWidth - m_nodeParametersWindow.RealWidth ); } } + public float AvailableCanvasHeight { get { return ( m_cameraInfo.height ); } } + public float CameraZoom { get { return m_cameraZoom; } set { m_cameraZoom = value; m_zoomChanged = true; } } + public int GraphCount { get { return m_graphCount; } set { m_graphCount = value; } } + public bool ForceAutoPanDir { get { return m_forceAutoPanDir; } set { m_forceAutoPanDir = value; } } + public bool OpenedAssetFromNode { get { return m_openedAssetFromNode; } set { m_openedAssetFromNode = value; } } + public bool IsShaderFunctionWindow { get { return m_isShaderFunctionWindow; } set { m_isShaderFunctionWindow = value; } } + public bool NodesLoadedCorrectly { get { return m_nodesLoadedCorrectly; } set { m_nodesLoadedCorrectly = value; } } + public double CurrentInactiveTime { get { return m_currentInactiveTime; } } + public string ReplaceMasterNodeData { get { return m_replaceMasterNodeData; } } + public AvailableShaderTypes ReplaceMasterNodeType { get { return m_replaceMasterNodeType; } } + public NodeWireReferencesUtils WireReferenceUtils { get { return m_wireReferenceUtils; } } + public ContextPalette WindowContextPallete { get { return m_contextPalette; } } + // This needs to go to UIUtils + public Texture2D WireTexture { get { return m_wireTexture; } } + public Event CurrentEvent { get { return m_currentEvent; } } + public string CurrentCommandName { get { return m_currentCommandName; } } + public InnerWindowEditorVariables InnerWindowVariables { get { return m_innerEditorVariables; } } + public TemplatesManager TemplatesManagerInstance { get { return m_templatesManager; } } + public Material CurrentMaterial { get { return CurrentGraph.CurrentMaterial; } } + public Clipboard ClipboardInstance { get { return m_clipboard; } } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/AmplifyShaderEditorWindow.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/AmplifyShaderEditorWindow.cs.meta new file mode 100644 index 00000000..6ce8e71f --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/AmplifyShaderEditorWindow.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: c8bcac0d66f920e49803925a85beb0ed +timeCreated: 1481126959 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/AmplifyShaderFunction.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/AmplifyShaderFunction.cs new file mode 100644 index 00000000..df83bedb --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/AmplifyShaderFunction.cs @@ -0,0 +1,189 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using UnityEngine; +using UnityEditor; +using System; +using System.Collections.Generic; +using AmplifyShaderEditor; + +[Serializable] +public class AmplifyShaderFunction : ScriptableObject +{ + [SerializeField] + private string m_functionInfo = string.Empty; + public string FunctionInfo + { + get { return m_functionInfo; } + set { m_functionInfo = value; } + } + + [SerializeField] + private string m_functionName = string.Empty; + public string FunctionName + { + get { if( m_functionName.Length == 0 ) return name; else return m_functionName; } + set { m_functionName = value; } + } + + [SerializeField] + [TextArea( 5, 15 )] + private string m_description = string.Empty; + public string Description + { + get { return m_description; } + set { m_description = value; } + } + + [SerializeField] + private AdditionalIncludesHelper m_additionalIncludes = new AdditionalIncludesHelper(); + //public AdditionalIncludesHelper AdditionalIncludes + //{ + // get { return m_additionalIncludes; } + // set { m_additionalIncludes = value; } + //} + + [SerializeField] + private AdditionalPragmasHelper m_additionalPragmas = new AdditionalPragmasHelper(); + //public AdditionalPragmasHelper AdditionalPragmas + //{ + // get { return m_additionalPragmas; } + // set { m_additionalPragmas = value; } + //} + + [SerializeField] + private TemplateAdditionalDirectivesHelper m_additionalDirectives = new TemplateAdditionalDirectivesHelper( " Additional Directives" ); + public TemplateAdditionalDirectivesHelper AdditionalDirectives + { + get { return m_additionalDirectives; } + set { m_additionalDirectives = value; } + } + + [SerializeField] + private FunctionNodeCategories m_nodeCategory = FunctionNodeCategories.Functions; + public FunctionNodeCategories NodeCategory + { + get { return m_nodeCategory; } + set { m_nodeCategory = value; } + } + + [SerializeField] + private string m_customNodeCategory = string.Empty; + public string CustomNodeCategory + { + get + { + if( m_nodeCategory == FunctionNodeCategories.Custom ) + { + if( string.IsNullOrEmpty( m_customNodeCategory ) ) + return "Functions"; + else + return m_customNodeCategory; + } + else + { + return UIUtils.CategoryPresets[ (int)m_nodeCategory ]; + //return new SerializedObject( this ).FindProperty( "m_nodeCategory" ).enumDisplayNames[ (int)m_nodeCategory ]; + } + } + } + + [SerializeField] + private PreviewLocation m_previewPosition = PreviewLocation.Auto; + public PreviewLocation PreviewPosition + { + get { return m_previewPosition; } + set { m_previewPosition = value; } + } + + [SerializeField] + private bool m_hidden = false; + public bool Hidden + { + get { return m_hidden; } + set { m_hidden = value; } + } + + public void UpdateDirectivesList() + { + m_additionalDirectives.CleanNullDirectives(); + m_additionalDirectives.UpdateDirectivesFromSaveItems(); + + if( m_additionalIncludes.IncludeList.Count > 0 ) + { + m_additionalDirectives.AddItems( AdditionalLineType.Include, m_additionalIncludes.IncludeList ); + m_additionalIncludes.IncludeList.Clear(); + } + + if( m_additionalPragmas.PragmaList.Count > 0 ) + { + m_additionalDirectives.AddItems( AdditionalLineType.Pragma, m_additionalPragmas.PragmaList ); + m_additionalPragmas.PragmaList.Clear(); + } + } + + public void ResetDirectivesOrigin() + { + //if( UIUtils.CurrentShaderVersion() < 16807 ) + // Although the correct version was 1.6.7 rev 07 this issue was only detected on v1.7.1. rev 00 + // So to avoid potential incorrect saves over shader functions, I decided to broaden up the version range + if( UIUtils.CurrentShaderVersion() < 17101 ) + { + m_additionalDirectives.ResetDirectivesOrigin(); + } + } +} + +public class ShaderFunctionDetector : AssetPostprocessor +{ + static void OnPostprocessAllAssets( string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths ) + { + if( UIUtils.CurrentWindow == null ) + return; + + bool markForRefresh = false; + AmplifyShaderFunction function = null; + for( int i = 0; i < importedAssets.Length; i++ ) + { + function = AssetDatabase.LoadAssetAtPath<AmplifyShaderFunction>( importedAssets[ i ] ); + if( function != null ) + { + markForRefresh = true; + break; + } + } + + if( deletedAssets.Length > 0 ) + markForRefresh = true; + + for( int i = 0; i < movedAssets.Length; i++ ) + { + function = AssetDatabase.LoadAssetAtPath<AmplifyShaderFunction>( movedAssets[ i ] ); + if( function != null ) + { + markForRefresh = true; + break; + } + } + + for( int i = 0; i < movedFromAssetPaths.Length; i++ ) + { + function = AssetDatabase.LoadAssetAtPath<AmplifyShaderFunction>( movedFromAssetPaths[ i ] ); + if( function != null ) + { + markForRefresh = true; + break; + } + } + + if( markForRefresh ) + { + markForRefresh = false; + if( function != null ) + { + IOUtils.UpdateSFandRefreshWindows( function ); + } + UIUtils.CurrentWindow.LateRefreshAvailableNodes(); + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/AmplifyShaderFunction.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/AmplifyShaderFunction.cs.meta new file mode 100644 index 00000000..35a93109 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/AmplifyShaderFunction.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 78b2425a2284af743826c689403a4924 +timeCreated: 1492703397 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: 50be8291f9514914aa55c66c49da67cf, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/AmplifyShaderFunctionEditor.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/AmplifyShaderFunctionEditor.cs new file mode 100644 index 00000000..b5e3e4d4 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/AmplifyShaderFunctionEditor.cs @@ -0,0 +1,152 @@ +using UnityEngine; +using UnityEditor; +using System; +using System.Text.RegularExpressions; +using System.IO; +using System.Collections.Generic; + +namespace AmplifyShaderEditor +{ + [CustomEditor( typeof( AmplifyShaderFunction ) )] + public class AmplifyShaderFunctionEditor : Editor + { + class FunctionDependency + { + public string AssetName; + public string AssetPath; + public FunctionDependency(string name, string path) + { + AssetName = name; + AssetPath = path; + } + } + + AmplifyShaderFunction m_target; + List<FunctionDependency> m_dependencies = new List<FunctionDependency>(); + + void OnEnable() + { + m_target = ( target as AmplifyShaderFunction ); + } + + public override void OnInspectorGUI() + { + //base.OnInspectorGUI(); + //base.serializedObject.Update(); + if( GUILayout.Button( "Open in Shader Editor" ) ) + { +#if UNITY_2018_3_OR_NEWER + ASEPackageManagerHelper.SetupLateShaderFunction( m_target ); +#else + AmplifyShaderEditorWindow.LoadShaderFunctionToASE( m_target, false ); +#endif + } + //EditorGUILayout.Separator(); + //m_target.FunctionInfo = EditorGUILayout.TextArea( m_target.FunctionInfo ); + + if( m_target.Description.Length > 0 ) + { + EditorGUILayout.HelpBox( m_target.Description, MessageType.Info ); + } + + EditorGUILayout.Space(); + if( GUILayout.Button( "Search Direct Dependencies" ) ) + { + m_dependencies.Clear(); + string guid = AssetDatabase.AssetPathToGUID( AssetDatabase.GetAssetPath( m_target ) ); + + string[] allSFs = AssetDatabase.FindAssets( "t:AmplifyShaderFunction", null ); + foreach( string guid1 in allSFs ) + { + string sfPath = AssetDatabase.GUIDToAssetPath( guid1 ); + bool found = SearchForGUID( guid, sfPath ); + if( found ) + { + //string n = Regex.Replace( sfPath, @"(\.\w+|[\w\d\/]+\/)", "" ); + string n = Regex.Replace( sfPath, @"[\w\d\/]+\/", "" ); + m_dependencies.Add(new FunctionDependency( n, sfPath ) ); + } + } + + string[] allSHs = AssetDatabase.FindAssets( "t:Shader", null ); + foreach( string guid1 in allSHs ) + { + string shPath = AssetDatabase.GUIDToAssetPath( guid1 ); + bool found = SearchForGUID( guid, shPath ); + if( found ) + { + string n = Regex.Replace( shPath, @"[\w\d\/]+\/", "" ); + m_dependencies.Add( new FunctionDependency( n, shPath ) ); + } + } + } + EditorGUILayout.Space(); + for( int i = 0; i < m_dependencies.Count; i++ ) + { + EditorGUILayout.BeginHorizontal(); + if( GUILayout.Button( m_dependencies[ i ].AssetName, "minibuttonleft" ) ) + { + SelectAtPath( m_dependencies[ i ].AssetPath ); + } + if( GUILayout.Button( "edit", "minibuttonright", GUILayout.Width(100) ) ) + { + if( m_dependencies[ i ].AssetName.EndsWith( ".asset" ) ) + { + var obj = AssetDatabase.LoadAssetAtPath<AmplifyShaderFunction>( m_dependencies[ i ].AssetPath ); + AmplifyShaderEditorWindow.LoadShaderFunctionToASE( obj, false ); + } + else + { + var obj = AssetDatabase.LoadAssetAtPath<Shader>( m_dependencies[ i ].AssetPath ); + AmplifyShaderEditorWindow.ConvertShaderToASE( obj ); + } + } + EditorGUILayout.EndHorizontal(); + } + } + + public void SelectAtPath( string path ) + { + var obj = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>( path ); + EditorGUIUtility.PingObject( obj ); + } + + public static bool SearchForGUID( string guid, string pathName ) + { + bool result = false; + int count = 0; + if( !string.IsNullOrEmpty( pathName ) && File.Exists( pathName ) ) + { + StreamReader fileReader = null; + try + { + fileReader = new StreamReader( pathName ); + + string line; + int index = -1; + while( ( line = fileReader.ReadLine() ) != null ) + { + index = line.IndexOf( guid ); + count++; + + if( index > -1 ) + { + result = true; + break; + } + } + } + catch( Exception e ) + { + Debug.LogException( e ); + } + finally + { + if( fileReader != null ) + fileReader.Close(); + } + } + return result; + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/AmplifyShaderFunctionEditor.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/AmplifyShaderFunctionEditor.cs.meta new file mode 100644 index 00000000..99b80bb9 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/AmplifyShaderFunctionEditor.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 8b2d6d1320661374db53aeb8057312b2 +timeCreated: 1491909065 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/AutoPanData.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/AutoPanData.cs new file mode 100644 index 00000000..9f028f3f --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/AutoPanData.cs @@ -0,0 +1,94 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using UnityEngine; + +namespace AmplifyShaderEditor +{ + public enum AutoPanLocation + { + TOP = 0, + BOTTOM, + LEFT, + RIGHT + } + + public class AutoPanData + { + private Rect m_area; + private float m_size; + private Vector2 m_velocity; + + private GUIStyle m_style; + private Color m_color = new Color( 1f, 0f, 0f, 0.5f ); + + private AutoPanLocation m_location; + private float m_adjustWidth = 0; + private float m_adjustInitialX = 0; + + public AutoPanData( AutoPanLocation location, float size, Vector2 vel ) + { + m_area = new Rect(); + m_size = size; + m_velocity = vel; + m_location = location; + } + + public bool CheckArea( Vector2 mousePosition, Rect window, bool draw ) + { + float totalSize = m_size + m_adjustWidth; + switch ( m_location ) + { + case AutoPanLocation.TOP: + { + m_area.x = m_adjustInitialX; + m_area.y = 0; + m_area.width = window.width; + m_area.height = totalSize; + } + break; + case AutoPanLocation.BOTTOM: + { + m_area.x = m_adjustInitialX; + m_area.y = window.height - totalSize; + m_area.width = window.width; + m_area.height = totalSize; + } + break; + case AutoPanLocation.LEFT: + { + m_area.x = m_adjustInitialX; + m_area.y = 0; + m_area.width = totalSize; + m_area.height = window.height; + } + break; + case AutoPanLocation.RIGHT: + { + m_area.x = m_adjustInitialX + window.width - totalSize; + m_area.y = 0; + m_area.width = totalSize; + m_area.height = window.height; + } + break; + } + + if ( draw ) + { + if ( m_style == null ) + { + m_style = UIUtils.Box; + } + Color bufferedColor = GUI.color; + GUI.color = m_color; + GUI.Label( m_area, string.Empty, m_style ); + GUI.color = bufferedColor; + } + return m_area.Contains( mousePosition ); + } + + public float AdjustWidth { set { m_adjustWidth = value; } } + public float AdjustInitialX { set { m_adjustInitialX = value; } } + public Vector2 Velocity { get { return m_velocity; } } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/AutoPanData.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/AutoPanData.cs.meta new file mode 100644 index 00000000..17e6b868 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/AutoPanData.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 711db07e8265cb740940568c4bc7345f +timeCreated: 1481126956 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Clipboard.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Clipboard.cs new file mode 100644 index 00000000..4f2405c4 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Clipboard.cs @@ -0,0 +1,250 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> +using System; +using UnityEngine; +using System.Collections.Generic; +using UnityEditor; + +namespace AmplifyShaderEditor +{ + + public class ClipboardData + { + public string Data = string.Empty; + public string Connections = string.Empty; + public int OldNodeId = -1; + public int NewNodeId = -1; + + public ClipboardData( string data, string connections, int oldNodeId ) + { + Data = data; + Connections = connections; + OldNodeId = oldNodeId; + } + + public override string ToString() + { + return Data + IOUtils.CLIPBOARD_DATA_SEPARATOR + Connections + IOUtils.CLIPBOARD_DATA_SEPARATOR + OldNodeId + IOUtils.CLIPBOARD_DATA_SEPARATOR + NewNodeId; + } + } + + public class Clipboard + { + public const string ClipboardId = "AMPLIFY_CLIPBOARD_ID"; + private readonly string[] ClipboardTagId = { "#CLIP_ITEM#" }; + private List<ClipboardData> m_clipboardStrData; + private Dictionary<int, ClipboardData> m_clipboardAuxData; + private Dictionary<string, ClipboardData> m_multiPassMasterNodeData; + + public Clipboard() + { + m_clipboardStrData = new List<ClipboardData>(); + m_clipboardAuxData = new Dictionary<int, ClipboardData>(); + m_multiPassMasterNodeData = new Dictionary<string, ClipboardData>(); + } + + public void AddMultiPassNodesToClipboard( List<TemplateMultiPassMasterNode> masterNodes ) + { + m_multiPassMasterNodeData.Clear(); + int templatesAmount = masterNodes.Count; + for( int i = 0; i < templatesAmount; i++ ) + { + if( !masterNodes[ i ].InvalidNode ) + { + string data = string.Empty; + string connection = string.Empty; + masterNodes[ i ].FullWriteToString( ref data, ref connection ); + ClipboardData clipboardData = new ClipboardData( data, connection, masterNodes[ i ].UniqueId ); + m_multiPassMasterNodeData.Add( masterNodes[ i ].PassUniqueName, clipboardData ); + } + } + } + + public void GetMultiPassNodesFromClipboard( List<TemplateMultiPassMasterNode> masterNodes ) + { + int templatesAmount = masterNodes.Count; + for( int i = 0; i < templatesAmount; i++ ) + { + if( m_multiPassMasterNodeData.ContainsKey( masterNodes[ i ].PassUniqueName ) ) + { + ClipboardData nodeData = m_multiPassMasterNodeData[ masterNodes[ i ].PassUniqueName ]; + string[] nodeParams = nodeData.Data.Split( IOUtils.FIELD_SEPARATOR ); + masterNodes[ i ].FullReadFromString( ref nodeParams ); + } + } + + for( int i = 0; i < templatesAmount; i++ ) + { + if( m_multiPassMasterNodeData.ContainsKey( masterNodes[ i ].PassUniqueName ) ) + { + masterNodes[ i ].SetReadOptions(); + masterNodes[ i ].ForceOptionsRefresh(); + } + } + + m_multiPassMasterNodeData.Clear(); + } + + public void AddToClipboard( List<ParentNode> selectedNodes , Vector3 initialPosition, ParentGraph graph ) + { + //m_clipboardStrData.Clear(); + //m_clipboardAuxData.Clear(); + + string clipboardData = IOUtils.Vector3ToString( initialPosition ) + ClipboardTagId[ 0 ]; + int masterNodeId = UIUtils.CurrentWindow.CurrentGraph.CurrentMasterNodeId; + int count = selectedNodes.Count; + for ( int i = 0; i < count; i++ ) + { + if ( UIUtils.CurrentWindow.IsShaderFunctionWindow || !graph.IsMasterNode( selectedNodes[ i ] )) + { + string nodeData = string.Empty; + string connections = string.Empty; + selectedNodes[ i ].ClipboardFullWriteToString( ref nodeData, ref connections ); + clipboardData += nodeData; + if ( !string.IsNullOrEmpty( connections ) ) + { + connections = connections.Substring( 0, connections.Length - 1 ); + clipboardData += "\n" + connections; + } + if ( i < count - 1 ) + clipboardData += ClipboardTagId[ 0 ]; + + //ClipboardData data = new ClipboardData( nodeData, connections, selectedNodes[ i ].UniqueId ); + //m_clipboardStrData.Add( data ); + //m_clipboardAuxData.Add( selectedNodes[ i ].UniqueId, data ); + } + } + + if ( !string.IsNullOrEmpty( clipboardData ) ) + { + EditorPrefs.SetString( ClipboardId, clipboardData ); + } + //for ( int i = 0; i < selectedNodes.Count; i++ ) + //{ + // if ( selectedNodes[ i ].UniqueId != masterNodeId ) + // { + // WireNode wireNode = selectedNodes[ i ] as WireNode; + // if ( wireNode != null ) + // { + // if ( !IsNodeChainValid( selectedNodes[ i ], true ) || !IsNodeChainValid( selectedNodes[ i ], false ) ) + // { + // UnityEngine.Debug.Log( "found invalid wire port" ); + // } + // } + // } + //} + } + + public Vector3 GetDataFromEditorPrefs() + { + Vector3 initialPos = Vector3.zero; + m_clipboardStrData.Clear(); + m_clipboardAuxData.Clear(); + string clipboardData = EditorPrefs.GetString( ClipboardId, string.Empty ); + if ( !string.IsNullOrEmpty( clipboardData ) ) + { + string[] clipboardDataArray = clipboardData.Split( ClipboardTagId, StringSplitOptions.None ); + initialPos = IOUtils.StringToVector3( clipboardDataArray[0] ); + for ( int i = 1; i < clipboardDataArray.Length; i++ ) + { + if ( !string.IsNullOrEmpty( clipboardDataArray[ i ] ) ) + { + int wiresIndex = clipboardDataArray[ i ].IndexOf( IOUtils.LINE_TERMINATOR ); + string nodeData = string.Empty; + string connections = string.Empty; + if ( wiresIndex < 0 ) + { + nodeData = clipboardDataArray[ i ]; + } + else + { + nodeData = clipboardDataArray[ i ].Substring( 0, wiresIndex ); + connections = clipboardDataArray[ i ].Substring( wiresIndex + 1 ); + } + string[] nodeDataArr = nodeData.Split( IOUtils.FIELD_SEPARATOR ); + if ( nodeDataArr.Length > 2 ) + { + int nodeId = Convert.ToInt32( nodeDataArr[ 2 ] ); + ClipboardData data = new ClipboardData( nodeData, connections, nodeId ); + m_clipboardStrData.Add( data ); + m_clipboardAuxData.Add( nodeId, data ); + } + + } + } + } + return initialPos; + } + + public bool IsNodeChainValid( ParentNode currentNode, bool forward ) + { + WireNode wireNode = currentNode as WireNode; + if ( wireNode == null ) + { + return m_clipboardAuxData.ContainsKey( currentNode.UniqueId ); + } + + if ( forward ) + { + if ( wireNode.InputPorts[ 0 ].ExternalReferences.Count > 0 ) + { + int nodeId = wireNode.InputPorts[ 0 ].ExternalReferences[ 0 ].NodeId; + if ( m_clipboardAuxData.ContainsKey( nodeId ) ) + { + return IsNodeChainValid( UIUtils.GetNode( nodeId ), forward ); + } + } + } + else + { + int nodeId = wireNode.OutputPorts[ 0 ].ExternalReferences[ 0 ].NodeId; + if ( m_clipboardAuxData.ContainsKey( nodeId ) ) + { + return IsNodeChainValid( UIUtils.GetNode( nodeId ), forward ); + } + } + return false; + } + + public void GenerateFullString() + { + string data = string.Empty; + for ( int i = 0; i < m_clipboardStrData.Count; i++ ) + { + data += m_clipboardStrData[ i ].ToString(); + if ( i < m_clipboardStrData.Count - 1 ) + { + data += IOUtils.LINE_TERMINATOR; + } + } + } + + public void ClearClipboard() + { + m_clipboardStrData.Clear(); + m_clipboardAuxData.Clear(); + m_multiPassMasterNodeData.Clear(); + } + + public ClipboardData GetClipboardData( int oldNodeId ) + { + if ( m_clipboardAuxData.ContainsKey( oldNodeId ) ) + return m_clipboardAuxData[ oldNodeId ]; + return null; + } + + public int GeNewNodeId( int oldNodeId ) + { + if ( m_clipboardAuxData.ContainsKey( oldNodeId ) ) + return m_clipboardAuxData[ oldNodeId ].NewNodeId; + return -1; + } + + public List<ClipboardData> CurrentClipboardStrData + { + get { return m_clipboardStrData; } + } + + public bool HasCachedMasterNodes { get { return m_multiPassMasterNodeData.Count > 0; } } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Clipboard.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Clipboard.cs.meta new file mode 100644 index 00000000..3e4b657c --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Clipboard.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 8850a8c4f3ca99f42bbf602c671ffb7f +timeCreated: 1481126957 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/ConfirmationWindow.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/ConfirmationWindow.cs new file mode 100644 index 00000000..896c432b --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/ConfirmationWindow.cs @@ -0,0 +1,120 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using UnityEditor; +using UnityEngine; + +namespace AmplifyShaderEditor +{ + public class ConfirmationWindow + { + public delegate ShaderLoadResult OnConfirmationSelected( bool value, Shader shader, Material material ); + public event OnConfirmationSelected OnConfirmationSelectedEvt; + + private const string m_yesStr = "Yes"; + private const string m_noStr = "No"; + private bool m_isActive = false; + private string m_currentMessage; + + private GUIStyle m_areaStyle; + private GUIContent m_content; + private GUIStyle m_buttonStyle; + private GUIStyle m_labelStyle; + + + private Shader m_shader; + private Material m_material; + private Rect m_area; + private bool m_autoDeactivate = true; + + + public ConfirmationWindow( float x, float y, float width, float height ) + { + m_content = new GUIContent( GUIContent.none ); + m_area = new Rect( x, y, width, height ); + } + + public void Destroy() + { + m_shader = null; + OnConfirmationSelectedEvt = null; + } + + public void ActivateConfirmation( Shader shader, Material material, string message, OnConfirmationSelected evt, bool autoDeactivate = true ) + { + OnConfirmationSelectedEvt = evt; + m_currentMessage = message; + m_shader = shader; + m_material = material; + m_autoDeactivate = autoDeactivate; + m_isActive = true; + } + + public void OnGUI() + { + if ( m_areaStyle == null ) + { + m_areaStyle = new GUIStyle( UIUtils.TextArea ); + m_areaStyle.stretchHeight = true; + m_areaStyle.stretchWidth = true; + m_areaStyle.fontSize = ( int ) Constants.DefaultTitleFontSize; + } + + if ( m_buttonStyle == null ) + { + m_buttonStyle = UIUtils.Button; + } + + if ( m_labelStyle == null ) + { + m_labelStyle = new GUIStyle( UIUtils.Label ); + m_labelStyle.alignment = TextAnchor.MiddleCenter; + m_labelStyle.wordWrap = true; + } + + m_area.x = ( int ) ( 0.5f * UIUtils.CurrentWindow.CameraInfo.width ); + m_area.y = ( int ) ( 0.5f * UIUtils.CurrentWindow.CameraInfo.height ); + + GUILayout.BeginArea( m_area, m_content, m_areaStyle ); + { + EditorGUILayout.BeginVertical(); + { + EditorGUILayout.Separator(); + EditorGUILayout.LabelField( m_currentMessage, m_labelStyle ); + + EditorGUILayout.Separator(); + EditorGUILayout.Separator(); + EditorGUILayout.BeginHorizontal(); + { + if ( GUILayout.Button( m_yesStr, m_buttonStyle ) ) + { + if ( OnConfirmationSelectedEvt != null ) + OnConfirmationSelectedEvt( true, m_shader, m_material ); + + if ( m_autoDeactivate ) + Deactivate(); + } + + if ( GUILayout.Button( m_noStr, m_buttonStyle ) ) + { + if ( OnConfirmationSelectedEvt != null ) + OnConfirmationSelectedEvt( false, m_shader, m_material ); + if ( m_autoDeactivate ) + Deactivate(); + } + } + EditorGUILayout.EndHorizontal(); + } + EditorGUILayout.EndVertical(); + } + GUILayout.EndArea(); + } + + public void Deactivate() + { + m_isActive = false; + OnConfirmationSelectedEvt = null; + } + public bool IsActive { get { return m_isActive; } } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/ConfirmationWindow.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/ConfirmationWindow.cs.meta new file mode 100644 index 00000000..7770352f --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/ConfirmationWindow.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 291cb40a04f835a4d89037cf3053c6a3 +timeCreated: 1481126954 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/ConsoleLogWindow.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/ConsoleLogWindow.cs new file mode 100644 index 00000000..937ebe21 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/ConsoleLogWindow.cs @@ -0,0 +1,288 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using System.Collections.Generic; +using UnityEditor; +using UnityEngine; + +namespace AmplifyShaderEditor +{ + [System.Serializable] + public class Toast + { + public MessageSeverity ItemType; + public string ItemMessage; + public double ItemTime; + public int ItemOwnerId; + public Toast( MessageSeverity itemType, string itemMessage, double itemTime,int itemOwnerId ) + { + ItemType = itemType; + ItemMessage = itemMessage; + ItemTime = itemTime; + ItemOwnerId = itemOwnerId; + } + } + + public class ConsoleLogWindow + { + public const int MAXWIDTH = 400; + public const float FADETIME = 7; + + private readonly GUIContent m_boxToggleContent = new GUIContent( "\u2261", "Toggle Message Box" ); + private readonly GUIContent m_clearContent = new GUIContent( "\u00D7", "Clear Messages" ); + + protected AmplifyShaderEditorWindow m_parentWindow = null; + + // needs to be serialized + private Vector2 m_currentScrollPos; + + int lastCall = -1; + + public ConsoleLogWindow( AmplifyShaderEditorWindow parentWindow ) + { + m_parentWindow = parentWindow; + } + + public void AddMessage( MessageSeverity itemType, string itemMessage , int itemOwnerId ) + { + var toast = new Toast( itemType, itemMessage, Time.realtimeSinceStartup, itemOwnerId ); + m_parentWindow.Messages.Insert( 0, toast ); + m_currentScrollPos.y = Mathf.Infinity; + + if( !m_parentWindow.MaximizeMessages ) + lastCall = Mathf.Max( (int)itemType, lastCall ); + + GUIContent gc = new GUIContent( m_parentWindow.Messages.Count + ": " + itemMessage ); + float maxWidth = m_parentWindow.MaxMsgWidth; + maxWidth = Mathf.Max( GUIStyle.none.CalcSize( gc ).x + 16, maxWidth ); + maxWidth = Mathf.Min( maxWidth, MAXWIDTH ); + m_parentWindow.MaxMsgWidth = maxWidth; + } + + public void Draw( Rect parentPosition, Vector2 mousePosition, int mouseButtonId, bool hasKeyboadFocus, float rightSide ) + { + EventType currentEventType = Event.current.type; + var messages = m_parentWindow.Messages; + var maximize = m_parentWindow.MaximizeMessages; + + Rect button = parentPosition; + button.width = 22; + button.height = 22; + button.x = parentPosition.x + parentPosition.width - button.width - rightSide - 8; + button.y = parentPosition.y + parentPosition.height - button.height - ( m_parentWindow.CurrentSelection == ASESelectionMode.Material ? 52 : 8 ); + + Rect toolbarArea = button; + toolbarArea.y -= 5; + if( maximize ) + { + toolbarArea.xMin -= m_parentWindow.MaxMsgWidth; + toolbarArea.yMin -= 66; + } + toolbarArea.x -= 6; + + bool needsRepaint = false; + if( maximize ) + { + GUIStyle labelStyle = UIUtils.ConsoleLogLabel; + toolbarArea.y -= 16 + 8; + GUILayout.BeginArea( toolbarArea, UIUtils.ConsoleLogMessage ); + EditorGUILayout.BeginVertical(); + m_currentScrollPos = EditorGUILayout.BeginScrollView( m_currentScrollPos ); + { + int count = messages.Count; + for( int i = count - 1; i >= 0; i-- ) + { + switch( messages[ i ].ItemType ) + { + case MessageSeverity.Error: + labelStyle.normal.textColor = Color.red; + break; + case MessageSeverity.Warning: + labelStyle.normal.textColor = Color.yellow; + break; + default: + case MessageSeverity.Normal: + labelStyle.normal.textColor = Color.white; + break; + } + + if( messages[ i ].ItemOwnerId < 0 ) + { + GUILayout.Label( ( count - i ) + ": " + messages[ i ].ItemMessage, labelStyle ); + } + else + { + if( GUILayout.Button( ( count - i ) + ": " + messages[ i ].ItemMessage, labelStyle ) ) + { + UIUtils.CurrentWindow.FocusOnNode( messages[ i ].ItemOwnerId, 1, true ); + } + } + } + } + EditorGUILayout.EndScrollView(); + EditorGUILayout.EndVertical(); + + GUILayout.EndArea(); + } + else + { + // draw toaster + int count = messages.Count; + Rect rect = toolbarArea; + rect.xMin -= 200; + + float startFade = FADETIME - 1; + for( int i = 0; i < count; i++ ) + { + GUIStyle msgstyle = UIUtils.ConsoleLogMessage; + float delta = (float)(Time.realtimeSinceStartup - messages[ i ].ItemTime); + if( delta > FADETIME ) + continue; + + if( delta < 0.1f ) + { + msgstyle.normal.textColor = Color.cyan; + } + else if( delta < startFade ) + { + switch( messages[ i ].ItemType ) + { + case MessageSeverity.Error: + msgstyle.normal.textColor = Color.red; + break; + case MessageSeverity.Warning: + msgstyle.normal.textColor = Color.yellow; + break; + default: + case MessageSeverity.Normal: + msgstyle.normal.textColor = Color.white; + break; + } + } + else + { + switch( messages[ i ].ItemType ) + { + case MessageSeverity.Error: + msgstyle.normal.textColor = new Color( 1, 0, 0, FADETIME - delta ); + break; + case MessageSeverity.Warning: + msgstyle.normal.textColor = new Color( 1, 1, 0, FADETIME - delta ); + break; + default: + case MessageSeverity.Normal: + msgstyle.normal.textColor = new Color( 1, 1, 1, FADETIME - delta ); + break; + } + } + + needsRepaint = true; + + GUIContent gc = new GUIContent( messages[ i ].ItemMessage ); + var sizes = msgstyle.CalcSize( gc ); + rect.xMin -= sizes.x - rect.width; + rect.height = sizes.y; + rect.y -= rect.height + 2; + if( messages[ i ].ItemOwnerId < 0 ) + { + GUI.Label( rect, gc, msgstyle ); + } + else + { + if( GUI.Button( rect, gc, msgstyle )) + { + UIUtils.CurrentWindow.FocusOnNode( messages[ i ].ItemOwnerId, 1, true ); + } + } + } + } + //GUI.color = cached; + + if( needsRepaint ) + m_parentWindow.MarkToRepaint(); + + GUIStyle style = UIUtils.ConsoleLogCircle; + + button.size = Vector2.one * 16; + + switch( lastCall ) + { + case 0: + style.normal.textColor = Color.cyan; + break; + case 1: + style.normal.textColor = Color.yellow; + break; + case 2: + style.normal.textColor = Color.red; + break; + default: + style.normal.textColor = new Color( 1, 1, 1, 0.5f ); + break; + } + + if( GUI.Button( button, m_boxToggleContent, style ) ) + { + maximize = !maximize; + m_parentWindow.MaximizeMessages = maximize; + m_currentScrollPos.y = Mathf.Infinity; + lastCall = -1; + } + + style.normal.textColor = new Color( 1, 1, 1, 0.5f ); + //GUI.color = cached; + button.x -= button.width + 2; + + if( maximize && GUI.Button( button, m_clearContent, style ) ) + { + if( messages.Count == 0 ) + { + maximize = false; + m_parentWindow.MaximizeMessages = maximize; + } + ClearMessages(); + } + + button.width += button.width + 2; + bool mouseOnTop = button.Contains( mousePosition ); + + if( currentEventType == EventType.MouseMove && mouseOnTop ) + m_parentWindow.MarkToRepaint(); + + if( DebugConsoleWindow.DeveloperMode ) + { + if( Event.current.type == EventType.KeyDown && Event.current.keyCode == KeyCode.Alpha1 ) + { + UIUtils.ShowMessage( "This is an info message\nwith two lines" ); + } + + if( Event.current.type == EventType.KeyDown && Event.current.keyCode == KeyCode.Alpha2 ) + { + UIUtils.ShowMessage( "This is a warning message", MessageSeverity.Warning ); + } + + if( Event.current.type == EventType.KeyDown && Event.current.keyCode == KeyCode.Alpha3 ) + { + + UIUtils.ShowMessage( "THIS IS AN ERROR MESSAGE!!", MessageSeverity.Error ); + } + } + } + + public void ClearMessages() + { + m_parentWindow.Messages.Clear(); + m_parentWindow.MaxMsgWidth = 100; + } + + public void Toggle() + { + + } + + public void Destroy() + { + m_parentWindow = null; + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/ConsoleLogWindow.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/ConsoleLogWindow.cs.meta new file mode 100644 index 00000000..617e129d --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/ConsoleLogWindow.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: ed706353a579cbb46b300406107108b1 +timeCreated: 1506345180 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/ContextMenuItem.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/ContextMenuItem.cs new file mode 100644 index 00000000..4834ee1f --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/ContextMenuItem.cs @@ -0,0 +1,81 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using System; +using UnityEngine; + +namespace AmplifyShaderEditor +{ + public class ContextMenuItem + { + private const string PALETTE_NAME_MOD_STR = " "; + + private string m_paletteName; + private string m_name; + private string m_tags; + private string m_category; + private string m_description; + private System.Type m_type; + private GUIContent m_guiContent; + private string m_nameWithShortcut; + private AmplifyShaderFunction m_function; + private NodeAttributes m_nodeAttributes; + + public ContextMenuItem( NodeAttributes nodeAttributes, System.Type type, string name, string tags, string category, string description, AmplifyShaderFunction function, KeyCode shortcut ) + { + m_nodeAttributes = nodeAttributes; + m_name = name; + m_tags = name + ( string.IsNullOrEmpty( tags ) ? "" : " " + tags ); + m_tags = m_tags.ToLower(); + m_nameWithShortcut = shortcut != KeyCode.None ? ( name + " [ " + UIUtils.KeyCodeToString( shortcut ) + " ]" ) : name; + m_paletteName = PALETTE_NAME_MOD_STR + m_name; + m_type = type; + m_category = category; + m_description = description; + m_function = function; + m_guiContent = new GUIContent( m_nameWithShortcut, m_description ); + } + + public int CompareTo( ContextMenuItem item , bool useWeights ) + { + if ( useWeights && NodeAttributes.SortOrderPriority > -1 && item.NodeAttributes.SortOrderPriority > -1 ) + { + if ( NodeAttributes.SortOrderPriority > item.NodeAttributes.SortOrderPriority ) + { + return 1; + } + else if ( NodeAttributes.SortOrderPriority == item.NodeAttributes.SortOrderPriority ) + { + return m_name.CompareTo( item.Name ); + } + else + { + return -1; + } + } + return m_name.CompareTo( item.Name ); + } + + public string PaletteName { get { return m_paletteName; } } + public string Name { get { return m_name; } } + public string Tags { get { return m_tags; } } + public string NameWithShortcut { get { return m_nameWithShortcut; } } + public string Category { get { return m_category; } } + public string Description { get { return m_description; } } + public AmplifyShaderFunction Function { get { return m_function; } } + public System.Type NodeType { get { return m_type; } } + public GUIContent ItemUIContent { get { return m_guiContent; } } + public NodeAttributes NodeAttributes { get { return m_nodeAttributes; } } + + public override string ToString() + { + return m_name + ":" + m_category + ":" + m_description; + } + + public void Destroy() + { + m_guiContent = null; + m_nodeAttributes = null; + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/ContextMenuItem.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/ContextMenuItem.cs.meta new file mode 100644 index 00000000..7b1fbe8c --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/ContextMenuItem.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 417f409230c530b468b8ab67dd6e3b8b +timeCreated: 1481126955 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/CustomStylesContainer.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/CustomStylesContainer.cs new file mode 100644 index 00000000..0de8b80a --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/CustomStylesContainer.cs @@ -0,0 +1,53 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +//using UnityEditor; +//using UnityEngine; +//namespace AmplifyShaderEditor +//{ +// //EditorGUIUtility.GetBuiltinSkin(EditorSkin.Inspector) +// // this might be a bit nonsense since I could use the GetBuiltinSkin directly but this way will bea easier to change to some custom visuals on some near future +// [System.Serializable] +// public class CustomStylesContainer +// { +// public GUIStyle FoldoutStyle +// { +// get { return EditorStyles.foldout; } +// } + +// public GUIStyle Label +// { +// get { return GUI.skin.label; } +// } + +// public GUIStyle Button +// { +// get { return GUI.skin.button; } +// } + +// public GUIStyle TextArea +// { +// get { return GUI.skin.textArea; } +// } + +// public GUIStyle Toggle +// { +// get { return GUI.skin.toggle; } +// } + +// public GUIStyle Window +// { +// get { return GUI.skin.window; } +// } + +// public GUIStyle Textfield +// { +// get { return GUI.skin.textField; } +// } + +// public GUIStyle Box +// { +// get { return GUI.skin.box; } +// } +// } +//} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/CustomStylesContainer.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/CustomStylesContainer.cs.meta new file mode 100644 index 00000000..b677796e --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/CustomStylesContainer.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 79d0d783b532b474192b191547bee1c1 +timeCreated: 1481126957 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/DebugConsoleWindow.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/DebugConsoleWindow.cs new file mode 100644 index 00000000..85f4604a --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/DebugConsoleWindow.cs @@ -0,0 +1,203 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +//#define ASE_CONSOLE_WINDOW + +using UnityEngine; +using UnityEditor; +using System.Collections.Generic; + +namespace AmplifyShaderEditor +{ + public sealed class DebugConsoleWindow : EditorWindow + { + private const float WindowSizeX = 250; + private const float WindowSizeY = 250; + private const float WindowPosX = 5; + private const float WindowPosY = 5; + private Rect m_availableArea; + + private bool m_wikiAreaFoldout = true; + private bool m_miscAreaFoldout = true; + private Vector2 m_currentScrollPos; + + private int m_minURLNode = 0; + private int m_maxURLNode = -1; + +#if ASE_CONSOLE_WINDOW + public readonly static bool DeveloperMode = true; + public static bool UseShaderPanelsInfo = true; + [MenuItem( "Window/Amplify Shader Editor/Open Debug Console" )] + static void OpenMainShaderGraph() + { + OpenWindow(); + } + [MenuItem( "Window/Amplify Shader Editor/Create Template Menu Items" )] + public static void CreateTemplateMenuItems() + { + UIUtils.CurrentWindow.TemplatesManagerInstance.CreateTemplateMenuItems(); + } + +#else + public readonly static bool DeveloperMode = false; + public static bool UseShaderPanelsInfo = false; +#endif + + public static DebugConsoleWindow OpenWindow() + { + if ( DeveloperMode ) + { + DebugConsoleWindow currentWindow = ( DebugConsoleWindow ) DebugConsoleWindow.GetWindow( typeof( DebugConsoleWindow ), false, "ASE Debug Console" ); + currentWindow.titleContent.tooltip = "Debug Options for ASE. Intented only for ASE development team"; + currentWindow.minSize = new Vector2( WindowSizeX, WindowSizeY ); + currentWindow.maxSize = new Vector2( WindowSizeX, 2 * WindowSizeY ); ; + currentWindow.wantsMouseMove = true; + return currentWindow; + } + return null; + } + + void OnGUI() + { + m_availableArea = new Rect( WindowPosX, WindowPosY, position.width - 2 * WindowPosX, position.height - 2 * WindowPosY ); + GUILayout.BeginArea( m_availableArea ); + { + m_currentScrollPos = EditorGUILayout.BeginScrollView( m_currentScrollPos, GUILayout.Width( 0 ), GUILayout.Height( 0 ) ); + { + EditorGUILayout.BeginVertical(); + { + AmplifyShaderEditorWindow window = UIUtils.CurrentWindow; + if ( window != null ) + { + EditorGUILayout.Separator(); + + NodeUtils.DrawPropertyGroup( ref m_wikiAreaFoldout, "Wiki Helper", ShowWikiHelperFunctions ); + + EditorGUILayout.Separator(); + + NodeUtils.DrawPropertyGroup( ref m_miscAreaFoldout, "Misc", ShowMiscFuntions ); + + EditorGUILayout.Separator(); + } + else + { + EditorGUILayout.LabelField( "Please open an ASE window to access debug options" ); + } + } + EditorGUILayout.EndVertical(); + } + EditorGUILayout.EndScrollView(); + } + GUILayout.EndArea(); + } + + void ShowWikiHelperFunctions() + { + AmplifyShaderEditorWindow window = UIUtils.CurrentWindow; + EditorGUILayout.Separator(); + + if ( GUILayout.Button( "Nodes Screen Shots" ) ) + { + window.CurrentNodeExporterUtils.ActivateAutoScreenShot( Application.dataPath + "/../NodesInfo/Shots/",0,-1 ); + } + + GUILayout.BeginHorizontal(); + if( GUILayout.Button( "Nodes URLs" ) ) + { + window.CurrentNodeExporterUtils.ActivateNodesURL( m_minURLNode, m_maxURLNode ); + } + m_minURLNode = EditorGUILayout.IntField( m_minURLNode ); + m_maxURLNode = EditorGUILayout.IntField( m_maxURLNode ); + GUILayout.EndHorizontal(); + + EditorGUILayout.Separator(); + + if( GUILayout.Button( "Nodes Undo Test" ) ) + { + window.CurrentNodeExporterUtils.ActivateAutoUndo(); + } + + EditorGUILayout.Separator(); + + if ( GUILayout.Button( "Nodes Info" ) ) + { + window.CurrentPaletteWindow.DumpAvailableNodes( false, Application.dataPath + "/../NodesInfo/" ); + window.CurrentPaletteWindow.DumpAvailableNodes( true, Application.dataPath + "/../NodesInfo/" ); + } + + EditorGUILayout.Separator(); + + if ( GUILayout.Button( "Shortcuts Info" ) ) + { + window.ShortcutManagerInstance.DumpShortcutsToDisk( Application.dataPath + "/../NodesInfo/" ); + } + } + + void ShowMiscFuntions() + { + AmplifyShaderEditorWindow window = UIUtils.CurrentWindow; + if ( GUILayout.Button( "Force Example Shader Compilation" ) ) + { + UIUtils.ForceExampleShaderCompilation(); + } + EditorGUILayout.Separator(); + + if ( GUILayout.Button( "Refresh Available Nodes" ) ) + { + window.RefreshAvaibleNodes(); + } + + EditorGUILayout.Separator(); + + if ( GUILayout.Button( "Dump Uniform Names" ) ) + { + //window.CurrentPaletteWindow.NewList() + window.DuplicatePrevBufferInstance.DumpUniformNames(); + } + + EditorGUILayout.Separator(); + + if ( GUILayout.Button( "Force Palette Update" ) ) + { + Debug.Log( UIUtils.CurrentWindow.IsShaderFunctionWindow ); + window.CurrentPaletteWindow.ForceUpdate = true; + } + + EditorGUILayout.Separator(); + + if( GUILayout.Button( "Detect Infinite Loops" ) ) + { + if( window.IsShaderFunctionWindow ) + { + Debug.Log( "Starting infinite loop detection over shader functions" ); + List<FunctionOutput> nodes = window.OutsideGraph.FunctionOutputNodes.NodesList; + for( int i = 0; i < nodes.Count; i++ ) + { + UIUtils.DetectNodeLoopsFrom( nodes[ i ], new Dictionary<int, int>() ); + } + } + else + { + if( window.OutsideGraph.MultiPassMasterNodes.Count > 0 ) + { + Debug.Log( "Starting infinite loop detection over shader from template" ); + List<TemplateMultiPassMasterNode> nodes = window.OutsideGraph.MultiPassMasterNodes.NodesList; + for( int i = 0; i < nodes.Count; i++ ) + { + UIUtils.DetectNodeLoopsFrom( nodes[ i ], new Dictionary<int, int>() ); + } + } + else + { + Debug.Log( "Starting infinite loop detection over standard shader" ); + UIUtils.DetectNodeLoopsFrom( window.OutsideGraph.CurrentMasterNode, new Dictionary<int, int>() ); + } + } + Debug.Log( "End infinite loop detection" ); + } + } + } +} + + + diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/DebugConsoleWindow.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/DebugConsoleWindow.cs.meta new file mode 100644 index 00000000..a9e53839 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/DebugConsoleWindow.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 52308890136cd7746a5a073c9be8f028 +timeCreated: 1487850100 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/DragAndDropTool.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/DragAndDropTool.cs new file mode 100644 index 00000000..2da02086 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/DragAndDropTool.cs @@ -0,0 +1,47 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using UnityEditor; +using UnityEngine; + +namespace AmplifyShaderEditor +{ + public class DragAndDropTool + { + public delegate void OnValidDropObject(params UnityEngine.Object[] draggedObjs ); + public event OnValidDropObject OnValidDropObjectEvt; + + public void Destroy() + { + OnValidDropObjectEvt = null; + } + + public void TestDragAndDrop( Rect dropArea ) + { + Event currentEvent = Event.current; + EventType currentEventType = currentEvent.type; + + switch (currentEventType) + { + case EventType.DragUpdated: + case EventType.DragPerform: + { + + if (!dropArea.Contains(currentEvent.mousePosition)) + return; + + DragAndDrop.visualMode = DragAndDropVisualMode.Copy; + if (currentEvent.type == EventType.DragPerform) + { + DragAndDrop.AcceptDrag(); + if (OnValidDropObjectEvt != null) + { + OnValidDropObjectEvt(DragAndDrop.objectReferences); + } + } + }break; + case EventType.DragExited:DragAndDrop.PrepareStartDrag();break; + } + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/DragAndDropTool.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/DragAndDropTool.cs.meta new file mode 100644 index 00000000..3ca3a86b --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/DragAndDropTool.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 41c9bd09aea1377459c7e62910711c22 +timeCreated: 1481126955 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/DuplicatePreventionBuffer.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/DuplicatePreventionBuffer.cs new file mode 100644 index 00000000..6f763338 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/DuplicatePreventionBuffer.cs @@ -0,0 +1,375 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace AmplifyShaderEditor +{ + [Serializable] + public class DuplicatePreventionBuffer + { + private const string VectorNameStr = "Vector "; + private const string TextureSampleNameStr = "Texture Sample "; + private const string MatrixNameStr = "Matrix "; + private const string IntNameStr = "Int "; + private const string FloatNameStr = "Float "; + private const string ColorNameStr = "Color "; + + [SerializeField] + private int[] m_availableUVChannelsArray = { -1, -1, -1, -1 }; + private string[] m_availableUVChannelsNamesArray = { "null", + "null", + "null", + "null" }; + + private Dictionary<string, int> m_availablePropertyNames = new Dictionary<string, int>(); + private Dictionary<string, int> m_availableUniformNames = new Dictionary<string, int>(); + private Dictionary<string, int> m_availableLocalVariableNames = new Dictionary<string, int>(); + + public void ReleaseAllUVChannels() + { + for ( int i = 0; i < m_availableUVChannelsArray.Length; i++ ) + { + m_availableUVChannelsArray[ i ] = -1; + } + } + + public bool RegisterUVChannel( int nodeId, int channelId, string name ) + { + if ( channelId < 0 || + channelId > ( m_availableUVChannelsArray.Length - 1 ) || + m_availableUVChannelsArray[ channelId ] >= 0 ) + { + return false; + } + + m_availableUVChannelsArray[ channelId ] = nodeId; + m_availableUVChannelsNamesArray[ channelId ] = name; + return true; + } + + + public bool ReleaseUVChannel( int nodeId, int channelId ) + { + if ( channelId < 0 || + channelId > ( m_availableUVChannelsArray.Length - 1 ) ) + { + return false; + } + + if ( m_availableUVChannelsArray[ channelId ] == nodeId ) + { + m_availableUVChannelsArray[ channelId ] = -1; + return true; + } + return false; + } + + public int RegisterFirstAvailableChannel( int nodeId , string name) + { + for ( int i = 0; i < m_availableUVChannelsArray.Length; i++ ) + { + if ( m_availableUVChannelsArray[ i ] == -1 ) + { + m_availableUVChannelsArray[ i ] = nodeId; + m_availableUVChannelsNamesArray[ i ] = name; + return i; + } + } + return -1; + } + + public bool IsChannelAvailable( int channelId ) + { + if ( channelId < 0 || + channelId > ( m_availableUVChannelsArray.Length - 1 ) ) + { + return false; + } + + return ( m_availableUVChannelsArray[ channelId ] < 0 ); + } + + public int GetFirstOccupiedChannel() + { + for ( int i = 0; i < 4; i++ ) + { + if ( m_availableUVChannelsArray[ i ] > -1 ) + return i; + } + return -1; + } + + public string GetChannelName( int channelId ) + { + if ( channelId < 0 || + channelId > ( m_availableUVChannelsArray.Length - 1 ) ) + { + return string.Empty; + } + + return m_availableUVChannelsNamesArray[ channelId ] ; + } + + public void SetChannelName( int channelId , string name ) + { + if ( channelId < 0 || + channelId > ( m_availableUVChannelsArray.Length - 1 ) ) + { + return; + } + m_availableUVChannelsNamesArray[ channelId ] = name; + } + + public bool RegisterLocalVariableName( int nodeId, string name ) + { + if ( name.Length == 0 ) + return false; + + if ( m_availableLocalVariableNames.ContainsKey( name ) ) + { + if ( m_availableLocalVariableNames[ name ] > -1 ) + { + return false; + } + else + { + m_availableLocalVariableNames[ name ] = nodeId; + return true; + } + } + + m_availableLocalVariableNames.Add( name, nodeId ); + return true; + } + + public int CheckUniformNameOwner( string name ) + { + if ( name.Length == 0 ) + return -1; + + if ( m_availableUniformNames.ContainsKey( name ) ) + { + return m_availableUniformNames[ name ]; + } + + return -1; + } + + public bool RegisterUniformName( int nodeId, string name ) + { + if ( name.Length == 0 ) + return false; + + if ( m_availableUniformNames.ContainsKey( name ) ) + { + if ( m_availableUniformNames[ name ] > -1 ) + { + return false; + } + else + { + m_availableUniformNames[ name ] = nodeId; + return true; + } + } + + m_availableUniformNames.Add( name, nodeId ); + return true; + } + + public void DumpUniformNames() + { + string val = "CONTENTS\n"; + foreach ( KeyValuePair<string, int> kvp in m_availableUniformNames ) + { + val += ( "key " + kvp.Key + " : value " + kvp.Value + "\n" ); + } + } + + public void DumpLocalVariableNames() + { + string val = "CONTENTS\n"; + foreach ( KeyValuePair<string, int> kvp in m_availableLocalVariableNames ) + { + val += ( "key " + kvp.Key + " : value " + kvp.Value + "\n" ); + } + } + + + public bool ReleaseUniformName( int nodeId, string name ) + { + if ( !string.IsNullOrEmpty(name) && name.Length == 0 ) + return false; + + if ( m_availableUniformNames.ContainsKey( name ) ) + { + if ( m_availableUniformNames[ name ] == nodeId ) + { + m_availableUniformNames.Remove( name ); + return true; + } + } + return false; + } + + public bool ReleaseLocalVariableName( int nodeId, string name ) + { + if ( name.Length == 0 ) + return false; + + if ( m_availableLocalVariableNames.ContainsKey( name ) ) + { + if ( m_availableLocalVariableNames[ name ] == nodeId ) + { + m_availableLocalVariableNames.Remove( name ); + return true; + } + } + return false; + } + + public void ReleaseAllUniformNames() + { + m_availableUniformNames.Clear(); + } + + public void ReleaseAllLocalVariableNames() + { + m_availableLocalVariableNames.Clear(); + } + + public void GetFirstAvailableName( int nodeId, WirePortDataType type , out string outProperty , out string outInspector, bool useCustomPrefix = false, string customPrefix = null) + { + string name = string.Empty; + if ( useCustomPrefix && customPrefix != null ) + { + name = customPrefix; + } + else + { + switch ( type ) + { + case WirePortDataType.OBJECT: + case WirePortDataType.FLOAT: + { + name = FloatNameStr; + } + break; + case WirePortDataType.INT: + { + name = IntNameStr; + } + break; + case WirePortDataType.FLOAT2: + case WirePortDataType.FLOAT3: + case WirePortDataType.FLOAT4: + { + name = VectorNameStr; + } + break; + case WirePortDataType.FLOAT3x3: + case WirePortDataType.FLOAT4x4: + { + name = MatrixNameStr; + } + break; + case WirePortDataType.COLOR: + { + name = ColorNameStr; + } + break; + } + } + + int count = 0; + bool foundName = false; + while ( !foundName ) + { + string inspectorName = name + count; + string propertyName = UIUtils.GeneratePropertyName( inspectorName , PropertyType.Property ); + + if ( IsUniformNameAvailable( propertyName ) ) + { + outInspector = inspectorName; + outProperty = propertyName; + RegisterUniformName( nodeId, propertyName ); + return; + } + count += 1; + } + outProperty = string.Empty; + outInspector = string.Empty; + UIUtils.ShowMessage( "Could not find a valid name " + MessageSeverity.Warning ); + } + + public bool IsUniformNameAvailable( string name ) + { + if ( m_availableUniformNames.ContainsKey( name ) && m_availableUniformNames[ name ] > -1 ) + return false; + return true; + } + + public bool IsLocalvariableNameAvailable( string name ) + { + if ( m_availableLocalVariableNames.ContainsKey( name ) && m_availableLocalVariableNames[ name ] > -1 ) + return false; + return true; + } + + public bool GetPropertyName( int nodeId, string name ) + { + if ( m_availablePropertyNames.ContainsKey( name ) ) + { + if ( m_availablePropertyNames[ name ] > -1 ) + { + return false; + } + else + { + m_availablePropertyNames[ name ] = nodeId; + return true; + } + } + + m_availablePropertyNames.Add( name, nodeId ); + return true; + } + + + public bool ReleasePropertyName( int nodeId, string name ) + { + if ( m_availablePropertyNames.ContainsKey( name ) ) + { + if ( m_availablePropertyNames[ name ] == nodeId ) + { + m_availablePropertyNames[ name ] = -1; + return true; + } + } + return false; + } + + public void ReleaseAllPropertyNames() + { + m_availablePropertyNames.Clear(); + } + + public bool IsPropertyNameAvailable( string name ) + { + if ( m_availablePropertyNames.ContainsKey( name ) && m_availablePropertyNames[ name ] > -1 ) + return false; + return true; + } + + public void ReleaseAllData() + { + ReleaseAllUVChannels(); + ReleaseAllUniformNames(); + ReleaseAllPropertyNames(); + ReleaseAllLocalVariableNames(); + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/DuplicatePreventionBuffer.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/DuplicatePreventionBuffer.cs.meta new file mode 100644 index 00000000..fd5e6614 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/DuplicatePreventionBuffer.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: a4cfbb4204c63ca4e8f7cec73f6b3ef8 +timeCreated: 1481126958 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/GraphContextMenu.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/GraphContextMenu.cs new file mode 100644 index 00000000..adcbfe4e --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/GraphContextMenu.cs @@ -0,0 +1,375 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using UnityEngine; +using UnityEditor; +using System; +using System.Text; +using System.Linq; +using System.Collections.Generic; +using System.Reflection; + +namespace AmplifyShaderEditor +{ + public class ShortcutKeyData + { + public bool IsPressed; + public System.Type NodeType; + public string Name; + public ShortcutKeyData( System.Type type, string name ) + { + NodeType = type; + Name = name; + IsPressed = false; + } + } + + public class GraphContextMenu + { + private List<ContextMenuItem> m_items; + private List<ContextMenuItem> m_itemFunctions; + private Dictionary<System.Type, NodeAttributes> m_itemsDict; + private Dictionary<System.Type, NodeAttributes> m_deprecatedItemsDict; + private Dictionary<System.Type, System.Type> m_castTypes; + private Dictionary<KeyCode, ShortcutKeyData> m_shortcutTypes; + + private KeyCode m_lastKeyPressed; + private ParentGraph m_currentGraph; + private bool m_correctlyLoaded = false; + + public GraphContextMenu( ParentGraph currentGraph ) + { + m_currentGraph = currentGraph; + m_correctlyLoaded = RefreshNodes( currentGraph ); + } + + private Type[] GetTypesInNamespace( Assembly assembly, string nameSpace ) + { + return assembly.GetTypes().Where( t => String.Equals( t.Namespace, nameSpace, StringComparison.Ordinal ) ).ToArray(); + } + + public bool RefreshNodes( ParentGraph currentGraph ) + { + if( m_items != null ) + { + m_items.Clear(); + m_items = null; + } + + if( m_itemFunctions != null ) + { + m_itemFunctions.Clear(); + m_itemFunctions = null; + } + + m_items = new List<ContextMenuItem>(); + m_itemFunctions = new List<ContextMenuItem>(); + + if( m_itemsDict != null ) + m_itemsDict.Clear(); + + m_itemsDict = new Dictionary<System.Type, NodeAttributes>(); + + if( m_deprecatedItemsDict != null ) + m_deprecatedItemsDict.Clear(); + + m_deprecatedItemsDict = new Dictionary<System.Type, NodeAttributes>(); + + if( m_castTypes != null ) + m_castTypes.Clear(); + + m_castTypes = new Dictionary<System.Type, System.Type>(); + + if( m_shortcutTypes != null ) + m_shortcutTypes.Clear(); + + m_shortcutTypes = new Dictionary<KeyCode, ShortcutKeyData>(); + + m_lastKeyPressed = KeyCode.None; + + // Fetch all available nodes by their attributes + try + { + //IEnumerable<System.Type> availableTypes = AppDomain.CurrentDomain.GetAssemblies().ToList().SelectMany( type => type.GetTypes() ); + Type[] availableTypes = GetTypesInNamespace( Assembly.GetExecutingAssembly(), "AmplifyShaderEditor" ); + foreach( System.Type type in availableTypes ) + { + foreach( NodeAttributes attribute in Attribute.GetCustomAttributes( type ).OfType<NodeAttributes>() ) + { + if( attribute.Available && !attribute.Deprecated ) + { + //if ( !UIUtils.CurrentWindow.IsShaderFunctionWindow && attribute.AvailableInFunctionsOnly ) + // continue; + + if( !UIUtils.HasColorCategory( attribute.Category ) ) + { + if( !String.IsNullOrEmpty( attribute.CustomCategoryColor ) ) + { + try + { + Color color = new Color(); + ColorUtility.TryParseHtmlString( attribute.CustomCategoryColor, out color ); + UIUtils.AddColorCategory( attribute.Category, color ); + } + catch( Exception e ) + { + Debug.LogException( e ); + UIUtils.AddColorCategory( attribute.Category, Constants.DefaultCategoryColor ); + } + } + //else + //{ + // UIUtils.AddColorCategory( attribute.Category, Constants.DefaultCategoryColor ); + //} + } + + if( attribute.CastType != null && attribute.CastType.Length > 0 && type != null ) + { + for( int i = 0; i < attribute.CastType.Length; i++ ) + { + m_castTypes.Add( attribute.CastType[ i ], type ); + } + } + + if( attribute.ShortcutKey != KeyCode.None && type != null ) + m_shortcutTypes.Add( attribute.ShortcutKey, new ShortcutKeyData( type, attribute.Name ) ); + + ContextMenuItem newItem = new ContextMenuItem( attribute, type, attribute.Name, attribute.Tags, attribute.Category, attribute.Description, null, attribute.ShortcutKey ); + if( UIUtils.GetNodeAvailabilityInBitArray( attribute.NodeAvailabilityFlags, NodeAvailability.SurfaceShader ) ) + m_items.Add( newItem ); + else if( UIUtils.GetNodeAvailabilityInBitArray( attribute.NodeAvailabilityFlags, currentGraph.ParentWindow.CurrentNodeAvailability ) ) + m_items.Add( newItem ); + else if( UIUtils.GetNodeAvailabilityInBitArray( attribute.NodeAvailabilityFlags, currentGraph.CurrentCanvasMode ) ) + m_items.Add( newItem ); + + m_itemsDict.Add( type, attribute ); + m_itemFunctions.Add( newItem ); + } + else + { + m_deprecatedItemsDict.Add( type, attribute ); + } + } + } + } + catch( ReflectionTypeLoadException exception ) + { + Debug.LogException( exception ); + return false; + } + + string[] guids = AssetDatabase.FindAssets( "t:AmplifyShaderFunction" ); + List<AmplifyShaderFunction> allFunctions = new List<AmplifyShaderFunction>(); + + for( int i = 0; i < guids.Length; i++ ) + { + allFunctions.Add( AssetDatabase.LoadAssetAtPath<AmplifyShaderFunction>( AssetDatabase.GUIDToAssetPath( guids[ i ] ) ) ); + } + + int functionCount = allFunctions.Count; + if( functionCount > 0 ) + { + m_castTypes.Add( typeof( AmplifyShaderFunction ), typeof( FunctionNode ) ); + } + + for( int i = 0; i < functionCount; i++ ) + { + if( !allFunctions[ i ].Hidden ) + { + NodeAttributes attribute = new NodeAttributes( allFunctions[ i ].FunctionName, allFunctions[ i ].CustomNodeCategory, allFunctions[ i ].Description, KeyCode.None, true, 0, int.MaxValue, typeof( AmplifyShaderFunction ) ); + System.Type type = typeof( FunctionNode ); + + ContextMenuItem newItem = new ContextMenuItem( attribute, type, AddSpacesToSentence( attribute.Name ), attribute.Tags, attribute.Category, attribute.Description, allFunctions[ i ], attribute.ShortcutKey ); + m_items.Add( newItem ); + m_itemFunctions.Add( newItem ); + } + } + + //Sort out the final list by name + m_items.Sort( ( x, y ) => x.Category.CompareTo( y.Category ) ); + m_itemFunctions.Sort( ( x, y ) => x.Category.CompareTo( y.Category ) ); + return true; + } + + public void Destroy() + { + for( int i = 0; i < m_items.Count; i++ ) + { + m_items[ i ].Destroy(); + } + + for( int i = 0; i < m_itemFunctions.Count; i++ ) + { + if( m_itemFunctions[ i ] != null ) + m_itemFunctions[ i ].Destroy(); + } + + m_items.Clear(); + m_items = null; + + m_itemFunctions.Clear(); + m_itemFunctions = null; + + m_itemsDict.Clear(); + m_itemsDict = null; + + m_deprecatedItemsDict.Clear(); + m_deprecatedItemsDict = null; + + m_castTypes.Clear(); + m_castTypes = null; + + m_shortcutTypes.Clear(); + m_shortcutTypes = null; + + } + + public static string AddSpacesToSentence( string text ) + { + if( string.IsNullOrEmpty( text ) ) + return string.Empty; + + bool lastIsUpper = char.IsUpper( text, 0 ); + bool lastIsLetter = char.IsLetter( text, 0 ); + StringBuilder title = new StringBuilder(); + title.Append( text[ 0 ] ); + for( int i = 1; i < text.Length; i++ ) + { + bool currIsUpper = char.IsUpper( text, i ); + bool currIsLetter = char.IsLetter( text, i ); + if( currIsUpper && !lastIsUpper && lastIsLetter ) + { + title.Append( " " ); + } + + // if current is a number and previous is a letter we space it (ie: Rotation2D = Rotation 2D) + if( lastIsLetter && char.IsNumber( text, i ) ) + { + title.Append( " " ); + } + + // if previous is upper, current is upper and the next two following are lower then we space it (ie: UVDistortion = UV Distortion) + if( i < text.Length - 1 ) + { + bool nextIsLower = char.IsLower( text, i + 1 ) && char.IsLetter( text, i + 1 ); + bool lastIsLower = i < text.Length - 2 ? char.IsLower( text, i + 2 ) && char.IsLetter( text, i + 2 ) : false; + if( lastIsUpper && currIsUpper && currIsLetter && nextIsLower && lastIsLower ) + { + title.Append( " " ); + } + } + lastIsUpper = currIsUpper; + lastIsLetter = currIsLetter; + title.Append( text[ i ] ); + } + return title.ToString(); + } + + public NodeAttributes GetNodeAttributesForType( System.Type type ) + { + if( type == null ) + { + Debug.LogError( "Invalid type detected" ); + return null; + } + + if( m_itemsDict.ContainsKey( type ) ) + return m_itemsDict[ type ]; + return null; + } + + public NodeAttributes GetDeprecatedNodeAttributesForType( System.Type type ) + { + if( m_deprecatedItemsDict.ContainsKey( type ) ) + return m_deprecatedItemsDict[ type ]; + return null; + } + + public void UpdateKeyPress( KeyCode key ) + { + if( key == KeyCode.None ) + return; + + m_lastKeyPressed = key; + if( m_shortcutTypes.ContainsKey( key ) ) + { + m_shortcutTypes[ key ].IsPressed = true; + } + } + + public void UpdateKeyReleased( KeyCode key ) + { + if( key == KeyCode.None ) + return; + + if( m_shortcutTypes.ContainsKey( key ) ) + { + m_shortcutTypes[ key ].IsPressed = false; + } + } + + public void ResetShortcutKeyStates() + { + foreach( KeyValuePair<KeyCode, ShortcutKeyData> kvp in m_shortcutTypes ) + { + kvp.Value.IsPressed = false; + } + } + + public ParentNode CreateNodeFromCastType( System.Type type ) + { + if( m_castTypes.ContainsKey( type ) ) + { + ParentNode newNode = (ParentNode)ScriptableObject.CreateInstance( m_castTypes[ type ] ); + return newNode; + } + return null; + } + + + public ParentNode CreateNodeFromShortcutKey() + { + if( m_lastKeyPressed == KeyCode.None ) + return null; + + if( m_shortcutTypes.ContainsKey( m_lastKeyPressed ) && m_shortcutTypes[ m_lastKeyPressed ].IsPressed ) + { + ParentNode newNode = (ParentNode)ScriptableObject.CreateInstance( m_shortcutTypes[ m_lastKeyPressed ].NodeType ); + return newNode; + } + return null; + } + + public bool CheckShortcutKey() + { + if( m_lastKeyPressed == KeyCode.None ) + return false; + + if( m_shortcutTypes.ContainsKey( m_lastKeyPressed ) && m_shortcutTypes[ m_lastKeyPressed ].IsPressed ) + { + return true; + } + return false; + } + + public List<ContextMenuItem> MenuItems + { + get + { + if( m_currentGraph.ParentWindow.IsShaderFunctionWindow ) + return m_itemFunctions; + else + return m_items; + } + } + + public List<ContextMenuItem> ItemFunctions { get { return m_itemFunctions; } } + public KeyCode LastKeyPressed + { + get { return m_lastKeyPressed; } + } + + public Dictionary<KeyCode, ShortcutKeyData> NodeShortcuts { get { return m_shortcutTypes; } } + public bool CorrectlyLoaded { get { return m_correctlyLoaded; } } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/GraphContextMenu.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/GraphContextMenu.cs.meta new file mode 100644 index 00000000..be8ed3c1 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/GraphContextMenu.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 5c34fc95a1ddd7d42bc74151061035f4 +timeCreated: 1481126956 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/MenuParent.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/MenuParent.cs new file mode 100644 index 00000000..2826d02c --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/MenuParent.cs @@ -0,0 +1,445 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using UnityEngine; +using UnityEditor; + +namespace AmplifyShaderEditor +{ + public enum MenuAnchor + { + TOP_LEFT = 0, + TOP_CENTER, + TOP_RIGHT, + MIDDLE_LEFT, + MIDDLE_CENTER, + MIDDLE_RIGHT, + BOTTOM_LEFT, + BOTTOM_CENTER, + BOTTOM_RIGHT, + NONE + } + + public enum MenuAutoSize + { + MATCH_VERTICAL = 0, + MATCH_HORIZONTAL, + NONE + } + + public class MenuParent + { + protected AmplifyShaderEditorWindow m_parentWindow = null; + + protected const float MinimizeButtonXSpacing = 5; + protected const float MinimizeButtonYSpacing = 5.5f; + protected const float ResizeAreaWidth = 5; + + protected const float MinimizeCollisionAdjust = 5; + + protected GUIStyle m_style; + protected GUIContent m_content; + protected Rect m_maximizedArea; + protected Rect m_transformedArea; + protected Rect m_resizeArea; + protected MenuAnchor m_anchor; + protected MenuAutoSize m_autoSize; + protected bool m_isActive = true; + protected bool m_isMaximized = true; + + protected bool m_lockOnMinimize = false; + protected bool m_preLockState = false; + + protected Rect m_minimizedArea; + protected Rect m_minimizeButtonPos; + protected float m_realWidth; + protected GUIStyle m_empty = new GUIStyle(); + + protected float m_resizeDelta; + + protected bool m_isResizing = false; + protected bool m_resizable = false; + protected GUIStyle m_resizeAreaStyle; + protected bool m_isMouseInside = false; + protected Vector2 m_currentScrollPos; + public MenuParent( AmplifyShaderEditorWindow parentWindow, float x, float y, float width, float height, string name, MenuAnchor anchor = MenuAnchor.NONE, MenuAutoSize autoSize = MenuAutoSize.NONE ) + { + m_parentWindow = parentWindow; + m_anchor = anchor; + m_autoSize = autoSize; + m_maximizedArea = new Rect( x, y, width, height ); + m_content = new GUIContent( GUIContent.none ); + m_content.text = name; + m_transformedArea = new Rect(); + m_resizeArea = new Rect(); + m_resizeArea.width = ResizeAreaWidth; + m_resizeAreaStyle = GUIStyle.none; + m_currentScrollPos = Vector2.zero; + } + + public void SetMinimizedArea( float x, float y, float width, float height ) + { + m_minimizedArea = new Rect( x, y, width, height ); + } + + protected void InitDraw( Rect parentPosition, Vector2 mousePosition, int mouseButtonId ) + { + if ( m_style == null ) + { + m_style = new GUIStyle( UIUtils.TextArea ); + m_style.stretchHeight = true; + m_style.stretchWidth = true; + m_style.fontSize = ( int ) Constants.DefaultTitleFontSize; + m_style.fontStyle = FontStyle.Normal; + Texture minimizeTex = UIUtils.GetCustomStyle( CustomStyle.MaximizeButton ).normal.background; + m_minimizeButtonPos = new Rect( 0, 0, minimizeTex.width, minimizeTex.height ); + } + + Rect currentArea = m_isMaximized ? m_maximizedArea : m_minimizedArea; + + if ( m_isMaximized ) + { + if ( m_resizable ) + { + if ( m_isResizing ) + { + if ( m_anchor == MenuAnchor.TOP_LEFT ) + m_resizeDelta = ( ParentWindow.CurrentEvent.mousePosition.x - m_maximizedArea.width ); + else if ( m_anchor == MenuAnchor.TOP_RIGHT ) + m_resizeDelta = ParentWindow.CurrentEvent.mousePosition.x - ( parentPosition.width - m_maximizedArea.width); + } + } + + m_realWidth = m_maximizedArea.width; + if ( m_resizable ) + { + if ( m_anchor == MenuAnchor.TOP_LEFT ) + { + currentArea.width += m_resizeDelta; + m_realWidth += m_resizeDelta; + } + else if ( m_anchor == MenuAnchor.TOP_RIGHT ) + { + currentArea.width -= m_resizeDelta; + m_realWidth -= m_resizeDelta; + } + } + } + else + { + if ( currentArea.x < 0 ) + { + m_realWidth = currentArea.width + currentArea.x; + } + else if ( ( currentArea.x + currentArea.width ) > parentPosition.width ) + { + m_realWidth = parentPosition.width - currentArea.x; + } + if ( m_realWidth < 0 ) + m_realWidth = 0; + } + + switch ( m_anchor ) + { + case MenuAnchor.TOP_LEFT: + { + m_transformedArea.x = currentArea.x; + m_transformedArea.y = currentArea.y; + if ( m_isMaximized ) + { + m_minimizeButtonPos.x = m_transformedArea.x + m_transformedArea.width - m_minimizeButtonPos.width - MinimizeButtonXSpacing; + m_minimizeButtonPos.y = m_transformedArea.y + MinimizeButtonYSpacing; + + m_resizeArea.x = m_transformedArea.x + m_transformedArea.width; + m_resizeArea.y = m_minimizeButtonPos.y; + m_resizeArea.height = m_transformedArea.height; + } + else + { + float width = ( m_transformedArea.width - m_transformedArea.x ); + m_minimizeButtonPos.x = m_transformedArea.x + width * 0.5f - m_minimizeButtonPos.width * 0.5f; + m_minimizeButtonPos.y = m_transformedArea.height * 0.5f - m_minimizeButtonPos.height * 0.5f; + } + } + break; + case MenuAnchor.TOP_CENTER: + { + m_transformedArea.x = parentPosition.width * 0.5f + currentArea.x; + m_transformedArea.y = currentArea.y; + } + break; + case MenuAnchor.TOP_RIGHT: + { + m_transformedArea.x = parentPosition.width - currentArea.x - currentArea.width; + m_transformedArea.y = currentArea.y; + if ( m_isMaximized ) + { + m_minimizeButtonPos.x = m_transformedArea.x + MinimizeButtonXSpacing; + m_minimizeButtonPos.y = m_transformedArea.y + MinimizeButtonYSpacing; + + m_resizeArea.x = m_transformedArea.x - ResizeAreaWidth; + m_resizeArea.y = m_minimizeButtonPos.y; + m_resizeArea.height = m_transformedArea.height; + } + else + { + float width = ( parentPosition.width - m_transformedArea.x ); + m_minimizeButtonPos.x = m_transformedArea.x + width * 0.5f - m_minimizeButtonPos.width * 0.5f; + m_minimizeButtonPos.y = m_transformedArea.height * 0.5f - m_minimizeButtonPos.height * 0.5f; + } + } + break; + case MenuAnchor.MIDDLE_LEFT: + { + m_transformedArea.x = currentArea.x; + m_transformedArea.y = parentPosition.height * 0.5f + currentArea.y; + } + break; + case MenuAnchor.MIDDLE_CENTER: + { + m_transformedArea.x = parentPosition.width * 0.5f + currentArea.x; + m_transformedArea.y = parentPosition.height * 0.5f + currentArea.y; + } + break; + case MenuAnchor.MIDDLE_RIGHT: + { + m_transformedArea.x = parentPosition.width - currentArea.x - currentArea.width; + m_transformedArea.y = parentPosition.height * 0.5f + currentArea.y; + } + break; + case MenuAnchor.BOTTOM_LEFT: + { + m_transformedArea.x = currentArea.x; + m_transformedArea.y = parentPosition.height - currentArea.y - currentArea.height; + } + break; + case MenuAnchor.BOTTOM_CENTER: + { + m_transformedArea.x = parentPosition.width * 0.5f + currentArea.x; + m_transformedArea.y = parentPosition.height - currentArea.y - currentArea.height; + } + break; + case MenuAnchor.BOTTOM_RIGHT: + { + m_transformedArea.x = parentPosition.width - currentArea.x - currentArea.width; + m_transformedArea.y = parentPosition.height - currentArea.y - currentArea.height; + } + break; + + case MenuAnchor.NONE: + { + m_transformedArea.x = currentArea.x; + m_transformedArea.y = currentArea.y; + } + break; + } + + switch ( m_autoSize ) + { + case MenuAutoSize.MATCH_HORIZONTAL: + { + m_transformedArea.width = parentPosition.width - m_transformedArea.x; + m_transformedArea.height = currentArea.height; + } + break; + + case MenuAutoSize.MATCH_VERTICAL: + { + m_transformedArea.width = currentArea.width; + m_transformedArea.height = parentPosition.height - m_transformedArea.y; + } + break; + case MenuAutoSize.NONE: + { + m_transformedArea.width = currentArea.width; + m_transformedArea.height = currentArea.height; + } + break; + } + + } + public virtual void Draw( Rect parentPosition, Vector2 mousePosition, int mouseButtonId, bool hasKeyboadFocus ) + { + InitDraw( parentPosition, mousePosition, mouseButtonId ); + if ( ParentWindow.CurrentEvent.type == EventType.MouseDrag && ParentWindow.CurrentEvent.button > 0 /*catches both middle and right mouse button*/ ) + { + m_isMouseInside = IsInside( mousePosition ); + if ( m_isMouseInside ) + { + m_currentScrollPos.x += Constants.MenuDragSpeed * ParentWindow.CurrentEvent.delta.x; + if ( m_currentScrollPos.x < 0 ) + m_currentScrollPos.x = 0; + m_currentScrollPos.y += Constants.MenuDragSpeed * ParentWindow.CurrentEvent.delta.y; + if ( m_currentScrollPos.y < 0 ) + m_currentScrollPos.y = 0; + + } + } + } + + public void PostDraw() + { + if ( !m_isMaximized ) + { + m_transformedArea.height = 35; + GUI.Label( m_transformedArea, m_content, m_style ); + } + + Color colorBuffer = GUI.color; + GUI.color = EditorGUIUtility.isProSkin ? Color.white : Color.black; + bool guiEnabledBuffer = GUI.enabled; + GUI.enabled = !m_lockOnMinimize; + Rect buttonArea = m_minimizeButtonPos; + + buttonArea.x -= MinimizeCollisionAdjust; + buttonArea.width += 2 * MinimizeCollisionAdjust; + + buttonArea.y -= MinimizeCollisionAdjust; + buttonArea.height += 2 * MinimizeCollisionAdjust; + + if ( m_parentWindow.CameraDrawInfo.CurrentEventType == EventType.Repaint ) + GUI.Label( m_minimizeButtonPos, string.Empty, UIUtils.GetCustomStyle( m_isMaximized ? CustomStyle.MinimizeButton : CustomStyle.MaximizeButton ) ); + + if( m_parentWindow.CameraDrawInfo.CurrentEventType == EventType.MouseDown && buttonArea.Contains( m_parentWindow.CameraDrawInfo.MousePosition ) ) + //if ( GUI.Button( buttonArea, string.Empty, m_empty ) ) + { + m_isMaximized = !m_isMaximized; + m_resizeDelta = 0; + } + + if ( m_resizable && m_isMaximized ) + { + EditorGUIUtility.AddCursorRect( m_resizeArea, MouseCursor.ResizeHorizontal ); + if ( !m_isResizing && GUI.RepeatButton( m_resizeArea, string.Empty, m_resizeAreaStyle ) ) + { + m_isResizing = true; + } + else + { + if ( m_isResizing ) + { + if ( ParentWindow.CurrentEvent.isMouse && ParentWindow.CurrentEvent.type != EventType.MouseDrag ) + { + m_isResizing = false; + } + } + } + + if ( m_realWidth < buttonArea.width ) + { + // Auto-minimize + m_isMaximized = false; + m_resizeDelta = 0; + m_isResizing = false; + } + else + { + float halfSizeWindow = 0.5f * ParentWindow.position.width; + if ( m_realWidth > halfSizeWindow ) + { + m_realWidth = 0.5f * ParentWindow.position.width; + if ( m_resizeDelta > 0 ) + { + m_resizeDelta = m_realWidth - m_maximizedArea.width; + } + else + { + m_resizeDelta = m_maximizedArea.width - m_realWidth; + } + } + } + } + + GUI.enabled = guiEnabledBuffer; + GUI.color = colorBuffer; + + } + + public void OnLostFocus() + { + if ( m_isResizing ) + { + m_isResizing = false; + } + } + + virtual public void Destroy() + { + m_empty = null; + m_resizeAreaStyle = null; + } + + public float InitialX + { + get { return m_maximizedArea.x; } + set { m_maximizedArea.x = value; } + } + + public float Width + { + get { return m_maximizedArea.width; } + set { m_maximizedArea.width = value; } + } + + public float RealWidth + { + get { return m_realWidth; } + } + public float Height + { + get { return m_maximizedArea.height; } + set { m_maximizedArea.height = value; } + } + + public Rect Size + { + get { return m_maximizedArea; } + } + + public virtual bool IsInside( Vector2 position ) + { + if ( !m_isActive ) + return false; + + return m_transformedArea.Contains( position ); + } + + public bool IsMaximized + { + get { return m_isMaximized; } + set { m_isMaximized = value; } + } + + public Rect TransformedArea + { + get { return m_transformedArea; } + } + + public bool Resizable { set { m_resizable = value; } } + public bool IsResizing { get { return m_isResizing; } } + public bool LockOnMinimize + { + set + { + if ( m_lockOnMinimize == value ) + return; + + m_lockOnMinimize = value; + if ( value ) + { + m_preLockState = m_isMaximized; + m_isMaximized = false; + } + else + { + m_isMaximized = m_preLockState; + } + } + } + public bool IsActive + { + get { return m_isActive; } + } + public AmplifyShaderEditorWindow ParentWindow { get { return m_parentWindow; } set { m_parentWindow = value; } } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/MenuParent.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/MenuParent.cs.meta new file mode 100644 index 00000000..2c0ba167 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/MenuParent.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 5d535d3799a3ef547aea607fdc8b947b +timeCreated: 1481126956 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/NodeParametersWindow.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/NodeParametersWindow.cs new file mode 100644 index 00000000..837b2f48 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/NodeParametersWindow.cs @@ -0,0 +1,555 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using UnityEngine; +using UnityEditor; +using System.Collections.Generic; +using UnityEditorInternal; + +namespace AmplifyShaderEditor +{ + public sealed class NodeParametersWindow : MenuParent + { + private int m_lastSelectedNode = -1; + private const string TitleStr = "Node Properties"; + private GUIStyle m_nodePropertiesStyle; + private GUIContent m_dummyContent = new GUIContent(); + private GUIStyle m_propertyAdjustment; + + private ReorderableList m_functionInputsReordableList = null; + private int m_functionInputsLastCount = 0; + + private ReorderableList m_functionSwitchesReordableList = null; + private int m_functionSwitchesLastCount = 0; + + private ReorderableList m_functionOutputsReordableList = null; + private int m_functionOutputsLastCount = 0; + + private ReorderableList m_propertyReordableList = null; + private int m_lastCount = 0; + + private bool m_forceUpdate = false; + + [SerializeField] + private List<PropertyNode> m_propertyReordableNodes = new List<PropertyNode>(); + + // width and height are between [0,1] and represent a percentage of the total screen area + public NodeParametersWindow( AmplifyShaderEditorWindow parentWindow ) : base( parentWindow, 0, 0, 285, 0, string.Empty, MenuAnchor.TOP_LEFT, MenuAutoSize.MATCH_VERTICAL ) + { + SetMinimizedArea( -225, 0, 260, 0 ); + } + + public void OnShaderFunctionLoad() + { + m_functionInputsReordableList = null; + m_functionSwitchesReordableList = null; + m_functionOutputsReordableList = null; + } + + public bool Draw( Rect parentPosition, ParentNode selectedNode, Vector2 mousePosition, int mouseButtonId, bool hasKeyboardFocus ) + { + bool changeCheck = false; + base.Draw( parentPosition, mousePosition, mouseButtonId, hasKeyboardFocus ); + if ( m_nodePropertiesStyle == null ) + { + m_nodePropertiesStyle = UIUtils.GetCustomStyle( CustomStyle.NodePropertiesTitle ); + m_nodePropertiesStyle.normal.textColor = m_nodePropertiesStyle.active.textColor = EditorGUIUtility.isProSkin ? new Color( 1f, 1f, 1f ) : new Color( 0f, 0f, 0f ); + } + + if ( m_isMaximized ) + { + KeyCode key = Event.current.keyCode; + if ( m_isMouseInside || hasKeyboardFocus ) + { + if ( key == ShortcutsManager.ScrollUpKey ) + { + m_currentScrollPos.y -= 10; + if ( m_currentScrollPos.y < 0 ) + { + m_currentScrollPos.y = 0; + } + Event.current.Use(); + } + + if ( key == ShortcutsManager.ScrollDownKey ) + { + m_currentScrollPos.y += 10; + Event.current.Use(); + } + } + + if( m_forceUpdate ) + { + if( m_propertyReordableList != null ) + m_propertyReordableList.ReleaseKeyboardFocus(); + m_propertyReordableList = null; + + if ( m_functionInputsReordableList != null ) + m_functionInputsReordableList.ReleaseKeyboardFocus(); + m_functionInputsReordableList = null; + + if( m_functionSwitchesReordableList != null ) + m_functionSwitchesReordableList.ReleaseKeyboardFocus(); + m_functionSwitchesReordableList = null; + + if ( m_functionOutputsReordableList != null ) + m_functionOutputsReordableList.ReleaseKeyboardFocus(); + m_functionOutputsReordableList = null; + m_forceUpdate = false; + } + + GUILayout.BeginArea( m_transformedArea, m_content, m_style ); + { + //Draw selected node parameters + if ( selectedNode != null ) + { + // this hack is need because without it the several FloatFields/Textfields/... would show wrong values ( different from the ones they were assigned to show ) + if ( m_lastSelectedNode != selectedNode.UniqueId ) + { + m_lastSelectedNode = selectedNode.UniqueId; + GUI.FocusControl( "" ); + } + + EditorGUILayout.BeginVertical(); + { + EditorGUILayout.Separator(); + if ( selectedNode.UniqueId == ParentWindow.CurrentGraph.CurrentMasterNodeId ) + { + m_dummyContent.text = "Output Node"; + } + else + { + if ( selectedNode.Attributes != null ) + { + + m_dummyContent.text = selectedNode.Attributes.Name; + } + else if ( selectedNode is CommentaryNode ) + { + m_dummyContent.text = "Commentary"; + } + else + { + m_dummyContent.text = TitleStr; + } + } + + EditorGUILayout.LabelField( m_dummyContent, m_nodePropertiesStyle ); + + EditorGUILayout.Separator(); + //UIUtils.RecordObject( selectedNode , "Changing properties on node " + selectedNode.UniqueId); + m_currentScrollPos = EditorGUILayout.BeginScrollView( m_currentScrollPos, GUILayout.Width( 0 ), GUILayout.Height( 0 ) ); + float labelWidth = EditorGUIUtility.labelWidth; + if ( selectedNode.TextLabelWidth > 0 ) + EditorGUIUtility.labelWidth = selectedNode.TextLabelWidth; + + changeCheck = selectedNode.SafeDrawProperties(); + EditorGUIUtility.labelWidth = labelWidth; + EditorGUILayout.EndScrollView(); + } + EditorGUILayout.EndVertical(); + + if ( changeCheck ) + { + if ( selectedNode.ConnStatus == NodeConnectionStatus.Connected ) + ParentWindow.SetSaveIsDirty(); + } + } + else + { + //Draw Graph Params + EditorGUILayout.BeginVertical(); + { + EditorGUILayout.Separator(); + EditorGUILayout.LabelField( "Graph Properties", m_nodePropertiesStyle ); + EditorGUILayout.Separator(); + + m_currentScrollPos = EditorGUILayout.BeginScrollView( m_currentScrollPos, GUILayout.Width( 0 ), GUILayout.Height( 0 ) ); + float labelWidth = EditorGUIUtility.labelWidth; + EditorGUIUtility.labelWidth = 90; + + bool generalIsVisible = m_parentWindow.InnerWindowVariables.ExpandedGeneralShaderOptions; + NodeUtils.DrawPropertyGroup( ref generalIsVisible, " General", DrawGeneralFunction ); + m_parentWindow.InnerWindowVariables.ExpandedGeneralShaderOptions = generalIsVisible; + AmplifyShaderFunction function = ParentWindow.CurrentGraph.CurrentShaderFunction; + if( function != null ) + { + //function.AdditionalIncludes.Draw( ParentWindow.CurrentGraph.CurrentOutputNode ); + //function.AdditionalPragmas.Draw( ParentWindow.CurrentGraph.CurrentOutputNode ); + function.AdditionalDirectives.Draw( ParentWindow.CurrentGraph.CurrentOutputNode ); + } + + bool inputIsVisible = m_parentWindow.InnerWindowVariables.ExpandedFunctionInputs; + NodeUtils.DrawPropertyGroup( ref inputIsVisible, " Function Inputs", DrawFunctionInputs ); + m_parentWindow.InnerWindowVariables.ExpandedFunctionInputs = inputIsVisible; + + bool swicthIsVisible = m_parentWindow.InnerWindowVariables.ExpandedFunctionSwitches; + NodeUtils.DrawPropertyGroup( ref swicthIsVisible, " Function Switches", DrawFunctionSwitches ); + m_parentWindow.InnerWindowVariables.ExpandedFunctionSwitches = swicthIsVisible; + + bool outputIsVisible = m_parentWindow.InnerWindowVariables.ExpandedFunctionOutputs; + NodeUtils.DrawPropertyGroup( ref outputIsVisible, " Function Outputs", DrawFunctionOutputs ); + m_parentWindow.InnerWindowVariables.ExpandedFunctionOutputs = outputIsVisible; + + bool properties = ParentWindow.InnerWindowVariables.ExpandedProperties; + NodeUtils.DrawPropertyGroup( ref properties, " Material Properties", DrawFunctionProperties ); + ParentWindow.InnerWindowVariables.ExpandedProperties = properties; + + EditorGUIUtility.labelWidth = labelWidth; + EditorGUILayout.EndScrollView(); + } + EditorGUILayout.EndVertical(); + } + } + // Close window area + GUILayout.EndArea(); + } + + PostDraw(); + return changeCheck; + } + + public void DrawGeneralFunction() + { + AmplifyShaderFunction function = ParentWindow.CurrentGraph.CurrentShaderFunction; + if ( function == null ) + return; + + float cacheWidth = EditorGUIUtility.labelWidth; + EditorGUIUtility.labelWidth = 115; + + SerializedObject serializedObject = new UnityEditor.SerializedObject( function ); + + if ( serializedObject != null ) + { + SerializedProperty temo = serializedObject.FindProperty( "m_description" ); + EditorGUILayout.PropertyField( temo, new GUIContent( " Description" ) ); + + SerializedProperty cat = serializedObject.FindProperty( "m_nodeCategory" ); + SerializedProperty ppos = serializedObject.FindProperty( "m_previewPosition" ); + + EditorGUILayout.PropertyField( ppos, new GUIContent( "Preview Position" ) ); + cat.intValue = ParentWindow.CurrentGraph.CurrentOutputNode.EditorGUILayoutPopup( "Category", cat.intValue, UIUtils.CategoryPresets ); + + if( cat.enumValueIndex == 0 ) + { + SerializedProperty custCat = serializedObject.FindProperty( "m_customNodeCategory" ); + EditorGUILayout.PropertyField( custCat, new GUIContent( "Custom" ) ); + } + SerializedProperty hidden = serializedObject.FindProperty( "m_hidden" ); + EditorGUILayout.PropertyField( hidden, new GUIContent( "Hidden" ) ); + serializedObject.ApplyModifiedProperties(); + } + EditorGUIUtility.labelWidth = cacheWidth; + } + + + public void DrawFunctionInputs() + { + List<FunctionInput> functionInputNodes = UIUtils.FunctionInputList(); + + if ( m_functionInputsReordableList == null || functionInputNodes.Count != m_functionInputsLastCount ) + { + functionInputNodes.Sort( ( x, y ) => { return x.OrderIndex.CompareTo( y.OrderIndex ); } ); + + m_functionInputsReordableList = new ReorderableList( functionInputNodes, typeof( FunctionInput ), true, false, false, false ); + m_functionInputsReordableList.headerHeight = 0; + m_functionInputsReordableList.footerHeight = 0; + m_functionInputsReordableList.showDefaultBackground = false; + + m_functionInputsReordableList.drawElementCallback = ( Rect rect, int index, bool isActive, bool isFocused ) => + { + EditorGUI.LabelField( rect, functionInputNodes[ index ].InputName ); + }; + + m_functionInputsReordableList.onChangedCallback = ( list ) => + { + //for ( int i = 0; i < functionInputNodes.Count; i++ ) + //{ + // functionInputNodes[ i ].OrderIndex = i; + //} + ForceInputReorder( ref functionInputNodes ); + }; + + m_functionInputsLastCount = m_functionInputsReordableList.count; + } + + if ( m_functionInputsReordableList != null ) + { + if ( m_propertyAdjustment == null ) + { + m_propertyAdjustment = new GUIStyle(); + m_propertyAdjustment.padding.left = 17; + } + EditorGUILayout.BeginVertical( m_propertyAdjustment ); + m_functionInputsReordableList.DoLayoutList(); + EditorGUILayout.EndVertical(); + } + } + + public void ForceInputReorder( ref List<FunctionInput> functionInputNodes ) + { + for( int i = 0; i < functionInputNodes.Count; i++ ) + { + functionInputNodes[ i ].OrderIndex = i; + } + } + + public void DrawFunctionSwitches() + { + List<FunctionSwitch> functionSwitchNodes = UIUtils.FunctionSwitchList(); + + if( m_functionSwitchesReordableList == null || functionSwitchNodes.Count != m_functionSwitchesLastCount ) + { + functionSwitchNodes.Sort( ( x, y ) => { return x.OrderIndex.CompareTo( y.OrderIndex ); } ); + + UIUtils.UpdateFunctionSwitchArr(); + + m_functionSwitchesReordableList = new ReorderableList( functionSwitchNodes, typeof( FunctionSwitch ), true, false, false, false ); + m_functionSwitchesReordableList.headerHeight = 0; + m_functionSwitchesReordableList.footerHeight = 0; + m_functionSwitchesReordableList.showDefaultBackground = false; + + m_functionSwitchesReordableList.drawElementCallback = ( Rect rect, int index, bool isActive, bool isFocused ) => + { + EditorGUI.LabelField( rect, functionSwitchNodes[ index ].OptionLabel ); + }; + + m_functionSwitchesReordableList.onChangedCallback = ( list ) => + { + ForceSwitchesReorder(ref functionSwitchNodes ); + }; + + m_functionSwitchesLastCount = m_functionSwitchesReordableList.count; + } + + if( m_functionSwitchesReordableList != null ) + { + if( m_propertyAdjustment == null ) + { + m_propertyAdjustment = new GUIStyle(); + m_propertyAdjustment.padding.left = 17; + } + EditorGUILayout.BeginVertical( m_propertyAdjustment ); + m_functionSwitchesReordableList.DoLayoutList(); + EditorGUILayout.EndVertical(); + } + } + + public void ForceSwitchesReorder( ref List<FunctionSwitch> functionSwitchNodes ) + { + for( int i = 0; i < functionSwitchNodes.Count; i++ ) + { + functionSwitchNodes[ i ].OrderIndex = i; + } + + UIUtils.UpdateFunctionSwitchArr(); + } + + public void DrawFunctionOutputs() + { + List<FunctionOutput> functionOutputNodes = UIUtils.FunctionOutputList(); + + if ( m_functionOutputsReordableList == null || functionOutputNodes.Count != m_functionOutputsLastCount ) + { + functionOutputNodes.Sort( ( x, y ) => { return x.OrderIndex.CompareTo( y.OrderIndex ); } ); + + m_functionOutputsReordableList = new ReorderableList( functionOutputNodes, typeof( FunctionOutput ), true, false, false, false ); + m_functionOutputsReordableList.headerHeight = 0; + m_functionOutputsReordableList.footerHeight = 0; + m_functionOutputsReordableList.showDefaultBackground = false; + + m_functionOutputsReordableList.drawElementCallback = ( Rect rect, int index, bool isActive, bool isFocused ) => + { + EditorGUI.LabelField( rect, functionOutputNodes[ index ].OutputName ); + }; + + m_functionOutputsReordableList.onChangedCallback = ( list ) => + { + for ( int i = 0; i < functionOutputNodes.Count; i++ ) + { + functionOutputNodes[ i ].OrderIndex = i; + } + }; + + m_functionOutputsLastCount = m_functionOutputsReordableList.count; + } + + if ( m_functionOutputsReordableList != null ) + { + if ( m_propertyAdjustment == null ) + { + m_propertyAdjustment = new GUIStyle(); + m_propertyAdjustment.padding.left = 17; + } + EditorGUILayout.BeginVertical( m_propertyAdjustment ); + m_functionOutputsReordableList.DoLayoutList(); + EditorGUILayout.EndVertical(); + } + } + + private void RefreshVisibleList( ref List<PropertyNode> allNodes ) + { + // temp reference for lambda expression + List<PropertyNode> nodes = allNodes; + m_propertyReordableNodes.Clear(); + + for( int i = 0; i < nodes.Count; i++ ) + { + ReordenatorNode rnode = nodes[ i ] as ReordenatorNode; + if( ( rnode == null || !rnode.IsInside ) && ( !m_propertyReordableNodes.Exists( x => x.PropertyName.Equals( nodes[ i ].PropertyName ) ) ) ) + m_propertyReordableNodes.Add( nodes[ i ] ); + } + + m_propertyReordableNodes.Sort( ( x, y ) => { return x.OrderIndex.CompareTo( y.OrderIndex ); } ); + } + + public void DrawFunctionProperties() + { + List<PropertyNode> nodes = UIUtils.PropertyNodesList(); + + if( nodes.Count != m_lastCount ) + { + RefreshVisibleList( ref nodes ); + m_lastCount = nodes.Count; + } + + if( m_propertyReordableList == null ) + { + m_propertyReordableList = new ReorderableList( m_propertyReordableNodes, typeof( PropertyNode ), true, false, false, false ) + { + headerHeight = 0, + footerHeight = 0, + showDefaultBackground = false, + + drawElementCallback = ( Rect rect, int index, bool isActive, bool isFocused ) => + { + var first = rect; + first.width *= 0.60f; + EditorGUI.LabelField( first, m_propertyReordableNodes[ index ].PropertyInspectorName ); + var second = rect; + second.width *= 0.4f; + second.x += first.width; + if( GUI.Button( second, m_propertyReordableNodes[ index ].PropertyName, new GUIStyle( "AssetLabel Partial" ) ) ) + { + UIUtils.FocusOnNode( m_propertyReordableNodes[ index ], 1, false ); + } + }, + + onReorderCallback = ( list ) => + { + ReorderList( ref nodes ); + } + }; + ReorderList( ref nodes ); + } + + if( m_propertyReordableList != null ) + { + if( m_propertyAdjustment == null ) + { + m_propertyAdjustment = new GUIStyle(); + m_propertyAdjustment.padding.left = 17; + } + EditorGUILayout.BeginVertical( m_propertyAdjustment ); + m_propertyReordableList.DoLayoutList(); + EditorGUILayout.EndVertical(); + } + } + + public void ForceReordering() + { + List<PropertyNode> nodes = UIUtils.PropertyNodesList(); + ReorderList( ref nodes ); + + List<FunctionInput> functionInputNodes = UIUtils.FunctionInputList(); + ForceInputReorder( ref functionInputNodes ); + + List<FunctionSwitch> functionSwitchNodes = UIUtils.FunctionSwitchList(); + ForceSwitchesReorder( ref functionSwitchNodes ); + //RecursiveLog(); + } + + private void RecursiveLog() + { + List<PropertyNode> nodes = UIUtils.PropertyNodesList(); + nodes.Sort( ( x, y ) => { return x.OrderIndex.CompareTo( y.OrderIndex ); } ); + for( int i = 0; i < nodes.Count; i++ ) + { + if( ( nodes[ i ] is ReordenatorNode ) ) + ( nodes[ i ] as ReordenatorNode ).RecursiveLog(); + else + Debug.Log( nodes[ i ].OrderIndex + " " + nodes[ i ].PropertyName ); + } + } + + + private void ReorderList( ref List<PropertyNode> nodes ) + { + // clear lock list before reordering because of multiple sf being used + for( int i = 0; i < nodes.Count; i++ ) + { + ReordenatorNode rnode = nodes[ i ] as ReordenatorNode; + if ( rnode != null ) + rnode.RecursiveClear(); + } + + int propoffset = 0; + int count = 0; + for ( int i = 0; i < m_propertyReordableNodes.Count; i++ ) + { + ReordenatorNode renode = m_propertyReordableNodes[ i ] as ReordenatorNode; + if ( renode != null ) + { + if ( !renode.IsInside ) + { + m_propertyReordableNodes[ i ].OrderIndex = count + propoffset; + + if ( renode.PropertyListCount > 0 ) + { + propoffset += renode.RecursiveCount(); + + // the same reordenator can exist multiple times, apply ordering to all of them + for( int j = 0; j < nodes.Count; j++ ) + { + ReordenatorNode pnode = ( nodes[ j ] as ReordenatorNode ); + if ( pnode != null && pnode.PropertyName.Equals( renode.PropertyName ) ) + { + pnode.OrderIndex = renode.RawOrderIndex; + pnode.RecursiveSetOrderOffset( renode.RawOrderIndex, true ); + } + } + } + else + { + count++; + } + } + else + { + m_propertyReordableNodes[ i ].OrderIndex = 0; + } + } + else + { + m_propertyReordableNodes[ i ].OrderIndex = count + propoffset; + count++; + } + } + } + + public override void Destroy() + { + base.Destroy(); + m_functionInputsReordableList = null; + m_functionOutputsReordableList = null; + m_propertyReordableList = null; + } + + public bool ForceUpdate + { + get { return m_forceUpdate; } + set { m_forceUpdate = value; } + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/NodeParametersWindow.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/NodeParametersWindow.cs.meta new file mode 100644 index 00000000..c49545cb --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/NodeParametersWindow.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: d09f21096aa7c9f438e91a6e7f2621fb +timeCreated: 1481126959 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/NodeWireReferencesUtils.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/NodeWireReferencesUtils.cs new file mode 100644 index 00000000..f1793a24 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/NodeWireReferencesUtils.cs @@ -0,0 +1,56 @@ +using UnityEngine; + +namespace AmplifyShaderEditor +{ + public class NodeWireReferencesUtils + { + public WireReference InputPortReference = new WireReference(); + public WireReference SwitchPortReference = new WireReference(); + public WireReference OutputPortReference = new WireReference(); + + public Vector2 SnapPosition = Vector2.zero; + public bool SnapEnabled = false; + public WireReference SnapPort = new WireReference(); + + public bool ValidReferences() + { + return ( InputPortReference.IsValid || OutputPortReference.IsValid ); + } + + public void InvalidateReferences() + { + InputPortReference.Invalidate(); + OutputPortReference.Invalidate(); + SnapPort.Invalidate(); + SnapEnabled = false; + } + + + public void SetOutputReference( int nodeId, int portId, WirePortDataType dataType, bool typeLocked ) + { + if( InputPortReference.IsValid ) + InputPortReference.Invalidate(); + OutputPortReference.SetReference( nodeId, portId, dataType, typeLocked ); + } + + public void SetInputReference( int nodeId, int portId, WirePortDataType dataType, bool typeLocked ) + { + if( OutputPortReference.IsValid ) + OutputPortReference.Invalidate(); + InputPortReference.SetReference( nodeId, portId, dataType, typeLocked ); + } + + public void ActivateSnap( Vector2 position, WirePort port ) + { + SnapPort.SetReference( port ); + SnapEnabled = true; + SnapPosition = position; + } + + public void DeactivateSnap() + { + SnapEnabled = false; + SnapPort.Invalidate(); + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/NodeWireReferencesUtils.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/NodeWireReferencesUtils.cs.meta new file mode 100644 index 00000000..6cc9bbec --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/NodeWireReferencesUtils.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: bfbc736093c900c418a7668e3003663a +timeCreated: 1500289690 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Palette.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Palette.meta new file mode 100644 index 00000000..71c42517 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Palette.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: a89b03eb735b82a4da19a8381846935f +folderAsset: yes +timeCreated: 1481126946 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Palette/ContextPalette.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Palette/ContextPalette.cs new file mode 100644 index 00000000..ae870612 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Palette/ContextPalette.cs @@ -0,0 +1,101 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using UnityEngine; +using System.Collections.Generic; +using System; + +namespace AmplifyShaderEditor +{ + public sealed class ContextPalette : PaletteParent + { + private Vector3 m_position; + private Vector2 m_startDropPosition; + public ContextPalette( AmplifyShaderEditorWindow parentWindow ) : base( parentWindow, 0, 0, 250, 250, string.Empty, MenuAnchor.NONE, MenuAutoSize.NONE ) + { + m_isActive = false; + OnPaletteNodeCreateEvt += OnOptionSelected; + m_searchFilterControl += "CONTEXTPALETTE"; + } + + public override void OnEnterPressed(int index = 0) + { + if ( m_searchFilter.Length > 0 && m_currentItems.Count > 0 ) + { + FireNodeCreateEvent( m_currentItems[ index ].NodeType, m_currentItems[ index ].Name, m_currentItems[ index ].Function ); + } + else + { + Disable(); + } + } + + public override void OnEscapePressed() + { + Disable(); + if ( m_parentWindow.WireReferenceUtils.ValidReferences() ) + { + m_parentWindow.WireReferenceUtils.InvalidateReferences(); + } + } + + public override void Draw( Rect parentPosition, Vector2 mousePosition, int mouseButtonId, bool hasKeyboadFocus ) + { + //if ( !_isActive ) + // return; + + if ( Event.current.type == EventType.MouseDown && !IsInside( Event.current.mousePosition ) ) + { + Disable(); + return; + } + base.Draw( parentPosition, mousePosition, mouseButtonId, hasKeyboadFocus ); + } + + + public void Show( Vector2 position, Rect cameraInfo ) + { + m_startDropPosition = position; + m_maximizedArea.x = ( position.x + m_maximizedArea.width ) > cameraInfo.width ? ( cameraInfo.width - 1.1f * m_maximizedArea.width ) : position.x; + m_maximizedArea.y = ( position.y + m_maximizedArea.height ) > cameraInfo.height ? ( cameraInfo.height - 1.1f * m_maximizedArea.height ) : position.y; + m_position = new Vector3( m_maximizedArea.x, m_maximizedArea.y, 0f ); + m_isActive = true; + m_focusOnSearch = true; + } + + + // This override is removing focus from our window ... need to figure out a workaround before re-using it + //public override bool CheckButton( GUIContent content, GUIStyle style, int buttonId ) + //{ + // if ( buttonId != m_validButtonId ) + // return false; + + // return GUILayout.Button( content, style ); + //} + + void OnOptionSelected( System.Type type, string name, AmplifyShaderFunction function ) + { + Disable(); + } + + public void Disable() + { + m_isActive = false; + } + + public Vector2 StartDropPosition + { + get { return m_startDropPosition; } + } + + public Vector3 CurrentPosition + { + get { return m_position; } + } + + public Vector2 CurrentPosition2D + { + get { return new Vector2( m_position.x, m_position.y ); } + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Palette/ContextPalette.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Palette/ContextPalette.cs.meta new file mode 100644 index 00000000..59f3f897 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Palette/ContextPalette.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 15597b146a1fc154abd63ac75cffb73f +timeCreated: 1481126953 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Palette/PaletteParent.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Palette/PaletteParent.cs new file mode 100644 index 00000000..67ce6e14 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Palette/PaletteParent.cs @@ -0,0 +1,573 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using UnityEngine; +using System.Collections.Generic; +using UnityEditor; +using System; +using System.Text.RegularExpressions; + +namespace AmplifyShaderEditor +{ + public class PaletteFilterData + { + public bool Visible; + public bool HasCommunityData; + public List<ContextMenuItem> Contents; + public PaletteFilterData( bool visible ) + { + Visible = visible; + Contents = new List<ContextMenuItem>(); + } + } + + public class PaletteParent : MenuParent + { + private const float ItemSize = 18; + public delegate void OnPaletteNodeCreate( System.Type type, string name, AmplifyShaderFunction function ); + public event OnPaletteNodeCreate OnPaletteNodeCreateEvt; + + private string m_searchFilterStr = "Search"; + protected string m_searchFilterControl = "SHADERNAMETEXTFIELDCONTROLNAME"; + protected bool m_focusOnSearch = false; + protected bool m_defaultCategoryVisible = false; + + //protected List<ContextMenuItem> m_allItems; + protected List<ContextMenuItem> m_currentItems; + protected Dictionary<string, PaletteFilterData> m_currentCategories; + private bool m_forceUpdate = true; + + + protected string m_searchFilter = string.Empty; + + private float m_searchLabelSize = -1; + private GUIStyle m_buttonStyle; + private GUIStyle m_foldoutStyle; + + protected bool m_previousWindowIsFunction = false; + + protected int m_validButtonId = 0; + protected int m_initialSeparatorAmount = 1; + + private Vector2 m_currScrollBarDims = new Vector2( 1, 1 ); + + public PaletteParent( AmplifyShaderEditorWindow parentWindow, float x, float y, float width, float height, string name, MenuAnchor anchor = MenuAnchor.NONE, MenuAutoSize autoSize = MenuAutoSize.NONE ) : base( parentWindow, x, y, width, height, name, anchor, autoSize ) + { + m_searchFilter = string.Empty; + m_currentCategories = new Dictionary<string, PaletteFilterData>(); + //m_allItems = items; + m_currentItems = new List<ContextMenuItem>(); + } + + public virtual void OnEnterPressed( int index = 0 ) { } + public virtual void OnEscapePressed() { } + + public void FireNodeCreateEvent( System.Type type, string name, AmplifyShaderFunction function ) + { + OnPaletteNodeCreateEvt( type, name, function ); + } + + public override void Draw( Rect parentPosition, Vector2 mousePosition, int mouseButtonId, bool hasKeyboadFocus ) + { + base.Draw( parentPosition, mousePosition, mouseButtonId, hasKeyboadFocus ); + if( m_previousWindowIsFunction != ParentWindow.IsShaderFunctionWindow ) + { + m_forceUpdate = true; + } + + m_previousWindowIsFunction = ParentWindow.IsShaderFunctionWindow; + + List<ContextMenuItem> allItems = ParentWindow.ContextMenuInstance.MenuItems; + + if( m_searchLabelSize < 0 ) + { + m_searchLabelSize = GUI.skin.label.CalcSize( new GUIContent( m_searchFilterStr ) ).x; + } + + if( m_foldoutStyle == null ) + { + m_foldoutStyle = new GUIStyle( GUI.skin.GetStyle( "foldout" ) ); + m_foldoutStyle.fontStyle = FontStyle.Bold; + } + + if( m_buttonStyle == null ) + { + m_buttonStyle = UIUtils.Label; + } + + Event currenEvent = Event.current; + + GUILayout.BeginArea( m_transformedArea, m_content, m_style ); + { + for( int i = 0; i < m_initialSeparatorAmount; i++ ) + { + EditorGUILayout.Separator(); + } + + if( currenEvent.type == EventType.KeyDown ) + { + KeyCode key = currenEvent.keyCode; + //if ( key == KeyCode.Return || key == KeyCode.KeypadEnter ) + // OnEnterPressed(); + + if( ( currenEvent.keyCode == KeyCode.KeypadEnter || currenEvent.keyCode == KeyCode.Return ) && currenEvent.type == EventType.KeyDown ) + { + int index = m_currentItems.FindIndex( x => GUI.GetNameOfFocusedControl().Equals( x.ItemUIContent.text + m_resizable ) ); + if( index > -1 ) + OnEnterPressed( index ); + else + OnEnterPressed(); + } + + if( key == KeyCode.Escape ) + OnEscapePressed(); + + if( m_isMouseInside || hasKeyboadFocus ) + { + if( key == ShortcutsManager.ScrollUpKey ) + { + m_currentScrollPos.y -= 10; + if( m_currentScrollPos.y < 0 ) + { + m_currentScrollPos.y = 0; + } + currenEvent.Use(); + } + + if( key == ShortcutsManager.ScrollDownKey ) + { + m_currentScrollPos.y += 10; + currenEvent.Use(); + } + } + + } + + float width = EditorGUIUtility.labelWidth; + EditorGUIUtility.labelWidth = m_searchLabelSize; + EditorGUI.BeginChangeCheck(); + { + GUI.SetNextControlName( m_searchFilterControl + m_resizable ); + m_searchFilter = EditorGUILayout.TextField( m_searchFilterStr, m_searchFilter ); + if( m_focusOnSearch ) + { + m_focusOnSearch = false; + EditorGUI.FocusTextInControl( m_searchFilterControl + m_resizable ); + } + } + if( EditorGUI.EndChangeCheck() ) + m_forceUpdate = true; + + EditorGUIUtility.labelWidth = width; + bool usingSearchFilter = ( m_searchFilter.Length == 0 ); + m_currScrollBarDims.x = m_transformedArea.width; + m_currScrollBarDims.y = m_transformedArea.height - 2 - 16 - 2 - 7 * m_initialSeparatorAmount - 2; + m_currentScrollPos = EditorGUILayout.BeginScrollView( m_currentScrollPos/*, GUILayout.Width( 242 ), GUILayout.Height( 250 - 2 - 16 - 2 - 7 - 2) */); + { + if( m_forceUpdate ) + { + m_forceUpdate = false; + + //m_currentItems.Clear(); + m_currentCategories.Clear(); + + if( usingSearchFilter ) + { + for( int i = 0; i < allItems.Count; i++ ) + { + //m_currentItems.Add( allItems[ i ] ); + if( !m_currentCategories.ContainsKey( allItems[ i ].Category ) ) + { + m_currentCategories.Add( allItems[ i ].Category, new PaletteFilterData( m_defaultCategoryVisible ) ); + //m_currentCategories[ allItems[ i ].Category ].HasCommunityData = allItems[ i ].NodeAttributes.FromCommunity || m_currentCategories[ allItems[ i ].Category ].HasCommunityData; + } + m_currentCategories[ allItems[ i ].Category ].Contents.Add( allItems[ i ] ); + } + } + else + { + for( int i = 0; i < allItems.Count; i++ ) + { + var searchList = m_searchFilter.Trim( ' ' ).ToLower().Split(' '); + + int matchesFound = 0; + for( int k = 0; k < searchList.Length; k++ ) + { + MatchCollection wordmatch = Regex.Matches( allItems[ i ].Tags, "\\b"+searchList[ k ] ); + if( wordmatch.Count > 0 ) + matchesFound++; + else + break; + } + + if( searchList.Length == matchesFound ) + { + //m_currentItems.Add( allItems[ i ] ); + if( !m_currentCategories.ContainsKey( allItems[ i ].Category ) ) + { + m_currentCategories.Add( allItems[ i ].Category, new PaletteFilterData( m_defaultCategoryVisible ) ); + //m_currentCategories[ allItems[ i ].Category ].HasCommunityData = allItems[ i ].NodeAttributes.FromCommunity || m_currentCategories[ allItems[ i ].Category ].HasCommunityData; + } + m_currentCategories[ allItems[ i ].Category ].Contents.Add( allItems[ i ] ); + } + } + } + var categoryEnumerator = m_currentCategories.GetEnumerator(); + while( categoryEnumerator.MoveNext() ) + { + categoryEnumerator.Current.Value.Contents.Sort( ( x, y ) => x.CompareTo( y, usingSearchFilter ) ); + } + + //sort current list respecting categories + m_currentItems.Clear(); + foreach( var item in m_currentCategories ) + { + for( int i = 0; i < item.Value.Contents.Count; i++ ) + { + m_currentItems.Add( item.Value.Contents[ i ] ); + } + } + } + + string watching = string.Empty; + + // unselect the main search field so it can focus list elements next + if( ( currenEvent.keyCode == KeyCode.DownArrow || currenEvent.keyCode == KeyCode.UpArrow ) && m_searchFilter.Length > 0 ) + { + if( GUI.GetNameOfFocusedControl().Equals( m_searchFilterControl + m_resizable ) ) + { + EditorGUI.FocusTextInControl( null ); + } + } + + if( currenEvent.keyCode == KeyCode.DownArrow && currenEvent.type == EventType.KeyDown ) + { + currenEvent.Use(); + + int nextIndex = m_currentItems.FindIndex( x => GUI.GetNameOfFocusedControl().Equals( x.ItemUIContent.text + m_resizable ) ) + 1; + if( nextIndex == m_currentItems.Count ) + nextIndex = 0; + + watching = m_currentItems[ nextIndex ].ItemUIContent.text + m_resizable; + GUI.FocusControl( watching ); + + } + + if( currenEvent.keyCode == KeyCode.UpArrow && currenEvent.type == EventType.KeyDown ) + { + currenEvent.Use(); + + int nextIndex = m_currentItems.FindIndex( x => GUI.GetNameOfFocusedControl().Equals( x.ItemUIContent.text + m_resizable ) ) - 1; + if( nextIndex < 0 ) + nextIndex = m_currentItems.Count - 1; + + watching = m_currentItems[ nextIndex ].ItemUIContent.text + m_resizable; + GUI.FocusControl( watching ); + } + + if( currenEvent.keyCode == KeyCode.Tab ) + { + ContextMenuItem item = m_currentItems.Find( x => GUI.GetNameOfFocusedControl().Equals( x.ItemUIContent.text + m_resizable ) ); + if( item != null ) + { + watching = item.ItemUIContent.text + m_resizable; + } + } + + float currPos = 0; + var enumerator = m_currentCategories.GetEnumerator(); + + float cache = EditorGUIUtility.labelWidth; + while( enumerator.MoveNext() ) + { + var current = enumerator.Current; + bool visible = GUILayout.Toggle( current.Value.Visible, current.Key, m_foldoutStyle ); + if( m_validButtonId == mouseButtonId ) + { + current.Value.Visible = visible; + } + + currPos += ItemSize; + if( m_searchFilter.Length > 0 || current.Value.Visible ) + { + for( int i = 0; i < current.Value.Contents.Count; i++ ) + { + //if ( !IsItemVisible( currPos ) ) + //{ + // // Invisible + // GUILayout.Space( ItemSize ); + //} + //else + { + currPos += ItemSize; + // Visible + EditorGUILayout.BeginHorizontal(); + GUILayout.Space( 16 ); + //if ( m_isMouseInside ) + //{ + // //GUI.SetNextControlName( current.Value.Contents[ i ].ItemUIContent.text ); + // if ( CheckButton( current.Value.Contents[ i ].ItemUIContent, m_buttonStyle, mouseButtonId ) ) + // { + // int controlID = GUIUtility.GetControlID( FocusType.Passive ); + // GUIUtility.hotControl = controlID; + // OnPaletteNodeCreateEvt( current.Value.Contents[ i ].NodeType, current.Value.Contents[ i ].Name, current.Value.Contents[ i ].Function ); + // } + //} + //else + { + Rect thisRect = EditorGUILayout.GetControlRect( false, 16f, EditorStyles.label ); + //if ( m_resizable ) + { + if( GUI.RepeatButton( thisRect, string.Empty, EditorStyles.label ) ) + { + int controlID = GUIUtility.GetControlID( FocusType.Passive ); + GUIUtility.hotControl = controlID; + OnPaletteNodeCreateEvt( current.Value.Contents[ i ].NodeType, current.Value.Contents[ i ].Name, current.Value.Contents[ i ].Function ); + //unfocus to make it focus the next text field correctly + GUI.FocusControl( null ); + } + } + GUI.SetNextControlName( current.Value.Contents[ i ].ItemUIContent.text + m_resizable ); + //EditorGUI.SelectableLabel( thisRect, current.Value.Contents[ i ].ItemUIContent.text, EditorStyles.label ); + //float cache = EditorGUIUtility.labelWidth; + EditorGUIUtility.labelWidth = thisRect.width; + EditorGUI.Toggle( thisRect, current.Value.Contents[ i ].ItemUIContent.text, false, EditorStyles.label ); + EditorGUIUtility.labelWidth = cache; + if( watching == current.Value.Contents[ i ].ItemUIContent.text + m_resizable ) + { + bool boundBottom = currPos - m_currentScrollPos.y > m_currScrollBarDims.y; + bool boundTop = currPos - m_currentScrollPos.y - 4 <= 0; + + if( boundBottom ) + m_currentScrollPos.y = currPos - m_currScrollBarDims.y + 2; + else if( boundTop ) + m_currentScrollPos.y = currPos - 18; + //else if ( boundBottom && !downDirection ) + // m_currentScrollPos.y = currPos - m_currScrollBarDims.y + 2; + //else if ( boundTop && downDirection ) + // m_currentScrollPos.y = currPos - 18; + } + } + EditorGUILayout.EndHorizontal(); + } + //currPos += ItemSize; + } + } + } + EditorGUIUtility.labelWidth = cache; + } + EditorGUILayout.EndScrollView(); + } + GUILayout.EndArea(); + + } + public void CheckCommunityNodes() + { + var enumerator = m_currentCategories.GetEnumerator(); + while( enumerator.MoveNext() ) + { + var current = enumerator.Current; + current.Value.HasCommunityData = false; + int count = current.Value.Contents.Count; + for( int i = 0; i < count; i++ ) + { + if( current.Value.Contents[ i ].NodeAttributes.FromCommunity ) + { + current.Value.HasCommunityData = true; + break; + } + } + } + } + + public void DumpAvailableNodes( bool fromCommunity, string pathname ) + { + string noTOCHeader = "__NOTOC__\n"; + string nodesHeader = "== Available Node Categories ==\n"; + string InitialCategoriesFormat = "[[#{0}|{0}]]<br>\n"; + string InitialCategories = string.Empty; + string CurrentCategoryFormat = "\n== {0} ==\n\n"; + //string NodesFootFormat = "[[Unity Products:Amplify Shader Editor/{0} | Learn More]] -\n[[#Top|Back to Categories]]\n"; + string NodesFootFormatSep = "[[#Top|Back to Top]]\n----\n"; + string OverallFoot = "[[Category:Nodes]]"; + + string NodeInfoBeginFormat = "<div class=\"nodecard\">\n"; + string nodeInfoBodyFormat = "{{| id=\"{2}\" class=\"wikitable\" |\n" + + "|- \n" + + "| <div>[[Unity Products:Amplify Shader Editor/{1}|<img class=\"responsive-img\" src=\"http://amplify.pt/Nodes/{0}.jpg\">]]</div>\n" + + "<div>\n" + + "{{| style=\"width: 100%; height: 150px;\"\n" + + "|-\n" + + "| [[Unity Products:Amplify Shader Editor/{1}|'''{2}''']]\n" + + "|- style=\"vertical-align:top; height: 100%;\" |\n" + + "|<p class=\"cardtext\">{3}</p>\n" + + "|- style=\"text-align:right;\" |\n" + + "|{4}[[Unity Products:Amplify Shader Editor/{1} | Learn More]]\n" + + "|}}</div>\n" + + "|}}\n"; + string NodeInfoEndFormat = "</div>\n"; + + //string NodeInfoBeginFormat = "<span style=\"color:#c00;display:block;\">This page is under construction!</span>\n\n"; + //string nodeInfoBodyFormat = "<img style=\"float:left; margin-right:10px;\" src=\"http://amplify.pt/Nodes/{0}.jpg\">\n[[Unity Products:Amplify Shader Editor/{1}|'''{2}''']]\n\n{3}"; + //string NodeInfoEndFormat = "\n\n[[Unity_Products:Amplify_Shader_Editor/Nodes | Back to Node List ]]\n[[Category:Nodes]][[Category:{0}]]\n\n\n"; + + //string NodeInfoBeginFormat = "{| cellpadding=\"10\"\n"; + //string nodeInfoBodyFormat = "|- style=\"vertical-align:top;\"\n| http://amplify.pt/Nodes/{0}.jpg\n| [[Unity Products:Amplify Shader Editor/{1} | <span style=\"font-size: 120%;\"><span id=\"{2}\"></span>'''{2}'''<span> ]] <br> {3}\n"; + //string NodeInfoEndFormat = "|}\n"; + + string nodesInfo = string.Empty; + BuildFullList( true ); + CheckCommunityNodes(); + var enumerator = m_currentCategories.GetEnumerator(); + while( enumerator.MoveNext() ) + { + var current = enumerator.Current; + if( fromCommunity && current.Value.HasCommunityData || !fromCommunity ) + { + InitialCategories += string.Format( InitialCategoriesFormat, current.Key ); + nodesInfo += string.Format( CurrentCategoryFormat, current.Key ); + int count = current.Value.Contents.Count; + for( int i = 0; i < count; i++ ) + { + if( ( fromCommunity && current.Value.Contents[ i ].NodeAttributes.FromCommunity ) + || !fromCommunity + //|| ( !fromCommunity && !current.Value.Contents[ i ].NodeAttributes.FromCommunity ) + ) + { + string nodeFullName = current.Value.Contents[ i ].Name; + string pictureFilename = UIUtils.ReplaceInvalidStrings( nodeFullName ); + + string pageFilename = UIUtils.RemoveWikiInvalidCharacters( pictureFilename ); + + pictureFilename = UIUtils.RemoveInvalidCharacters( pictureFilename ); + + string nodeDescription = current.Value.Contents[ i ].ItemUIContent.tooltip; + string communityText = string.Empty; + if( current.Value.Contents[ i ].NodeAttributes.FromCommunity ) + communityText = "<small class=\"cardauthor\">( originally by "+ current.Value.Contents[ i ].NodeAttributes.Community + " )</small> "; + + string nodeInfoBody = string.Format( nodeInfoBodyFormat, pictureFilename, pageFilename, nodeFullName, nodeDescription, communityText ); + //string nodeInfoFoot = string.Format( NodesFootFormat, pageFilename ); + + nodesInfo += ( NodeInfoBeginFormat + nodeInfoBody + NodeInfoEndFormat ); + //nodesInfo += ( NodeInfoBeginFormat + nodeInfoBody + string.Format( NodeInfoEndFormat, current.Key ) ); + //if ( i != ( count - 1 ) ) + //{ + // nodesInfo += NodesFootFormatSep; + //} + } + } + nodesInfo += NodesFootFormatSep; + } + } + + string finalText = noTOCHeader + nodesHeader + InitialCategories + nodesInfo + OverallFoot; + + if( !System.IO.Directory.Exists( pathname ) ) + { + System.IO.Directory.CreateDirectory( pathname ); + } + // Save file + string nodesPathname = pathname + ( fromCommunity ? "AvailableNodesFromCommunity.txt" : "AvailableNodes.txt" ); + Debug.Log( " Creating nodes file at " + nodesPathname ); + IOUtils.SaveTextfileToDisk( finalText, nodesPathname, false ); + BuildFullList( false ); + } + + public virtual bool CheckButton( GUIContent content, GUIStyle style, int buttonId ) + { + if( buttonId != m_validButtonId ) + { + GUILayout.Label( content, style ); + return false; + } + + return GUILayout.RepeatButton( content, style ); + } + + public void FillList( ref List<ContextMenuItem> list, bool forceAllItems ) + { + List<ContextMenuItem> allList = forceAllItems ? ParentWindow.ContextMenuInstance.ItemFunctions : ParentWindow.ContextMenuInstance.MenuItems; + + list.Clear(); + int count = allList.Count; + for( int i = 0; i < count; i++ ) + { + list.Add( allList[ i ] ); + } + } + + public Dictionary<string, PaletteFilterData> BuildFullList( bool forceAllNodes = false ) + { + //Only need to build if search filter is active and list is set according to it + if( m_searchFilter.Length > 0 || !m_isActive || m_currentCategories.Count == 0 ) + { + m_currentItems.Clear(); + m_currentCategories.Clear(); + + List<ContextMenuItem> allItems = forceAllNodes ? ParentWindow.ContextMenuInstance.ItemFunctions : ParentWindow.ContextMenuInstance.MenuItems; + + for( int i = 0; i < allItems.Count; i++ ) + { + if( allItems[ i ].Name.IndexOf( m_searchFilter, StringComparison.InvariantCultureIgnoreCase ) >= 0 || + allItems[ i ].Category.IndexOf( m_searchFilter, StringComparison.InvariantCultureIgnoreCase ) >= 0 + ) + { + m_currentItems.Add( allItems[ i ] ); + if( !m_currentCategories.ContainsKey( allItems[ i ].Category ) ) + { + m_currentCategories.Add( allItems[ i ].Category, new PaletteFilterData( m_defaultCategoryVisible ) ); + //m_currentCategories[ allItems[ i ].Category ].HasCommunityData = allItems[ i ].NodeAttributes.FromCommunity || m_currentCategories[ allItems[ i ].Category ].HasCommunityData; + } + m_currentCategories[ allItems[ i ].Category ].Contents.Add( allItems[ i ] ); + } + } + + var categoryEnumerator = m_currentCategories.GetEnumerator(); + while( categoryEnumerator.MoveNext() ) + { + categoryEnumerator.Current.Value.Contents.Sort( ( x, y ) => x.CompareTo( y, false ) ); + } + + //mark to force update and take search filter into account + m_forceUpdate = true; + } + return m_currentCategories; + } + + private bool IsItemVisible( float currPos ) + { + if( ( currPos < m_currentScrollPos.y && ( currPos + ItemSize ) < m_currentScrollPos.y ) || + ( currPos > ( m_currentScrollPos.y + m_currScrollBarDims.y ) && + ( currPos + ItemSize ) > ( m_currentScrollPos.y + m_currScrollBarDims.y ) ) ) + { + return false; + } + return true; + } + + public override void Destroy() + { + base.Destroy(); + + //m_allItems = null; + + m_currentItems.Clear(); + m_currentItems = null; + + m_currentCategories.Clear(); + m_currentCategories = null; + + OnPaletteNodeCreateEvt = null; + m_buttonStyle = null; + m_foldoutStyle = null; + } + + //public void Clear() { + // m_allItems.Clear(); + // m_allItems = new List<ContextMenuItem>(); + //} + + public bool ForceUpdate { get { return m_forceUpdate; } set { m_forceUpdate = value; } } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Palette/PaletteParent.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Palette/PaletteParent.cs.meta new file mode 100644 index 00000000..b9d921f2 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Palette/PaletteParent.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: df4c2f840dca60a4cb118325ce2febfa +timeCreated: 1481126959 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Palette/PalettePopUp.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Palette/PalettePopUp.cs new file mode 100644 index 00000000..84cfbc4a --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Palette/PalettePopUp.cs @@ -0,0 +1,73 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using UnityEngine; + +namespace AmplifyShaderEditor +{ + public class PalettePopUp + { + private const int DeltaX = 5; + private Rect m_areaSettings; + private Vector2 m_mouseDeltaPos = new Vector2( 10, -10 ); + private bool m_isActive = false; + private GUIContent m_content; + private GUIStyle m_style; + private GUIStyle m_fontStyle; + private GUIContent m_labelContent; + + public PalettePopUp() + { + m_content = new GUIContent( GUIContent.none ); + m_areaSettings = new Rect( 0, 0, 100, 30 ); + m_labelContent = new GUIContent( "Test Label" ); + } + + public void Activate( string label ) + { + m_labelContent.text = label; + m_areaSettings.width = -1; + m_isActive = true; + } + + public void Deactivate() + { + m_isActive = false; + } + + public void Draw( Vector2 mousePos ) + { + if ( m_style == null ) + { + m_style = UIUtils.TextArea; + } + + if ( m_fontStyle == null ) + { + m_fontStyle = new GUIStyle( UIUtils.Label ); + m_fontStyle.fontSize = 15; + } + + if ( m_areaSettings.width < 0 ) + { + m_areaSettings.width = m_fontStyle.CalcSize( m_labelContent ).x + 2 * DeltaX; + } + + m_areaSettings.position = mousePos + m_mouseDeltaPos; + GUI.Label( m_areaSettings, m_content, m_style ); + m_areaSettings.position += new Vector2( DeltaX,DeltaX); + GUI.Label( m_areaSettings, m_labelContent, m_fontStyle ); + } + + public void Destroy() + { + m_content = null; + m_style = null; + } + + public bool IsActive + { + get { return m_isActive; } + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Palette/PalettePopUp.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Palette/PalettePopUp.cs.meta new file mode 100644 index 00000000..f0f84d43 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Palette/PalettePopUp.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: bc4f137f15efe1d42b7bcbf984ec1545 +timeCreated: 1481126958 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Palette/PaletteWindow.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Palette/PaletteWindow.cs new file mode 100644 index 00000000..f0b6960f --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Palette/PaletteWindow.cs @@ -0,0 +1,33 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using System.Collections.Generic; +using UnityEngine; + +namespace AmplifyShaderEditor +{ + public sealed class PaletteWindow : PaletteParent + { + public PaletteWindow( AmplifyShaderEditorWindow parentWindow ) : base( parentWindow, 0, 0, 250, 0, string.Empty, MenuAnchor.TOP_RIGHT, MenuAutoSize.MATCH_VERTICAL ) + { + m_searchFilterControl += "PALETTEWINDOW"; + m_initialSeparatorAmount = 4; + SetMinimizedArea( -225, 0, 260, 0 ); + } + + public override void Draw( Rect parentPosition, Vector2 mousePosition, int mouseButtonId, bool hasKeyboadFocus ) + { + if ( m_isMaximized ) + { + base.Draw( parentPosition, mousePosition, mouseButtonId, hasKeyboadFocus ); + } + else + { + InitDraw( parentPosition, mousePosition, mouseButtonId ); + } + PostDraw(); + } + } +} + + diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Palette/PaletteWindow.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Palette/PaletteWindow.cs.meta new file mode 100644 index 00000000..521f7761 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Palette/PaletteWindow.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 63408b264ef8cb346a5ce9e559a5ed22 +timeCreated: 1481126956 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/PortLegendInfo.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/PortLegendInfo.cs new file mode 100644 index 00000000..9f76a512 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/PortLegendInfo.cs @@ -0,0 +1,469 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using UnityEditor; +using UnityEngine; +using System.Collections.Generic; + +namespace AmplifyShaderEditor +{ + class NodeDescriptionInfo + { + public bool FoldoutValue; + public string Category; + public string[,] Contents; + } + + public sealed class PortLegendInfo : EditorWindow + { + private const string NoASEWindowWarning = "Please Open the ASE to get access to shortcut info"; + private const float PixelSeparator = 5; + private const string EditorShortcutsTitle = "Editor Shortcuts"; + private const string MenuShortcutsTitle = "Menu Shortcuts"; + private const string NodesShortcutsTitle = "Nodes Shortcuts"; + private const string PortShortcutsTitle = "Port Shortcuts"; + private const string PortLegendTitle = "Port Legend"; + private const string NodesDescTitle = "Node Info"; + private const string CompatibleAssetsTitle = "Compatible Assets"; + + private const string KeyboardUsageTemplate = "[{0}] - {1}"; + private const string m_lockedStr = "Locked Port"; + + private const float WindowSizeX = 350; + private const float WindowSizeY = 300; + private const float WindowPosX = 5; + private const float WindowPosY = 5; + + private int TitleLabelWidth = 150; + private Rect m_availableArea; + + private bool m_portAreaFoldout = true; + private bool m_editorShortcutAreaFoldout = true; + private bool m_menuShortcutAreaFoldout = true; + private bool m_nodesShortcutAreaFoldout = true; + private bool m_nodesDescriptionAreaFoldout = true; + private bool m_compatibleAssetsFoldout = true; + + private Vector2 m_currentScrollPos; + + private GUIStyle m_portStyle; + private GUIStyle m_labelStyleBold; + private GUIStyle m_labelStyle; + + private GUIStyle m_nodeInfoLabelStyleBold; + private GUIStyle m_nodeInfoLabelStyle; + + private GUIStyle m_nodeInfoFoldoutStyle; + + private GUIContent m_content = new GUIContent( "Helper", "Shows helper info for ASE users" ); + private bool m_init = true; + + private List<ShortcutItem> m_editorShortcuts = null; + private List<ShortcutItem> m_nodesShortcuts = null; + private List<NodeDescriptionInfo> m_nodeDescriptionsInfo = null; + private List<string[]> m_compatibleAssetsInfo = null; + + public static PortLegendInfo OpenWindow() + { + PortLegendInfo currentWindow = ( PortLegendInfo ) PortLegendInfo.GetWindow( typeof( PortLegendInfo ), false ); + currentWindow.minSize = new Vector2( WindowSizeX, WindowSizeY ); + currentWindow.maxSize = new Vector2( WindowSizeX * 2, 2 * WindowSizeY ); ; + currentWindow.wantsMouseMove = true; + return currentWindow; + } + + public void Init() + { + m_init = false; + wantsMouseMove = false; + titleContent = m_content; + m_portStyle = new GUIStyle( UIUtils.GetCustomStyle( CustomStyle.PortEmptyIcon ) ); + m_portStyle.alignment = TextAnchor.MiddleLeft; + m_portStyle.imagePosition = ImagePosition.ImageOnly; + m_portStyle.margin = new RectOffset( 5, 0, 5, 0 ); + + m_labelStyleBold = new GUIStyle( UIUtils.InputPortLabel ); + m_labelStyleBold.fontStyle = FontStyle.Bold; + m_labelStyleBold.fontSize = ( int ) ( Constants.TextFieldFontSize ); + + + m_labelStyle = new GUIStyle( UIUtils.InputPortLabel ); + m_labelStyle.clipping = TextClipping.Overflow; + m_labelStyle.imagePosition = ImagePosition.TextOnly; + m_labelStyle.contentOffset = new Vector2( -10, 0 ); + m_labelStyle.fontSize = ( int ) ( Constants.TextFieldFontSize ); + + m_nodeInfoLabelStyleBold = new GUIStyle( UIUtils.InputPortLabel ); + m_nodeInfoLabelStyleBold.fontStyle = FontStyle.Bold; + m_nodeInfoLabelStyleBold.fontSize = ( int ) ( Constants.TextFieldFontSize ); + + m_nodeInfoLabelStyle = new GUIStyle( UIUtils.InputPortLabel ); + m_nodeInfoLabelStyle.clipping = TextClipping.Clip; + m_nodeInfoLabelStyle.imagePosition = ImagePosition.TextOnly; + m_nodeInfoLabelStyle.fontSize = ( int ) ( Constants.TextFieldFontSize ); + + + m_nodeInfoFoldoutStyle = new GUIStyle( ( GUIStyle ) "foldout" ); + m_nodeInfoFoldoutStyle.fontStyle = FontStyle.Bold; + + if ( !EditorGUIUtility.isProSkin ) + { + m_labelStyleBold.normal.textColor = m_labelStyle.normal.textColor = Color.black; + m_nodeInfoLabelStyleBold.normal.textColor = m_labelStyle.normal.textColor = Color.black; + m_nodeInfoLabelStyle.normal.textColor = m_labelStyle.normal.textColor = Color.black; + } + + m_availableArea = new Rect( WindowPosX, WindowPosY, WindowSizeX - 2 * WindowPosX, WindowSizeY - 2 * WindowPosY ); + } + + void DrawPort( WirePortDataType type ) + { + EditorGUILayout.BeginHorizontal(); + { + GUI.color = UIUtils.GetColorForDataType( type, false ); + GUILayout.Box( string.Empty, m_portStyle, GUILayout.Width( UIUtils.PortsSize.x ), GUILayout.Height( UIUtils.PortsSize.y ) ); + GUI.color = Color.white; + EditorGUILayout.LabelField( UIUtils.GetNameForDataType( type ), m_labelStyle ); + } + EditorGUILayout.EndHorizontal(); + EditorGUILayout.Separator(); + } + + void OnGUI() + { + if ( !UIUtils.Initialized || UIUtils.CurrentWindow == null ) + { + EditorGUILayout.LabelField( NoASEWindowWarning ); + return; + } + + if ( m_init ) + { + Init(); + } + + TitleLabelWidth = (int)(this.position.width * 0.42f); + + KeyCode key = Event.current.keyCode; + if ( key == ShortcutsManager.ScrollUpKey ) + { + m_currentScrollPos.y -= 10; + if ( m_currentScrollPos.y < 0 ) + { + m_currentScrollPos.y = 0; + } + Event.current.Use(); + } + + if ( key == ShortcutsManager.ScrollDownKey ) + { + m_currentScrollPos.y += 10; + Event.current.Use(); + } + + if ( Event.current.type == EventType.MouseDrag && Event.current.button > 0 ) + { + m_currentScrollPos.x += Constants.MenuDragSpeed * Event.current.delta.x; + if ( m_currentScrollPos.x < 0 ) + { + m_currentScrollPos.x = 0; + } + + m_currentScrollPos.y += Constants.MenuDragSpeed * Event.current.delta.y; + if ( m_currentScrollPos.y < 0 ) + { + m_currentScrollPos.y = 0; + } + } + + m_availableArea = new Rect( WindowPosX, WindowPosY, position.width - 2 * WindowPosX, position.height - 2 * WindowPosY ); + GUILayout.BeginArea( m_availableArea ); + { + if ( GUILayout.Button( "Wiki Page" ) ) + { + Application.OpenURL( Constants.HelpURL ); + } + + m_currentScrollPos = GUILayout.BeginScrollView( m_currentScrollPos ); + { + EditorGUILayout.BeginVertical(); + { + NodeUtils.DrawPropertyGroup( ref m_portAreaFoldout, PortLegendTitle, DrawPortInfo ); + float currLabelWidth = EditorGUIUtility.labelWidth; + EditorGUIUtility.labelWidth = 1; + NodeUtils.DrawPropertyGroup( ref m_editorShortcutAreaFoldout, EditorShortcutsTitle, DrawEditorShortcuts ); + NodeUtils.DrawPropertyGroup( ref m_menuShortcutAreaFoldout, MenuShortcutsTitle, DrawMenuShortcuts ); + NodeUtils.DrawPropertyGroup( ref m_nodesShortcutAreaFoldout, NodesShortcutsTitle, DrawNodesShortcuts ); + NodeUtils.DrawPropertyGroup( ref m_compatibleAssetsFoldout, CompatibleAssetsTitle, DrawCompatibleAssets ); + NodeUtils.DrawPropertyGroup( ref m_nodesDescriptionAreaFoldout, NodesDescTitle, DrawNodeDescriptions ); + EditorGUIUtility.labelWidth = currLabelWidth; + } + EditorGUILayout.EndVertical(); + } + GUILayout.EndScrollView(); + } + GUILayout.EndArea(); + + } + + void DrawPortInfo() + { + Color originalColor = GUI.color; + + DrawPort( WirePortDataType.OBJECT ); + DrawPort( WirePortDataType.INT ); + DrawPort( WirePortDataType.FLOAT ); + DrawPort( WirePortDataType.FLOAT2 ); + DrawPort( WirePortDataType.FLOAT3 ); + DrawPort( WirePortDataType.FLOAT4 ); + DrawPort( WirePortDataType.COLOR ); + DrawPort( WirePortDataType.SAMPLER2D ); + DrawPort( WirePortDataType.FLOAT3x3 ); + DrawPort( WirePortDataType.FLOAT4x4 ); + + EditorGUILayout.BeginHorizontal(); + { + GUI.color = Constants.LockedPortColor; + GUILayout.Box( string.Empty, m_portStyle, GUILayout.Width( UIUtils.PortsSize.x ), GUILayout.Height( UIUtils.PortsSize.y ) ); + GUI.color = Color.white; + EditorGUILayout.LabelField( m_lockedStr, m_labelStyle ); + } + EditorGUILayout.EndHorizontal(); + + GUI.color = originalColor; + } + + public void DrawEditorShortcuts() + { + AmplifyShaderEditorWindow window = UIUtils.CurrentWindow; + if ( window != null ) + { + if ( m_editorShortcuts == null ) + { + m_editorShortcuts = window.ShortcutManagerInstance.AvailableEditorShortcutsList; + } + + EditorGUI.indentLevel--; + int count = m_editorShortcuts.Count; + for ( int i = 0; i < count; i++ ) + { + DrawItem( m_editorShortcuts[ i ].Name, m_editorShortcuts[ i ].Description ); + } + DrawItem( "Q", "Alternative Pan modifier" ); + DrawItem( "Ctrl + F", "Find nodes" ); + DrawItem( "LMB Drag", "Box selection" ); + DrawItem( "MMB/RMB Drag", "Camera pan" ); + DrawItem( "Alt + MMB/RMB Drag", "Zoom graph" ); + DrawItem( "Shift/Ctrl + Node Select", "Add/Remove from selection" ); + DrawItem( "Shift + Node Drag", "Node move with offset" ); + DrawItem( "Ctrl + Node Drag", "Node move with snap" ); + DrawItem( "MMB/RMB + Drag Panel", "Scroll panel" ); + DrawItem( "Alt + LMB Drag", "Additive box selection" ); + DrawItem( "Alt + Shift + Drag", "Subtractive box selection" ); + DrawItem( "Alt + Node Drag", "Auto-(Dis)Connect node on existing wire connection" ); + EditorGUI.indentLevel++; + + } + else + { + EditorGUILayout.LabelField( NoASEWindowWarning ); + } + } + + public void DrawMenuShortcuts() + { + AmplifyShaderEditorWindow window = UIUtils.CurrentWindow; + if ( window != null ) + { + EditorGUI.indentLevel--; + DrawItem( ShortcutsManager.ScrollUpKey.ToString(), "Scroll Up Menu" ); + DrawItem( ShortcutsManager.ScrollDownKey.ToString(), "Scroll Down Menu" ); + DrawItem( "RMB Drag", "Scroll Menu" ); + EditorGUI.indentLevel++; + } + else + { + EditorGUILayout.LabelField( NoASEWindowWarning ); + } + } + + void DrawItem( string name, string description ) + { + GUILayout.BeginHorizontal(); + GUILayout.Label( name, m_labelStyleBold , GUILayout.Width( TitleLabelWidth ) ); + GUILayout.Label( description, m_labelStyle ); + GUILayout.EndHorizontal(); + GUILayout.Space( PixelSeparator ); + } + + public void DrawNodesShortcuts() + { + AmplifyShaderEditorWindow window = UIUtils.CurrentWindow; + if ( window != null ) + { + if ( m_nodesShortcuts == null || m_nodesShortcuts.Count == 0 ) + { + m_nodesShortcuts = window.ShortcutManagerInstance.AvailableNodesShortcutsList; + } + + EditorGUI.indentLevel--; + int count = m_nodesShortcuts.Count; + for ( int i = 0; i < count; i++ ) + { + DrawItem( m_nodesShortcuts[ i ].Name, m_nodesShortcuts[ i ].Description ); + } + EditorGUI.indentLevel++; + } + else + { + EditorGUILayout.LabelField( NoASEWindowWarning ); + } + } + string CreateCompatibilityString( string source ) + { + string[] split = source.Split( '.' ); + if ( split != null && split.Length > 1 ) + { + return split[ 1 ]; + } + else + { + return source; + } + } + public void DrawCompatibleAssets() + { + AmplifyShaderEditorWindow window = UIUtils.CurrentWindow; + if ( window != null ) + { + if ( m_compatibleAssetsInfo == null ) + { + m_compatibleAssetsInfo = new List<string[]>(); + List<ContextMenuItem> items = window.ContextMenuInstance.MenuItems; + int count = items.Count; + for ( int i = 0; i < count; i++ ) + { + if ( items[ i ].NodeAttributes != null && items[ i ].NodeAttributes.CastType != null ) + { + string types = string.Empty; + if ( items[ i ].NodeAttributes.CastType.Length > 1 ) + { + for ( int j = 0; j < items[ i ].NodeAttributes.CastType.Length; j++ ) + { + types += CreateCompatibilityString( items[ i ].NodeAttributes.CastType[ j ].ToString() ); + + + if ( j < items[ i ].NodeAttributes.CastType.Length - 1 ) + { + types += ", "; + } + } + } + else + { + types = CreateCompatibilityString( items[ i ].NodeAttributes.CastType[ 0 ].ToString() ); + } + m_compatibleAssetsInfo.Add( new string[] { items[ i ].NodeAttributes.Name + ": ", types } ); + } + } + } + EditorGUI.indentLevel--; + int nodeCount = m_compatibleAssetsInfo.Count; + for ( int j = 0; j < nodeCount; j++ ) + { + DrawItem( m_compatibleAssetsInfo[ j ][ 0 ], m_compatibleAssetsInfo[ j ][ 1 ] ); + } + EditorGUI.indentLevel++; + } + else + { + EditorGUILayout.LabelField( NoASEWindowWarning ); + } + } + + public void DrawNodeDescriptions() + { + AmplifyShaderEditorWindow window = UIUtils.CurrentWindow; + if ( window != null ) + { + if ( m_nodeDescriptionsInfo == null ) + { + //fetch node info + m_nodeDescriptionsInfo = new List<NodeDescriptionInfo>(); + Dictionary<string, PaletteFilterData> nodeData = window.CurrentPaletteWindow.BuildFullList(); + var enumerator = nodeData.GetEnumerator(); + while ( enumerator.MoveNext() ) + { + List<ContextMenuItem> nodes = enumerator.Current.Value.Contents; + int count = nodes.Count; + + NodeDescriptionInfo currInfo = new NodeDescriptionInfo(); + currInfo.Contents = new string[ count, 2 ]; + currInfo.Category = enumerator.Current.Key; + + for ( int i = 0; i < count; i++ ) + { + currInfo.Contents[ i, 0 ] = nodes[ i ].Name + ':'; + currInfo.Contents[ i, 1 ] = nodes[ i ].Description; + } + m_nodeDescriptionsInfo.Add( currInfo ); + } + } + + //draw + { + GUILayout.Space( 5 ); + int count = m_nodeDescriptionsInfo.Count; + EditorGUI.indentLevel--; + for ( int i = 0; i < count; i++ ) + { + m_nodeDescriptionsInfo[ i ].FoldoutValue = EditorGUILayout.Foldout( m_nodeDescriptionsInfo[ i ].FoldoutValue, m_nodeDescriptionsInfo[ i ].Category, m_nodeInfoFoldoutStyle ); + if ( m_nodeDescriptionsInfo[ i ].FoldoutValue ) + { + EditorGUI.indentLevel++; + int nodeCount = m_nodeDescriptionsInfo[ i ].Contents.GetLength( 0 ); + for ( int j = 0; j < nodeCount; j++ ) + { + GUILayout.Label( m_nodeDescriptionsInfo[ i ].Contents[ j, 0 ], m_nodeInfoLabelStyleBold ); + GUILayout.Label( m_nodeDescriptionsInfo[ i ].Contents[ j, 1 ], m_nodeInfoLabelStyle ); + GUILayout.Space( PixelSeparator ); + } + EditorGUI.indentLevel--; + } + GUILayout.Space( PixelSeparator ); + } + EditorGUI.indentLevel++; + } + } + else + { + EditorGUILayout.LabelField( NoASEWindowWarning ); + } + } + + private void OnDestroy() + { + m_nodesShortcuts = null; + m_editorShortcuts = null; + m_portStyle = null; + m_labelStyle = null; + m_labelStyleBold = null; + m_nodeInfoLabelStyle = null; + m_nodeInfoLabelStyleBold = null; + m_nodeInfoFoldoutStyle = null; + m_init = false; + + if ( m_nodeDescriptionsInfo != null ) + { + m_nodeDescriptionsInfo.Clear(); + m_nodeDescriptionsInfo = null; + } + + if( m_compatibleAssetsInfo != null ) + { + m_compatibleAssetsInfo.Clear(); + m_compatibleAssetsInfo = null; + } + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/PortLegendInfo.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/PortLegendInfo.cs.meta new file mode 100644 index 00000000..42646fce --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/PortLegendInfo.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 20dad8f4196f0e643a9c56d1202e74dc +timeCreated: 1481126954 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/SceneSaveCallback.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/SceneSaveCallback.cs new file mode 100644 index 00000000..56e24518 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/SceneSaveCallback.cs @@ -0,0 +1,37 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +namespace AmplifyShaderEditor +{ + // Catch when scene is saved (Ctr+S) and also save ase shader + public class SceneSaveCallback : UnityEditor.AssetModificationProcessor + { + private const string UnityStr = ".unity"; + + static string[] OnWillSaveAssets( string[] paths ) + { + bool canSave = false; + + if ( paths.Length == 0 ) + { + canSave = true; + } + else + { + for ( int i = 0; i < paths.Length; i++ ) + { + // Only save shader when saving scenes + if ( !string.IsNullOrEmpty( paths[ i ] ) && paths[ i ].Contains( UnityStr ) ) + { + canSave = true; + break; + } + } + } + if ( canSave && UIUtils.CurrentWindow ) + UIUtils.CurrentWindow.SetCtrlSCallback( false ); + + return paths; + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/SceneSaveCallback.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/SceneSaveCallback.cs.meta new file mode 100644 index 00000000..a91c39b3 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/SceneSaveCallback.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 708e90c98affcb04aa2fcfedf4329a7c +timeCreated: 1481126956 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/ShaderEditorModeWindow.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/ShaderEditorModeWindow.cs new file mode 100644 index 00000000..6a987d42 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/ShaderEditorModeWindow.cs @@ -0,0 +1,192 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using UnityEngine; +using UnityEditor; + +namespace AmplifyShaderEditor +{ + public sealed class ShaderEditorModeWindow : MenuParent + { + private static readonly Color OverallColorOn = new Color( 1f, 1f, 1f, 0.9f ); + private static readonly Color OverallColorOff = new Color( 1f, 1f, 1f, 0.3f ); + private static readonly Color FontColorOff = new Color( 1f, 1f, 1f, 0.4f ); + private const float DeltaY = 15; + private const float DeltaX = 10; + + private const float CollSizeX = 180; + private const float CollSizeY = 70; + + //private static string MatFormat = "<size=20>MATERIAL</size>\n{0}"; + //private static string ShaderFormat = "<size=20>SHADER</size>\n{0}"; + //private const string CurrMatStr = "MATERIAL"; + //private const string CurrShaderStr = "SHADER"; + + private const string NoMaterialStr = "No Material"; + private const string NoShaderStr = "No Shader"; + + private bool m_init = true; + private string m_previousShaderName = string.Empty; + private string m_previousMaterialName = string.Empty; + private string m_previousShaderFunctionName = string.Empty; + + private Vector2 m_auxVector2; + private GUIContent m_leftAuxContent = new GUIContent(); + private GUIContent m_rightAuxContent = new GUIContent(); + private GUIStyle m_leftButtonStyle = null; + private GUIStyle m_rightButtonStyle = null; + private Rect m_leftButtonRect; + private Rect m_rightButtonRect; + + public ShaderEditorModeWindow( AmplifyShaderEditorWindow parentWindow ) : base( parentWindow, 0, 0, 0, 0, "ShaderEditorModeWindow", MenuAnchor.BOTTOM_CENTER, MenuAutoSize.NONE ) { } + + public void ConfigStyle( GUIStyle style ) + { + style.normal.textColor = FontColorOff; + style.hover.textColor = FontColorOff; + style.active.textColor = FontColorOff; + style.focused.textColor = FontColorOff; + + style.onNormal.textColor = FontColorOff; + style.onHover.textColor = FontColorOff; + style.onActive.textColor = FontColorOff; + style.onFocused.textColor = FontColorOff; + } + + + public void Draw( Rect graphArea, Vector2 mousePos, Shader currentShader, Material currentMaterial, float usableArea, float leftPos, float rightPos /*, bool showLastSelection*/ ) + { + EventType currentEventType = Event.current.type; + + if( !( currentEventType == EventType.Repaint || currentEventType == EventType.MouseDown || currentEventType == EventType.MouseMove ) ) + return; + + if ( m_init ) + { + m_init = false; + GUIStyle shaderModeTitle = UIUtils.GetCustomStyle( CustomStyle.ShaderModeTitle ); + GUIStyle shaderModeNoShader = UIUtils.GetCustomStyle( CustomStyle.ShaderModeNoShader ); + GUIStyle materialModeTitle = UIUtils.GetCustomStyle( CustomStyle.MaterialModeTitle ); + GUIStyle shaderNoMaterialModeTitle = UIUtils.GetCustomStyle( CustomStyle.ShaderNoMaterialModeTitle ); + + ConfigStyle( shaderModeTitle ); + ConfigStyle( shaderModeNoShader ); + ConfigStyle( materialModeTitle ); + ConfigStyle( shaderNoMaterialModeTitle ); + } + Color buffereredColor = GUI.color; + + MasterNode currentMasterNode = ParentWindow.CurrentGraph.CurrentMasterNode; + // Shader Mode + if ( currentMasterNode != null ) + { + m_leftButtonStyle = UIUtils.GetCustomStyle( currentShader == null ? CustomStyle.ShaderModeNoShader : CustomStyle.ShaderModeTitle ); + m_leftButtonRect = graphArea; + m_leftButtonRect.x = 10 + leftPos; + m_leftButtonRect.y += m_leftButtonRect.height - 38 - 15; + string shaderName = ( currentShader != null ) ? ( currentShader.name ) : NoShaderStr; + + if ( m_previousShaderName != shaderName ) + { + m_previousShaderName = shaderName; + m_leftAuxContent.text = "<size=20>SHADER</size>\n" + shaderName; + } + + m_auxVector2 = m_leftButtonStyle.CalcSize( m_leftAuxContent ); + m_leftButtonRect.width = m_auxVector2.x + 30 + 4; + m_leftButtonRect.height = 38; + + bool mouseOnTop = m_leftButtonRect.Contains( mousePos ); + GUI.color = mouseOnTop ? OverallColorOn : OverallColorOff; + GUI.Label( m_leftButtonRect, m_leftAuxContent, m_leftButtonStyle ); + + if( currentEventType == EventType.MouseMove && mouseOnTop ) + m_parentWindow.MarkToRepaint(); + + if ( currentEventType == EventType.MouseDown && mouseOnTop && currentShader != null ) + { + Event.current.Use(); + Selection.activeObject = currentShader; + EditorGUIUtility.PingObject( Selection.activeObject ); + } + + // Material Mode + if ( currentMaterial != null ) + { + m_rightButtonStyle = UIUtils.GetCustomStyle( CustomStyle.MaterialModeTitle ); + m_rightButtonRect = graphArea; + string matName = ( currentMaterial != null ) ? ( currentMaterial.name ) : NoMaterialStr; + + if ( m_previousMaterialName != matName ) + { + m_previousMaterialName = matName; + m_rightAuxContent.text = "<size=20>MATERIAL</size>\n" + matName; + } + + m_auxVector2 = m_rightButtonStyle.CalcSize( m_rightAuxContent ); + m_rightButtonRect.width = m_auxVector2.x + 30 + 4; + m_rightButtonRect.height = 38; + + m_rightButtonRect.x = graphArea.xMax - m_rightButtonRect.width - rightPos - 10; + m_rightButtonRect.y = graphArea.yMax - 38 - 15; + + bool mouseOnTopRight = m_rightButtonRect.Contains( mousePos ); + GUI.color = mouseOnTopRight ? OverallColorOn : OverallColorOff; + GUI.Label( m_rightButtonRect, m_rightAuxContent, m_rightButtonStyle ); + + if( currentEventType == EventType.MouseMove && mouseOnTopRight ) + m_parentWindow.MarkToRepaint(); + + if ( currentEventType == EventType.MouseDown && mouseOnTopRight ) + { + Event.current.Use(); + Selection.activeObject = currentMaterial; + EditorGUIUtility.PingObject( Selection.activeObject ); + } + } + } + + // Shader Function + else if ( currentMasterNode == null && ParentWindow.CurrentGraph.CurrentOutputNode != null ) + { + m_leftButtonStyle = UIUtils.GetCustomStyle( CustomStyle.ShaderFunctionMode ); + m_leftButtonRect = graphArea; + m_leftButtonRect.x = 10 + leftPos; + m_leftButtonRect.y += m_leftButtonRect.height - 38 - 15; + string functionName = ( ParentWindow.CurrentGraph.CurrentShaderFunction != null ) ? ( ParentWindow.CurrentGraph.CurrentShaderFunction.name ) : "No Shader Function"; + + if ( m_previousShaderFunctionName != functionName ) + { + m_previousShaderFunctionName = functionName; + m_leftAuxContent.text = "<size=20>SHADER FUNCTION</size>\n" + functionName; + } + + m_auxVector2 = m_leftButtonStyle.CalcSize( m_leftAuxContent ); + m_leftButtonRect.width = m_auxVector2.x + 30 + 4; + m_leftButtonRect.height = 38; + + bool mouseOnTop = m_leftButtonRect.Contains( mousePos ); + GUI.color = mouseOnTop ? OverallColorOn : OverallColorOff; + GUI.Label( m_leftButtonRect, m_leftAuxContent, m_leftButtonStyle ); + + if ( currentEventType == EventType.MouseDown && mouseOnTop && ParentWindow.CurrentGraph.CurrentShaderFunction != null ) + { + Event.current.Use(); + Selection.activeObject = ParentWindow.CurrentGraph.CurrentShaderFunction; + EditorGUIUtility.PingObject( Selection.activeObject ); + } + } + + GUI.color = buffereredColor; + } + + public override void Destroy() + { + base.Destroy(); + m_leftAuxContent = null; + m_rightAuxContent = null; + m_leftButtonStyle = null; + m_rightButtonStyle = null; + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/ShaderEditorModeWindow.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/ShaderEditorModeWindow.cs.meta new file mode 100644 index 00000000..5f0a8f61 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/ShaderEditorModeWindow.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 672d96e3a4f68d44f9456d2fc53d4d73 +timeCreated: 1481126956 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/ShaderLibrary.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/ShaderLibrary.cs new file mode 100644 index 00000000..e405e2e2 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/ShaderLibrary.cs @@ -0,0 +1,91 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using UnityEditor; +using System.Collections.Generic; +using System; +using UnityEngine; + +namespace AmplifyShaderEditor +{ + [Serializable] + public class ShaderLibrary : EditorWindow + { + private const string SHADER_LIB_FILE = "/AmplifyShaderEditor/Resources/ShaderLibrary/ShaderLibrary.txt"; + private bool m_init = false; + private Vector2 m_scrollPos = new Vector2(); + [SerializeField] + private List<string> m_shaders = new List<string>(); + void Init() + { + m_init = true; + string list = IOUtils.LoadTextFileFromDisk( Application.dataPath + SHADER_LIB_FILE ); + if ( String.IsNullOrEmpty( list ) ) + return; + + string[] listArr = list.Split( IOUtils.FIELD_SEPARATOR ); + for ( int i = 0; i < listArr.Length; i++ ) + { + m_shaders.Add( listArr[ i ] ); + } + + UIUtils.MainSkin.customStyles[ 10 ].active.background = Texture2D.whiteTexture; + + UIUtils.MainSkin.customStyles[ 6 ].fixedHeight = UIUtils.MainSkin.customStyles[ 6 ].normal.background.height; + UIUtils.MainSkin.customStyles[ 6 ].fixedWidth = UIUtils.MainSkin.customStyles[ 6 ].normal.background.width; + + UIUtils.MainSkin.customStyles[ 7 ].fixedHeight = UIUtils.MainSkin.customStyles[ 7 ].normal.background.height; + UIUtils.MainSkin.customStyles[ 7 ].fixedWidth = UIUtils.MainSkin.customStyles[ 7 ].normal.background.width; + + UIUtils.MainSkin.customStyles[ 8 ].fixedHeight = UIUtils.MainSkin.customStyles[ 8 ].normal.background.height; + UIUtils.MainSkin.customStyles[ 8 ].fixedWidth = UIUtils.MainSkin.customStyles[ 8 ].normal.background.width; + + UIUtils.MainSkin.customStyles[ 9 ].fixedHeight = UIUtils.MainSkin.customStyles[ 9 ].normal.background.height; + UIUtils.MainSkin.customStyles[ 9 ].fixedWidth = UIUtils.MainSkin.customStyles[ 9 ].normal.background.width; + + } + + void OnGUI() + { + if ( !m_init ) + { + Init(); + } + + Rect availableArea = position; + + availableArea.y = 100f; + availableArea.x = 0.05f * availableArea.width; + availableArea.height *= 0.5f; + availableArea.width *= 0.9f; + EditorGUILayout.BeginVertical(); + { + EditorGUILayout.LabelField( "Shader Library", UIUtils.MainSkin.customStyles[ 5 ] ); + GUILayout.Space( 10 ); + EditorGUILayout.BeginHorizontal(); + { + GUILayout.Space( 0.05f * position.width ); + GUILayout.Button( string.Empty, UIUtils.MainSkin.customStyles[ 8 ] ); + GUILayout.Button( string.Empty, UIUtils.MainSkin.customStyles[ 9 ] ); + GUILayout.Space( 0.8f*position.width ); + GUILayout.Button( string.Empty, UIUtils.MainSkin.customStyles[ 7 ] ); + GUILayout.Button( string.Empty, UIUtils.MainSkin.customStyles[ 6 ] ); + } + EditorGUILayout.EndHorizontal(); + + GUILayout.BeginArea( availableArea ); + m_scrollPos = EditorGUILayout.BeginScrollView( m_scrollPos, UIUtils.MainSkin.box ); + { + for ( int i = 0; i < m_shaders.Count; i++ ) + { + GUILayout.Button( m_shaders[ i ], UIUtils.MainSkin.customStyles[ 10 ] ); + } + } + EditorGUILayout.EndScrollView(); + GUILayout.EndArea(); + } + EditorGUILayout.EndVertical(); + + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/ShaderLibrary.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/ShaderLibrary.cs.meta new file mode 100644 index 00000000..9a6c519a --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/ShaderLibrary.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: cbdd03f297692584391b9dc0625a80ed +timeCreated: 1481126959 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Tools.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Tools.meta new file mode 100644 index 00000000..4f191887 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Tools.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 3857a2f02c659104fa6f0fe94cfe00dd +folderAsset: yes +timeCreated: 1481126945 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Tools/ToolsMenuButton.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Tools/ToolsMenuButton.cs new file mode 100644 index 00000000..a1994638 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Tools/ToolsMenuButton.cs @@ -0,0 +1,249 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using UnityEngine; +using UnityEditor; +using System.Collections.Generic; + +namespace AmplifyShaderEditor +{ + public sealed class ToolsMenuButton : ToolsMenuButtonParent + { + public delegate void ToolButtonPressed( ToolButtonType type ); + public event ToolButtonPressed ToolButtonPressedEvt; + + private Rect m_buttonArea; + private List<Texture2D> m_buttonTexture; + private string m_buttonTexturePath; + private ToolButtonType m_buttonType; + private GUIStyle m_style; + private bool m_enabled = true; + private bool m_drawOnFunction = true; + + private List<string> m_cachedStates; + private int m_bufferedState = -1; + private string m_bufferedTooltip = string.Empty; + + public ToolsMenuButton( AmplifyShaderEditorWindow parentWindow, ToolButtonType type, float x, float y, float width, float height, string texturePath, string text, string tooltip, float buttonSpacing = -1, bool drawOnFunction = true ) : base( parentWindow, text, tooltip, buttonSpacing ) + { + m_buttonArea = new Rect( x, y, width, height ); + m_buttonType = type; + + m_buttonTexturePath = texturePath; + m_cachedStates = new List<string>(); + m_drawOnFunction = drawOnFunction; + } + + public void AddState( string state ) + { + m_cachedStates.Add( state ); + } + + public override void Destroy() + { + ToolButtonPressedEvt = null; + if ( m_buttonTexture != null ) + { + for ( int i = 0; i < m_buttonTexture.Count; i++ ) + { + Resources.UnloadAsset( m_buttonTexture[ i ] ); + } + m_buttonTexture.Clear(); + } + m_buttonTexture = null; + } + protected override void Init() + { + base.Init(); + if ( m_buttonTexture == null ) + { + m_buttonTexturePath = AssetDatabase.GUIDToAssetPath( m_buttonTexturePath ); + m_buttonTexture = new List<Texture2D>(); + m_buttonTexture.Add( AssetDatabase.LoadAssetAtPath( m_buttonTexturePath, typeof( Texture2D ) ) as Texture2D ); + } + + if ( m_cachedStates.Count > 0 ) + { + for ( int i = 0; i < m_cachedStates.Count; i++ ) + { + m_cachedStates[ i ] = AssetDatabase.GUIDToAssetPath( m_cachedStates[ i ] ); + m_buttonTexture.Add( AssetDatabase.LoadAssetAtPath( m_cachedStates[ i ], typeof( Texture2D ) ) as Texture2D ); + } + m_cachedStates.Clear(); + } + + if ( m_style == null ) + { + m_style = new GUIStyle( /*UIUtils.Button*/ GUIStyle.none ); + m_style.normal.background = m_buttonTexture[ 0 ]; + + m_style.hover.background = m_buttonTexture[ 0 ]; + m_style.hover.textColor = m_style.normal.textColor; + + m_style.active.background = m_buttonTexture[ 0 ]; + m_style.active.textColor = m_style.normal.textColor; + + m_style.onNormal.background = m_buttonTexture[ 0 ]; + m_style.onNormal.textColor = m_style.normal.textColor; + + m_style.onHover.background = m_buttonTexture[ 0 ]; + m_style.onHover.textColor = m_style.normal.textColor; + + m_style.onActive.background = m_buttonTexture[ 0 ]; + m_style.onActive.textColor = m_style.normal.textColor; + + m_style.clipping = TextClipping.Overflow; + m_style.fontStyle = FontStyle.Bold; + m_style.alignment = TextAnchor.LowerCenter; + m_style.contentOffset = new Vector2( 0, 15 ); + m_style.fontSize = 10; + bool resizeFromTexture = false; + if ( m_buttonArea.width > 0 ) + { + m_style.fixedWidth = m_buttonArea.width; + } + else + { + resizeFromTexture = true; + } + + if ( m_buttonArea.height > 0 ) + { + m_style.fixedHeight = m_buttonArea.height; + } + else + { + resizeFromTexture = true; + } + + if ( resizeFromTexture ) + { + m_buttonArea.width = m_style.fixedWidth = m_buttonTexture[ 0 ].width; + m_buttonArea.height = m_style.fixedHeight = m_buttonTexture[ 0 ].height; + } + } + + } + public override void Draw() + { + base.Draw(); + bool guiEnabledBuffer = GUI.enabled; + GUI.enabled = m_enabled; + + if ( GUILayout.Button( m_content, m_style ) && ToolButtonPressedEvt != null ) + { + ToolButtonPressedEvt( m_buttonType ); + } + GUI.enabled = guiEnabledBuffer; + } + + public override void Draw( float x, float y ) + { + if ( !(m_parentWindow.CameraDrawInfo.CurrentEventType == EventType.MouseDown || m_parentWindow.CameraDrawInfo.CurrentEventType == EventType.Repaint ) ) + return; + + if ( m_parentWindow.CurrentGraph.CurrentMasterNode == null && !m_drawOnFunction) + return; + + + base.Draw( x, y ); + + if ( m_bufferedState > -1 ) + { + if ( string.IsNullOrEmpty( m_bufferedTooltip ) ) + { + SetStateOnButton( m_bufferedState ); + } + else + { + SetStateOnButton( m_bufferedState, m_bufferedTooltip ); + } + + m_bufferedState = -1; + m_bufferedTooltip = string.Empty; + } + + + m_buttonArea.x = x; + m_buttonArea.y = y; + + if ( m_parentWindow.CameraDrawInfo.CurrentEventType == EventType.MouseDown && m_buttonArea.Contains( m_parentWindow.CameraDrawInfo.MousePosition ) && ToolButtonPressedEvt != null ) + { + ToolButtonPressedEvt( m_buttonType ); + Event.current.Use(); + m_parentWindow.CameraDrawInfo.CurrentEventType = EventType.Used; + } + else if ( m_parentWindow.CameraDrawInfo.CurrentEventType == EventType.Repaint ) + { + GUI.Label( m_buttonArea, m_content, m_style ); + } + + //if ( GUI.Button( m_buttonArea, m_content, m_style ) && ToolButtonPressedEvt != null ) + //{ + // ToolButtonPressedEvt( m_buttonType ); + //} + } + + public override void Draw( Vector2 pos ) + { + Draw( pos.x, pos.y ); + } + + public override void SetStateOnButton( int state, string tooltip ) + { + + if ( m_buttonTexture == null || m_style == null ) + { + m_bufferedState = state; + m_bufferedTooltip = tooltip; + return; + } + + + if ( state < 0 || state >= m_buttonTexture.Count ) + { + return; + } + + base.SetStateOnButton( state, tooltip ); + m_style.normal.background = m_buttonTexture[ state ]; + m_style.hover.background = m_buttonTexture[ state ]; + m_style.active.background = m_buttonTexture[ state ]; + m_style.onNormal.background = m_buttonTexture[ state ]; + m_style.onHover.background = m_buttonTexture[ state ]; + m_style.onActive.background = m_buttonTexture[ state ]; + } + + public override void SetStateOnButton( int state ) + { + if ( m_buttonTexture == null || m_style == null ) + { + m_bufferedState = state; + return; + } + + if ( state < 0 || state >= m_buttonTexture.Count ) + { + return; + } + base.SetStateOnButton( state ); + m_style.normal.background = m_buttonTexture[ state ]; + m_style.hover.background = m_buttonTexture[ state ]; + m_style.active.background = m_buttonTexture[ state ]; + m_style.onNormal.background = m_buttonTexture[ state ]; + m_style.onHover.background = m_buttonTexture[ state ]; + m_style.onActive.background = m_buttonTexture[ state ]; + } + + public bool IsInside( Vector2 pos ) + { + return m_buttonArea.Contains( pos ); + } + + public bool Enabled + { + get { return m_enabled; } + set { m_enabled = value; } + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Tools/ToolsMenuButton.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Tools/ToolsMenuButton.cs.meta new file mode 100644 index 00000000..11180c87 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Tools/ToolsMenuButton.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 890f4ed5c9f62af43bda6584705fa0be +timeCreated: 1481126957 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Tools/ToolsMenuButtonParent.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Tools/ToolsMenuButtonParent.cs new file mode 100644 index 00000000..b3136b4c --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Tools/ToolsMenuButtonParent.cs @@ -0,0 +1,75 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using UnityEngine; + +namespace AmplifyShaderEditor +{ + public class ToolsMenuButtonParent + { + protected AmplifyShaderEditorWindow m_parentWindow = null; + private float m_buttonSpacing = 10; + private int m_currentState = 0; + private bool m_isInitialized = false; + protected GUIContent m_content; + public ToolsMenuButtonParent( AmplifyShaderEditorWindow parentWindow, string text, string tooltip, float buttonSpacing ) + { + m_parentWindow = parentWindow; + m_content = new GUIContent( text, tooltip ); + + if ( buttonSpacing > 0 ) + m_buttonSpacing = buttonSpacing; + } + + public virtual void Draw() + { + if ( !m_isInitialized ) + { + Init(); + } + + //GUILayout.Space( m_buttonSpacing ); + } + + public virtual void Draw( Vector2 pos ) + { + Draw( pos.x, pos.y ); + } + + public virtual void Draw( float x ,float y ) + { + if ( !m_isInitialized ) + { + Init(); + } + } + + protected virtual void Init() + { + m_isInitialized = false; + } + + public virtual void SetStateOnButton( int state, string tooltip ) + { + m_currentState = state; + m_content.tooltip = tooltip; + } + + public virtual void SetStateOnButton( int state ) + { + m_currentState = state; + } + + public virtual void Destroy() { } + + public float ButtonSpacing + { + get { return m_buttonSpacing; } + } + + public int CurrentState + { + get { return m_currentState; } + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Tools/ToolsMenuButtonParent.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Tools/ToolsMenuButtonParent.cs.meta new file mode 100644 index 00000000..b14de18d --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Tools/ToolsMenuButtonParent.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: a3bf3644c2c2fbb4fa0dd8b86effc6e1 +timeCreated: 1481126958 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Tools/ToolsMenuButtonSep.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Tools/ToolsMenuButtonSep.cs new file mode 100644 index 00000000..69d11eb1 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Tools/ToolsMenuButtonSep.cs @@ -0,0 +1,41 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using UnityEngine; +using UnityEditor; + +namespace AmplifyShaderEditor +{ + public sealed class ToolsMenuButtonSep : ToolsMenuButtonParent + { + private Color m_splitterColor = EditorGUIUtility.isProSkin ? new Color( 0.157f, 0.157f, 0.157f ) : new Color( 0.5f, 0.5f, 0.5f ); + [SerializeField] + private GUIStyle m_sepStyle; + public ToolsMenuButtonSep( AmplifyShaderEditorWindow parentWindow = null, string text = null, string tooltip = null, float buttonSpacing = -1 ) : base( parentWindow, text, tooltip, buttonSpacing ) { } + + public override void Draw() + { + base.Draw(); + if ( m_sepStyle == null ) + { + m_sepStyle = new GUIStyle(); + m_sepStyle.normal.background = Texture2D.whiteTexture; + m_sepStyle.hover.background = Texture2D.whiteTexture; + m_sepStyle.active.background = Texture2D.whiteTexture; + m_sepStyle.onNormal.background = Texture2D.whiteTexture; + m_sepStyle.onHover.background = Texture2D.whiteTexture; + m_sepStyle.onActive.background = Texture2D.whiteTexture; + m_sepStyle.stretchHeight = true; + } + Color originalColor = GUI.color; + GUI.color = m_splitterColor; + GUILayout.Box( string.Empty, m_sepStyle, GUILayout.MaxWidth( 2 ), GUILayout.ExpandHeight( true ) ); + GUI.color = originalColor; + } + + public override void Destroy() + { + m_sepStyle = null; + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Tools/ToolsMenuButtonSep.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Tools/ToolsMenuButtonSep.cs.meta new file mode 100644 index 00000000..55672938 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Tools/ToolsMenuButtonSep.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: b4c65a9d96791c34eb587cea9662161f +timeCreated: 1481126958 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Tools/ToolsWindow.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Tools/ToolsWindow.cs new file mode 100644 index 00000000..ccb0f4b0 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Tools/ToolsWindow.cs @@ -0,0 +1,632 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using UnityEngine; +using UnityEditor; +using System; +using System.Collections.Generic; + +namespace AmplifyShaderEditor +{ + public enum ToolButtonType + { + Update = 0, + Live, + OpenSourceCode, + CleanUnusedNodes, + //SelectShader, + New, + Open, + Save, + Library, + Options, + Help, + MasterNode, + FocusOnMasterNode, + FocusOnSelection, + ShowInfoWindow, + ShowTipsWindow, + ShowConsole, + TakeScreenshot, + Share + } + + public enum ToolbarType + { + File, + Help + } + + public class ToolbarMenuTab + { + private Rect m_tabArea; + private GenericMenu m_tabMenu; + public ToolbarMenuTab( float x, float y, float width, float height ) + { + m_tabMenu = new GenericMenu(); + m_tabArea = new Rect( x, y, width, height ); + } + + public void ShowMenu() + { + m_tabMenu.DropDown( m_tabArea ); + } + + public void AddItem( string itemName, GenericMenu.MenuFunction callback ) + { + m_tabMenu.AddItem( new GUIContent( itemName ), false, callback ); + } + } + + [Serializable] + public sealed class ToolsWindow : MenuParent + { + private static readonly Color RightIconsColorOff = new Color( 1f, 1f, 1f, 0.8f ); + private static readonly Color LeftIconsColorOff = new Color( 1f, 1f, 1f, 0.5f ); + + private static readonly Color RightIconsColorOn = new Color( 1f, 1f, 1f, 1.0f ); + private static readonly Color LeftIconsColorOn = new Color( 1f, 1f, 1f, 0.8f ); + + private const float TabY = 9; + private const float TabX = 5; + private const string ShaderFileTitleStr = "Current Shader"; + private const string FileToolbarStr = "File"; + private const string HelpToolbarStr = "Help"; + private const string LiveShaderStr = "Live Shader"; + private const string LoadOnSelectionStr = "Load on selection"; + private const string CurrentObjectStr = "Current Object: "; + + + public ToolsMenuButton.ToolButtonPressed ToolButtonPressedEvt; + //private GUIStyle m_toolbarButtonStyle; + private GUIStyle m_toggleStyle; + private GUIStyle m_borderStyle; + + // left + private ToolsMenuButton m_updateButton; + private ToolsMenuButton m_liveButton; + private ToolsMenuButton m_openSourceCodeButton; + + //middle right + private ToolsMenuButton m_cleanUnusedNodesButton; + private ToolsMenuButton m_focusOnMasterNodeButton; + private ToolsMenuButton m_focusOnSelectionButton; + + // right + private ToolsMenuButton m_shareButton; + private ToolsMenuButton m_takeScreenshotButton; + private ToolsMenuButton m_showInfoWindowButton; + + // hidden + private ToolsMenuButton m_showTipsWindowButton; + private ToolsMenuButton m_showConsoleWindowButton; + + //Used for collision detection to invalidate inputs on graph area + private Rect m_areaLeft = new Rect( 0, 0, 140, 40 ); + private Rect m_areaRight = new Rect( 0, 0, 75, 40 ); + private Rect m_boxRect; + private Rect m_borderRect; + + public const double InactivityRefreshTime = 0.25; + private int m_currentSelected = 0; + + //Search Bar + private const string SearchBarId = "ASE_SEARCH_BAR"; + private bool m_searchBarVisible = false; + private bool m_selectSearchBarTextfield = false; + private bool m_refreshSearchResultList = false; + + private Rect m_searchBarSize; + private string m_searchBarValue = string.Empty; + private List<ParentNode> m_searchResultNodes = new List<ParentNode>(); + + // width and height are between [0,1] and represent a percentage of the total screen area + public ToolsWindow( AmplifyShaderEditorWindow parentWindow ) : base( parentWindow, 0, 0, 0, 64, "Tools", MenuAnchor.TOP_LEFT, MenuAutoSize.NONE ) + { + m_updateButton = new ToolsMenuButton( m_parentWindow, ToolButtonType.Update, 0, 0, -1, -1, IOUtils.UpdateOutdatedGUID, string.Empty, "Create and apply shader to material.", 5 ); + m_updateButton.ToolButtonPressedEvt += OnButtonPressedEvent; + m_updateButton.AddState( IOUtils.UpdateOFFGUID ); + m_updateButton.AddState( IOUtils.UpdateUpToDatedGUID ); + + m_liveButton = new ToolsMenuButton( m_parentWindow, ToolButtonType.Live, 0, 0, -1, -1, IOUtils.LiveOffGUID, string.Empty, "Automatically saves shader when canvas is changed.", 50 ); + m_liveButton.ToolButtonPressedEvt += OnButtonPressedEvent; + m_liveButton.AddState( IOUtils.LiveOnGUID ); + m_liveButton.AddState( IOUtils.LivePendingGUID ); + + //ToolsMenuButton cleanUnusedNodesButton = new ToolsMenuButton( m_parentWindow, ToolButtonType.CleanUnusedNodes, 0, 0, -1, -1, IOUtils.CleanupOFFGUID, string.Empty, "Remove all nodes not connected to the master node.", 77 ); + //cleanUnusedNodesButton.ToolButtonPressedEvt += OnButtonPressedEvent; + //cleanUnusedNodesButton.AddState( IOUtils.CleanUpOnGUID ); + //m_list[ ( int ) ToolButtonType.CleanUnusedNodes ] = cleanUnusedNodesButton; + + m_openSourceCodeButton = new ToolsMenuButton( m_parentWindow, ToolButtonType.OpenSourceCode, 0, 0, -1, -1, IOUtils.OpenSourceCodeOFFGUID, string.Empty, "Open shader file in your default shader editor.", 80, false ); + m_openSourceCodeButton.ToolButtonPressedEvt += OnButtonPressedEvent; + m_openSourceCodeButton.AddState( IOUtils.OpenSourceCodeONGUID ); + + + // middle right + m_cleanUnusedNodesButton = new ToolsMenuButton( m_parentWindow, ToolButtonType.CleanUnusedNodes, 0, 0, -1, -1, IOUtils.CleanupOFFGUID, string.Empty, "Remove all nodes not connected to the master node.", 77 ); + m_cleanUnusedNodesButton.ToolButtonPressedEvt += OnButtonPressedEvent; + m_cleanUnusedNodesButton.AddState( IOUtils.CleanUpOnGUID ); + + m_focusOnMasterNodeButton = new ToolsMenuButton( m_parentWindow, ToolButtonType.FocusOnMasterNode, 0, 0, -1, -1, IOUtils.FocusNodeGUID, string.Empty, "Focus on active master node.", -1, false ); + m_focusOnMasterNodeButton.ToolButtonPressedEvt += OnButtonPressedEvent; + + m_focusOnSelectionButton = new ToolsMenuButton( m_parentWindow, ToolButtonType.FocusOnSelection, 0, 0, -1, -1, IOUtils.FitViewGUID, string.Empty, "Focus on selection or fit to screen if none selected." ); + m_focusOnSelectionButton.ToolButtonPressedEvt += OnButtonPressedEvent; + + + // right + m_shareButton = new ToolsMenuButton( m_parentWindow, ToolButtonType.Share, 0, 0, -1, -1, IOUtils.ShareOFFGUID, string.Empty, "Share selection", 100 ); + m_shareButton.ToolButtonPressedEvt += OnButtonPressedEvent; + m_shareButton.AddState( IOUtils.ShareONGUID ); + + m_takeScreenshotButton = new ToolsMenuButton( m_parentWindow, ToolButtonType.TakeScreenshot, 0, 0, -1, -1, IOUtils.TakeScreenshotOFFGUID, string.Empty, "Take ScreenShot (WINDOWS ONLY).", 100 ); + m_takeScreenshotButton.ToolButtonPressedEvt += OnButtonPressedEvent; + m_takeScreenshotButton.AddState( IOUtils.TakeScreenshotONGUID ); + + m_showInfoWindowButton = new ToolsMenuButton( m_parentWindow, ToolButtonType.ShowInfoWindow, 0, 0, -1, -1, IOUtils.ShowInfoWindowGUID, string.Empty, "Open Helper Window." ); + m_showInfoWindowButton.ToolButtonPressedEvt += OnButtonPressedEvent; + + + // hidden + m_showTipsWindowButton = new ToolsMenuButton( m_parentWindow, ToolButtonType.ShowTipsWindow, 0, 0, -1, -1, IOUtils.ShowTipsWindowGUID, string.Empty, "Open Quick Tips!" ); + m_showTipsWindowButton.ToolButtonPressedEvt += OnButtonPressedEvent; + + m_showConsoleWindowButton = new ToolsMenuButton( m_parentWindow, ToolButtonType.ShowConsole, 0, 0, -1, -1, IOUtils.ShowConsoleWindowGUID, string.Empty, "Show internal console", 74 ); + m_showConsoleWindowButton.ToolButtonPressedEvt += OnButtonPressedEvent; + m_showConsoleWindowButton.AddState( IOUtils.ShowConsoleWindowGUID ); + + m_searchBarSize = new Rect( 0, TabY + 4, 110, 60 ); + } + + void OnShowPortLegend() + { + ParentWindow.ShowPortInfo(); + } + + override public void Destroy() + { + base.Destroy(); + //for ( int i = 0; i < m_list.Length; i++ ) + //{ + // m_list[ i ].Destroy(); + //} + //m_list = null; + + m_searchResultNodes.Clear(); + m_searchResultNodes = null; + + m_updateButton.Destroy(); + m_updateButton = null; + + m_liveButton.Destroy(); + m_liveButton = null; + + m_openSourceCodeButton.Destroy(); + m_openSourceCodeButton = null; + + m_focusOnMasterNodeButton.Destroy(); + m_focusOnMasterNodeButton = null; + + m_focusOnSelectionButton.Destroy(); + m_focusOnSelectionButton = null; + + m_showInfoWindowButton.Destroy(); + m_showInfoWindowButton = null; + + m_takeScreenshotButton.Destroy(); + m_takeScreenshotButton = null; + + m_shareButton.Destroy(); + m_shareButton = null; + + m_showTipsWindowButton.Destroy(); + m_showTipsWindowButton = null; + + m_cleanUnusedNodesButton.Destroy(); + m_cleanUnusedNodesButton = null; + + m_showConsoleWindowButton.Destroy(); + m_showConsoleWindowButton = null; + } + + void OnButtonPressedEvent( ToolButtonType type ) + { + if ( ToolButtonPressedEvt != null ) + ToolButtonPressedEvt( type ); + } + + public override void Draw( Rect parentPosition, Vector2 mousePosition, int mouseButtonId, bool hasKeyboadFocus ) + { + base.Draw( parentPosition, mousePosition, mouseButtonId, hasKeyboadFocus ); + + Color bufferedColor = GUI.color; + m_areaLeft.x = m_transformedArea.x + TabX; + m_areaRight.x = m_transformedArea.x + m_transformedArea.width - 75 - TabX; + + //if ( m_toolbarButtonStyle == null ) + //{ + // m_toolbarButtonStyle = new GUIStyle( UIUtils.Button ); + // m_toolbarButtonStyle.fixedWidth = 100; + //} + + if ( m_toggleStyle == null ) + { + m_toggleStyle = UIUtils.Toggle; + } + + //for ( int i = 0; i < m_list.Length; i++ ) + //{ + // GUI.color = m_list[ i ].IsInside( mousePosition ) ? LeftIconsColorOn : LeftIconsColorOff; + // m_list[ i ].Draw( TabX + m_transformedArea.x + m_list[ i ].ButtonSpacing, TabY ); + //} + GUI.color = m_updateButton.IsInside( mousePosition ) ? LeftIconsColorOn : LeftIconsColorOff; + m_updateButton.Draw( TabX + m_transformedArea.x + m_updateButton.ButtonSpacing, TabY ); + + GUI.color = m_liveButton.IsInside( mousePosition ) ? LeftIconsColorOn : LeftIconsColorOff; + m_liveButton.Draw( TabX + m_transformedArea.x + m_liveButton.ButtonSpacing, TabY ); + + GUI.color = m_openSourceCodeButton.IsInside( mousePosition ) ? LeftIconsColorOn : LeftIconsColorOff; + m_openSourceCodeButton.Draw( TabX + m_transformedArea.x + m_openSourceCodeButton.ButtonSpacing, TabY ); + + if ( m_searchBarVisible ) + { + m_searchBarSize.x = m_transformedArea.x + m_transformedArea.width - 320 - TabX; + string currentFocus = GUI.GetNameOfFocusedControl(); + + if ( Event.current.type == EventType.KeyDown ) + { + KeyCode keyCode = Event.current.keyCode; + if ( Event.current.shift ) + { + if ( keyCode == KeyCode.F3 || + ( ( keyCode == KeyCode.KeypadEnter || keyCode == KeyCode.Return ) && + ( currentFocus.Equals( SearchBarId ) || string.IsNullOrEmpty( currentFocus ) ) ) ) + SelectPrevious(); + } + else + { + if ( keyCode == KeyCode.F3 || + ( ( keyCode == KeyCode.KeypadEnter || keyCode == KeyCode.Return ) && + ( currentFocus.Equals( SearchBarId ) || string.IsNullOrEmpty( currentFocus ) ) ) ) + SelectNext(); + } + } + + if( currentFocus.Equals( SearchBarId ) || ( m_parentWindow.CameraDrawInfo.CurrentEventType == EventType.MouseDown && m_searchBarSize.Contains( m_parentWindow.CameraDrawInfo.MousePosition ) ) || m_selectSearchBarTextfield ) + { + EditorGUI.BeginChangeCheck(); + { + GUI.SetNextControlName( SearchBarId ); + m_searchBarValue = EditorGUI.TextField( m_searchBarSize, m_searchBarValue, UIUtils.ToolbarSearchTextfield ); + } + if ( EditorGUI.EndChangeCheck() ) + { + m_refreshSearchResultList = true; + } + } else + { + GUI.Label( m_searchBarSize, m_searchBarValue, UIUtils.ToolbarSearchTextfield ); + } + + m_searchBarSize.x += m_searchBarSize.width; + if ( m_parentWindow.CameraDrawInfo.CurrentEventType == EventType.MouseDown && m_searchBarSize.Contains( m_parentWindow.CameraDrawInfo.MousePosition ) ) + { + if ( string.IsNullOrEmpty( m_searchBarValue ) ) + { + m_searchBarVisible = false; + m_refreshSearchResultList = false; + } + else + { + m_searchBarValue = string.Empty; + m_searchResultNodes.Clear(); + m_currentSelected = -1; + } + } + + GUI.Label( m_searchBarSize, string.Empty, UIUtils.ToolbarSearchCancelButton ); + + + + if ( Event.current.isKey && Event.current.keyCode == KeyCode.Escape ) + { + m_searchBarVisible = false; + m_refreshSearchResultList = false; + GUI.FocusControl( null ); + m_selectSearchBarTextfield = false; + } + + if ( m_refreshSearchResultList && ( m_parentWindow.CurrentInactiveTime > InactivityRefreshTime ) ) + { + RefreshList(); + } + } + + if ( m_selectSearchBarTextfield ) + { + m_selectSearchBarTextfield = false; + EditorGUI.FocusTextInControl( SearchBarId ); + //GUI.FocusControl( SearchBarId ); + } + + //if ( Event.current.control && Event.current.isKey && Event.current.keyCode == KeyCode.F && Event.current.type == EventType.KeyDown ) + if( m_parentWindow.CurrentCommandName.Equals("Find") ) + { + if ( !m_searchBarVisible ) + { + m_searchBarVisible = true; + m_refreshSearchResultList = false; + } + m_selectSearchBarTextfield = true; + } + + GUI.color = m_shareButton.IsInside( mousePosition ) ? RightIconsColorOn : RightIconsColorOff; + m_shareButton.Draw( m_transformedArea.x + m_transformedArea.width - 195 - TabX, TabY ); + + GUI.color = m_takeScreenshotButton.IsInside( mousePosition ) ? RightIconsColorOn : RightIconsColorOff; + m_takeScreenshotButton.Draw( m_transformedArea.x + m_transformedArea.width - 165 - TabX, TabY ); + + + + GUI.color = m_focusOnSelectionButton.IsInside( mousePosition ) ? RightIconsColorOn : RightIconsColorOff; + m_focusOnSelectionButton.Draw( m_transformedArea.x + m_transformedArea.width - 120 - TabX, TabY ); + + GUI.color = m_focusOnMasterNodeButton.IsInside( mousePosition ) ? RightIconsColorOn : RightIconsColorOff; + m_focusOnMasterNodeButton.Draw( m_transformedArea.x + m_transformedArea.width - 85 - TabX, TabY ); + + GUI.color = m_cleanUnusedNodesButton.IsInside( mousePosition ) ? RightIconsColorOn : RightIconsColorOff; + m_cleanUnusedNodesButton.Draw( m_transformedArea.x + m_transformedArea.width - 50 - TabX, TabY ); + + GUI.color = m_showInfoWindowButton.IsInside( mousePosition ) ? RightIconsColorOn : RightIconsColorOff; + m_showInfoWindowButton.Draw( m_transformedArea.x + m_transformedArea.width - 25 - TabX, TabY ); + + + //GUI.color = m_showTipsWindowButton.IsInside( mousePosition ) ? RightIconsColorOn : RightIconsColorOff; + //m_showTipsWindowButton.Draw( m_transformedArea.x + m_transformedArea.width - 190 - TabX, TabY ); + + //GUI.color = m_showConsoleWindowButton.IsInside( mousePosition ) ? RightIconsColorOn : RightIconsColorOff; + //m_showConsoleWindowButton.Draw( m_transformedArea.x + m_transformedArea.width - 195 - TabX, TabY ); + + GUI.color = bufferedColor; + + } + + public void OnNodeRemovedFromGraph( ParentNode node ) + { + m_searchResultNodes.Remove( node ); + } + + int m_previousNodeCount = 0; + + void RefreshList() + { + m_refreshSearchResultList = false; + m_currentSelected = -1; + m_searchResultNodes.Clear(); + if ( !string.IsNullOrEmpty( m_searchBarValue ) ) + { + List<ParentNode> nodes = m_parentWindow.CurrentGraph.AllNodes; + int count = nodes.Count; + m_previousNodeCount = count; + for ( int i = 0; i < count; i++ ) + { + if ( nodes[ i ].CheckFindText( m_searchBarValue ) ) + { + m_searchResultNodes.Add( nodes[ i ] ); + } + } + } + } + + void SelectNext() + { + if ( m_refreshSearchResultList || m_parentWindow.CurrentGraph.AllNodes.Count != m_previousNodeCount ) + { + RefreshList(); + } + + if ( m_searchResultNodes.Count > 0 ) + { + m_currentSelected = ( m_currentSelected + 1 ) % m_searchResultNodes.Count; + m_parentWindow.FocusOnNode( m_searchResultNodes[ m_currentSelected ], 1, true ,true); + } + } + + void SelectPrevious() + { + if ( m_refreshSearchResultList || m_parentWindow.CurrentGraph.AllNodes.Count != m_previousNodeCount ) + { + RefreshList(); + } + + if ( m_searchResultNodes.Count > 0 ) + { + m_currentSelected = ( m_currentSelected > 1 ) ? ( m_currentSelected - 1 ) : ( m_searchResultNodes.Count - 1 ); + m_parentWindow.FocusOnNode( m_searchResultNodes[ m_currentSelected ], 1, true ); + } + } + + + public void SetStateOnButton( ToolButtonType button, int state, string tooltip ) + { + switch ( button ) + { + case ToolButtonType.New: + case ToolButtonType.Open: + case ToolButtonType.Save: + case ToolButtonType.Library: + case ToolButtonType.Options: + case ToolButtonType.Help: + case ToolButtonType.MasterNode: break; + case ToolButtonType.OpenSourceCode: + { + m_openSourceCodeButton.SetStateOnButton( state, tooltip ); + } + break; + case ToolButtonType.Update: + { + m_updateButton.SetStateOnButton( state, tooltip ); + } + break; + case ToolButtonType.Live: + { + m_liveButton.SetStateOnButton( state, tooltip ); + } + break; + case ToolButtonType.TakeScreenshot: + { + m_takeScreenshotButton.SetStateOnButton( state, tooltip ); + } + break; + case ToolButtonType.CleanUnusedNodes: + //case eToolButtonType.SelectShader: + { + m_cleanUnusedNodesButton.SetStateOnButton( state, tooltip ); + } + break; + case ToolButtonType.FocusOnMasterNode: + { + m_focusOnMasterNodeButton.SetStateOnButton( state, tooltip ); + } + break; + case ToolButtonType.FocusOnSelection: + { + m_focusOnSelectionButton.SetStateOnButton( state, tooltip ); + } + break; + case ToolButtonType.Share: + { + m_shareButton.SetStateOnButton( state, tooltip ); + } + break; + case ToolButtonType.ShowInfoWindow: + { + m_showInfoWindowButton.SetStateOnButton( state, tooltip ); + } + break; + case ToolButtonType.ShowTipsWindow: + { + m_showTipsWindowButton.SetStateOnButton( state, tooltip ); + } + break; + case ToolButtonType.ShowConsole: + { + m_showConsoleWindowButton.SetStateOnButton( state, tooltip ); + } + break; + } + } + + public void SetStateOnButton( ToolButtonType button, int state ) + { + switch ( button ) + { + case ToolButtonType.New: + case ToolButtonType.Open: + case ToolButtonType.Save: + case ToolButtonType.Library: + case ToolButtonType.Options: + case ToolButtonType.Help: + case ToolButtonType.MasterNode: break; + case ToolButtonType.OpenSourceCode: + { + m_openSourceCodeButton.SetStateOnButton( state ); + } + break; + case ToolButtonType.Update: + { + m_updateButton.SetStateOnButton( state ); + } + break; + case ToolButtonType.Live: + { + m_liveButton.SetStateOnButton( state ); + } + break; + case ToolButtonType.TakeScreenshot: + { + m_takeScreenshotButton.SetStateOnButton( state ); + } + break; + case ToolButtonType.CleanUnusedNodes: + //case eToolButtonType.SelectShader: + { + m_cleanUnusedNodesButton.SetStateOnButton( state ); + } + break; + case ToolButtonType.FocusOnMasterNode: + { + m_focusOnMasterNodeButton.SetStateOnButton( state ); + } + break; + case ToolButtonType.FocusOnSelection: + { + m_focusOnSelectionButton.SetStateOnButton( state ); + } + break; + case ToolButtonType.Share: + { + m_shareButton.SetStateOnButton( state ); + } + break; + case ToolButtonType.ShowInfoWindow: + { + m_showInfoWindowButton.SetStateOnButton( state ); + } + break; + case ToolButtonType.ShowTipsWindow: + { + m_showTipsWindowButton.SetStateOnButton( state ); + }break; + case ToolButtonType.ShowConsole: + { + m_showConsoleWindowButton.SetStateOnButton( state ); + } + break; + } + } + + public void DrawShaderTitle( MenuParent nodeParametersWindow, MenuParent paletteWindow, float availableCanvasWidth, float graphAreaHeight, string shaderName ) + { + float leftAdjust = nodeParametersWindow.IsMaximized ? nodeParametersWindow.RealWidth : 0; + float rightAdjust = paletteWindow.IsMaximized ? 0 : paletteWindow.RealWidth; + + m_boxRect = new Rect( leftAdjust + rightAdjust, 0, availableCanvasWidth, 35 ); + m_boxRect.x += paletteWindow.IsMaximized ? 0 : -paletteWindow.RealWidth; + m_boxRect.width += nodeParametersWindow.IsMaximized ? 0 : nodeParametersWindow.RealWidth; + m_boxRect.width += paletteWindow.IsMaximized ? 0 : paletteWindow.RealWidth; + m_borderRect = new Rect( m_boxRect ); + m_borderRect.height = graphAreaHeight; + + int extra = m_searchBarVisible ? (int)m_searchBarSize.width + 20: 0; + //m_boxRect.xMax -= ( paletteWindow.IsMaximized ? 195 : 230 ) + extra; + //m_boxRect.xMin += nodeParametersWindow.IsMaximized ? 95 : 145; + + UIUtils.ToolbarMainTitle.padding.right = ( paletteWindow.IsMaximized ? 195 : 230 ) + extra; + UIUtils.ToolbarMainTitle.padding.left = nodeParametersWindow.IsMaximized ? 110 : 145; + + if ( m_borderStyle == null ) + { + m_borderStyle = ( ParentWindow.CurrentGraph.CurrentMasterNode == null ) ? UIUtils.GetCustomStyle( CustomStyle.ShaderFunctionBorder ) : UIUtils.GetCustomStyle( CustomStyle.ShaderBorder ); + } + + GUI.Label( m_borderRect, shaderName, m_borderStyle ); + GUI.Label( m_boxRect, shaderName, UIUtils.ToolbarMainTitle ); + } + + public override bool IsInside( Vector2 position ) + { + if ( !m_isActive ) + return false; + + return m_boxRect.Contains( position ) || m_areaLeft.Contains( position ) || m_areaRight.Contains( position ); + } + + public GUIStyle BorderStyle + { + get { return m_borderStyle; } + set { m_borderStyle = value; } + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Tools/ToolsWindow.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Tools/ToolsWindow.cs.meta new file mode 100644 index 00000000..3bd8f546 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Menu/Tools/ToolsWindow.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: b1c1f3bedf849cb41a1648bf895bc0f7 +timeCreated: 1481126958 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: |