private void CreateSearchTree() { List <SearchTreeEntry> tree = provider.CreateSearchTree(m_Context); if (tree != null) { m_Tree = tree.ToArray(); } else { m_Tree = new SearchTreeEntry[0]; } // Rebuild stack if (m_SelectionStack.Count == 0) { m_SelectionStack.Add(m_Tree[0] as SearchTreeGroupEntry); } else { // The root is always the match for level 0 SearchTreeGroupEntry match = m_Tree[0] as SearchTreeGroupEntry; int level = 0; while (true) { // Assign the match for the current level SearchTreeGroupEntry oldSearchTreeEntry = m_SelectionStack[level]; m_SelectionStack[level] = match; m_SelectionStack[level].selectedIndex = oldSearchTreeEntry.selectedIndex; m_SelectionStack[level].scroll = oldSearchTreeEntry.scroll; // See if we reached last SearchTreeEntry of stack level++; if (level == m_SelectionStack.Count) { break; } // Try to find a child of the same name as we had before List <SearchTreeEntry> children = GetChildren(activeTree, match); SearchTreeEntry childMatch = children.FirstOrDefault(c => c.name == m_SelectionStack[level].name); if (childMatch != null && childMatch is SearchTreeGroupEntry) { match = childMatch as SearchTreeGroupEntry; } else { // If we couldn't find the child, remove all further SearchTreeEntrys from the stack m_SelectionStack.RemoveRange(level, m_SelectionStack.Count - level); } } } s_DirtyList = false; RebuildSearch(); }
private List <SearchTreeEntry> GetChildren(SearchTreeEntry[] tree, SearchTreeEntry parent) { List <SearchTreeEntry> children = new List <SearchTreeEntry>(); int level = -1; int i = 0; for (i = 0; i < tree.Length; i++) { if (tree[i] == parent) { level = parent.level + 1; i++; break; } } if (level == -1) { return(children); } for (; i < tree.Length; i++) { SearchTreeEntry e = tree[i]; if (e.level < level) { break; } if (e.level > level && !hasSearch) { continue; } children.Add(e); } return(children); }
private void SelectEntry(SearchTreeEntry e, bool shouldInvokeCallback) { if (e is SearchTreeGroupEntry) { if (!hasSearch) { m_LastTime = System.DateTime.Now.Ticks; if (m_AnimTarget == 0) { m_AnimTarget = 1; } else if (m_Anim == 1) { m_Anim = 0; m_SelectionStack.Add(e as SearchTreeGroupEntry); } } } else if (shouldInvokeCallback && provider.OnSelectEntry(e, m_Context)) { Close(); } }
private void ListGUI(SearchTreeEntry[] tree, SearchTreeGroupEntry parent) { // Start of scroll view list parent.scroll = GUILayout.BeginScrollView(parent.scroll); EditorGUIUtility.SetIconSize(new Vector2(16, 16)); List <SearchTreeEntry> children = GetChildren(tree, parent); Rect selectedRect = new Rect(); // Iterate through the children for (int i = 0; i < children.Count; i++) { SearchTreeEntry e = children[i]; Rect r = GUILayoutUtility.GetRect(16, 20, GUILayout.ExpandWidth(true)); // Select the SearchTreeEntry the mouse cursor is over. // Only do it on mouse move - keyboard controls are allowed to overwrite this until the next time the mouse moves. if (Event.current.type == EventType.MouseMove || Event.current.type == EventType.MouseDown) { if (parent.selectedIndex != i && r.Contains(Event.current.mousePosition)) { parent.selectedIndex = i; Repaint(); } } bool selected = false; // Handle selected item if (i == parent.selectedIndex) { selected = true; selectedRect = r; } // Draw SearchTreeEntry if (Event.current.type == EventType.Repaint) { GUIStyle labelStyle = (e is SearchTreeGroupEntry) ? s_Styles.groupButton : s_Styles.componentButton; labelStyle.Draw(r, e.content, false, false, selected, selected); if ((e is SearchTreeGroupEntry)) { float yOffset = (r.height - s_Styles.rightArrow.fixedHeight) / 2; Rect arrowRect = new Rect( r.xMax - s_Styles.rightArrow.fixedWidth - s_Styles.rightArrow.margin.right, r.y + yOffset, s_Styles.rightArrow.fixedWidth, s_Styles.rightArrow.fixedHeight); s_Styles.rightArrow.Draw(arrowRect, false, false, false, false); } } if (Event.current.type == EventType.MouseDown && r.Contains(Event.current.mousePosition)) { Event.current.Use(); parent.selectedIndex = i; SelectEntry(e, true); } } EditorGUIUtility.SetIconSize(Vector2.zero); GUILayout.EndScrollView(); // Scroll to show selected if (m_ScrollToSelected && Event.current.type == EventType.Repaint) { m_ScrollToSelected = false; Rect scrollRect = GUILayoutUtility.GetLastRect(); if (selectedRect.yMax - scrollRect.height > parent.scroll.y) { parent.scroll.y = selectedRect.yMax - scrollRect.height; Repaint(); } if (selectedRect.y < parent.scroll.y) { parent.scroll.y = selectedRect.y; Repaint(); } } }