Esempio n. 1
0
        private void OnHeaderGUI(FuzzyOptionNode parent, Rect headerPosition)
        {
            EditorGUIUtility.SetIconSize(new Vector2(IconSize.Small, IconSize.Small));
            var headerContent = new GUIContent(new GUIContent(parent.option.headerLabel, parent.option.showHeaderIcon ? parent.option.icon?[IconSize.Small] : null));

            headerWidth = Styles.header.CalcSize(headerContent).x;
            GUI.Label(headerPosition, headerContent, Styles.header);
            EditorGUIUtility.SetIconSize(default(Vector2));
        }
Esempio n. 2
0
        private void SelectChild(FuzzyOptionNode node)
        {
            if (node == null)
            {
                return;
            }

            if (node.hasChildren)
            {
                EnterChild(node);
            }
            else if (callback != null)
            {
                callback(node.option);
            }
        }
Esempio n. 3
0
        private void Initialize(IFuzzyOptionTree optionTree, Action <IFuzzyOption> callback)
        {
            tree = optionTree;

            // Create the hierarchy

            stack = new Stack <FuzzyOptionNode>();
            root  = new FuzzyOptionNode(new Root(optionTree.header));

            ExecuteTask(delegate
            {
                optionTree.Prewarm();

                Populate(root, optionTree.Root());

                // Fit height to children if there is no depth and no search

                var hasSubChildren = root.children.Any(option => option.hasChildren);

                if (!optionTree.searchable && !hasSubChildren)
                {
                    height = 0;

                    if (!string.IsNullOrEmpty(root.option.headerLabel))
                    {
                        height += Styles.headerHeight;
                    }

                    height += root.children.Count * Styles.optionHeight + 1;
                }
            });

            // Add favorites

            favoritesRoot = new FuzzyOptionNode(new FavoritesRoot());
            UpdateFavorites();

            // Setup the search

            searchRoot = new FuzzyOptionNode(new SearchRoot());
            Search();

            // Assign the callback

            this.callback = callback;
            // Show and focus the window
        }
Esempio n. 4
0
        private void OnLevelGUI(float anim, FuzzyOptionNode parent, FuzzyOptionNode grandParent)
        {
            anim = Mathf.Floor(anim) + Mathf.SmoothStep(0, 1, Mathf.Repeat(anim, 1));

            var levelPosition = new Rect
                                (
                position.width * (1 - anim) + 1,
                tree.searchable ? 30 : 0,
                position.width - 2,
                height - (tree.searchable ? 31 : 1)
                                );

            GUILayout.BeginArea(levelPosition);

            if (grandParent != null || !string.IsNullOrEmpty(parent.option.headerLabel))
            {
                var headerPosition = GUILayoutUtility.GetRect(10, Styles.headerHeight);

                OnHeaderGUI(parent, headerPosition);

                if (grandParent != null)
                {
                    var leftArrowPosition = new Rect(headerPosition.x + 4, headerPosition.y + 7, 13, 13);

                    if (e.type == EventType.Repaint)
                    {
                        Styles.leftArrow.Draw(leftArrowPosition, false, false, false, false);
                    }

                    if (!isAnimating)
                    {
                        if (e.type == EventType.MouseDown && (e.button == (int)MouseButton.Right || headerPosition.Contains(e.mousePosition)))
                        {
                            SelectParent();
                            e.Use();

                            GUIUtility.ExitGUI();
                        }
                    }
                }
            }

            OnOptionsGUI(parent, levelPosition.height - Styles.headerHeight);

            GUILayout.EndArea();
        }
Esempio n. 5
0
        private void EnterChild(FuzzyOptionNode node)
        {
            if (node == null || !node.hasChildren)
            {
                return;
            }

            ExecuteTask(delegate
            {
                Populate(node, tree.Children(node.option.value));
            });

            lastRepaintTime = DateTime.Now;

            if (animTarget == 0)
            {
                animTarget = 1;
            }
            else if (anim == 1)
            {
                anim = 0;
                stack.Push(node);
            }
        }
