Example #1
0
        public ThreadTable(TreeViewState state, MultiColumnHeader multicolumnHeader, List <string> threadNames, List <string> threadUINames, ThreadSelection threadSelection) : base(state, multicolumnHeader)
        {
            StateChanged = false;

            m_AllThreadIdentifier = new ThreadIdentifier();
            m_AllThreadIdentifier.SetName("All");
            m_AllThreadIdentifier.SetAll();

            Assert.AreEqual(m_SortOptions.Length, Enum.GetValues(typeof(MyColumns)).Length, "Ensure number of sort options are in sync with number of MyColumns enum values");

            // Custom setup
            rowHeight = kRowHeights;
            showAlternatingRowBackgrounds = true;
            columnIndexForTreeFoldouts    = (int)(MyColumns.GroupName);
            showBorder           = true;
            customFoldoutYOffset = (kRowHeights - EditorGUIUtility.singleLineHeight) * 0.5f; // center foldout in the row since we also center content. See RowGUI
            // extraSpaceBeforeIconAndLabel = 0;
            multicolumnHeader.sortingChanged        += OnSortingChanged;
            multicolumnHeader.visibleColumnsChanged += OnVisibleColumnsChanged;

            m_ThreadNames     = threadNames;
            m_ThreadUINames   = threadUINames;
            m_ThreadSelection = new ThreadSelection(threadSelection);
#if UNITY_2018_3_OR_NEWER
            this.foldoutOverride += DoFoldout;
#endif
            Reload();
        }
Example #2
0
        public void SetGroup(string groupName)
        {
            groups.Clear();
            selection.Clear();

            ThreadIdentifier allThreadSelection = new ThreadIdentifier(groupName, ThreadIdentifier.kAll);

            groups.Add(allThreadSelection.threadNameWithIndex);
        }
