暫無描述
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

AdvancedDropdownDataSource.cs 4.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. #if UNITY_EDITOR
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using UnityEditor;
  5. namespace UnityEngine.InputSystem.Editor
  6. {
  7. internal abstract class AdvancedDropdownDataSource
  8. {
  9. private static readonly string kSearchHeader = L10n.Tr("Search");
  10. public AdvancedDropdownItem mainTree { get; private set; }
  11. public AdvancedDropdownItem searchTree { get; private set; }
  12. public List<int> selectedIDs { get; } = new List<int>();
  13. protected AdvancedDropdownItem root => mainTree;
  14. protected List<AdvancedDropdownItem> m_SearchableElements;
  15. public void ReloadData()
  16. {
  17. mainTree = FetchData();
  18. }
  19. protected abstract AdvancedDropdownItem FetchData();
  20. public void RebuildSearch(string search)
  21. {
  22. searchTree = Search(search);
  23. }
  24. protected bool AddMatchItem(AdvancedDropdownItem e, string name, string[] searchWords, List<AdvancedDropdownItem> matchesStart, List<AdvancedDropdownItem> matchesWithin)
  25. {
  26. var didMatchAll = true;
  27. var didMatchStart = false;
  28. // See if we match ALL the search words.
  29. for (var w = 0; w < searchWords.Length; w++)
  30. {
  31. var search = searchWords[w];
  32. if (name.Contains(search))
  33. {
  34. // If the start of the item matches the first search word, make a note of that.
  35. if (w == 0 && name.StartsWith(search))
  36. didMatchStart = true;
  37. }
  38. else
  39. {
  40. // As soon as any word is not matched, we disregard this item.
  41. didMatchAll = false;
  42. break;
  43. }
  44. }
  45. // We always need to match all search words.
  46. // If we ALSO matched the start, this item gets priority.
  47. if (didMatchAll)
  48. {
  49. if (didMatchStart)
  50. matchesStart.Add(e);
  51. else
  52. matchesWithin.Add(e);
  53. }
  54. return didMatchAll;
  55. }
  56. protected virtual AdvancedDropdownItem PerformCustomSearch(string searchString)
  57. {
  58. return null;
  59. }
  60. protected virtual AdvancedDropdownItem Search(string searchString)
  61. {
  62. if (m_SearchableElements == null)
  63. {
  64. BuildSearchableElements();
  65. }
  66. if (string.IsNullOrEmpty(searchString))
  67. return null;
  68. var searchTree = PerformCustomSearch(searchString);
  69. if (searchTree == null)
  70. {
  71. // Support multiple search words separated by spaces.
  72. var searchWords = searchString.ToLower().Split(' ');
  73. // We keep two lists. Matches that matches the start of an item always get first priority.
  74. var matchesStart = new List<AdvancedDropdownItem>();
  75. var matchesWithin = new List<AdvancedDropdownItem>();
  76. foreach (var e in m_SearchableElements)
  77. {
  78. var name = e.searchableName.ToLower().Replace(" ", "");
  79. AddMatchItem(e, name, searchWords, matchesStart, matchesWithin);
  80. }
  81. searchTree = new AdvancedDropdownItem(kSearchHeader);
  82. matchesStart.Sort();
  83. foreach (var element in matchesStart)
  84. {
  85. searchTree.AddChild(element);
  86. }
  87. matchesWithin.Sort();
  88. foreach (var element in matchesWithin)
  89. {
  90. searchTree.AddChild(element);
  91. }
  92. }
  93. return searchTree;
  94. }
  95. private void BuildSearchableElements()
  96. {
  97. m_SearchableElements = new List<AdvancedDropdownItem>();
  98. BuildSearchableElements(root);
  99. }
  100. private void BuildSearchableElements(AdvancedDropdownItem item)
  101. {
  102. if (!item.children.Any())
  103. {
  104. if (!item.IsSeparator())
  105. m_SearchableElements.Add(item);
  106. return;
  107. }
  108. foreach (var child in item.children)
  109. {
  110. BuildSearchableElements(child);
  111. }
  112. }
  113. }
  114. }
  115. #endif // UNITY_EDITOR