Esempio n. 6
0
        private void OnOptionsGUI(FuzzyOptionNode parent, float scrollViewHeight)
        {
            if (parent.isLoading || (tree.showBackgroundWorkerProgress && BackgroundWorker.hasProgress))
            {
                LudiqGUI.BeginVertical();
                LudiqGUI.FlexibleSpace();
                LudiqGUI.BeginHorizontal();
                LudiqGUI.FlexibleSpace();
                LudiqGUI.LoaderLayout();
                LudiqGUI.FlexibleSpace();
                LudiqGUI.EndHorizontal();

                LudiqGUI.Space(16);
                LudiqGUI.BeginHorizontal();
                LudiqGUI.Space(10);
                var progressBarPosition = GUILayoutUtility.GetRect(GUIContent.none, GUIStyle.none, GUILayout.Height(19), GUILayout.ExpandWidth(true));

                if (progressBarPosition.width > 0 && progress > 0)
                {
                    if (tree.showBackgroundWorkerProgress && BackgroundWorker.hasProgress)
                    {
                        EditorGUI.ProgressBar(progressBarPosition, BackgroundWorker.progressProportion, BackgroundWorker.progressLabel);
                    }
                    else if (showProgress)
                    {
                        EditorGUI.ProgressBar(progressBarPosition, progress, progressText);
                    }
                }

                LudiqGUI.Space(10);
                LudiqGUI.EndHorizontal();

                LudiqGUI.FlexibleSpace();
                LudiqGUI.EndVertical();

                return;
            }

            parent.scroll = GUILayout.BeginScrollView(parent.scroll);

            EditorGUIUtility.SetIconSize(new Vector2(IconSize.Small, IconSize.Small));

            var selectedOptionPosition = default(Rect);

            if (e.type == EventType.Repaint)
            {
                minOptionWidth = 0;
            }

            foreach (var node in parent.children)
            {
                node.EnsureDrawable();

                minOptionWidth = Mathf.Max(minOptionWidth, Mathf.Min(node.width, Styles.maxOptionWidth));
            }

            for (var i = 0; i < parent.children.Count; i++)
            {
                var node = parent.children[i];

                var optionPosition = GUILayoutUtility.GetRect(IconSize.Small, Styles.optionHeight, GUILayout.ExpandWidth(true));

                if (!isAnimating)
                {
                    if (((e.type == EventType.MouseMove && GUIUtility.GUIToScreenPoint(e.mousePosition) != lastMouseMovePosition) || e.type == EventType.MouseDown) &&
                        parent.selectedIndex != i && optionPosition.Contains(e.mousePosition))
                    {
                        parent.selectedIndex = i;

                        requireRepaint = true;

                        lastMouseMovePosition = GUIUtility.GUIToScreenPoint(e.mousePosition);

                        GUIUtility.ExitGUI();
                    }
                }

                var optionIsSelected = false;

                if (i == parent.selectedIndex)
                {
                    optionIsSelected       = true;
                    selectedOptionPosition = optionPosition;
                }

                // Clipping
                if (optionPosition.yMax < parent.scroll.y || optionPosition.yMin > parent.scroll.y + scrollViewHeight)
                {
                    continue;
                }

                if (e.type == EventType.Repaint)
                {
                    node.style.Draw(optionPosition, node.label, false, false, optionIsSelected, optionIsSelected);
                }

                var right = optionPosition.xMax;

                if (node.hasChildren)
                {
                    right -= 13;
                    var rightArrowPosition = new Rect(right, optionPosition.y + 4, 13, 13);

                    if (e.type == EventType.Repaint)
                    {
                        Styles.rightArrow.Draw(rightArrowPosition, false, false, false, false);
                    }
                }

                if (!node.hasChildren && tree.selected.Contains(node.option.value))
                {
                    right -= 16;
                    var checkPosition = new Rect(right, optionPosition.y + 4, 12, 12);

                    if (e.type == EventType.Repaint)
                    {
                        Styles.check.Draw(checkPosition, false, false, false, false);
                    }
                }

                if (tree.favorites != null && tree.CanFavorite(node.option.value) && (optionIsSelected || tree.favorites.Contains(node.option.value)))
                {
                    right -= 19;
                    var starPosition = new Rect(right, optionPosition.y + 2, IconSize.Small, IconSize.Small);

                    EditorGUI.BeginChangeCheck();

                    var isFavorite = tree.favorites.Contains(node.option.value);

                    isFavorite = GUI.Toggle(starPosition, isFavorite, GUIContent.none, Styles.star);

                    if (EditorGUI.EndChangeCheck())
                    {
                        if (isFavorite)
                        {
                            tree.favorites.Add(node.option.value);
                        }
                        else
                        {
                            tree.favorites.Remove(node.option.value);
                        }

                        tree.OnFavoritesChange();

                        UpdateFavorites();
                    }
                }

                if (!isAnimating)
                {
                    if (e.type == EventType.MouseDown && e.button == (int)MouseButton.Left && optionPosition.Contains(e.mousePosition))
                    {
                        e.Use();
                        parent.selectedIndex = i;
                        SelectChild(node);

                        GUIUtility.ExitGUI();
                    }
                }
            }

            EditorGUIUtility.SetIconSize(default(Vector2));

            GUILayout.EndScrollView();

            if (scrollToSelected && e.type == EventType.Repaint)
            {
                scrollToSelected = false;

                var lastRect = GUILayoutUtility.GetLastRect();


                if (selectedOptionPosition.yMax - lastRect.height > parent.scroll.y)
                {
                    var scroll = parent.scroll;
                    scroll.y      = selectedOptionPosition.yMax - lastRect.height;
                    parent.scroll = scroll;

                    requireRepaint = true;
                }

                if (selectedOptionPosition.y < parent.scroll.y)
                {
                    var scroll = parent.scroll;
                    scroll.y      = selectedOptionPosition.y;
                    parent.scroll = scroll;

                    requireRepaint = true;
                }
            }
        }