Example #3
0
        public void SetAll()
        {
            groups.Clear();
            selection.Clear();

            ThreadIdentifier allThreadSelection = new ThreadIdentifier("All", ThreadIdentifier.kAll);

            groups.Add(allThreadSelection.threadNameWithIndex);
        }
        protected override TreeViewItem BuildRoot()
        {
            int idForHiddenRoot      = -1;
            int depthForHiddenRoot   = -1;
            ProfileTreeViewItem root = new ProfileTreeViewItem(idForHiddenRoot, depthForHiddenRoot, "root", null);

            int depth = 0;

            var top = new ThreadTreeViewItem(-1, depth, m_AllThreadIdentifier.name, m_AllThreadIdentifier);

            root.AddChild(top);

            var expandList = new List <int>()
            {
                -1
            };
            string       lastThreadName = "";
            TreeViewItem node           = root;

            for (int index = 0; index < m_ThreadNames.Count; ++index)
            {
                var threadNameWithIndex = m_ThreadNames[index];
                if (threadNameWithIndex == m_AllThreadIdentifier.threadNameWithIndex)
                {
                    continue;
                }

                var threadIdentifier = new ThreadIdentifier(threadNameWithIndex);
                var item             = new ThreadTreeViewItem(index, depth, m_ThreadUINames[index], threadIdentifier);

                if (threadIdentifier.name != lastThreadName)
                {
                    // New threads at root
                    node  = top;
                    depth = 0;
                }

                node.AddChild(item);


                if (threadIdentifier.name != lastThreadName)
                {
                    // Extra instances hang of the parent
                    lastThreadName = threadIdentifier.name;
                    node           = item;
                    depth          = 1;
                }
            }

            SetExpanded(expandList);

            SetupDepthsFromParentsAndChildren(root);

            return(root);
        }
        protected int GetChildCount(ThreadIdentifier selectedThreadIdentifier, out int selected)
        {
            int count         = 0;
            int selectedCount = 0;

            if (selectedThreadIdentifier.index == ThreadIdentifier.kAll)
            {
                if (selectedThreadIdentifier.name == "All")
                {
                    for (int index = 0; index < m_ThreadNames.Count; ++index)
                    {
                        var threadNameWithIndex = m_ThreadNames[index];
                        var threadIdentifier    = new ThreadIdentifier(threadNameWithIndex);

                        if (threadIdentifier.index != ThreadIdentifier.kAll)
                        {
                            count++;
                            if (m_ThreadSelection.selection.Contains(threadNameWithIndex))
                            {
                                selectedCount++;
                            }
                        }
                    }
                }
                else
                {
                    for (int index = 0; index < m_ThreadNames.Count; ++index)
                    {
                        var threadNameWithIndex = m_ThreadNames[index];
                        var threadIdentifier    = new ThreadIdentifier(threadNameWithIndex);

                        if (selectedThreadIdentifier.name == threadIdentifier.name &&
                            threadIdentifier.index != ThreadIdentifier.kAll)
                        {
                            count++;
                            if (m_ThreadSelection.selection.Contains(threadNameWithIndex))
                            {
                                selectedCount++;
                            }
                        }
                    }
                }
            }

            selected = selectedCount;
            return(count);
        }
        void CellGUI(Rect cellRect, ThreadTreeViewItem item, MyColumns column, ref RowGUIArgs args)
        {
            // Center cell rect vertically (makes it easier to place controls, icons etc in the cells)
            CenterRectUsingSingleLineHeight(ref cellRect);

            switch (column)
            {
            case MyColumns.ThreadName:
            {
                args.rowRect = cellRect;
                // base.RowGUI(args);    // Required to show tree indenting

                // Draw manually to keep indenting by add a tooltip
                Rect rect = cellRect;
                if (Event.current.rawType == EventType.Repaint)
                {
                    int selectedChildren;
                    int childCount = GetChildCount(item.threadIdentifier, out selectedChildren);

                    string text;
                    string tooltip;
                    string fullThreadName = item.threadIdentifier.name;
                    string groupName      = GetItemGroupName(item);
                    // string threadName = ProfileData.GetThreadNameWithoutGroup(fullThreadName, out groupName);

                    if (childCount <= 1)
                    {
                        text    = item.displayName;
                        tooltip = (groupName == "") ? text : string.Format("{0}\n{1}", text, groupName);
                    }
                    else if (selectedChildren != childCount)
                    {
                        text    = string.Format("{0} ({1} of {2})", fullThreadName, selectedChildren, childCount);
                        tooltip = (groupName == "") ? text : string.Format("{0}\n{1}", text, groupName);
                    }
                    else
                    {
                        text    = string.Format("{0} (All)", fullThreadName);
                        tooltip = (groupName == "") ? text : string.Format("{0}\n{1}", text, groupName);
                    }
                    var content = new GUIContent(text, tooltip);

                    if (activeLineStyle == null)
                    {
                        // activeLineStyle = DefaultStyles.boldLabel;
                        activeLineStyle = new GUIStyle(DefaultStyles.label);
                        activeLineStyle.normal.textColor = DefaultStyles.boldLabel.onActive.textColor;
                    }

                    // The rect is assumed indented and sized after the content when pinging
                    float indent = GetContentIndent(item) + extraSpaceBeforeIconAndLabel;
                    rect.xMin += indent;

                    int iconRectWidth            = 16;
                    int kSpaceBetweenIconAndText = 2;

                    // Draw icon
                    Rect iconRect = rect;
                    iconRect.width = iconRectWidth;
                    // iconRect.x += 7f;

                    Texture icon = args.item.icon;
                    if (icon != null)
                    {
                        GUI.DrawTexture(iconRect, icon, ScaleMode.ScaleToFit);
                    }

                    rect.xMin += icon == null ? 0 : iconRectWidth + kSpaceBetweenIconAndText;

                    //bool mouseOver = rect.Contains(Event.current.mousePosition);
                    //DefaultStyles.label.Draw(rect, content, mouseOver, false, args.selected, args.focused);

                    // Must use this call to draw tooltip
                    EditorGUI.LabelField(rect, content, args.selected ? activeLineStyle : DefaultStyles.label);
                }
            }
            break;

            case MyColumns.GroupName:
            {
                string groupName = GetItemGroupName(item);
                var    content   = new GUIContent(groupName, groupName);
                EditorGUI.LabelField(cellRect, content);
            }
            break;

            case MyColumns.State:
                bool oldState = ThreadSelected(item.threadIdentifier);
                bool newState = EditorGUI.Toggle(cellRect, oldState);
                if (newState != oldState)
                {
                    if (item.threadIdentifier.threadNameWithIndex == m_AllThreadIdentifier.threadNameWithIndex)
                    {
                        // Record active groups
                        m_ThreadSelection.groups.Clear();
                        if (newState)
                        {
                            if (!m_ThreadSelection.groups.Contains(item.threadIdentifier.threadNameWithIndex))
                            {
                                m_ThreadSelection.groups.Add(item.threadIdentifier.threadNameWithIndex);
                            }
                        }

                        // Update selection
                        m_ThreadSelection.selection.Clear();
                        if (newState)
                        {
                            foreach (string threadNameWithIndex in m_ThreadNames)
                            {
                                if (threadNameWithIndex != m_AllThreadIdentifier.threadNameWithIndex)
                                {
                                    var threadIdentifier = new ThreadIdentifier(threadNameWithIndex);
                                    if (threadIdentifier.index != ThreadIdentifier.kAll)
                                    {
                                        m_ThreadSelection.selection.Add(threadNameWithIndex);
                                    }
                                }
                            }
                        }
                    }
                    else if (item.threadIdentifier.index == ThreadIdentifier.kAll)
                    {
                        // Record active groups
                        if (newState)
                        {
                            if (!m_ThreadSelection.groups.Contains(item.threadIdentifier.threadNameWithIndex))
                            {
                                m_ThreadSelection.groups.Add(item.threadIdentifier.threadNameWithIndex);
                            }
                        }
                        else
                        {
                            m_ThreadSelection.groups.Remove(item.threadIdentifier.threadNameWithIndex);
                            // When turning off a sub group, turn of the 'all' group too
                            m_ThreadSelection.groups.Remove(m_AllThreadIdentifier.threadNameWithIndex);
                        }

                        // Update selection
                        if (newState)
                        {
                            foreach (string threadNameWithIndex in m_ThreadNames)
                            {
                                var threadIdentifier = new ThreadIdentifier(threadNameWithIndex);
                                if (threadIdentifier.name == item.threadIdentifier.name &&
                                    threadIdentifier.index != ThreadIdentifier.kAll)
                                {
                                    if (!m_ThreadSelection.selection.Contains(threadNameWithIndex))
                                    {
                                        m_ThreadSelection.selection.Add(threadNameWithIndex);
                                    }
                                }
                            }
                        }
                        else
                        {
                            var removeSelection = new List <string>();
                            foreach (string threadNameWithIndex in m_ThreadSelection.selection)
                            {
                                var threadIdentifier = new ThreadIdentifier(threadNameWithIndex);
                                if (threadIdentifier.name == item.threadIdentifier.name &&
                                    threadIdentifier.index != ThreadIdentifier.kAll)
                                {
                                    removeSelection.Add(threadNameWithIndex);
                                }
                            }
                            foreach (string threadNameWithIndex in removeSelection)
                            {
                                m_ThreadSelection.selection.Remove(threadNameWithIndex);
                            }
                        }
                    }
                    else
                    {
                        if (newState)
                        {
                            m_ThreadSelection.selection.Add(item.threadIdentifier.threadNameWithIndex);
                        }
                        else
                        {
                            m_ThreadSelection.selection.Remove(item.threadIdentifier.threadNameWithIndex);

                            // Turn off any group its in too
                            var groupIdentifier = new ThreadIdentifier(item.threadIdentifier);
                            groupIdentifier.SetAll();
                            m_ThreadSelection.groups.Remove(groupIdentifier.threadNameWithIndex);

                            // Turn of the 'all' group too
                            m_ThreadSelection.groups.Remove(m_AllThreadIdentifier.threadNameWithIndex);
                        }
                    }
                }
                break;
            }
        }
        bool ThreadSelected(ThreadIdentifier selectedThreadIdentifier)
        {
            if (ProfileAnalyzer.MatchThreadFilter(selectedThreadIdentifier.threadNameWithIndex, m_ThreadSelection.selection))
            {
                return(true);
            }

            // If querying the 'All' filter then check if all selected
            if (selectedThreadIdentifier.threadNameWithIndex == m_AllThreadIdentifier.threadNameWithIndex)
            {
                // Check all threads without All in the name are selected
                foreach (var threadNameWithIndex in m_ThreadNames)
                {
                    var threadIdentifier = new ThreadIdentifier(threadNameWithIndex);
                    if (threadIdentifier.index == ThreadIdentifier.kAll || threadIdentifier.index == ThreadIdentifier.kSingle)
                    {
                        continue;
                    }

                    if (!m_ThreadSelection.selection.Contains(threadNameWithIndex))
                    {
                        return(false);
                    }
                }

                return(true);
            }

            // Need to check 'all' and thread group all.
            if (selectedThreadIdentifier.index == ThreadIdentifier.kAll)
            {
                // Count all threads that match this thread group
                int count = 0;
                foreach (var threadNameWithIndex in m_ThreadNames)
                {
                    var threadIdentifier = new ThreadIdentifier(threadNameWithIndex);
                    if (threadIdentifier.index == ThreadIdentifier.kAll || threadIdentifier.index == ThreadIdentifier.kSingle)
                    {
                        continue;
                    }

                    if (selectedThreadIdentifier.name != threadIdentifier.name)
                    {
                        continue;
                    }

                    count++;
                }

                // Count all the threads we have selected that match this thread group
                int selectedCount = 0;
                foreach (var threadNameWithIndex in m_ThreadSelection.selection)
                {
                    var threadIdentifier = new ThreadIdentifier(threadNameWithIndex);
                    if (selectedThreadIdentifier.name != threadIdentifier.name)
                    {
                        continue;
                    }
                    if (threadIdentifier.index > count)
                    {
                        continue;
                    }

                    selectedCount++;
                }

                if (count == selectedCount)
                {
                    return(true);
                }
            }

            return(false);
        }
 public ThreadTreeViewItem(int id, int depth, string displayName, ThreadIdentifier threadIdentifier) : base(id, depth, displayName)
 {
     this.threadIdentifier = threadIdentifier;
 }
