| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945 | // Amplify Shader Editor - Visual Shader Editing Tool// Copyright (c) Amplify Creations, Lda <info@amplify.pt>using UnityEngine;using UnityEditor;using System;using System.Linq;using System.Collections.Generic;namespace AmplifyShaderEditor{	[Serializable]	public class TemplateOptionsUIHelper	{		public struct ReadOptions		{			public string Name;			public string Selection;			public Int64 Timestamp;		}		private const string CustomOptionsLabel = " Custom Options";		private bool m_isSubShader = false;		[SerializeField]		private bool m_passCustomOptionsFoldout = true;		[SerializeField]		private string m_passCustomOptionsLabel = CustomOptionsLabel;		[SerializeField]		private int m_passCustomOptionsSizeCheck = 0;		[SerializeField]		private List<TemplateOptionUIItem> m_passCustomOptionsUI = new List<TemplateOptionUIItem>();		[NonSerialized]		private Dictionary<string, TemplateOptionUIItem> m_passCustomOptionsUIDict = new Dictionary<string, TemplateOptionUIItem>();		[NonSerialized]		private TemplateMultiPassMasterNode m_owner;		[NonSerialized]		private List<ReadOptions> m_readOptions = null;		[SerializeField]		private List<TemplateOptionPortItem> m_passCustomOptionsPorts = new List<TemplateOptionPortItem>();		public TemplateOptionsUIHelper( bool isSubShader )		{			m_isSubShader = isSubShader;		}		public void CopyOptionsValuesFrom( TemplateOptionsUIHelper origin )		{			for( int i = 0; i < origin.PassCustomOptionsUI.Count; i++ )			{				m_passCustomOptionsUI[ i ].CopyValuesFrom( origin.PassCustomOptionsUI[ i ] );			}		}		public void Destroy()		{			for( int i = 0; i < m_passCustomOptionsUI.Count; i++ )			{				m_passCustomOptionsUI[ i ].Destroy();			}			m_passCustomOptionsUI.Clear();			m_passCustomOptionsUI = null;			m_passCustomOptionsUIDict.Clear();			m_passCustomOptionsUIDict = null;			m_passCustomOptionsPorts.Clear();			m_passCustomOptionsPorts = null;		}		public void DrawCustomOptions( TemplateMultiPassMasterNode owner )		{			m_owner = owner;			if( m_passCustomOptionsUI.Count > 0 )			{				NodeUtils.DrawNestedPropertyGroup( ref m_passCustomOptionsFoldout, m_passCustomOptionsLabel, DrawCustomOptionsBlock );			}		}		public void DrawCustomOptionsBlock()		{			float currWidth = EditorGUIUtility.labelWidth;			float size = Mathf.Max( UIUtils.CurrentWindow.ParametersWindow.TransformedArea.width * 0.385f, 0 );			EditorGUIUtility.labelWidth = size;			for( int i = 0; i < m_passCustomOptionsUI.Count; i++ )			{				m_passCustomOptionsUI[ i ].Draw( m_owner );			}			EditorGUILayout.Space();			EditorGUIUtility.labelWidth = currWidth;		}		private InputPort MatchInputPortForTemplateAction( TemplateMultiPassMasterNode passMasterNode, TemplateActionItem action )		{			InputPort port;			if ( action.ActionDataIdx > -1 )			{				port = passMasterNode.GetInputPortByUniqueId( action.ActionDataIdx );			}			else			{				// @diogo: hacky.. but it'll have to do, for crude backwards compatibility				if ( action.ActionData.StartsWith( "_" ) )				{					port = passMasterNode.GetInputPortByExternalLinkId( action.ActionData );				}				else				{					port = passMasterNode.GetInputPortByName( action.ActionData );				}			}			return port;		}		private bool TestActionItemConditional( TemplateActionItem actionItem )		{			bool succeeded = true;			TemplateActionItemConditional conditional = actionItem.ActionConditional;			if ( conditional != null && conditional.IsValid )			{				TemplateOptionUIItem referenceItem = m_passCustomOptionsUI.Find( x => ( x.Options.Name.Equals( conditional.Option ) ) );				if ( referenceItem != null )				{					bool equal = conditional.Value.Equals( referenceItem.Options.Options[ referenceItem.CurrentOption ] );					if ( conditional.Condition == TemplateActionItemConditional.Conditional.Equal )					{						succeeded = equal;					}					else if ( conditional.Condition == TemplateActionItemConditional.Conditional.NotEqual )					{						succeeded = !equal;					}				}			}			return succeeded;		}		public void OnCustomOptionSelected( bool actionFromUser, bool isRefreshing, bool invertAction, TemplateMultiPassMasterNode owner, TemplateOptionUIItem uiItem, int recursionLevel, params TemplateActionItem[] validActions )		{			uiItem.CheckOnExecute = false;			for( int i = 0; i < validActions.Length; i++ )			{				// @diogo: test conditional before running				if ( !TestActionItemConditional( validActions[ i ] ) )				{					continue;				}				AseOptionsActionType actionType = validActions[ i ].ActionType;				if( invertAction )				{					if( !TemplateOptionsToolsHelper.InvertAction( validActions[ i ].ActionType, ref actionType ) )					{						continue;					}				}				switch( actionType )				{					case AseOptionsActionType.RefreshOption:					{						if ( !uiItem.IsVisible || recursionLevel > 0 )							break;						TemplateOptionUIItem item = m_passCustomOptionsUI.Find( x => ( x.Options.Name.Equals( validActions[ i ].ActionData ) ) );						if ( item != null )						{							item.Update( recursionLevel + 1, isRefreshing );						}						else						{							Debug.LogFormat( "Could not find Option {0} for action '{1}' on template {2}", validActions[ i ].ActionData, validActions[ i ].ActionType, owner.CurrentTemplate.DefaultShaderName );						}					}					break;					case AseOptionsActionType.ShowOption:					{						TemplateOptionUIItem item = m_passCustomOptionsUI.Find( x => ( x.Options.Name.Equals( validActions[ i ].ActionData ) ) );						if( item != null )						{							if( isRefreshing )							{								string optionId = validActions[ i ].PassName + validActions[ i ].ActionData + "Option";								owner.ContainerGraph.ParentWindow.TemplatesManagerInstance.SetOptionsValue( optionId, true );							}							// this prevents options from showing up when loading by checking if they were hidden by another option							// it works on the assumption that an option that may possible hide this one is checked first							if( !isRefreshing )								item.IsVisible = true;							else if( item.WasVisible )								item.IsVisible = true;							if( !invertAction && validActions[ i ].ActionDataIdx > -1 )								item.CurrentOption = validActions[ i ].ActionDataIdx;							item.CheckEnDisable( actionFromUser );						}						else						{							Debug.LogFormat( "Could not find Option {0} for action '{1}' on template {2}", validActions[ i ].ActionData, validActions[ i ].ActionType, owner.CurrentTemplate.DefaultShaderName );						}					}					break;					case AseOptionsActionType.HideOption:					{						TemplateOptionUIItem item = m_passCustomOptionsUI.Find( x => ( x.Options.Name.Equals( validActions[ i ].ActionData ) ) );						if( item != null )						{							bool flag = false;							if( isRefreshing )							{								string optionId = validActions[ i ].PassName + validActions[ i ].ActionData + "Option";								flag = owner.ContainerGraph.ParentWindow.TemplatesManagerInstance.SetOptionsValue( optionId, false );							}							item.IsVisible = false || flag;							if( !invertAction && validActions[ i ].ActionDataIdx > -1 )								item.CurrentOption = validActions[ i ].ActionDataIdx;							item.CheckEnDisable( actionFromUser );						}						else						{							Debug.LogFormat( "Could not find Option {0} for action '{1}' on template {2}", validActions[ i ].ActionData, validActions[ i ].ActionType, owner.CurrentTemplate.DefaultShaderName );						}					}					break;					case AseOptionsActionType.SetOption:					{						if( !uiItem.IsVisible )							break;						TemplateOptionUIItem item = m_passCustomOptionsUI.Find( x => ( x.Options.Name.Equals( validActions[ i ].ActionData ) ) );						if( item != null )						{							item.CurrentOption = validActions[ i ].ActionDataIdx;							item.Update( recursionLevel, isRefreshing );						}						else						{							Debug.LogFormat( "Could not find Option {0} for action '{1}' on template {2}", validActions[ i ].ActionData, validActions[ i ].ActionType, owner.CurrentTemplate.DefaultShaderName );						}					}					break;					case AseOptionsActionType.HidePort:					{						TemplateMultiPassMasterNode passMasterNode = owner;						if( !string.IsNullOrEmpty( validActions[ i ].PassName ) )						{							passMasterNode = owner.ContainerGraph.GetMasterNodeOfPass( validActions[ i ].PassName,owner.LODIndex );						}						if( passMasterNode != null )						{							InputPort port = MatchInputPortForTemplateAction( passMasterNode, validActions[ i ] );							if( port != null )							{								if( isRefreshing )								{									string optionId = validActions[ i ].PassName + port.Name;									owner.ContainerGraph.ParentWindow.TemplatesManagerInstance.SetOptionsValue( optionId, port.IsConnected );									port.Visible = port.IsConnected;								}								else								{									port.Visible = false;								}								passMasterNode.SizeIsDirty = true;							}							else							{								Debug.LogFormat( "Could not find port {0},{1} for action '{2}' on template {3}", validActions[ i ].ActionDataIdx, validActions[ i ].ActionData, validActions[ i ].ActionType, owner.CurrentTemplate.DefaultShaderName );							}						}						else						{							Debug.LogFormat( "Could not find pass {0} for action {1} '{2}' on template {3}", validActions[ i ].PassName, validActions[ i ].ActionType, validActions[ i ].ActionData, owner.CurrentTemplate.DefaultShaderName );						}					}					break;					case AseOptionsActionType.ShowPort:					{						if( !uiItem.IsVisible )							break;						TemplateMultiPassMasterNode passMasterNode = owner;						if( !string.IsNullOrEmpty( validActions[ i ].PassName ) )						{							passMasterNode = owner.ContainerGraph.GetMasterNodeOfPass( validActions[ i ].PassName, owner.LODIndex );						}						if( passMasterNode != null )						{							InputPort port = MatchInputPortForTemplateAction( passMasterNode, validActions[ i ] );							if( port != null )							{								if( isRefreshing )								{									string optionId = validActions[ i ].PassName + port.Name;									owner.ContainerGraph.ParentWindow.TemplatesManagerInstance.SetOptionsValue( optionId, true );								}								port.Visible = true;								passMasterNode.SizeIsDirty = true;							}							else							{								Debug.LogFormat( "Could not find port {0},{1} for action '{2}' on template {3}", validActions[ i ].ActionDataIdx, validActions[ i ].ActionData, validActions[ i ].ActionType, owner.CurrentTemplate.DefaultShaderName );							}						}						else						{							Debug.LogFormat( "Could not find pass {0} for action {1} '{2}' on template {3}", validActions[ i ].PassName, validActions[ i ].ActionType, validActions[ i ].ActionData, owner.CurrentTemplate.DefaultShaderName );						}					}					break;					case AseOptionsActionType.SetPortName:					{						if( !uiItem.IsVisible )							break;						TemplateMultiPassMasterNode passMasterNode = owner;						if( !string.IsNullOrEmpty( validActions[ i ].PassName ) )						{							passMasterNode = owner.ContainerGraph.GetMasterNodeOfPass( validActions[ i ].PassName, owner.LODIndex );						}						if( passMasterNode != null )						{							InputPort port = MatchInputPortForTemplateAction( passMasterNode, validActions[ i ] );							if( port != null )							{								port.Name = validActions[ i ].ActionData2;								passMasterNode.SizeIsDirty = true;							}							else							{								Debug.LogFormat( "Could not find port {0},{1} for action '{2}' on template {3}", validActions[ i ].ActionData, validActions[ i ].ActionType, validActions[ i ].ActionData, owner.CurrentTemplate.DefaultShaderName );							}						}						else						{							Debug.LogFormat( "Could not find pass {0}, {1} for action '{2}' on template {3}", validActions[ i ].PassName, validActions[ i ].ActionType, validActions[ i ].ActionData, owner.CurrentTemplate.DefaultShaderName );						}					}					break;					case AseOptionsActionType.SetDefine:					{						if( !uiItem.IsVisible )						{							uiItem.CheckOnExecute = true;							break;						}						//Debug.Log( "DEFINE " + validActions[ i ].ActionData );						if( validActions[ i ].AllPasses )						{							string actionData = validActions[ i ].ActionData;							string defineValue = string.Empty;							bool isPragma = false;							if( actionData.StartsWith( "pragma" ) )							{								defineValue = "#" + actionData;								isPragma = true;							}							else							{								defineValue = "#define " + validActions[ i ].ActionData;							}							if( isRefreshing )							{								owner.ContainerGraph.ParentWindow.TemplatesManagerInstance.SetOptionsValue( defineValue, true );							}							List<TemplateMultiPassMasterNode> nodes = owner.ContainerGraph.GetMultiPassMasterNodes( owner.LODIndex );							int count = nodes.Count;							for( int nodeIdx = 0; nodeIdx < count; nodeIdx++ )							{								nodes[ nodeIdx ].OptionsDefineContainer.AddDirective( defineValue, false, isPragma );							}						}						else if( !string.IsNullOrEmpty( validActions[ i ].PassName ) )						{							TemplateMultiPassMasterNode passMasterNode = owner.ContainerGraph.GetMasterNodeOfPass( validActions[ i ].PassName, owner.LODIndex );							if( passMasterNode != null )							{								string actionData = validActions[ i ].ActionData;								string defineValue = string.Empty;								bool isPragma = false;								if( actionData.StartsWith( "pragma" ) )								{									defineValue = "#" + actionData;									isPragma = true;								}								else								{									defineValue = "#define " + validActions[ i ].ActionData;								}								if( isRefreshing )								{									string optionsId = validActions[ i ].PassName + defineValue;									owner.ContainerGraph.ParentWindow.TemplatesManagerInstance.SetOptionsValue( optionsId, true );								}								passMasterNode.OptionsDefineContainer.AddDirective( defineValue, false, isPragma );							}							else							{								Debug.LogFormat( "Could not find pass {0} for action {1} '{2}' on template {3}", validActions[ i ].PassName, validActions[ i ].ActionType, validActions[ i ].ActionData, owner.CurrentTemplate.DefaultShaderName );							}						}						else						{							uiItem.CheckOnExecute = true;						}					}					break;					case AseOptionsActionType.RemoveDefine:					{						//Debug.Log( "UNDEFINE " + validActions[ i ].ActionData );						if( validActions[ i ].AllPasses )						{							string actionData = validActions[ i ].ActionData;							string defineValue = string.Empty;							if( actionData.StartsWith( "pragma" ) )							{								defineValue = "#" + actionData;							}							else							{								defineValue = "#define " + validActions[ i ].ActionData;							}							bool flag = false;							if( isRefreshing )							{								flag = owner.ContainerGraph.ParentWindow.TemplatesManagerInstance.SetOptionsValue( defineValue, false );							}							if( !flag )							{								List<TemplateMultiPassMasterNode> nodes = owner.ContainerGraph.GetMultiPassMasterNodes( owner.LODIndex );								int count = nodes.Count;								for( int nodeIdx = 0; nodeIdx < count; nodeIdx++ )								{									nodes[ nodeIdx ].OptionsDefineContainer.RemoveDirective( defineValue );								}							}						}						else if( !string.IsNullOrEmpty( validActions[ i ].PassName ) )						{							TemplateMultiPassMasterNode passMasterNode = owner.ContainerGraph.GetMasterNodeOfPass( validActions[ i ].PassName, owner.LODIndex );							if( passMasterNode != null )							{								string actionData = validActions[ i ].ActionData;								string defineValue = string.Empty;								if( actionData.StartsWith( "pragma" ) )								{									defineValue = "#" + actionData;								}								else								{									defineValue = "#define " + validActions[ i ].ActionData;								}								bool flag = false;								if( isRefreshing )								{									string optionId = validActions[ i ].PassName + defineValue;									flag = owner.ContainerGraph.ParentWindow.TemplatesManagerInstance.SetOptionsValue( optionId, false );								}								if( !flag )								{									passMasterNode.OptionsDefineContainer.RemoveDirective( defineValue );								}							}							else							{								Debug.LogFormat( "Could not find pass {0} for action {1} '{2}' on template {3}", validActions[ i ].PassName, validActions[ i ].ActionType, validActions[ i ].ActionData, owner.CurrentTemplate.DefaultShaderName );							}						}						else						{							uiItem.CheckOnExecute = false;						}					}					break;					case AseOptionsActionType.SetUndefine:					{						if( !uiItem.IsVisible )						{							uiItem.CheckOnExecute = true;							break;						}						if( validActions[ i ].AllPasses )						{							string defineValue = "#undef " + validActions[ i ].ActionData;							if( isRefreshing )							{								owner.ContainerGraph.ParentWindow.TemplatesManagerInstance.SetOptionsValue( defineValue, true );							}							List<TemplateMultiPassMasterNode> nodes = owner.ContainerGraph.GetMultiPassMasterNodes(owner.LODIndex);							int count = nodes.Count;							for( int nodeIdx = 0; nodeIdx < count; nodeIdx++ )							{								nodes[ nodeIdx ].OptionsDefineContainer.AddDirective( defineValue, false );							}						}						else if( !string.IsNullOrEmpty( validActions[ i ].PassName ) )						{							TemplateMultiPassMasterNode passMasterNode = owner.ContainerGraph.GetMasterNodeOfPass( validActions[ i ].PassName, owner.LODIndex );							if( passMasterNode != null )							{								string defineValue = "#undef " + validActions[ i ].ActionData;								if( isRefreshing )								{									string optionsId = validActions[ i ].PassName + defineValue;									owner.ContainerGraph.ParentWindow.TemplatesManagerInstance.SetOptionsValue( optionsId, true );								}								passMasterNode.OptionsDefineContainer.AddDirective( defineValue, false );							}							else							{								Debug.LogFormat( "Could not find pass {0} for action {1} '{2}' on template {3}", validActions[ i ].PassName, validActions[ i ].ActionType, validActions[ i ].ActionData, owner.CurrentTemplate.DefaultShaderName );							}						}						else						{							uiItem.CheckOnExecute = true;						}					}					break;					case AseOptionsActionType.RemoveUndefine:					{						if( validActions[ i ].AllPasses )						{							string defineValue = "#undef " + validActions[ i ].ActionData;							bool flag = false;							if( isRefreshing )							{								flag = owner.ContainerGraph.ParentWindow.TemplatesManagerInstance.SetOptionsValue( defineValue, false );							}							if( !flag )							{								List<TemplateMultiPassMasterNode> nodes = owner.ContainerGraph.GetMultiPassMasterNodes( owner.LODIndex );								int count = nodes.Count;								for( int nodeIdx = 0; nodeIdx < count; nodeIdx++ )								{									nodes[ nodeIdx ].OptionsDefineContainer.RemoveDirective( defineValue );								}							}						}						else if( !string.IsNullOrEmpty( validActions[ i ].PassName ) )						{							TemplateMultiPassMasterNode passMasterNode = owner.ContainerGraph.GetMasterNodeOfPass( validActions[ i ].PassName, owner.LODIndex );							if( passMasterNode != null )							{								bool flag = false;								string defineValue = "#undef " + validActions[ i ].ActionData;								if( isRefreshing )								{									string optionId = validActions[ i ].PassName + defineValue;									flag = owner.ContainerGraph.ParentWindow.TemplatesManagerInstance.SetOptionsValue( optionId, false );								}								if( !flag )								{									passMasterNode.OptionsDefineContainer.RemoveDirective( defineValue );								}							}							else							{								Debug.LogFormat( "Could not find pass {0} for action {1} '{2}' on template {3}", validActions[ i ].PassName, validActions[ i ].ActionType, validActions[ i ].ActionData, owner.CurrentTemplate.DefaultShaderName );							}						}						else						{							uiItem.CheckOnExecute = false;						}					}					break;					case AseOptionsActionType.ExcludePass:					{						string optionId = validActions[ i ].ActionData + "Pass";						//bool flag = isRefreshing ? owner.ContainerGraph.ParentWindow.TemplatesManagerInstance.SetOptionsValue( optionId, false ) : false;						//if( !flag )						//	owner.SetPassVisible( validActions[ i ].ActionData, false );						owner.ContainerGraph.ParentWindow.TemplatesManagerInstance.SetOptionsValue( optionId , false ) ;						owner.SetPassVisible( validActions[ i ].ActionData , false );					}					break;					case AseOptionsActionType.IncludePass:					{						if( !uiItem.IsVisible )							break;						string optionId = validActions[ i ].ActionData + "Pass";						owner.ContainerGraph.ParentWindow.TemplatesManagerInstance.SetOptionsValue( optionId, true );						owner.SetPassVisible( validActions[ i ].ActionData, true );					}					break;					case AseOptionsActionType.SetPropertyOnPass:					{						//Debug.Log( "PASSPROP " + validActions[ i ].ActionData );						//Refresh happens on hotcode reload and shader load and in those situation						// The property own serialization handles its setup						if( isRefreshing )							continue;						if( !string.IsNullOrEmpty( validActions[ i ].PassName ) )						{							TemplateMultiPassMasterNode passMasterNode = owner.ContainerGraph.GetMasterNodeOfPass( validActions[ i ].PassName, owner.LODIndex );							if( passMasterNode != null )							{								passMasterNode.SetPropertyActionFromItem( actionFromUser, passMasterNode.PassModule, validActions[ i ] );							}							else							{								Debug.LogFormat( "Could not find pass {0} for action {1} '{2}' on template {3}", validActions[ i ].PassName, validActions[ i ].ActionType, validActions[ i ].ActionData, owner.CurrentTemplate.DefaultShaderName );							}						}						else						{							owner.SetPropertyActionFromItem( actionFromUser, owner.PassModule, validActions[ i ] );						}					}					break;					case AseOptionsActionType.SetPropertyOnSubShader:					{						//Refresh happens on hotcode reload and shader load and in those situation						// The property own serialization handles its setup						if( isRefreshing )							continue;						owner.SetPropertyActionFromItem( actionFromUser, owner.SubShaderModule, validActions[ i ] );					}					break;					case AseOptionsActionType.SetShaderProperty:					{						//This action is only check when shader is compiled over						//the TemplateMultiPassMasterNode via the on CheckPropertyChangesOnOptions() method					}					break;					case AseOptionsActionType.ExcludeAllPassesBut:					{						//This action is only check when shader is compiled over						//the TemplateMultiPassMasterNode via the on CheckExcludeAllPassOptions() method					}					break;					case AseOptionsActionType.SetMaterialProperty:					{						if( isRefreshing )							continue;						if( !uiItem.IsVisible )							break;						if( owner.ContainerGraph.CurrentMaterial != null )						{							string prop = validActions[ i ].ActionData;							if( owner.ContainerGraph.CurrentMaterial.HasProperty( prop ) )							{								if( uiItem.Options.UIWidget == AseOptionsUIWidget.Float || uiItem.Options.UIWidget == AseOptionsUIWidget.FloatRange )									owner.ContainerGraph.CurrentMaterial.SetFloat( prop, uiItem.CurrentFieldValue );								else									owner.ContainerGraph.CurrentMaterial.SetInt( prop, (int)uiItem.CurrentFieldValue );								if( MaterialInspector.Instance != null )									MaterialInspector.Instance.Repaint();							}						}					}					break;				}			}		}		public void SetupCustomOptionsFromTemplate( TemplateMultiPassMasterNode owner, bool newTemplate )		{			TemplateOptionsContainer customOptionsContainer = m_isSubShader ? owner.SubShader.CustomOptionsContainer : owner.Pass.CustomOptionsContainer;			if( !newTemplate && customOptionsContainer.Body.Length == m_passCustomOptionsSizeCheck )			{				for( int i = 0; i < m_passCustomOptionsUI.Count; i++ )				{					if( m_passCustomOptionsUI[ i ].EmptyEvent )					{						if( m_isSubShader )						{							m_passCustomOptionsUI[ i ].OnActionPerformedEvt += owner.OnCustomSubShaderOptionSelected;						}						else						{							m_passCustomOptionsUI[ i ].OnActionPerformedEvt += owner.OnCustomPassOptionSelected;						}					}				}				return;			}			m_passCustomOptionsLabel = string.IsNullOrEmpty( customOptionsContainer.Name ) ? CustomOptionsLabel : " " + customOptionsContainer.Name;			for( int i = 0; i < m_passCustomOptionsUI.Count; i++ )			{				m_passCustomOptionsUI[ i ].Destroy();			}			m_passCustomOptionsUI.Clear();			m_passCustomOptionsUIDict.Clear();			m_passCustomOptionsPorts.Clear();			if( customOptionsContainer.Enabled )			{				m_passCustomOptionsSizeCheck = customOptionsContainer.Body.Length;				for( int i = 0; i < customOptionsContainer.Options.Length; i++ )				{					switch( customOptionsContainer.Options[ i ].Type )					{						case AseOptionsType.Option:						{							TemplateOptionUIItem item = new TemplateOptionUIItem( customOptionsContainer.Options[ i ] );							if( m_isSubShader )							{								item.OnActionPerformedEvt += owner.OnCustomSubShaderOptionSelected;							}							else							{								item.OnActionPerformedEvt += owner.OnCustomPassOptionSelected;							}							m_passCustomOptionsUI.Add( item );							m_passCustomOptionsUIDict.Add( customOptionsContainer.Options[ i ].Id, item );						}						break;						case AseOptionsType.Port:						{							TemplateOptionPortItem item = new TemplateOptionPortItem( owner, customOptionsContainer.Options[ i ] );							m_passCustomOptionsPorts.Add( item );							//if( m_isSubShader )							//{							//	if( string.IsNullOrEmpty( customOptionsContainer.Options[ i ].Id ) )							//	{							//		//No pass name selected. inject on all passes							//		TemplateOptionPortItem item = new TemplateOptionPortItem( owner, customOptionsContainer.Options[ i ] );							//		m_passCustomOptionsPorts.Add( item );							//	}							//	else if( customOptionsContainer.Options[ i ].Id.Equals( owner.PassName ) )							//	{							//		TemplateOptionPortItem item = new TemplateOptionPortItem( owner, customOptionsContainer.Options[ i ] );							//		m_passCustomOptionsPorts.Add( item );							//	}							//}							//else							//{							//	TemplateOptionPortItem item = new TemplateOptionPortItem( owner, customOptionsContainer.Options[ i ] );							//	m_passCustomOptionsPorts.Add( item );							//}						}						break;						case AseOptionsType.Field:						{							TemplateOptionUIItem item = new TemplateOptionUIItem( customOptionsContainer.Options[ i ] );							if( m_isSubShader )							{								item.OnActionPerformedEvt += owner.OnCustomSubShaderOptionSelected;							}							else							{								item.OnActionPerformedEvt += owner.OnCustomPassOptionSelected;							}							m_passCustomOptionsUI.Add( item );							m_passCustomOptionsUIDict.Add( customOptionsContainer.Options[ i ].Id, item );						}						break;					}				}			}			else			{				m_passCustomOptionsSizeCheck = 0;			}		}		public void SetCustomOptionsInfo( TemplateMultiPassMasterNode masterNode, ref MasterNodeDataCollector dataCollector )		{			if( masterNode == null )				return;			for( int i = 0; i < m_passCustomOptionsUI.Count; i++ )			{				m_passCustomOptionsUI[ i ].FillDataCollector( ref dataCollector );			}			for( int i = 0; i < m_passCustomOptionsPorts.Count; i++ )			{				m_passCustomOptionsPorts[ i ].FillDataCollector( masterNode, ref dataCollector );			}		}		public void CheckImediateActionsForPort( TemplateMultiPassMasterNode masterNode , int portId )		{			for( int i = 0; i < m_passCustomOptionsPorts.Count; i++ )			{				m_passCustomOptionsPorts[ i ].CheckImediateActionsForPort( masterNode, portId );			}		}		public void SetSubShaderCustomOptionsPortsInfo( TemplateMultiPassMasterNode masterNode, ref MasterNodeDataCollector dataCollector  )		{			if( masterNode == null )				return;			//for( int i = 0; i < m_passCustomOptionsPorts.Count; i++ )			//{			//	if( string.IsNullOrEmpty( m_passCustomOptionsPorts[ i ].Options.Id ) ||			//		masterNode.PassUniqueName.Equals( m_passCustomOptionsPorts[ i ].Options.Id ) )			//	{			//		m_passCustomOptionsPorts[ i ].FillDataCollector( masterNode, ref dataCollector );			//	}			//}			for( int i = 0; i < m_passCustomOptionsPorts.Count; i++ )			{				m_passCustomOptionsPorts[ i ].SubShaderFillDataCollector( masterNode, ref dataCollector );			}		}		public void RefreshCustomOptionsDict()		{			if( m_passCustomOptionsUIDict.Count != m_passCustomOptionsUI.Count )			{				m_passCustomOptionsUIDict.Clear();				int count = m_passCustomOptionsUI.Count;				for( int i = 0; i < count; i++ )				{					m_passCustomOptionsUIDict.Add( m_passCustomOptionsUI[ i ].Options.Id, m_passCustomOptionsUI[ i ] );				}			}		}		public void ReadFromString( ref uint index, ref string[] nodeParams )		{			RefreshCustomOptionsDict();			int savedOptions = Convert.ToInt32( nodeParams[ index++ ] );			m_readOptions = new List<ReadOptions>();			for( int i = 0; i < savedOptions; i++ )			{				string optionName = nodeParams[ index++ ];				string optionSelection = nodeParams[ index++ ];				Int64 optionTimestamp = ( UIUtils.CurrentShaderVersion() > 18929 ) ? Convert.ToInt64( nodeParams[ index++ ] ):0;				m_readOptions.Add( new ReadOptions() { Name = optionName , Selection = optionSelection , Timestamp = optionTimestamp });			}		}		public void WriteToString( ref string nodeInfo )		{			int optionsCount = m_passCustomOptionsUI.Count;			IOUtils.AddFieldValueToString( ref nodeInfo , optionsCount );			for( int i = 0 ; i < optionsCount ; i++ )			{				IOUtils.AddFieldValueToString( ref nodeInfo , m_passCustomOptionsUI[ i ].Options.Id );				if( m_passCustomOptionsUI[ i ].Options.Type == AseOptionsType.Field )					IOUtils.AddFieldValueToString( ref nodeInfo , m_passCustomOptionsUI[ i ].FieldValue.WriteToSingle() );				else					IOUtils.AddFieldValueToString( ref nodeInfo , m_passCustomOptionsUI[ i ].CurrentOption );				IOUtils.AddFieldValueToString( ref nodeInfo , m_passCustomOptionsUI[ i ].LastClickedTimestamp );			}		}		public void SetReadOptions()		{			if( m_readOptions != null )			{				for( int i = 0 ; i < m_readOptions.Count ; i++ )				{					if( m_passCustomOptionsUIDict.ContainsKey( m_readOptions[ i ].Name ) )					{						m_passCustomOptionsUIDict[ m_readOptions[ i ].Name ].LastClickedTimestamp = m_readOptions[ i ].Timestamp;						if( m_passCustomOptionsUIDict[ m_readOptions[ i ].Name ].Options.Type == AseOptionsType.Field )						{							m_passCustomOptionsUIDict[ m_readOptions[ i ].Name ].FieldValue.ReadFromSingle( m_readOptions[ i ].Selection );							foreach( var item in m_passCustomOptionsUIDict[ m_readOptions[ i ].Name ].Options.ActionsPerOption.Rows )							{								if( item.Columns.Length > 0 && item.Columns[ 0 ].ActionType == AseOptionsActionType.SetMaterialProperty )								{									if( UIUtils.CurrentWindow.CurrentGraph.CurrentMaterial != null )									{										if( UIUtils.CurrentWindow.CurrentGraph.CurrentMaterial.HasProperty( item.Columns[ 0 ].ActionData ) )										{											m_passCustomOptionsUIDict[ m_readOptions[ i ].Name ].CurrentFieldValue = UIUtils.CurrentWindow.CurrentGraph.CurrentMaterial.GetFloat( item.Columns[ 0 ].ActionData );										}									}								}							}						}						else							m_passCustomOptionsUIDict[ m_readOptions[ i ].Name ].CurrentOptionIdx = Convert.ToInt32( m_readOptions[ i ].Selection );					}				}			}		}		public void Refresh()		{			//int count = m_passCustomOptionsUI.Count;			//for( int i = 0; i < count; i++ )			//{			//	m_passCustomOptionsUI[ i ].Refresh();			//}			List<TemplateOptionUIItem> sortedList = m_passCustomOptionsUI.OrderBy( item => item.LastClickedTimestamp ).ToList();			int count = sortedList.Count;			for( int i = 0 ; i < count ; i++ )			{				sortedList[ i ].Update();			}		}		public void CheckDisable()		{			int count = m_passCustomOptionsUI.Count;			for( int i = 0; i < count; i++ )			{				m_passCustomOptionsUI[ i ].CheckEnDisable(false);			}		}		public List<TemplateOptionUIItem> PassCustomOptionsUI { get { return m_passCustomOptionsUI; } }	}}
 |