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 void ListGUI(SearchTreeEntry[] tree, float anim, SearchTreeGroupEntry parent, SearchTreeGroupEntry grandParent) { // Smooth the fractional part of the anim value anim = Mathf.Floor(anim) + Mathf.SmoothStep(0, 1, Mathf.Repeat(anim, 1)); // Calculate rect for animated area Rect animRect = position; animRect.x = position.width * (1 - anim) + 1; animRect.y = k_HeaderHeight; animRect.height -= k_HeaderHeight; animRect.width -= 2; // Start of animated area (the part that moves left and right) GUILayout.BeginArea(animRect); // Header Rect headerRect = GUILayoutUtility.GetRect(10, 25); string name = parent.name; GUI.Label(headerRect, name, s_Styles.header); // Back button if (grandParent != null) { float yOffset = (headerRect.height - s_Styles.leftArrow.fixedHeight) / 2; Rect arrowRect = new Rect( headerRect.x + s_Styles.leftArrow.margin.left, headerRect.y + yOffset, s_Styles.leftArrow.fixedWidth, s_Styles.leftArrow.fixedHeight); if (Event.current.type == EventType.Repaint) { s_Styles.leftArrow.Draw(arrowRect, false, false, false, false); } if (Event.current.type == EventType.MouseDown && headerRect.Contains(Event.current.mousePosition)) { GoToParent(); Event.current.Use(); } } ListGUI(tree, parent); GUILayout.EndArea(); }
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(); } } }