Example #9
0
        void CellGUI(Rect cellRect, ThreadTreeViewItem item, MyColumns column, ref RowGUIArgs args)
        {
            // Center cell rect vertically (makes it easier to place controls, icons etc in the cells)
            CenterRectUsingSingleLineHeight(ref cellRect);

            switch (column)
            {
            case MyColumns.ThreadName:
            {
                args.rowRect = cellRect;
                // base.RowGUI(args);    // Required to show tree indenting

                // Draw manually to keep indenting while add a tooltip
                Rect rect = cellRect;
                if (Event.current.rawType == EventType.Repaint)
                {
                    string text;
                    string tooltip;
                    GetThreadTreeViewItemInfo(item, out text, out tooltip);
                    var content = new GUIContent(text, tooltip);

                    if (activeLineStyle == null)
                    {
                        // activeLineStyle = DefaultStyles.boldLabel;
                        activeLineStyle = new GUIStyle(DefaultStyles.label);
                        activeLineStyle.normal.textColor = DefaultStyles.boldLabel.onActive.textColor;
                    }

                    // rect = DrawIndent(rect, item, ref args);

                    //bool mouseOver = rect.Contains(Event.current.mousePosition);
                    //DefaultStyles.label.Draw(rect, content, mouseOver, false, args.selected, args.focused);

                    // Must use this call to draw tooltip
                    EditorGUI.LabelField(rect, content, args.selected ? activeLineStyle : DefaultStyles.label);
                }
            }
            break;

            case MyColumns.GroupName:
            {
                Rect rect = cellRect;
                if (Event.current.rawType == EventType.Repaint)
                {
                    rect = DrawIndent(rect, item, ref args);

                    string groupName = GetItemGroupName(item);
                    var    content   = new GUIContent(groupName, groupName);
                    EditorGUI.LabelField(rect, content);
                }
            }
            break;

            case MyColumns.State:
                bool oldState = GetThreadSelectedState(item.threadIdentifier) == ThreadSelected.Selected;
                bool newState = EditorGUI.Toggle(cellRect, oldState);
                if (newState != oldState)
                {
                    if (item.threadIdentifier.threadNameWithIndex == m_AllThreadIdentifier.threadNameWithIndex)
                    {
                        // Record active groups
                        m_ThreadSelection.groups.Clear();
                        if (newState)
                        {
                            if (!m_ThreadSelection.groups.Contains(item.threadIdentifier.threadNameWithIndex))
                            {
                                m_ThreadSelection.groups.Add(item.threadIdentifier.threadNameWithIndex);
                            }
                        }

                        // Update selection
                        m_ThreadSelection.selection.Clear();
                        if (newState)
                        {
                            foreach (string threadNameWithIndex in m_ThreadNames)
                            {
                                if (threadNameWithIndex != m_AllThreadIdentifier.threadNameWithIndex)
                                {
                                    var threadIdentifier = new ThreadIdentifier(threadNameWithIndex);
                                    if (threadIdentifier.index != ThreadIdentifier.kAll)
                                    {
                                        m_ThreadSelection.selection.Add(threadNameWithIndex);
                                    }
                                }
                            }
                        }
                    }
                    else if (item.threadIdentifier.index == ThreadIdentifier.kAll)
                    {
                        // Record active groups
                        if (newState)
                        {
                            if (!m_ThreadSelection.groups.Contains(item.threadIdentifier.threadNameWithIndex))
                            {
                                m_ThreadSelection.groups.Add(item.threadIdentifier.threadNameWithIndex);
                            }
                        }
                        else
                        {
                            m_ThreadSelection.groups.Remove(item.threadIdentifier.threadNameWithIndex);
                            // When turning off a sub group, turn of the 'all' group too
                            m_ThreadSelection.groups.Remove(m_AllThreadIdentifier.threadNameWithIndex);
                        }

                        // Update selection
                        if (newState)
                        {
                            foreach (string threadNameWithIndex in m_ThreadNames)
                            {
                                var threadIdentifier = new ThreadIdentifier(threadNameWithIndex);
                                if (threadIdentifier.name == item.threadIdentifier.name &&
                                    threadIdentifier.index != ThreadIdentifier.kAll)
                                {
                                    if (!m_ThreadSelection.selection.Contains(threadNameWithIndex))
                                    {
                                        m_ThreadSelection.selection.Add(threadNameWithIndex);
                                    }
                                }
                            }
                        }
                        else
                        {
                            var removeSelection = new List <string>();
                            foreach (string threadNameWithIndex in m_ThreadSelection.selection)
                            {
                                var threadIdentifier = new ThreadIdentifier(threadNameWithIndex);
                                if (threadIdentifier.name == item.threadIdentifier.name &&
                                    threadIdentifier.index != ThreadIdentifier.kAll)
                                {
                                    removeSelection.Add(threadNameWithIndex);
                                }
                            }
                            foreach (string threadNameWithIndex in removeSelection)
                            {
                                m_ThreadSelection.selection.Remove(threadNameWithIndex);
                            }
                        }
                    }
                    else
                    {
                        if (newState)
                        {
                            m_ThreadSelection.selection.Add(item.threadIdentifier.threadNameWithIndex);
                        }
                        else
                        {
                            m_ThreadSelection.selection.Remove(item.threadIdentifier.threadNameWithIndex);

                            // Turn off any group its in too
                            var groupIdentifier = new ThreadIdentifier(item.threadIdentifier);
                            groupIdentifier.SetAll();
                            m_ThreadSelection.groups.Remove(groupIdentifier.threadNameWithIndex);

                            // Turn of the 'all' group too
                            m_ThreadSelection.groups.Remove(m_AllThreadIdentifier.threadNameWithIndex);
                        }
                    }

                    StateChanged = true;

                    // Re-sort
                    SortIfNeeded(GetRows());
                }
                break;
            }
        }
 /// <summary>Initialise ThreadIdentifier from another ThreadIdentifier</summary>
 /// <param name="threadIdentifier">The other ThreadIdentifier</param>
 public ThreadIdentifier(ThreadIdentifier threadIdentifier)
 {
     name  = threadIdentifier.name;
     index = threadIdentifier.index;
     threadNameWithIndex = threadIdentifier.threadNameWithIndex;
 }