PaletteParent.cs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573
  1. // Amplify Shader Editor - Visual Shader Editing Tool
  2. // Copyright (c) Amplify Creations, Lda <info@amplify.pt>
  3. using UnityEngine;
  4. using System.Collections.Generic;
  5. using UnityEditor;
  6. using System;
  7. using System.Text.RegularExpressions;
  8. namespace AmplifyShaderEditor
  9. {
  10. public class PaletteFilterData
  11. {
  12. public bool Visible;
  13. public bool HasCommunityData;
  14. public List<ContextMenuItem> Contents;
  15. public PaletteFilterData( bool visible )
  16. {
  17. Visible = visible;
  18. Contents = new List<ContextMenuItem>();
  19. }
  20. }
  21. public class PaletteParent : MenuParent
  22. {
  23. private const float ItemSize = 18;
  24. public delegate void OnPaletteNodeCreate( System.Type type, string name, AmplifyShaderFunction function );
  25. public event OnPaletteNodeCreate OnPaletteNodeCreateEvt;
  26. private string m_searchFilterStr = "Search";
  27. protected string m_searchFilterControl = "SHADERNAMETEXTFIELDCONTROLNAME";
  28. protected bool m_focusOnSearch = false;
  29. protected bool m_defaultCategoryVisible = false;
  30. //protected List<ContextMenuItem> m_allItems;
  31. protected List<ContextMenuItem> m_currentItems;
  32. protected Dictionary<string, PaletteFilterData> m_currentCategories;
  33. private bool m_forceUpdate = true;
  34. protected string m_searchFilter = string.Empty;
  35. private float m_searchLabelSize = -1;
  36. private GUIStyle m_buttonStyle;
  37. private GUIStyle m_foldoutStyle;
  38. protected bool m_previousWindowIsFunction = false;
  39. protected int m_validButtonId = 0;
  40. protected int m_initialSeparatorAmount = 1;
  41. private Vector2 m_currScrollBarDims = new Vector2( 1, 1 );
  42. 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 )
  43. {
  44. m_searchFilter = string.Empty;
  45. m_currentCategories = new Dictionary<string, PaletteFilterData>();
  46. //m_allItems = items;
  47. m_currentItems = new List<ContextMenuItem>();
  48. }
  49. public virtual void OnEnterPressed( int index = 0 ) { }
  50. public virtual void OnEscapePressed() { }
  51. public void FireNodeCreateEvent( System.Type type, string name, AmplifyShaderFunction function )
  52. {
  53. OnPaletteNodeCreateEvt( type, name, function );
  54. }
  55. public override void Draw( Rect parentPosition, Vector2 mousePosition, int mouseButtonId, bool hasKeyboadFocus )
  56. {
  57. base.Draw( parentPosition, mousePosition, mouseButtonId, hasKeyboadFocus );
  58. if( m_previousWindowIsFunction != ParentWindow.IsShaderFunctionWindow )
  59. {
  60. m_forceUpdate = true;
  61. }
  62. m_previousWindowIsFunction = ParentWindow.IsShaderFunctionWindow;
  63. List<ContextMenuItem> allItems = ParentWindow.ContextMenuInstance.MenuItems;
  64. if( m_searchLabelSize < 0 )
  65. {
  66. m_searchLabelSize = GUI.skin.label.CalcSize( new GUIContent( m_searchFilterStr ) ).x;
  67. }
  68. if( m_foldoutStyle == null )
  69. {
  70. m_foldoutStyle = new GUIStyle( GUI.skin.GetStyle( "foldout" ) );
  71. m_foldoutStyle.fontStyle = FontStyle.Bold;
  72. }
  73. if( m_buttonStyle == null )
  74. {
  75. m_buttonStyle = UIUtils.Label;
  76. }
  77. Event currenEvent = Event.current;
  78. GUILayout.BeginArea( m_transformedArea, m_content, m_style );
  79. {
  80. for( int i = 0; i < m_initialSeparatorAmount; i++ )
  81. {
  82. EditorGUILayout.Separator();
  83. }
  84. if( currenEvent.type == EventType.KeyDown )
  85. {
  86. KeyCode key = currenEvent.keyCode;
  87. //if ( key == KeyCode.Return || key == KeyCode.KeypadEnter )
  88. // OnEnterPressed();
  89. if( ( currenEvent.keyCode == KeyCode.KeypadEnter || currenEvent.keyCode == KeyCode.Return ) && currenEvent.type == EventType.KeyDown )
  90. {
  91. int index = m_currentItems.FindIndex( x => GUI.GetNameOfFocusedControl().Equals( x.ItemUIContent.text + m_resizable ) );
  92. if( index > -1 )
  93. OnEnterPressed( index );
  94. else
  95. OnEnterPressed();
  96. }
  97. if( key == KeyCode.Escape )
  98. OnEscapePressed();
  99. if( m_isMouseInside || hasKeyboadFocus )
  100. {
  101. if( key == ShortcutsManager.ScrollUpKey )
  102. {
  103. m_currentScrollPos.y -= 10;
  104. if( m_currentScrollPos.y < 0 )
  105. {
  106. m_currentScrollPos.y = 0;
  107. }
  108. currenEvent.Use();
  109. }
  110. if( key == ShortcutsManager.ScrollDownKey )
  111. {
  112. m_currentScrollPos.y += 10;
  113. currenEvent.Use();
  114. }
  115. }
  116. }
  117. float width = EditorGUIUtility.labelWidth;
  118. EditorGUIUtility.labelWidth = m_searchLabelSize;
  119. EditorGUI.BeginChangeCheck();
  120. {
  121. GUI.SetNextControlName( m_searchFilterControl + m_resizable );
  122. m_searchFilter = EditorGUILayout.TextField( m_searchFilterStr, m_searchFilter );
  123. if( m_focusOnSearch )
  124. {
  125. m_focusOnSearch = false;
  126. EditorGUI.FocusTextInControl( m_searchFilterControl + m_resizable );
  127. }
  128. }
  129. if( EditorGUI.EndChangeCheck() )
  130. m_forceUpdate = true;
  131. EditorGUIUtility.labelWidth = width;
  132. bool usingSearchFilter = ( m_searchFilter.Length == 0 );
  133. m_currScrollBarDims.x = m_transformedArea.width;
  134. m_currScrollBarDims.y = m_transformedArea.height - 2 - 16 - 2 - 7 * m_initialSeparatorAmount - 2;
  135. m_currentScrollPos = EditorGUILayout.BeginScrollView( m_currentScrollPos/*, GUILayout.Width( 242 ), GUILayout.Height( 250 - 2 - 16 - 2 - 7 - 2) */);
  136. {
  137. if( m_forceUpdate )
  138. {
  139. m_forceUpdate = false;
  140. //m_currentItems.Clear();
  141. m_currentCategories.Clear();
  142. if( usingSearchFilter )
  143. {
  144. for( int i = 0; i < allItems.Count; i++ )
  145. {
  146. //m_currentItems.Add( allItems[ i ] );
  147. if( !m_currentCategories.ContainsKey( allItems[ i ].Category ) )
  148. {
  149. m_currentCategories.Add( allItems[ i ].Category, new PaletteFilterData( m_defaultCategoryVisible ) );
  150. //m_currentCategories[ allItems[ i ].Category ].HasCommunityData = allItems[ i ].NodeAttributes.FromCommunity || m_currentCategories[ allItems[ i ].Category ].HasCommunityData;
  151. }
  152. m_currentCategories[ allItems[ i ].Category ].Contents.Add( allItems[ i ] );
  153. }
  154. }
  155. else
  156. {
  157. for( int i = 0; i < allItems.Count; i++ )
  158. {
  159. var searchList = m_searchFilter.Trim( ' ' ).ToLower().Split(' ');
  160. int matchesFound = 0;
  161. for( int k = 0; k < searchList.Length; k++ )
  162. {
  163. MatchCollection wordmatch = Regex.Matches( allItems[ i ].Tags, "\\b"+searchList[ k ] );
  164. if( wordmatch.Count > 0 )
  165. matchesFound++;
  166. else
  167. break;
  168. }
  169. if( searchList.Length == matchesFound )
  170. {
  171. //m_currentItems.Add( allItems[ i ] );
  172. if( !m_currentCategories.ContainsKey( allItems[ i ].Category ) )
  173. {
  174. m_currentCategories.Add( allItems[ i ].Category, new PaletteFilterData( m_defaultCategoryVisible ) );
  175. //m_currentCategories[ allItems[ i ].Category ].HasCommunityData = allItems[ i ].NodeAttributes.FromCommunity || m_currentCategories[ allItems[ i ].Category ].HasCommunityData;
  176. }
  177. m_currentCategories[ allItems[ i ].Category ].Contents.Add( allItems[ i ] );
  178. }
  179. }
  180. }
  181. var categoryEnumerator = m_currentCategories.GetEnumerator();
  182. while( categoryEnumerator.MoveNext() )
  183. {
  184. categoryEnumerator.Current.Value.Contents.Sort( ( x, y ) => x.CompareTo( y, usingSearchFilter ) );
  185. }
  186. //sort current list respecting categories
  187. m_currentItems.Clear();
  188. foreach( var item in m_currentCategories )
  189. {
  190. for( int i = 0; i < item.Value.Contents.Count; i++ )
  191. {
  192. m_currentItems.Add( item.Value.Contents[ i ] );
  193. }
  194. }
  195. }
  196. string watching = string.Empty;
  197. // unselect the main search field so it can focus list elements next
  198. if( ( currenEvent.keyCode == KeyCode.DownArrow || currenEvent.keyCode == KeyCode.UpArrow ) && m_searchFilter.Length > 0 )
  199. {
  200. if( GUI.GetNameOfFocusedControl().Equals( m_searchFilterControl + m_resizable ) )
  201. {
  202. EditorGUI.FocusTextInControl( null );
  203. }
  204. }
  205. if( currenEvent.keyCode == KeyCode.DownArrow && currenEvent.type == EventType.KeyDown )
  206. {
  207. currenEvent.Use();
  208. int nextIndex = m_currentItems.FindIndex( x => GUI.GetNameOfFocusedControl().Equals( x.ItemUIContent.text + m_resizable ) ) + 1;
  209. if( nextIndex == m_currentItems.Count )
  210. nextIndex = 0;
  211. watching = m_currentItems[ nextIndex ].ItemUIContent.text + m_resizable;
  212. GUI.FocusControl( watching );
  213. }
  214. if( currenEvent.keyCode == KeyCode.UpArrow && currenEvent.type == EventType.KeyDown )
  215. {
  216. currenEvent.Use();
  217. int nextIndex = m_currentItems.FindIndex( x => GUI.GetNameOfFocusedControl().Equals( x.ItemUIContent.text + m_resizable ) ) - 1;
  218. if( nextIndex < 0 )
  219. nextIndex = m_currentItems.Count - 1;
  220. watching = m_currentItems[ nextIndex ].ItemUIContent.text + m_resizable;
  221. GUI.FocusControl( watching );
  222. }
  223. if( currenEvent.keyCode == KeyCode.Tab )
  224. {
  225. ContextMenuItem item = m_currentItems.Find( x => GUI.GetNameOfFocusedControl().Equals( x.ItemUIContent.text + m_resizable ) );
  226. if( item != null )
  227. {
  228. watching = item.ItemUIContent.text + m_resizable;
  229. }
  230. }
  231. float currPos = 0;
  232. var enumerator = m_currentCategories.GetEnumerator();
  233. float cache = EditorGUIUtility.labelWidth;
  234. while( enumerator.MoveNext() )
  235. {
  236. var current = enumerator.Current;
  237. bool visible = GUILayout.Toggle( current.Value.Visible, current.Key, m_foldoutStyle );
  238. if( m_validButtonId == mouseButtonId )
  239. {
  240. current.Value.Visible = visible;
  241. }
  242. currPos += ItemSize;
  243. if( m_searchFilter.Length > 0 || current.Value.Visible )
  244. {
  245. for( int i = 0; i < current.Value.Contents.Count; i++ )
  246. {
  247. //if ( !IsItemVisible( currPos ) )
  248. //{
  249. // // Invisible
  250. // GUILayout.Space( ItemSize );
  251. //}
  252. //else
  253. {
  254. currPos += ItemSize;
  255. // Visible
  256. EditorGUILayout.BeginHorizontal();
  257. GUILayout.Space( 16 );
  258. //if ( m_isMouseInside )
  259. //{
  260. // //GUI.SetNextControlName( current.Value.Contents[ i ].ItemUIContent.text );
  261. // if ( CheckButton( current.Value.Contents[ i ].ItemUIContent, m_buttonStyle, mouseButtonId ) )
  262. // {
  263. // int controlID = GUIUtility.GetControlID( FocusType.Passive );
  264. // GUIUtility.hotControl = controlID;
  265. // OnPaletteNodeCreateEvt( current.Value.Contents[ i ].NodeType, current.Value.Contents[ i ].Name, current.Value.Contents[ i ].Function );
  266. // }
  267. //}
  268. //else
  269. {
  270. Rect thisRect = EditorGUILayout.GetControlRect( false, 16f, EditorStyles.label );
  271. //if ( m_resizable )
  272. {
  273. if( GUI.RepeatButton( thisRect, string.Empty, EditorStyles.label ) )
  274. {
  275. int controlID = GUIUtility.GetControlID( FocusType.Passive );
  276. GUIUtility.hotControl = controlID;
  277. OnPaletteNodeCreateEvt( current.Value.Contents[ i ].NodeType, current.Value.Contents[ i ].Name, current.Value.Contents[ i ].Function );
  278. //unfocus to make it focus the next text field correctly
  279. GUI.FocusControl( null );
  280. }
  281. }
  282. GUI.SetNextControlName( current.Value.Contents[ i ].ItemUIContent.text + m_resizable );
  283. //EditorGUI.SelectableLabel( thisRect, current.Value.Contents[ i ].ItemUIContent.text, EditorStyles.label );
  284. //float cache = EditorGUIUtility.labelWidth;
  285. EditorGUIUtility.labelWidth = thisRect.width;
  286. EditorGUI.Toggle( thisRect, current.Value.Contents[ i ].ItemUIContent.text, false, EditorStyles.label );
  287. EditorGUIUtility.labelWidth = cache;
  288. if( watching == current.Value.Contents[ i ].ItemUIContent.text + m_resizable )
  289. {
  290. bool boundBottom = currPos - m_currentScrollPos.y > m_currScrollBarDims.y;
  291. bool boundTop = currPos - m_currentScrollPos.y - 4 <= 0;
  292. if( boundBottom )
  293. m_currentScrollPos.y = currPos - m_currScrollBarDims.y + 2;
  294. else if( boundTop )
  295. m_currentScrollPos.y = currPos - 18;
  296. //else if ( boundBottom && !downDirection )
  297. // m_currentScrollPos.y = currPos - m_currScrollBarDims.y + 2;
  298. //else if ( boundTop && downDirection )
  299. // m_currentScrollPos.y = currPos - 18;
  300. }
  301. }
  302. EditorGUILayout.EndHorizontal();
  303. }
  304. //currPos += ItemSize;
  305. }
  306. }
  307. }
  308. EditorGUIUtility.labelWidth = cache;
  309. }
  310. EditorGUILayout.EndScrollView();
  311. }
  312. GUILayout.EndArea();
  313. }
  314. public void CheckCommunityNodes()
  315. {
  316. var enumerator = m_currentCategories.GetEnumerator();
  317. while( enumerator.MoveNext() )
  318. {
  319. var current = enumerator.Current;
  320. current.Value.HasCommunityData = false;
  321. int count = current.Value.Contents.Count;
  322. for( int i = 0; i < count; i++ )
  323. {
  324. if( current.Value.Contents[ i ].NodeAttributes.FromCommunity )
  325. {
  326. current.Value.HasCommunityData = true;
  327. break;
  328. }
  329. }
  330. }
  331. }
  332. public void DumpAvailableNodes( bool fromCommunity, string pathname )
  333. {
  334. string noTOCHeader = "__NOTOC__\n";
  335. string nodesHeader = "== Available Node Categories ==\n";
  336. string InitialCategoriesFormat = "[[#{0}|{0}]]<br>\n";
  337. string InitialCategories = string.Empty;
  338. string CurrentCategoryFormat = "\n== {0} ==\n\n";
  339. //string NodesFootFormat = "[[Unity Products:Amplify Shader Editor/{0} | Learn More]] -\n[[#Top|Back to Categories]]\n";
  340. string NodesFootFormatSep = "[[#Top|Back to Top]]\n----\n";
  341. string OverallFoot = "[[Category:Nodes]]";
  342. string NodeInfoBeginFormat = "<div class=\"nodecard\">\n";
  343. string nodeInfoBodyFormat = "{{| id=\"{2}\" class=\"wikitable\" |\n" +
  344. "|- \n" +
  345. "| <div>[[Unity Products:Amplify Shader Editor/{1}|<img class=\"responsive-img\" src=\"http://amplify.pt/Nodes/{0}.jpg\">]]</div>\n" +
  346. "<div>\n" +
  347. "{{| style=\"width: 100%; height: 150px;\"\n" +
  348. "|-\n" +
  349. "| [[Unity Products:Amplify Shader Editor/{1}|'''{2}''']]\n" +
  350. "|- style=\"vertical-align:top; height: 100%;\" |\n" +
  351. "|<p class=\"cardtext\">{3}</p>\n" +
  352. "|- style=\"text-align:right;\" |\n" +
  353. "|{4}[[Unity Products:Amplify Shader Editor/{1} | Learn More]]\n" +
  354. "|}}</div>\n" +
  355. "|}}\n";
  356. string NodeInfoEndFormat = "</div>\n";
  357. //string NodeInfoBeginFormat = "<span style=\"color:#c00;display:block;\">This page is under construction!</span>\n\n";
  358. //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}";
  359. //string NodeInfoEndFormat = "\n\n[[Unity_Products:Amplify_Shader_Editor/Nodes | Back to Node List ]]\n[[Category:Nodes]][[Category:{0}]]\n\n\n";
  360. //string NodeInfoBeginFormat = "{| cellpadding=\"10\"\n";
  361. //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";
  362. //string NodeInfoEndFormat = "|}\n";
  363. string nodesInfo = string.Empty;
  364. BuildFullList( true );
  365. CheckCommunityNodes();
  366. var enumerator = m_currentCategories.GetEnumerator();
  367. while( enumerator.MoveNext() )
  368. {
  369. var current = enumerator.Current;
  370. if( fromCommunity && current.Value.HasCommunityData || !fromCommunity )
  371. {
  372. InitialCategories += string.Format( InitialCategoriesFormat, current.Key );
  373. nodesInfo += string.Format( CurrentCategoryFormat, current.Key );
  374. int count = current.Value.Contents.Count;
  375. for( int i = 0; i < count; i++ )
  376. {
  377. if( ( fromCommunity && current.Value.Contents[ i ].NodeAttributes.FromCommunity )
  378. || !fromCommunity
  379. //|| ( !fromCommunity && !current.Value.Contents[ i ].NodeAttributes.FromCommunity )
  380. )
  381. {
  382. string nodeFullName = current.Value.Contents[ i ].Name;
  383. string pictureFilename = UIUtils.ReplaceInvalidStrings( nodeFullName );
  384. string pageFilename = UIUtils.RemoveWikiInvalidCharacters( pictureFilename );
  385. pictureFilename = UIUtils.RemoveInvalidCharacters( pictureFilename );
  386. string nodeDescription = current.Value.Contents[ i ].ItemUIContent.tooltip;
  387. string communityText = string.Empty;
  388. if( current.Value.Contents[ i ].NodeAttributes.FromCommunity )
  389. communityText = "<small class=\"cardauthor\">( originally by "+ current.Value.Contents[ i ].NodeAttributes.Community + " )</small> ";
  390. string nodeInfoBody = string.Format( nodeInfoBodyFormat, pictureFilename, pageFilename, nodeFullName, nodeDescription, communityText );
  391. //string nodeInfoFoot = string.Format( NodesFootFormat, pageFilename );
  392. nodesInfo += ( NodeInfoBeginFormat + nodeInfoBody + NodeInfoEndFormat );
  393. //nodesInfo += ( NodeInfoBeginFormat + nodeInfoBody + string.Format( NodeInfoEndFormat, current.Key ) );
  394. //if ( i != ( count - 1 ) )
  395. //{
  396. // nodesInfo += NodesFootFormatSep;
  397. //}
  398. }
  399. }
  400. nodesInfo += NodesFootFormatSep;
  401. }
  402. }
  403. string finalText = noTOCHeader + nodesHeader + InitialCategories + nodesInfo + OverallFoot;
  404. if( !System.IO.Directory.Exists( pathname ) )
  405. {
  406. System.IO.Directory.CreateDirectory( pathname );
  407. }
  408. // Save file
  409. string nodesPathname = pathname + ( fromCommunity ? "AvailableNodesFromCommunity.txt" : "AvailableNodes.txt" );
  410. Debug.Log( " Creating nodes file at " + nodesPathname );
  411. IOUtils.SaveTextfileToDisk( finalText, nodesPathname, false );
  412. BuildFullList( false );
  413. }
  414. public virtual bool CheckButton( GUIContent content, GUIStyle style, int buttonId )
  415. {
  416. if( buttonId != m_validButtonId )
  417. {
  418. GUILayout.Label( content, style );
  419. return false;
  420. }
  421. return GUILayout.RepeatButton( content, style );
  422. }
  423. public void FillList( ref List<ContextMenuItem> list, bool forceAllItems )
  424. {
  425. List<ContextMenuItem> allList = forceAllItems ? ParentWindow.ContextMenuInstance.ItemFunctions : ParentWindow.ContextMenuInstance.MenuItems;
  426. list.Clear();
  427. int count = allList.Count;
  428. for( int i = 0; i < count; i++ )
  429. {
  430. list.Add( allList[ i ] );
  431. }
  432. }
  433. public Dictionary<string, PaletteFilterData> BuildFullList( bool forceAllNodes = false )
  434. {
  435. //Only need to build if search filter is active and list is set according to it
  436. if( m_searchFilter.Length > 0 || !m_isActive || m_currentCategories.Count == 0 )
  437. {
  438. m_currentItems.Clear();
  439. m_currentCategories.Clear();
  440. List<ContextMenuItem> allItems = forceAllNodes ? ParentWindow.ContextMenuInstance.ItemFunctions : ParentWindow.ContextMenuInstance.MenuItems;
  441. for( int i = 0; i < allItems.Count; i++ )
  442. {
  443. if( allItems[ i ].Name.IndexOf( m_searchFilter, StringComparison.InvariantCultureIgnoreCase ) >= 0 ||
  444. allItems[ i ].Category.IndexOf( m_searchFilter, StringComparison.InvariantCultureIgnoreCase ) >= 0
  445. )
  446. {
  447. m_currentItems.Add( allItems[ i ] );
  448. if( !m_currentCategories.ContainsKey( allItems[ i ].Category ) )
  449. {
  450. m_currentCategories.Add( allItems[ i ].Category, new PaletteFilterData( m_defaultCategoryVisible ) );
  451. //m_currentCategories[ allItems[ i ].Category ].HasCommunityData = allItems[ i ].NodeAttributes.FromCommunity || m_currentCategories[ allItems[ i ].Category ].HasCommunityData;
  452. }
  453. m_currentCategories[ allItems[ i ].Category ].Contents.Add( allItems[ i ] );
  454. }
  455. }
  456. var categoryEnumerator = m_currentCategories.GetEnumerator();
  457. while( categoryEnumerator.MoveNext() )
  458. {
  459. categoryEnumerator.Current.Value.Contents.Sort( ( x, y ) => x.CompareTo( y, false ) );
  460. }
  461. //mark to force update and take search filter into account
  462. m_forceUpdate = true;
  463. }
  464. return m_currentCategories;
  465. }
  466. private bool IsItemVisible( float currPos )
  467. {
  468. if( ( currPos < m_currentScrollPos.y && ( currPos + ItemSize ) < m_currentScrollPos.y ) ||
  469. ( currPos > ( m_currentScrollPos.y + m_currScrollBarDims.y ) &&
  470. ( currPos + ItemSize ) > ( m_currentScrollPos.y + m_currScrollBarDims.y ) ) )
  471. {
  472. return false;
  473. }
  474. return true;
  475. }
  476. public override void Destroy()
  477. {
  478. base.Destroy();
  479. //m_allItems = null;
  480. m_currentItems.Clear();
  481. m_currentItems = null;
  482. m_currentCategories.Clear();
  483. m_currentCategories = null;
  484. OnPaletteNodeCreateEvt = null;
  485. m_buttonStyle = null;
  486. m_foldoutStyle = null;
  487. }
  488. //public void Clear() {
  489. // m_allItems.Clear();
  490. // m_allItems = new List<ContextMenuItem>();
  491. //}
  492. public bool ForceUpdate { get { return m_forceUpdate; } set { m_forceUpdate = value; } }
  493. }
  494. }