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