Esempio n. 7
0
        public void Populate(FuzzyOptionNode node, IEnumerable <object> childrenValues, CancellationToken?cancellation = null)
        {
            if (node.isPopulated)
            {
                return;
            }

            var i = 0;

            var _childrenValues = childrenValues.ToArray();

            lock (guiLock)
            {
                node.hasChildren = _childrenValues.Length > 0;
            }

            foreach (var childValue in _childrenValues)
            {
                var childOption = tree.Option(childValue);

                try
                {
                    childOption.OnPopulate();
                }
                catch (ThreadAbortException)
                {
                    throw;
                }
                catch (Exception ex)
                {
                    Debug.LogWarning($"Failed to display {childOption.GetType()}: \n{ex}");
                    continue;
                }

                DisplayProgressBar($"{childOption.label}... ({++i} / {_childrenValues.Length})", (float)i / _childrenValues.Length);

                var hasChildren = tree.Children(childValue).Any();

                var include = !childOption.parentOnly || hasChildren;

                if (!include)
                {
                    continue;
                }

                string label;

                if (node == searchRoot)
                {
                    label = tree.SearchResultLabel(childValue, query);
                }
                else if (node == favoritesRoot)
                {
                    label = tree.FavoritesLabel(childValue);
                }
                else
                {
                    label = childOption.label;
                }

                var childNode = new FuzzyOptionNode(childOption, label);

                childNode.hasChildren = hasChildren;

                lock (guiLock)
                {
                    node.children.Add(childNode);
                }

                cancellation?.ThrowIfCancellationRequested();
            }

            lock (guiLock)
            {
                node.isPopulated = true;
            }
        }