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