protected void GoToParent() { if (viewsStack.Count == 0) { return; } lastTime = DateTime.Now.Ticks; if (newAnimTarget > 0) { newAnimTarget = -1 + newAnimTarget; } else { newAnimTarget = -1; } animationTree = currentlyRenderedTree; currentlyRenderedTree = viewsStack.Pop(); }
protected bool AddMatchItem(AdvancedDropdownItem e, string name, string[] searchWords, List <AdvancedDropdownItem> matchesStart, List <AdvancedDropdownItem> matchesWithin) { bool didMatchAll = true; bool didMatchStart = false; // See if we match ALL the search words. for (int w = 0; w < searchWords.Length; w++) { string search = searchWords[w]; if (name.Contains(search)) { // If the start of the item matches the first search word, make a note of that. if (w == 0 && name.StartsWith(search)) { didMatchStart = true; } } else { // As soon as any word is not matched, we disregard this item. didMatchAll = false; break; } } // We always need to match all search words. // If we ALSO matched the start, this item gets priority. if (didMatchAll) { if (didMatchStart) { matchesStart.Add(e); } else { matchesWithin.Add(e); } } return(didMatchAll); }
protected virtual AdvancedDropdownItem Search(string searchString) { if (searchableElements == null) { BuildSearchableElements(); } if (string.IsNullOrEmpty(searchString)) { return(null); } // Support multiple search words separated by spaces. string[] searchWords = searchString.ToLower().Split(' '); // We keep two lists. Matches that matches the start of an item always get first priority. List <AdvancedDropdownItem> matchesStart = new List <AdvancedDropdownItem> (); List <AdvancedDropdownItem> matchesWithin = new List <AdvancedDropdownItem> (); foreach (AdvancedDropdownItem e in searchableElements) { string name = e.SearchableName.ToLower().Replace(" ", ""); AddMatchItem(e, name, searchWords, matchesStart, matchesWithin); } AdvancedDropdownItem searchTree = new AdvancedDropdownItem(SearchHeader); matchesStart.Sort(); foreach (AdvancedDropdownItem element in matchesStart) { searchTree.AddChild(element); } matchesWithin.Sort(); foreach (AdvancedDropdownItem element in matchesWithin) { searchTree.AddChild(element); } return(searchTree); }
private void DrawDropdown(float anim, AdvancedDropdownItem group) { // Start of animated area (the part that moves left and right) Rect areaPosition = new Rect(0, 0, position.width, position.height); // Adjust to the frame areaPosition.x += BorderThickness; areaPosition.y += BorderThickness; areaPosition.height -= BorderThickness * 2; areaPosition.width -= BorderThickness * 2; GUILayout.BeginArea(gui.GetAnimRect(areaPosition, anim)); // Header if (ShowHeader) { gui.DrawHeader(group, GoToParent, viewsStack.Count > 0); } DrawList(group); GUILayout.EndArea(); }
private AdvancedDropdownItemState GetStateForItem(AdvancedDropdownItem item) { if (lastSelectedState != null && lastSelectedState.itemId == item.Id) { return(lastSelectedState); } for (int i = 0; i < states.Length; i++) { if (states[i].itemId == item.Id) { lastSelectedState = states[i]; return(lastSelectedState); } } Array.Resize(ref states, states.Length + 1); states[states.Length - 1] = new AdvancedDropdownItemState(item); lastSelectedState = states[states.Length - 1]; return(states[states.Length - 1]); }
internal void MoveUpSelection(AdvancedDropdownItem item) { AdvancedDropdownItemState state = GetStateForItem(item); int selectedIndex = state.selectedIndex; do { --selectedIndex; }while (selectedIndex >= 0 && item.Children.ElementAt(selectedIndex).IsSeparator()); if (selectedIndex < 0) { selectedIndex = item.Children.Count() - 1; } if (selectedIndex >= 0) { SetSelectionOnItem(item, selectedIndex); } }
internal virtual void DrawItem(AdvancedDropdownItem item, string name, Texture2D icon, bool enabled, bool drawArrow, bool selected, bool hasSearch) { GUIContent content = new GUIContent(name, icon); Texture imgTemp = content.image; //we need to pretend we have an icon to calculate proper width in case if (content.image == null) { content.image = Texture2D.whiteTexture; } Rect rect = GUILayoutUtility.GetRect(content, LineStyle, GUILayout.ExpandWidth(true)); content.image = imgTemp; if (Event.current.type != EventType.Repaint) { return; } Texture imageTemp = content.image; if (content.image == null) { LineStyle.Draw(rect, GUIContent.none, false, false, selected, selected); rect.x += IconSize.x + 1; rect.width -= IconSize.x + 1; } EditorGUI.BeginDisabledGroup(!enabled); LineStyle.Draw(rect, content, false, false, selected, selected); content.image = imageTemp; if (drawArrow) { float size = LineStyle.lineHeight; Rect arrowRect = new Rect(rect.x + rect.width - size, rect.y, size, size); LineStyle.Draw(arrowRect, Styles.arrowRightContent, false, false, false, false); } EditorGUI.EndDisabledGroup(); }
private void SetSelectionFromState() { int selectedIndex = state.GetSelectedIndex(currentlyRenderedTree); while (selectedIndex >= 0) { AdvancedDropdownItem child = state.GetSelectedChild(currentlyRenderedTree); if (child == null) { break; } selectedIndex = state.GetSelectedIndex(child); if (selectedIndex < 0) { break; } viewsStack.Push(currentlyRenderedTree); currentlyRenderedTree = child; } }
internal Vector2 GetScrollState(AdvancedDropdownItem item) { return(GetStateForItem(item).scroll); }
private void HandleKeyboard() { Event evt = Event.current; if (evt.type == EventType.KeyDown) { // Special handling when in new script panel if (SpecialKeyboardHandling(evt)) { return; } // Always do these if (evt.keyCode == KeyCode.DownArrow) { state.MoveDownSelection(currentlyRenderedTree); scrollToSelected = true; evt.Use(); } if (evt.keyCode == KeyCode.UpArrow) { state.MoveUpSelection(currentlyRenderedTree); scrollToSelected = true; evt.Use(); } if (evt.keyCode == KeyCode.Return || evt.keyCode == KeyCode.KeypadEnter) { AdvancedDropdownItem selected = state.GetSelectedChild(currentlyRenderedTree); if (selected != null) { if (selected.Children.Any()) { GoToChild(); } else { if (SelectionChanged != null) { SelectionChanged(state.GetSelectedChild(currentlyRenderedTree)); } if (CloseOnSelection) { CloseWindow(); } } } evt.Use(); } // Do these if we're not in search mode if (!HasSearch) { if (evt.keyCode == KeyCode.LeftArrow || evt.keyCode == KeyCode.Backspace) { GoToParent(); evt.Use(); } if (evt.keyCode == KeyCode.RightArrow) { int idx = state.GetSelectedIndex(currentlyRenderedTree); if (idx > -1 && currentlyRenderedTree.Children.ElementAt(idx).Children.Any()) { GoToChild(); } evt.Use(); } if (evt.keyCode == KeyCode.Escape) { Close(); evt.Use(); } } } }
public void AddChild(AdvancedDropdownItem child) { children.Add(child); }
public AdvancedDropdownItemState(AdvancedDropdownItem item) { itemId = item.Id; }
public void RebuildSearch(string search) { searchTree = Search(search); }
private void DrawList(AdvancedDropdownItem item) { // Start of scroll view list state.SetScrollState(item, GUILayout.BeginScrollView(state.GetScrollState(item), GUIStyle.none, GUI.skin.verticalScrollbar)); EditorGUIUtility.SetIconSize(gui.IconSize); Rect selectedRect = new Rect(); for (int i = 0; i < item.Children.Count(); i++) { AdvancedDropdownItem child = item.Children.ElementAt(i); bool selected = state.GetSelectedIndex(item) == i; if (child.IsSeparator()) { gui.DrawLineSeparator(); } else { gui.DrawItem(child, child.Name, child.Icon, child.Enabled, child.Children.Any(), selected, HasSearch); } Rect r = GUILayoutUtility.GetLastRect(); if (selected) { selectedRect = r; } // Skip input handling for the tree used for animation if (item != currentlyRenderedTree) { continue; } // Select the element 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.MouseDrag) { if (!selected && r.Contains(Event.current.mousePosition)) { state.SetSelectedIndex(item, i); Event.current.Use(); } } if (Event.current.type == EventType.MouseUp && r.Contains(Event.current.mousePosition)) { state.SetSelectedIndex(item, i); AdvancedDropdownItem selectedChild = state.GetSelectedChild(item); if (selectedChild.Children.Any()) { GoToChild(); } else { if (!selectedChild.IsSeparator() && SelectionChanged != null) { SelectionChanged(selectedChild); } if (CloseOnSelection) { CloseWindow(); GUIUtility.ExitGUI(); } } Event.current.Use(); } } EditorGUIUtility.SetIconSize(Vector2.zero); GUILayout.EndScrollView(); // Scroll to selected on windows creation if (scrollToSelected && initialSelectionPosition != 0) { float diffOfPopupAboveTheButton = buttonRectScreenPos.y - position.y; diffOfPopupAboveTheButton -= gui.SearchHeight + gui.HeaderHeight; state.SetScrollState(item, new Vector2(0, initialSelectionPosition - diffOfPopupAboveTheButton)); scrollToSelected = false; initialSelectionPosition = 0; } // Scroll to show selected else if (scrollToSelected && Event.current.type == EventType.Repaint) { scrollToSelected = false; Rect scrollRect = GUILayoutUtility.GetLastRect(); if (selectedRect.yMax - scrollRect.height > state.GetScrollState(item).y) { state.SetScrollState(item, new Vector2(0, selectedRect.yMax - scrollRect.height)); Repaint(); } if (selectedRect.y < state.GetScrollState(item).y) { state.SetScrollState(item, new Vector2(0, selectedRect.y)); Repaint(); } } }
internal void SetSelectedIndex(AdvancedDropdownItem item, int index) { GetStateForItem(item).selectedIndex = index; }
internal int GetSelectedIndex(AdvancedDropdownItem item) { return(GetStateForItem(item).selectedIndex); }
protected virtual void ItemSelected(AdvancedDropdownItem item) { }
internal void SetScrollState(AdvancedDropdownItem item, Vector2 scrollState) { GetStateForItem(item).scroll = scrollState; }
public void ReloadData() { mainTree = FetchData(); }