FunctionSwitch.cs 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886
  1. // Amplify Shader Editor - Visual Shader Editing Tool
  2. // Copyright (c) Amplify Creations, Lda <info@amplify.pt>
  3. using UnityEngine;
  4. using UnityEditor;
  5. using System;
  6. using System.Collections.Generic;
  7. namespace AmplifyShaderEditor
  8. {
  9. [Serializable]
  10. [NodeAttributes( "Function Switch", "Functions", "Function Switch allows switching options at compile time for shader function", NodeAvailabilityFlags = (int)NodeAvailability.ShaderFunction )]
  11. public sealed class FunctionSwitch : ParentNode
  12. {
  13. private const string InputPortNameStr = "In ";
  14. private const string ToggleFalseStr = "False";
  15. private const string ToggleTrueStr = "True";
  16. private const string CurrSelectedStr = "Current";
  17. private const string MaxAmountStr = "Amount";
  18. private const int MaxAllowedAmount = 10;
  19. private const int MinComboSize = 50;
  20. private const int MaxComboSize = 105;
  21. [SerializeField]
  22. private string m_optionLabel = "Option";
  23. [SerializeField]
  24. private string[] AvailableInputsLabels = { "In 0", "In 1" };
  25. [SerializeField]
  26. private int[] AvailableInputsValues = { 0, 1 };
  27. [SerializeField]
  28. private int m_previousSelectedInput = 0;
  29. [SerializeField]
  30. private int m_currentSelectedInput = 0;
  31. [SerializeField]
  32. private int m_maxAmountInputs = 2;
  33. [SerializeField]
  34. private bool m_toggleMode = false;
  35. [SerializeField]
  36. private string[] m_optionNames = { "In 0", "In 1", "In 2", "In 3", "In 4", "In 5", "In 6", "In 7", "In 8", "In 9" };
  37. [SerializeField]
  38. private int m_orderIndex = -1;
  39. [SerializeField]
  40. private TexReferenceType m_referenceType = TexReferenceType.Object;
  41. [SerializeField]
  42. private FunctionSwitch m_functionSwitchReference = null;
  43. [SerializeField]
  44. private int m_referenceUniqueId = -1;
  45. [SerializeField]
  46. private bool m_validReference = false;
  47. private bool m_asDrawn = false;
  48. private GUIContent m_checkContent;
  49. private GUIContent m_popContent;
  50. private const double MaxTimestamp = 1;
  51. private bool m_nameModified = false;
  52. private double m_lastTimeNameModified = 0;
  53. private Rect m_varRect;
  54. private Rect m_imgRect;
  55. private bool m_editing;
  56. private int m_cachedPropertyId = -1;
  57. private bool m_dirtySettings = false;
  58. [SerializeField]
  59. private int m_refMaxInputs = -1;
  60. [SerializeField]
  61. private string m_refOptionLabel = string.Empty;
  62. [SerializeField]
  63. private int m_refSelectedInput = -1;
  64. protected override void CommonInit( int uniqueId )
  65. {
  66. base.CommonInit( uniqueId );
  67. for( int i = 0; i < MaxAllowedAmount; i++ )
  68. {
  69. AddInputPort( WirePortDataType.FLOAT, false, InputPortNameStr + i );
  70. m_inputPorts[ i ].Visible = ( i < 2 );
  71. m_inputPorts[ i ].SetFreeForAll();
  72. }
  73. AddOutputPort( WirePortDataType.FLOAT, " " );
  74. m_checkContent = new GUIContent();
  75. m_checkContent.image = UIUtils.CheckmarkIcon;
  76. m_popContent = new GUIContent();
  77. m_popContent.image = UIUtils.PopupIcon;
  78. m_textLabelWidth = 100;
  79. m_autoWrapProperties = true;
  80. m_insideSize.Set( 80, 25 );
  81. m_previewShaderGUID = "a58e46feaa5e3d14383bfeac24d008bc";
  82. }
  83. public void SetCurrentSelectedInput( int newValue, int prevValue )
  84. {
  85. m_previousSelectedInput = prevValue;
  86. if( m_validReference )
  87. m_currentSelectedInput = Mathf.Clamp( newValue, 0, m_refMaxInputs - 1 );
  88. else
  89. m_currentSelectedInput = Mathf.Clamp( newValue, 0, m_maxAmountInputs - 1 );
  90. m_outputPorts[ 0 ].ChangeType( m_inputPorts[ m_currentSelectedInput ].DataType, false );
  91. PreviewIsDirty = true;
  92. ChangeSignalPropagation();
  93. }
  94. public int GetCurrentSelectedInput()
  95. {
  96. return m_currentSelectedInput;
  97. }
  98. public override void SetPreviewInputs()
  99. {
  100. base.SetPreviewInputs();
  101. if( m_cachedPropertyId == -1 )
  102. m_cachedPropertyId = Shader.PropertyToID( "_Current" );
  103. PreviewMaterial.SetInt( m_cachedPropertyId, m_currentSelectedInput );
  104. }
  105. protected override void OnUniqueIDAssigned()
  106. {
  107. base.OnUniqueIDAssigned();
  108. if( m_referenceType == TexReferenceType.Object )
  109. {
  110. UIUtils.RegisterFunctionSwitchNode( this );
  111. }
  112. else
  113. {
  114. if( ContainerGraph.ParentWindow.CustomGraph != null )
  115. UIUtils.RegisterFunctionSwitchNode( this );
  116. UIUtils.RegisterFunctionSwitchCopyNode( this );
  117. }
  118. }
  119. public override void Destroy()
  120. {
  121. base.Destroy();
  122. m_functionSwitchReference = null;
  123. m_referenceUniqueId = -1;
  124. if( m_referenceType == TexReferenceType.Object )
  125. {
  126. UIUtils.UnregisterFunctionSwitchNode( this );
  127. }
  128. else
  129. {
  130. UIUtils.UnregisterFunctionSwitchNode( this );
  131. UIUtils.UnregisterFunctionSwitchCopyNode( this );
  132. }
  133. }
  134. public override void OnConnectedOutputNodeChanges( int portId, int otherNodeId, int otherPortId, string name, WirePortDataType type )
  135. {
  136. base.OnConnectedOutputNodeChanges( portId, otherNodeId, otherPortId, name, type );
  137. m_inputPorts[ portId ].MatchPortToConnection();
  138. if( portId == m_currentSelectedInput )
  139. m_outputPorts[ 0 ].ChangeType( m_inputPorts[ portId ].DataType, false );
  140. }
  141. public override void OnInputPortConnected( int portId, int otherNodeId, int otherPortId, bool activateNode = true )
  142. {
  143. InputPort port = GetInputPortByUniqueId( portId );
  144. int arrayPos = m_inputPorts.IndexOf( port );
  145. if( activateNode && m_connStatus == NodeConnectionStatus.Connected && arrayPos == m_currentSelectedInput )
  146. {
  147. port.GetOutputNode().ActivateNode( m_activeNode, m_activePort, m_activeType );
  148. }
  149. OnNodeChange();
  150. SetSaveIsDirty();
  151. m_inputPorts[ portId ].MatchPortToConnection();
  152. if( arrayPos == m_currentSelectedInput )
  153. m_outputPorts[ 0 ].ChangeType( m_inputPorts[ portId ].DataType, false );
  154. }
  155. public override void ActivateNode( int signalGenNodeId, int signalGenPortId, Type signalGenNodeType )
  156. {
  157. if( m_selfPowered )
  158. return;
  159. ConnStatus = m_restrictions.GetRestiction( signalGenNodeType, signalGenPortId ) ? NodeConnectionStatus.Error : NodeConnectionStatus.Connected;
  160. m_activeConnections += 1;
  161. m_activeType = signalGenNodeType;
  162. m_activeNode = signalGenNodeId;
  163. m_activePort = signalGenPortId;
  164. if( m_activeConnections == 1 )
  165. if( m_inputPorts[ m_currentSelectedInput ].IsConnected )
  166. m_inputPorts[ m_currentSelectedInput ].GetOutputNode().ActivateNode( signalGenNodeId, signalGenPortId, signalGenNodeType );
  167. SetSaveIsDirty();
  168. }
  169. public override void DeactivateInputPortNode( int deactivatedPort, bool forceComplete )
  170. {
  171. InputPort port = GetInputPortByUniqueId( deactivatedPort );
  172. if( deactivatedPort == m_currentSelectedInput )
  173. port.GetOutputNode().DeactivateNode( deactivatedPort, false );
  174. }
  175. public override void DeactivateNode( int deactivatedPort, bool forceComplete )
  176. {
  177. if( m_selfPowered )
  178. return;
  179. SetSaveIsDirty();
  180. m_activeConnections -= 1;
  181. if( ( forceComplete || m_activeConnections <= 0 ) )
  182. {
  183. m_activeConnections = 0;
  184. ConnStatus = NodeConnectionStatus.Not_Connected;
  185. for( int i = 0; i < m_inputPorts.Count; i++ )
  186. {
  187. if( m_inputPorts[ i ].IsConnected && i == m_currentSelectedInput )
  188. {
  189. ParentNode node = m_inputPorts[ i ].GetOutputNode();
  190. if( node != null )
  191. node.DeactivateNode( deactivatedPort == -1 ? m_inputPorts[ i ].PortId : deactivatedPort, false );
  192. }
  193. }
  194. }
  195. }
  196. public void ChangeSignalPropagation()
  197. {
  198. if( m_previousSelectedInput != m_currentSelectedInput && ConnStatus == NodeConnectionStatus.Connected )
  199. {
  200. if( m_inputPorts[ m_previousSelectedInput ].IsConnected )
  201. m_inputPorts[ m_previousSelectedInput ].GetOutputNode().DeactivateNode( m_inputPorts[ m_previousSelectedInput ].PortId, false );
  202. if( m_inputPorts[ m_currentSelectedInput ].IsConnected )
  203. m_inputPorts[ m_currentSelectedInput ].GetOutputNode().ActivateNode( UniqueId, m_inputPorts[ m_currentSelectedInput ].PortId, m_activeType );
  204. }
  205. }
  206. public bool DrawOption( ParentNode owner, bool forceDraw = false )
  207. {
  208. if( !IsConnected && !forceDraw )
  209. {
  210. //EditorGUILayout.LabelField( "Not Connected" );
  211. return false;
  212. }
  213. if( m_asDrawn ) //used to prevent the same property to be drawn more than once
  214. return false;
  215. if( m_validReference )
  216. {
  217. return m_functionSwitchReference.DrawOption( owner, true );
  218. }
  219. int prev = m_currentSelectedInput;
  220. m_asDrawn = true;
  221. if( m_toggleMode )
  222. {
  223. m_currentSelectedInput = owner.EditorGUILayoutToggle( m_optionLabel, ( m_currentSelectedInput != 0 ? true : false ) ) ? 1 : 0;
  224. if( m_currentSelectedInput != prev )
  225. {
  226. SetCurrentSelectedInput( m_currentSelectedInput, prev );
  227. return true;
  228. }
  229. else
  230. {
  231. return false;
  232. }
  233. }
  234. else
  235. {
  236. m_currentSelectedInput = owner.EditorGUILayoutIntPopup( m_optionLabel, m_currentSelectedInput, AvailableInputsLabels, AvailableInputsValues );
  237. if( m_currentSelectedInput != prev )
  238. {
  239. SetCurrentSelectedInput( m_currentSelectedInput, prev );
  240. return true;
  241. }
  242. else
  243. {
  244. return false;
  245. }
  246. }
  247. }
  248. public void CheckReference()
  249. {
  250. if( m_referenceType != TexReferenceType.Instance )
  251. {
  252. m_validReference = false;
  253. return;
  254. }
  255. if( m_functionSwitchReference == null )
  256. {
  257. m_validReference = false;
  258. ResetToSelf();
  259. return;
  260. }
  261. if( m_referenceUniqueId != m_functionSwitchReference.UniqueId )
  262. {
  263. UpdateFromSelected();
  264. }
  265. if( m_refSelectedInput != m_functionSwitchReference.GetCurrentSelectedInput() || m_refMaxInputs != m_functionSwitchReference.MaxAmountInputs || m_refOptionLabel != m_functionSwitchReference.OptionLabel )
  266. {
  267. UpdateFromSelected();
  268. }
  269. if( m_functionSwitchReference.DirtySettings )
  270. {
  271. UpdateFromSelected();
  272. }
  273. m_validReference = true;
  274. }
  275. void ResetToSelf()
  276. {
  277. m_functionSwitchReference = null;
  278. m_validReference = false;
  279. m_referenceUniqueId = -1;
  280. m_refMaxInputs = -1;
  281. m_refOptionLabel = string.Empty;
  282. m_refSelectedInput = -1;
  283. for( int i = 0; i < MaxAllowedAmount; i++ )
  284. {
  285. m_inputPorts[ i ].Visible = ( i < m_maxAmountInputs );
  286. m_inputPorts[ i ].Name = m_optionNames[ i ];
  287. }
  288. if( m_currentSelectedInput >= m_maxAmountInputs )
  289. {
  290. m_currentSelectedInput = m_maxAmountInputs - 1;
  291. }
  292. UpdateLabels();
  293. m_sizeIsDirty = true;
  294. }
  295. void UpdateFromSelected()
  296. {
  297. if( m_referenceUniqueId < 0 )
  298. return;
  299. m_functionSwitchReference = UIUtils.GetNode( m_referenceUniqueId ) as FunctionSwitch;
  300. if( m_functionSwitchReference != null )
  301. {
  302. m_validReference = true;
  303. for( int i = 0; i < MaxAllowedAmount; i++ )
  304. {
  305. m_inputPorts[ i ].Visible = ( i < m_functionSwitchReference.MaxAmountInputs );
  306. m_inputPorts[ i ].Name = m_functionSwitchReference.InputPorts[ i ].Name;
  307. }
  308. UpdateLabels();
  309. m_refMaxInputs = m_functionSwitchReference.m_maxAmountInputs;
  310. m_refOptionLabel = m_functionSwitchReference.OptionLabel;
  311. m_refSelectedInput = m_functionSwitchReference.GetCurrentSelectedInput();
  312. OrderIndex = m_functionSwitchReference.OrderIndex;
  313. SetCurrentSelectedInput( m_functionSwitchReference.GetCurrentSelectedInput(), m_currentSelectedInput );
  314. }
  315. m_sizeIsDirty = true;
  316. m_isDirty = true;
  317. }
  318. public override void DrawProperties()
  319. {
  320. base.DrawProperties();
  321. EditorGUI.BeginChangeCheck();
  322. {
  323. EditorGUI.BeginChangeCheck();
  324. m_referenceType = (TexReferenceType)EditorGUILayoutPopup( Constants.ReferenceTypeStr, (int)m_referenceType, Constants.ReferenceArrayLabels );
  325. if( EditorGUI.EndChangeCheck() )
  326. {
  327. if( m_referenceType == TexReferenceType.Object )
  328. {
  329. if( ContainerGraph.ParentWindow.CustomGraph == null )
  330. UIUtils.UnregisterFunctionSwitchCopyNode( this );
  331. UIUtils.RegisterFunctionSwitchNode( this );
  332. ResetToSelf();
  333. }
  334. else
  335. {
  336. if( ContainerGraph.ParentWindow.CustomGraph == null )
  337. UIUtils.UnregisterFunctionSwitchNode( this );
  338. UIUtils.RegisterFunctionSwitchCopyNode( this );
  339. }
  340. }
  341. if( m_referenceType == TexReferenceType.Instance )
  342. {
  343. EditorGUI.BeginChangeCheck();
  344. string[] arr = new string[ UIUtils.FunctionSwitchList().Count ];
  345. int[] ids = new int[ UIUtils.FunctionSwitchList().Count ];
  346. for( int i = 0; i < arr.Length; i++ )
  347. {
  348. arr[ i ] = i + " - " + UIUtils.FunctionSwitchList()[ i ].OptionLabel;
  349. ids[ i ] = UIUtils.FunctionSwitchList()[ i ].UniqueId;
  350. }
  351. m_referenceUniqueId = EditorGUILayout.IntPopup( Constants.AvailableReferenceStr, m_referenceUniqueId, arr, ids );
  352. if( EditorGUI.EndChangeCheck() )
  353. {
  354. UpdateFromSelected();
  355. }
  356. return;
  357. }
  358. EditorGUI.BeginChangeCheck();
  359. m_optionLabel = EditorGUILayoutTextField( "Option Label", m_optionLabel );
  360. if( EditorGUI.EndChangeCheck() )
  361. {
  362. m_optionLabel = UIUtils.RemoveInvalidEnumCharacters( m_optionLabel );
  363. if( string.IsNullOrEmpty( m_optionLabel ) )
  364. {
  365. m_optionLabel = "Option";
  366. }
  367. UIUtils.UpdateFunctionSwitchData( UniqueId, m_optionLabel );
  368. }
  369. EditorGUI.BeginChangeCheck();
  370. m_toggleMode = EditorGUILayoutToggle( "Toggle Mode", m_toggleMode );
  371. if( EditorGUI.EndChangeCheck() )
  372. {
  373. if( m_toggleMode )
  374. {
  375. m_inputPorts[ 0 ].Name = ToggleFalseStr;
  376. m_inputPorts[ 1 ].Name = ToggleTrueStr;
  377. for( int i = 0; i < MaxAllowedAmount; i++ )
  378. {
  379. m_inputPorts[ i ].Visible = ( i < 2 );
  380. }
  381. if( m_currentSelectedInput >= 2 )
  382. {
  383. m_currentSelectedInput = 1;
  384. }
  385. UpdateLabels();
  386. m_sizeIsDirty = true;
  387. }
  388. else
  389. {
  390. m_inputPorts[ 0 ].Name = m_optionNames[ 0 ];
  391. m_inputPorts[ 1 ].Name = m_optionNames[ 1 ];
  392. for( int i = 0; i < MaxAllowedAmount; i++ )
  393. {
  394. m_inputPorts[ i ].Visible = ( i < m_maxAmountInputs );
  395. }
  396. if( m_currentSelectedInput >= m_maxAmountInputs )
  397. {
  398. m_currentSelectedInput = m_maxAmountInputs - 1;
  399. }
  400. UpdateLabels();
  401. m_sizeIsDirty = true;
  402. }
  403. }
  404. if( !m_toggleMode )
  405. {
  406. EditorGUI.BeginChangeCheck();
  407. m_maxAmountInputs = EditorGUILayoutIntSlider( MaxAmountStr, m_maxAmountInputs, 2, MaxAllowedAmount );
  408. if( EditorGUI.EndChangeCheck() )
  409. {
  410. for( int i = 0; i < MaxAllowedAmount; i++ )
  411. {
  412. m_inputPorts[ i ].Visible = ( i < m_maxAmountInputs );
  413. }
  414. if( m_currentSelectedInput >= m_maxAmountInputs )
  415. {
  416. m_currentSelectedInput = m_maxAmountInputs - 1;
  417. }
  418. UpdateLabels();
  419. m_sizeIsDirty = true;
  420. }
  421. EditorGUI.indentLevel++;
  422. for( int i = 0; i < m_maxAmountInputs; i++ )
  423. {
  424. EditorGUI.BeginChangeCheck();
  425. m_inputPorts[ i ].Name = EditorGUILayoutTextField( "Item " + i, m_inputPorts[ i ].Name );
  426. if( EditorGUI.EndChangeCheck() )
  427. {
  428. m_nameModified = true;
  429. m_lastTimeNameModified = EditorApplication.timeSinceStartup;
  430. m_inputPorts[ i ].Name = UIUtils.RemoveInvalidEnumCharacters( m_inputPorts[ i ].Name );
  431. m_optionNames[ i ] = m_inputPorts[ i ].Name;
  432. if( string.IsNullOrEmpty( m_inputPorts[ i ].Name ) )
  433. {
  434. m_inputPorts[ i ].Name = InputPortNameStr + i;
  435. }
  436. m_sizeIsDirty = true;
  437. }
  438. }
  439. EditorGUI.indentLevel--;
  440. if( m_nameModified )
  441. {
  442. UpdateLabels();
  443. }
  444. }
  445. if( m_toggleMode )
  446. {
  447. EditorGUI.BeginChangeCheck();
  448. int prevVal = m_currentSelectedInput;
  449. m_currentSelectedInput = EditorGUILayoutToggle( CurrSelectedStr, ( m_currentSelectedInput != 0 ? true : false ) ) ? 1 : 0;
  450. if( EditorGUI.EndChangeCheck() )
  451. SetCurrentSelectedInput( m_currentSelectedInput, prevVal );
  452. }
  453. else
  454. {
  455. EditorGUI.BeginChangeCheck();
  456. int prevVal = m_currentSelectedInput;
  457. m_currentSelectedInput = EditorGUILayoutIntPopup( CurrSelectedStr, m_currentSelectedInput, AvailableInputsLabels, AvailableInputsValues );
  458. if( EditorGUI.EndChangeCheck() )
  459. {
  460. SetCurrentSelectedInput( m_currentSelectedInput, prevVal );
  461. }
  462. }
  463. }
  464. if( EditorGUI.EndChangeCheck() )
  465. {
  466. m_dirtySettings = true;
  467. }
  468. }
  469. public override void RefreshExternalReferences()
  470. {
  471. base.RefreshExternalReferences();
  472. if( UIUtils.CurrentShaderVersion() > 14205 )
  473. {
  474. if( m_referenceType == TexReferenceType.Instance )
  475. {
  476. m_functionSwitchReference = UIUtils.GetNode( m_referenceUniqueId ) as FunctionSwitch;
  477. UpdateFromSelected();
  478. }
  479. }
  480. SetCurrentSelectedInput( m_currentSelectedInput, m_previousSelectedInput );
  481. }
  482. public void UpdateLabels()
  483. {
  484. int maxinputs = m_maxAmountInputs;
  485. if( m_validReference )
  486. maxinputs = m_functionSwitchReference.MaxAmountInputs;
  487. AvailableInputsLabels = new string[ maxinputs ];
  488. AvailableInputsValues = new int[ maxinputs ];
  489. for( int i = 0; i < maxinputs; i++ )
  490. {
  491. AvailableInputsLabels[ i ] = m_optionNames[ i ];
  492. AvailableInputsValues[ i ] = i;
  493. }
  494. }
  495. public override void OnNodeLogicUpdate( DrawInfo drawInfo )
  496. {
  497. base.OnNodeLogicUpdate( drawInfo );
  498. CheckReference();
  499. if( m_dirtySettings )
  500. m_dirtySettings = false;
  501. }
  502. public override void OnNodeLayout( DrawInfo drawInfo )
  503. {
  504. float finalSize = 0;
  505. if( !m_toggleMode )
  506. {
  507. GUIContent dropdown = new GUIContent( m_inputPorts[ m_currentSelectedInput ].Name );
  508. int cacheSize = UIUtils.GraphDropDown.fontSize;
  509. UIUtils.GraphDropDown.fontSize = 10;
  510. Vector2 calcSize = UIUtils.GraphDropDown.CalcSize( dropdown );
  511. UIUtils.GraphDropDown.fontSize = cacheSize;
  512. finalSize = Mathf.Clamp( calcSize.x, MinComboSize, MaxComboSize );
  513. if( m_insideSize.x != finalSize )
  514. {
  515. m_insideSize.Set( finalSize, 25 );
  516. m_sizeIsDirty = true;
  517. }
  518. }
  519. base.OnNodeLayout( drawInfo );
  520. bool toggleMode = m_toggleMode;
  521. if( m_validReference )
  522. {
  523. toggleMode = m_functionSwitchReference.m_toggleMode;
  524. }
  525. if( toggleMode )
  526. {
  527. m_varRect = m_remainingBox;
  528. m_varRect.size = Vector2.one * 22 * drawInfo.InvertedZoom;
  529. m_varRect.center = m_remainingBox.center;
  530. if( m_showPreview )
  531. m_varRect.y = m_remainingBox.y;
  532. }
  533. else
  534. {
  535. m_varRect = m_remainingBox;
  536. m_varRect.width = finalSize * drawInfo.InvertedZoom;
  537. m_varRect.height = 16 * drawInfo.InvertedZoom;
  538. m_varRect.x = m_remainingBox.xMax - m_varRect.width;
  539. m_varRect.y += 1 * drawInfo.InvertedZoom;
  540. m_imgRect = m_varRect;
  541. m_imgRect.x = m_varRect.xMax - 16 * drawInfo.InvertedZoom;
  542. m_imgRect.width = 16 * drawInfo.InvertedZoom;
  543. m_imgRect.height = m_imgRect.width;
  544. }
  545. }
  546. public override void DrawGUIControls( DrawInfo drawInfo )
  547. {
  548. if( m_validReference )
  549. {
  550. base.DrawGUIControls( drawInfo );
  551. }
  552. else
  553. {
  554. base.DrawGUIControls( drawInfo );
  555. if( drawInfo.CurrentEventType != EventType.MouseDown )
  556. return;
  557. if( m_varRect.Contains( drawInfo.MousePosition ) )
  558. {
  559. m_editing = true;
  560. }
  561. else if( m_editing )
  562. {
  563. m_editing = false;
  564. }
  565. }
  566. }
  567. public override void Draw( DrawInfo drawInfo )
  568. {
  569. base.Draw( drawInfo );
  570. if( m_nameModified )
  571. {
  572. if( ( EditorApplication.timeSinceStartup - m_lastTimeNameModified ) > MaxTimestamp )
  573. {
  574. m_nameModified = false;
  575. }
  576. }
  577. if( m_validReference )
  578. {
  579. SetAdditonalTitleTextOnCallback( m_functionSwitchReference.OptionLabel, ( instance, newSubTitle ) => instance.AdditonalTitleContent.text = string.Format( Constants.SubTitleVarNameFormatStr, newSubTitle ) );
  580. }
  581. else
  582. {
  583. SetAdditonalTitleTextOnCallback( m_optionLabel, ( instance, newSubTitle ) => instance.AdditonalTitleContent.text = string.Format( Constants.SubTitleValueFormatStr, newSubTitle ) );
  584. if( m_editing )
  585. {
  586. if( m_toggleMode )
  587. {
  588. if( GUI.Button( m_varRect, GUIContent.none, UIUtils.GraphButton ) )
  589. {
  590. PreviewIsDirty = true;
  591. int prevVal = m_currentSelectedInput;
  592. m_currentSelectedInput = m_currentSelectedInput == 1 ? 0 : 1;
  593. if( m_currentSelectedInput != prevVal )
  594. SetCurrentSelectedInput( m_currentSelectedInput, prevVal );
  595. m_editing = false;
  596. }
  597. if( m_currentSelectedInput == 1 )
  598. {
  599. GUI.Label( m_varRect, m_checkContent, UIUtils.GraphButtonIcon );
  600. }
  601. }
  602. else
  603. {
  604. EditorGUI.BeginChangeCheck();
  605. int prevVal = m_currentSelectedInput;
  606. m_currentSelectedInput = EditorGUIIntPopup( m_varRect, m_currentSelectedInput, AvailableInputsLabels, AvailableInputsValues, UIUtils.GraphDropDown );
  607. if( EditorGUI.EndChangeCheck() )
  608. {
  609. PreviewIsDirty = true;
  610. SetCurrentSelectedInput( m_currentSelectedInput, prevVal );
  611. m_editing = false;
  612. }
  613. }
  614. }
  615. }
  616. }
  617. public override void OnNodeRepaint( DrawInfo drawInfo )
  618. {
  619. base.OnNodeRepaint( drawInfo );
  620. if( !m_isVisible )
  621. return;
  622. if( ContainerGraph.LodLevel <= ParentGraph.NodeLOD.LOD2 )
  623. {
  624. if( m_validReference )
  625. {
  626. bool cacheState = GUI.enabled;
  627. GUI.enabled = false;
  628. if( m_functionSwitchReference.m_toggleMode )
  629. {
  630. GUI.Label( m_varRect, GUIContent.none, UIUtils.GraphButton );
  631. if( m_functionSwitchReference.GetCurrentSelectedInput() == 1 )
  632. {
  633. GUI.Label( m_varRect, m_checkContent, UIUtils.GraphButtonIcon );
  634. }
  635. }
  636. else
  637. {
  638. GUI.Label( m_varRect, m_functionSwitchReference.AvailableInputsLabels[ m_currentSelectedInput ], UIUtils.GraphDropDown );
  639. }
  640. GUI.enabled = cacheState;
  641. }
  642. else
  643. {
  644. if( !m_editing )
  645. {
  646. if( m_toggleMode )
  647. {
  648. GUI.Label( m_varRect, GUIContent.none, UIUtils.GraphButton );
  649. if( m_currentSelectedInput == 1 )
  650. {
  651. GUI.Label( m_varRect, m_checkContent, UIUtils.GraphButtonIcon );
  652. }
  653. }
  654. else
  655. {
  656. GUI.Label( m_varRect, AvailableInputsLabels[ m_currentSelectedInput ], UIUtils.GraphDropDown );
  657. GUI.Label( m_imgRect, m_popContent, UIUtils.GraphButtonIcon );
  658. }
  659. }
  660. }
  661. }
  662. }
  663. public override void PropagateNodeData( NodeData nodeData, ref MasterNodeDataCollector dataCollector )
  664. {
  665. if( m_inputPorts[ m_currentSelectedInput ].IsConnected )
  666. m_inputPorts[ m_currentSelectedInput ].GetOutputNode().PropagateNodeData( nodeData, ref dataCollector );
  667. }
  668. public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar )
  669. {
  670. return m_inputPorts[ m_currentSelectedInput ].GeneratePortInstructions( ref dataCollector );
  671. }
  672. public override void ReadFromString( ref string[] nodeParams )
  673. {
  674. base.ReadFromString( ref nodeParams );
  675. m_optionLabel = GetCurrentParam( ref nodeParams );
  676. m_toggleMode = Convert.ToBoolean( GetCurrentParam( ref nodeParams ) );
  677. m_currentSelectedInput = Convert.ToInt32( GetCurrentParam( ref nodeParams ) );
  678. m_previousSelectedInput = m_currentSelectedInput;
  679. m_maxAmountInputs = Convert.ToInt32( GetCurrentParam( ref nodeParams ) );
  680. m_orderIndex = Convert.ToInt32( GetCurrentParam( ref nodeParams ) );
  681. for( int i = 0; i < MaxAllowedAmount; i++ )
  682. {
  683. m_inputPorts[ i ].Visible = ( i < m_maxAmountInputs );
  684. }
  685. if( m_currentSelectedInput >= m_maxAmountInputs )
  686. {
  687. m_currentSelectedInput = m_maxAmountInputs - 1;
  688. }
  689. for( int i = 0; i < m_maxAmountInputs; i++ )
  690. {
  691. m_optionNames[ i ] = GetCurrentParam( ref nodeParams );
  692. m_inputPorts[ i ].Name = m_optionNames[ i ];
  693. }
  694. if( m_toggleMode )
  695. {
  696. m_inputPorts[ 0 ].Name = ToggleFalseStr;
  697. m_inputPorts[ 1 ].Name = ToggleTrueStr;
  698. }
  699. UpdateLabels();
  700. m_sizeIsDirty = true;
  701. UIUtils.UpdateFunctionSwitchData( UniqueId, m_optionLabel );
  702. UIUtils.UpdateFunctionSwitchCopyData( UniqueId, m_optionLabel );
  703. if( UIUtils.CurrentShaderVersion() > 14205 )
  704. {
  705. m_referenceType = (TexReferenceType)Enum.Parse( typeof( TexReferenceType ), GetCurrentParam( ref nodeParams ) );
  706. m_referenceUniqueId = Convert.ToInt32( GetCurrentParam( ref nodeParams ) );
  707. if( m_referenceType == TexReferenceType.Object )
  708. {
  709. if( ContainerGraph.ParentWindow.CustomGraph == null )
  710. UIUtils.UnregisterFunctionSwitchCopyNode( this );
  711. UIUtils.RegisterFunctionSwitchNode( this );
  712. ResetToSelf();
  713. }
  714. else
  715. {
  716. if( ContainerGraph.ParentWindow.CustomGraph == null )
  717. UIUtils.UnregisterFunctionSwitchNode( this );
  718. UIUtils.RegisterFunctionSwitchCopyNode( this );
  719. }
  720. }
  721. }
  722. public override void WriteToString( ref string nodeInfo, ref string connectionsInfo )
  723. {
  724. base.WriteToString( ref nodeInfo, ref connectionsInfo );
  725. IOUtils.AddFieldValueToString( ref nodeInfo, m_optionLabel );
  726. IOUtils.AddFieldValueToString( ref nodeInfo, m_toggleMode );
  727. IOUtils.AddFieldValueToString( ref nodeInfo, m_currentSelectedInput );
  728. IOUtils.AddFieldValueToString( ref nodeInfo, m_maxAmountInputs );
  729. IOUtils.AddFieldValueToString( ref nodeInfo, m_orderIndex );
  730. for( int i = 0; i < m_maxAmountInputs; i++ )
  731. {
  732. IOUtils.AddFieldValueToString( ref nodeInfo, m_optionNames[ i ] );
  733. }
  734. IOUtils.AddFieldValueToString( ref nodeInfo, m_referenceType );
  735. IOUtils.AddFieldValueToString( ref nodeInfo, ( m_functionSwitchReference != null ? m_functionSwitchReference.UniqueId : -1 ) );
  736. }
  737. public int OrderIndex
  738. {
  739. get { return m_orderIndex; }
  740. set { m_orderIndex = value; }
  741. }
  742. public string OptionLabel
  743. {
  744. get { return m_optionLabel; }
  745. set { m_optionLabel = value; }
  746. }
  747. public bool AsDrawn { get { return m_asDrawn; } set { m_asDrawn = value; } }
  748. public override string DataToArray { get { return m_optionLabel; } }
  749. public int MaxAmountInputs
  750. {
  751. get { return m_maxAmountInputs; }
  752. }
  753. public bool DirtySettings { get { return m_dirtySettings; } }
  754. }
  755. }