Пример #1
0
        public override void    SetSettings(NGSettings ngsettings)
        {
            GeneralSettings    general    = ngsettings.Get <GeneralSettings>();
            LogSettings        log        = ngsettings.Get <LogSettings>();
            StackTraceSettings stackTrace = ngsettings.Get <StackTraceSettings>();

            //general.openMode = ConsoleSettings.ModeOpen.AssetDatabaseOpenAsset;
            //general.horizontalScrollbar = true;
            general.filterUselessStackFrame = false;

            //log.giveFocusToEditor = true;
            log.forceFocusOnModifier = EventModifiers.Alt;
            log.displayTime          = true;
            //log.timeFormat = "HH:mm:ss.fff";

            stackTrace.displayFilepath         = StackTraceSettings.PathDisplay.Visible;
            stackTrace.displayRelativeToAssets = false;

            stackTrace.displayReturnValue   = true;
            stackTrace.displayReflectedType = StackTraceSettings.DisplayReflectedType.NamespaceAndClass;
            stackTrace.displayArgumentType  = true;
            stackTrace.displayArgumentName  = true;

            stackTrace.previewLinesBeforeStackFrame = 4;
            stackTrace.previewLinesAfterStackFrame  = 4;
            stackTrace.displayTabAsSpaces           = 4;
        }
Пример #2
0
        private static void     SetAsCategory(object data)
        {
            StackTraceSettings stackTrace = HQ.Settings.Get <StackTraceSettings>();
            string             frame      = data as string;

            // Fetch "namespace.class[:.]method(".
            int n = frame.IndexOf("(");

            if (n == -1)
            {
                return;
            }

            string method      = frame.Substring(0, n);
            string placeholder = "Category Name";

            for (int i = 0; i < stackTrace.categories.Count; i++)
            {
                if (stackTrace.categories[i].method == method)
                {
                    placeholder = stackTrace.categories[i].category;
                    break;
                }
            }

            PromptWindow.Start(placeholder, RowUtility.SetCategory, method);
        }
Пример #3
0
        public override void    OnGUI(Rect r)
        {
            this.currentVars = this.perWindowVars.Get(RowUtility.drawingWindow);

            r.y += 2F;
            r    = this.DrawFolderTabs(r);

            if (this.folders.Count > 0)
            {
                Folder folder = this.folders[this.currentVars.workingFolder];
                folder.rowsDrawer.DrawRows(r, false);

                if (folder.viewingNote != null && string.IsNullOrEmpty(folder.viewingNote.note) == false)
                {
                    if (Event.current.type == EventType.MouseMove)
                    {
                        if (folder.noteRect.Contains(Event.current.mousePosition) == false)
                        {
                            folder.viewingNote = null;
                            return;
                        }
                    }

                    StackTraceSettings stackTrace = HQ.Settings.Get <StackTraceSettings>();

                    folder.noteRect.y += Constants.SingleLineHeight;
                    EditorGUI.DrawRect(folder.noteRect, stackTrace.previewSourceCodeBackgroundColor);
                    GUI.Label(folder.noteRect, folder.viewingNote.note, stackTrace.PreviewSourceCodeStyle);
                    folder.noteRect.y -= Constants.SingleLineHeight;

                    RowUtility.drawingWindow.Repaint();
                }
            }
        }
Пример #4
0
        public override void    SetTheme(NGSettings instance)
        {
            LogSettings        log        = instance.Get <LogSettings>();
            StackTraceSettings stackTrace = instance.Get <StackTraceSettings>();

            log.styleOverride.ResetStyle();
            log.styleOverride.overrideMask |= (int)GUIStyleOverride.Overrides.Alignment;
            log.styleOverride.alignment     = TextAnchor.UpperLeft;
            log.styleOverride.overrideMask |= (int)GUIStyleOverride.Overrides.FontSize;
            log.styleOverride.fontSize      = 16;
            log.height = 24F;

            log.timeStyleOverride.ResetStyle();
            log.timeStyleOverride.overrideMask |= (int)GUIStyleOverride.Overrides.FontSize;
            log.timeStyleOverride.fontSize      = 12;

            log.collapseLabelStyleOverride.fixedHeight = 16F;

            stackTrace.height = 20F;

            stackTrace.styleOverride.ResetStyle();
            stackTrace.styleOverride.overrideMask |= (int)GUIStyleOverride.Overrides.FontSize;
            stackTrace.styleOverride.fontSize      = 14;

            stackTrace.previewHeight = 24F;

            stackTrace.previewSourceCodeStyleOverride.ResetStyle();
            stackTrace.previewSourceCodeStyleOverride.overrideMask |= (int)GUIStyleOverride.Overrides.Alignment;
            stackTrace.previewSourceCodeStyleOverride.alignment     = TextAnchor.MiddleLeft;
            stackTrace.previewSourceCodeStyleOverride.overrideMask |= (int)GUIStyleOverride.Overrides.FontSize;
            stackTrace.previewSourceCodeStyleOverride.fontSize      = 16;
        }
Пример #5
0
        private static void     SetStackTraceSettings(StackTraceSettings stackTrace)
        {
            stackTrace.styleOverride.ResetStyle();
            stackTrace.styleOverride.baseStyleName = "label";
            stackTrace.styleOverride.overrideMask |= (int)GUIStyleOverride.Overrides.WordWrap;
            stackTrace.styleOverride.wordWrap      = false;
            stackTrace.styleOverride.overrideMask |= (int)GUIStyleOverride.Overrides.RichText;
            stackTrace.styleOverride.richText      = true;
            stackTrace.styleOverride.overrideMask |= (int)GUIStyleOverride.Overrides.Margin;
            stackTrace.styleOverride.margin        = new RectOffset(0, 0, GUI.skin.label.margin.top, GUI.skin.label.margin.bottom);

            stackTrace.returnValueColor   = new Color(78F / 255F, 50F / 255F, 255F / 255F);
            stackTrace.reflectedTypeColor = new Color(103F / 255F, 103F / 255F, 103F / 255F);
            stackTrace.methodNameColor    = new Color(49F / 255F, 68F / 255F, 84F / 255F);
            stackTrace.argumentTypeColor  = new Color(84F / 255F, 40F / 255, 250F / 255F);
            stackTrace.argumentNameColor  = new Color(170F / 255F, 115F / 255F, 114F / 255F);
            stackTrace.filepathColor      = new Color(69F / 255F, 69F / 255F, 69F / 255F);
            stackTrace.lineColor          = new Color(44F / 255F, 6F / 255F, 199F / 255F);

            stackTrace.previewTextColor = stackTrace.filepathColor;
            stackTrace.previewLineColor = stackTrace.lineColor;

            stackTrace.previewSourceCodeBackgroundColor         = new Color(174F / 255F, 177F / 255F, 177F / 255F);
            stackTrace.previewSourceCodeMainLineBackgroundColor = new Color(161F / 255F, 161F / 255F, 161F / 255F);

            stackTrace.previewSourceCodeStyleOverride.ResetStyle();
            stackTrace.previewSourceCodeStyleOverride.baseStyleName = "label";
            stackTrace.previewSourceCodeStyleOverride.overrideMask |= (int)GUIStyleOverride.Overrides.RichText;
            stackTrace.previewSourceCodeStyleOverride.richText      = true;
            stackTrace.previewSourceCodeStyleOverride.overrideMask |= (int)GUIStyleOverride.Overrides.Margin;
            stackTrace.previewSourceCodeStyleOverride.margin        = new RectOffset(0, 0, GUI.skin.label.margin.top, GUI.skin.label.margin.bottom);

            stackTrace.styleOverride.CopyTo(stackTrace.previewSourceCodeStyleOverride);
            stackTrace.previewSourceCodeStyleOverride.margin = new RectOffset();

            if (stackTrace.keywords.Length >= 3)
            {
                if (stackTrace.keywords[0].keywords.Length > 0 &&
                    stackTrace.keywords[0].keywords[0] == ";")
                {
                    stackTrace.keywords[0].color = new Color(96F / 255F, 69F / 255F, 0F / 255F);
                }
                if (stackTrace.keywords[1].keywords.Length > 0 &&
                    stackTrace.keywords[1].keywords[0] == "this")
                {
                    stackTrace.keywords[1].color = new Color(141F / 255F, 47F / 255F, 212F / 255F);
                }
                if (stackTrace.keywords[2].keywords.Length > 0 &&
                    stackTrace.keywords[2].keywords[0] == "var")
                {
                    stackTrace.keywords[2].color = new Color(186F / 255F, 99F / 255F, 218F / 255F);
                }
            }
        }
Пример #6
0
        private static void     AddFrameFilter(string filter)
        {
            StackTraceSettings stackTrace = HQ.Settings.Get <StackTraceSettings>();

            if (stackTrace.filters.Contains(filter) == false)
            {
                stackTrace.filters.Add(filter);
                HQ.InvalidateSettings();
                EditorUtility.DisplayDialog(Constants.PackageTitle, "\"" + filter + "\" has been added to the filters.", "OK");
            }
            else
            {
                EditorUtility.DisplayDialog(Constants.PackageTitle, "\"" + filter + "\" is already a filter.", "OK");
            }
        }
Пример #7
0
        private static void     OnGUIGeneralStackTrace()
        {
            StackTraceSettings stackTraceSettings = HQ.Settings.Get <StackTraceSettings>();
            LogSettings        logSettings        = HQ.Settings.Get <LogSettings>();

            ConsoleSettingsEditor.generalStackTraceScrollPosition = EditorGUILayout.BeginScrollView(ConsoleSettingsEditor.generalStackTraceScrollPosition);
            {
                EditorGUI.BeginChangeCheck();
                ConsoleSettingsEditor.sectionStackTrace.OnGUI();
                if (EditorGUI.EndChangeCheck() == true)
                {
                    LogConditionParser.cachedFrames.Clear();
                    LogConditionParser.cachedFramesArrays.Clear();
                    MainModule.methodsCategories.Clear();
                }

                GUILayout.Space(10F);
            }
            EditorGUILayout.EndScrollView();

            EditorGUILayout.BeginVertical(GUILayoutOptionPool.Height(16F + 2 * logSettings.height + 8 * Constants.SingleLineHeight));
            EditorGUILayout.BeginHorizontal(GeneralStyles.Toolbar);
            EditorGUILayout.LabelField("Preview :");
            EditorGUILayout.EndHorizontal();

            if (stackTraceSettings.skipUnreachableFrame == true)
            {
                ConsoleSettingsEditor.DrawStackFrame(0, "Sub Frame.", "Assets/An/Existing/File.cs", true);
            }
            else
            {
                ConsoleSettingsEditor.DrawStackFrame(0, "Top Frame.", "A/File/Somewhere/That/Does/Not/Exist.cs", false);
                ConsoleSettingsEditor.DrawStackFrame(1, "Sub Frame.", "Assets/An/Existing/File.cs", true);
            }

            ConsoleSettingsEditor.DrawStackFrameCode(1, false, "using UnityEngine;");
            ConsoleSettingsEditor.DrawStackFrameCode(2, false, "private static class Foo : Object");
            ConsoleSettingsEditor.DrawStackFrameCode(3, false, "{");
            ConsoleSettingsEditor.DrawStackFrameCode(4, false, "	public internal void	Func(Vector2 v)");
            ConsoleSettingsEditor.DrawStackFrameCode(5, false, "	{");
            ConsoleSettingsEditor.DrawStackFrameCode(6, true, "		Debug.Log(\"Someting\");");
            ConsoleSettingsEditor.DrawStackFrameCode(7, false, "	}");
            ConsoleSettingsEditor.DrawStackFrameCode(8, false, "}");

            EditorGUILayout.EndVertical();
        }
Пример #8
0
        private static void     DrawStackFrameCode(int i, bool mainLine, string content)
        {
            StackTraceSettings settings = HQ.Settings.Get <StackTraceSettings>();
            Rect r = GUILayoutUtility.GetRect(0F, settings.previewHeight, settings.PreviewSourceCodeStyle);

            if (Event.current.type == EventType.Repaint)
            {
                if (mainLine == false)
                {
                    EditorGUI.DrawRect(r, settings.previewSourceCodeBackgroundColor);
                }
                else
                {
                    EditorGUI.DrawRect(r, settings.previewSourceCodeMainLineBackgroundColor);
                }
            }

            GUI.Label(r, Utility.Color(i.ToString(), settings.previewLineColor) + ConsoleUtility.ColorLine(content), settings.PreviewSourceCodeStyle);
            r.y += r.height;
        }
Пример #9
0
        private static void     DrawStackFrame(int i, string a, string filepath, bool fileExist)
        {
            StackTraceSettings settings = HQ.Settings.Get <StackTraceSettings>();
            Rect  r     = GUILayoutUtility.GetRect(0F, settings.height, settings.Style);
            float width = r.width;

            // Substract viewRect to avoid scrollbar.
            r.height = settings.height;

            // Display the stack trace.
            r.width = width - 16F;
            FrameBuilder.Clear();
            FrameBuilder.returnType    = "Void";
            FrameBuilder.namespaceName = "namespace";
            FrameBuilder.classType     = "class";
            FrameBuilder.methodName    = "func";
            FrameBuilder.fileName      = filepath;
            FrameBuilder.fileExist     = fileExist;
            FrameBuilder.line          = 1234;
            FrameBuilder.parameterTypes.Add("Rect");
            FrameBuilder.parameterNames.Add("r");
            FrameBuilder.parameterTypes.Add("int");
            FrameBuilder.parameterNames.Add("a");

            if (i == 0)
            {
                GUI.Button(r, FrameBuilder.ToString("→ ", settings), settings.Style);
            }
            else
            {
                GUI.Button(r, FrameBuilder.ToString("↑ ", settings), settings.Style);
            }

            r.x     = r.width;
            r.width = 16F;
            GUI.Button(r, "+", settings.Style);

            r.y += r.height;
        }
Пример #10
0
        private static void     SetCategory(object data, string category)
        {
            StackTraceSettings stackTrace = HQ.Settings.Get <StackTraceSettings>();
            string             method     = data as string;

            for (int i = 0; i < stackTrace.categories.Count; i++)
            {
                if (stackTrace.categories[i].method == method)
                {
                    if (string.IsNullOrEmpty(category) == false)
                    {
                        stackTrace.categories[i].category = category;
                    }
                    else
                    {
                        stackTrace.categories.RemoveAt(i);
                    }

                    LogConditionParser.cachedFrames.Clear();
                    LogConditionParser.cachedFramesArrays.Clear();
                    MainModule.methodsCategories.Clear();
                    return;
                }
            }

            if (string.IsNullOrEmpty(category) == false)
            {
                stackTrace.categories.Add(new StackTraceSettings.MethodCategory()
                {
                    category = category, method = method
                });

                LogConditionParser.cachedFrames.Clear();
                LogConditionParser.cachedFramesArrays.Clear();
                MainModule.methodsCategories.Clear();
            }
        }
Пример #11
0
        private Frame   ParseStackFrame(string raw, int n)
        {
            Frame frame = new Frame();

            frame.raw = raw;

            FrameBuilder.Clear();

            StringBuilder buffer = Utility.GetBuffer();

            try
            {
                // Exception/Error log.
                if ((this.log.mode & (Mode.ScriptingException |
                                      Mode.ScriptingError |
                                      Mode.Error |
                                      Mode.Fatal |
                                      Mode.GraphCompileError)) != 0)
                {
                    buffer.Append(raw);

                    // For convenience, just convert it to a normal log, using the StringBuilder, also for convenience.
                    int lastDot = 0;
                    for (int i = 0; i < buffer.Length; ++i)
                    {
                        // Detect next symbol, skip constructors and static constructors. (".ctor" and ".cctor")
                        if (buffer[i] == '.' &&
                            i > 0 &&
                            buffer[i - 1] != '.' &&
                            buffer[i - 1] != ':')
                        {
                            lastDot = i;
                        }
                        else if (buffer[i] == ':')
                        {
                            lastDot = i;
                        }
                        // Delete any spaces before parameters.
                        else if (buffer[i] == ' ')
                        {
                            buffer.Remove(i, 1);
                            --i;
                        }

                        // Find start of method and avoid special prefix starting with a parenthese.
                        if (buffer[i] == '(' && i > 0)
                        {
                            buffer[lastDot] = ':';
                            break;
                        }
                    }

                    raw           = buffer.ToString();
                    buffer.Length = 0;
                }

                // Handle "Rethrow as Exception:"
                if (raw.StartsWith("Rethrow") == true)
                {
                    return(null);
                }

                // Too much stacks get truncated possibly anywhere.
                if (raw.EndsWith("<messagetruncated>") == true || raw.EndsWith("<message truncated>") == true || raw.EndsWith("<message truncated") == true)
                {
                    return(null);
                }

                //InternalNGDebug.LogFile("raw="+raw);

                StackTraceSettings stackTrace = HQ.Settings.Get <StackTraceSettings>();

                bool unreachableFrame = false;

                int endClass = raw.IndexOf(':');
                FrameBuilder.classType = raw.Substring(0, endClass);

                int endMethod = raw.IndexOf('(', endClass);
                FrameBuilder.methodName = raw.Substring(endClass + 1, endMethod - endClass - 1);

                int    endParameters = raw.IndexOf(')', endMethod);
                string allParameters = raw.Substring(endMethod + 1, endParameters - endMethod - 1);

                int startFilepath = raw.IndexOf("at ", endMethod);

                // Handle yield context, i.e. "Namespace.Class.<Method>c__Iterator23:MoveNext".
                if (FrameBuilder.classType.Contains("<") == true)
                {
                    unreachableFrame = true;
                    buffer.Append(FrameBuilder.classType);

                    int startYieldMethod = FrameBuilder.classType.IndexOf('<');
                    int endYieldMethod   = FrameBuilder.classType.IndexOf('>');

                    buffer.Remove(endYieldMethod, buffer.Length - endYieldMethod);
                    buffer.Remove(0, startYieldMethod + 1);

                    if (stackTrace.displayReturnValue == true)
                    {
                        FrameBuilder.returnType = "YieldInstruction";
                    }

                    FrameBuilder.classType  = "";
                    FrameBuilder.methodName = buffer.ToString();

                    buffer.Length = 0;
                }
                // Handle special prefix, i.e. "(wrapper remoting-invoke-with-check) Namespace.Class".
                else if (FrameBuilder.classType.Contains("(") == true)
                {
                    buffer.Append(FrameBuilder.classType);
                    buffer.Remove(0, FrameBuilder.classType.IndexOf(')') + 1);
                    FrameBuilder.classType = buffer.ToString();

                    buffer.Length = 0;
                }
                // Handle generic method, i.e. "Namespace.Class.Method[Type]".
                else if (FrameBuilder.methodName.Contains("[") == true)
                {
                    buffer.Append(FrameBuilder.methodName);

                    int startGenericType = FrameBuilder.methodName.IndexOf('[');
                    int endGenericType   = FrameBuilder.methodName.LastIndexOf(']');

                    buffer.Remove(startGenericType, endGenericType - startGenericType + 1);

                    FrameBuilder.methodName = buffer.ToString();

                    buffer.Length = 0;
                }

                // Split namespace from class.
                int m = FrameBuilder.classType.LastIndexOf('.');
                if (m != -1)
                {
                    FrameBuilder.namespaceName = FrameBuilder.classType.Substring(0, m);
                    FrameBuilder.classType     = FrameBuilder.classType.Substring(m + 1);
                }

                //InternalNGDebug.LogFile("class=" + FrameBuilder.classType);
                //InternalNGDebug.LogFile("method=" + FrameBuilder.methodName);
                //InternalNGDebug.LogFile("param=" + allParameters);

                if (startFilepath != -1)
                {
                    int    endFilepath = raw.LastIndexOf(':', raw.Length - 1);
                    string filepath    = raw.Substring(startFilepath + 3, endFilepath - startFilepath - 3);

                    int    endLine = raw.IndexOf(')', endFilepath);
                    string line    = raw.Substring(endFilepath + 1, endLine - endFilepath - 1);

                    // Skip non-editable frame.
                    frame.fileExist = ConsoleUtility.files.FileExist(filepath);
                    if (frame.fileExist == false &&
                        stackTrace.skipUnreachableFrame == true)
                    {
                        return(null);
                    }

                    frame.fileName         = filepath;
                    frame.line             = int.Parse(line);
                    FrameBuilder.fileExist = frame.fileExist;
                    //InternalNGDebug.LogFile("filepath="+filepath);
                    //InternalNGDebug.LogFile("line=" + int.Parse(line));
                }
                // It is not guaranteed that the fileName is the first frame. Use it in the only case of total failure. i.e. Debug.Log*()
                else if (string.IsNullOrEmpty(this.log.file) == true && n == 0)
                {
                    frame.fileName = this.log.file;
                    frame.line     = this.log.line;
                }
                else
                {
                    frame.fileName = string.Empty;
                }

                FrameBuilder.fileName = frame.fileName;
                FrameBuilder.line     = frame.line;

                if (FrameBuilder.classType == string.Empty &&
                    string.IsNullOrEmpty(frame.fileName) == true)
                {
                    return(null);
                }

                if (unreachableFrame == false &&
                    (stackTrace.displayReturnValue == true ||
                     stackTrace.displayArgumentName == true))
                {
                    FastClassCache.HashClass classType = ConsoleUtility.classes.GetType(FrameBuilder.namespaceName, FrameBuilder.classType);

                    if (classType != null)
                    {
                        if (FrameBuilder.methodName == ".cctor" ||                         // Static constructor.
                            FrameBuilder.methodName == ".ctor")                            // Normal constructor.
                        {
                            string[] parameters = allParameters.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

                            // Many parameters includes ambiguity.
                            if (parameters.Length > 0 && classType.type != null)
                            {
                                ConstructorInfo ci = this.GetConstructorFromParameters(classType.type, parameters);

                                // Append data from the found constructor.
                                if (ci != null)
                                {
                                    FrameBuilder.namespaceName = ci.ReflectedType.Namespace;
                                    FrameBuilder.classType     = ci.ReflectedType.Name;

                                    if (stackTrace.displayArgumentType == true ||
                                        stackTrace.displayArgumentName == true)
                                    {
                                        this.AppendParameters(ci.GetParameters());
                                    }
                                }
                                // Append every data as we can from the condition.
                                else
                                {
                                    this.AddConditionParameters(parameters);
                                }
                            }
                        }
                        else if (classType.methods != null)
                        {
                            MethodInfo methodInfo = classType.methods.GetMethod(FrameBuilder.methodName, allParameters);

                            // Append data from the found method.
                            if (methodInfo != null)
                            {
                                FrameBuilder.isStaticMethod = methodInfo.IsStatic;

                                NGLoggerAttribute[] attributes = methodInfo.GetCustomAttributes(typeof(NGLoggerAttribute), false) as NGLoggerAttribute[];
                                if (attributes.Length > 0)
                                {
                                    frame.category = attributes[0].tag;
                                }

                                if (stackTrace.displayReturnValue == true)
                                {
                                    FrameBuilder.returnType = methodInfo.ReturnType.Name;
                                }

                                if (methodInfo.ReflectedType.IsGenericTypeDefinition == true)
                                {
                                    m = FrameBuilder.classType.IndexOf("[");

                                    if (m != -1)
                                    {
                                        string[] genericTypes = FrameBuilder.classType.Substring(m + 1, FrameBuilder.classType.Length - m - 2).Split(',');                                                // Removed the 2 brackets.

                                        for (int i = 0; i < genericTypes.Length; i++)
                                        {
                                            Type type = Utility.GetType(genericTypes[i]);

                                            if (type != null)
                                            {
                                                FrameBuilder.genericTypes.Add(type.Name);
                                            }
                                            else
                                            {
                                                FrameBuilder.genericTypes.Add(genericTypes[i]);
                                            }
                                        }
                                    }
                                    else
                                    {
                                        foreach (var type in methodInfo.ReflectedType.GetGenericArguments())
                                        {
                                            FrameBuilder.genericTypes.Add(type.Name);
                                        }
                                    }
                                }

                                FrameBuilder.namespaceName = methodInfo.ReflectedType.Namespace;
                                FrameBuilder.classType     = methodInfo.ReflectedType.Name;
                                FrameBuilder.methodName    = methodInfo.Name;

                                if (stackTrace.displayArgumentType == true ||
                                    stackTrace.displayArgumentName == true)
                                {
                                    this.AppendParameters(methodInfo.GetParameters());
                                }
                            }
                            // Append every data as we can from the condition.
                            else
                            {
                                string[] parameters = allParameters.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

                                this.AddConditionParameters(parameters);
                            }
                        }
                    }
                }

                // Get custom Category from NGSettings, it does not have priority over attribute!
                if (frame.category == null)
                {
                    string methodName = FrameBuilder.namespaceName + '.' + FrameBuilder.classType + ':' + FrameBuilder.methodName;

                    for (int i = 0; i < stackTrace.categories.Count; i++)
                    {
                        if (stackTrace.categories[i].method == methodName)
                        {
                            frame.category = stackTrace.categories[i].category;
                            break;
                        }
                    }
                }

                if (n == 0)
                {
                    frame.frameString = FrameBuilder.ToString("→ ", stackTrace);
                }
                else
                {
                    frame.frameString = FrameBuilder.ToString("↑ ", stackTrace);
                }

                //if (HQ.Settings.general.horizontalScrollbar == true)
                //{
                //	// Calcul max width
                //	Utility.content.text = frame.frameString;
                //	Vector2	size = HQ.Settings.stackTrace.style.CalcSize(Utility.content);
                //	if (this.maxWidthFrame < size.x)
                //		this.maxWidthFrame = size.x;
                //}
            }
            catch (Exception ex)
            {
                InternalNGDebug.LogFileException("Raw " + n + "=" + raw + Environment.NewLine + FrameBuilder.ToRawString(), ex);
                InternalNGDebug.LogFile(frame.frameString);
                return(null);
            }
            finally
            {
                Utility.RestoreBuffer(buffer);
            }

            return(frame);
        }
Пример #12
0
        /// <summary></summary>
        /// <remarks>Test your Color in Unity 4, because rich text is buggy over there.</remarks>
        /// <param name="instance"></param>
        public override void    SetTheme(NGSettings instance)
        {
            GeneralSettings    general    = instance.Get <GeneralSettings>();
            LogSettings        log        = instance.Get <LogSettings>();
            StackTraceSettings stackTrace = instance.Get <StackTraceSettings>();
            Color defaultNormalColor      = new Color(180F / 255F, 180F / 255F, 180F / 255F);

            general.consoleBackground = new Color(0F, 0F, 0F, 200F / 255F);

            general.MenuButtonStyle                      = new GUIStyle("ToolbarButton");
            general.MenuButtonStyle.clipping             = TextClipping.Overflow;
            general.MenuButtonStyle.normal.background    = AssetDatabase.LoadAssetAtPath(HQ.RootPath + "/NGConsole/Editor/Themes/CMDTheme/MenuButton.png", typeof(Texture2D)) as Texture2D;
            general.MenuButtonStyle.normal.textColor     = new Color(51F / 255F, 228F / 255F, 1F, 1F);
            general.MenuButtonStyle.hover.background     = null;
            general.MenuButtonStyle.active.background    = AssetDatabase.LoadAssetAtPath(HQ.RootPath + "/NGConsole/Editor/Themes/CMDTheme/MenuButtonActive.png", typeof(Texture2D)) as Texture2D;
            general.MenuButtonStyle.active.textColor     = new Color(180F / 255F, 180F / 255F, 180F / 255F, 1F);
            general.MenuButtonStyle.focused.background   = null;
            general.MenuButtonStyle.onNormal.background  = AssetDatabase.LoadAssetAtPath(HQ.RootPath + "/NGConsole/Editor/Themes/CMDTheme/MenuButtonFocused.png", typeof(Texture2D)) as Texture2D;
            general.MenuButtonStyle.onNormal.textColor   = general.MenuButtonStyle.active.textColor;
            general.MenuButtonStyle.onHover.background   = null;
            general.MenuButtonStyle.onActive.background  = general.MenuButtonStyle.active.background;
            general.MenuButtonStyle.onActive.textColor   = general.MenuButtonStyle.active.textColor;
            general.MenuButtonStyle.onFocused.background = null;
            general.MenuButtonStyle.padding              = new RectOffset(6, 6, 0, 0);
            general.MenuButtonStyle.font                 = AssetDatabase.LoadAssetAtPath(HQ.RootPath + "/NGConsole/Editor/Themes/CMDTheme/Consolas.ttf", typeof(Font)) as Font;
            general.MenuButtonStyle.fontSize             = 13;
            general.MenuButtonStyle.fixedHeight          = 16;

            general.ToolbarStyle = new GUIStyle("Toolbar");
            general.ToolbarStyle.normal.background = null;

            log.selectedBackground = new Color(19F / 255F, 30F / 255F, 47F / 255F);
            log.evenBackground     = new Color(0F, 0F, 0F);
            log.oddBackground      = new Color(8F / 255F, 8F / 255F, 8F / 255F);

            log.Style                   = new GUIStyle(GUI.skin.label);
            log.Style.font              = general.MenuButtonStyle.font;
            log.Style.fontSize          = 13;
            log.Style.alignment         = TextAnchor.UpperLeft;
            log.Style.wordWrap          = false;
            log.Style.richText          = true;
            log.Style.clipping          = TextClipping.Clip;
            log.Style.normal.textColor  = defaultNormalColor;
            log.Style.hover.textColor   = defaultNormalColor;
            log.Style.active.textColor  = defaultNormalColor;
            log.Style.focused.textColor = defaultNormalColor;
            log.Style.margin.left       = 0;
            log.Style.margin.right      = 0;

            log.TimeStyle                  = new GUIStyle(GUI.skin.label);
            log.TimeStyle.alignment        = TextAnchor.MiddleLeft;
            log.TimeStyle.normal.textColor = new Color(58F / 255F, 206F / 255F, 255F / 255F);

            log.CollapseLabelStyle               = new GUIStyle("CN CountBadge");
            log.CollapseLabelStyle.alignment     = TextAnchor.LowerLeft;
            log.CollapseLabelStyle.fontSize      = 10;
            log.CollapseLabelStyle.contentOffset = new Vector2(0F, 2F);
            log.CollapseLabelStyle.richText      = false;
            log.CollapseLabelStyle.clipping      = TextClipping.Overflow;
            log.CollapseLabelStyle.margin        = new RectOffset(0, 0, 0, 0);
            log.CollapseLabelStyle.fixedHeight   = 16F;

            log.ContentStyle          = new GUIStyle(GUI.skin.label);
            log.ContentStyle.wordWrap = true;
            log.ContentStyle.richText = true;

            stackTrace.Style                   = new GUIStyle(log.Style);
            stackTrace.Style.font              = general.MenuButtonStyle.font;
            stackTrace.Style.fontSize          = 13;
            stackTrace.Style.hover.background  = Utility.CreateDotTexture(.17F, .17F, .17F, 1F);
            stackTrace.Style.active.background = null;
            stackTrace.Style.margin.left       = 0;
            stackTrace.Style.margin.right      = 0;

            stackTrace.returnValueColor   = new Color(92F / 255F, 193F / 255F, 114F / 255F);
            stackTrace.reflectedTypeColor = new Color(141F / 255F, 141F / 255F, 141F / 255F);
            stackTrace.methodNameColor    = new Color(171F / 255F, 171F / 255F, 171F / 255F);
            stackTrace.argumentTypeColor  = new Color(92F / 255F, 193F / 255, 114F / 255F);
            stackTrace.argumentNameColor  = new Color(4F / 255F, 255F / 255F, 224F / 255F);
            stackTrace.filepathColor      = new Color(167F / 255F, 172F / 255F, 172F / 255F);
            stackTrace.lineColor          = new Color(141F / 255F, 141F / 255F, 255F / 255F);

            stackTrace.previewTextColor = new Color(167F / 255F, 172F / 255F, 172F / 255F);
            stackTrace.previewLineColor = new Color(141F / 255F, 141F / 255F, 255F / 255F);

            stackTrace.previewSourceCodeBackgroundColor         = new Color(.11484375F, .11484375F, .11484375F);
            stackTrace.previewSourceCodeMainLineBackgroundColor = new Color(.01484375F, 0.01484375F, .01484375F);
            stackTrace.PreviewSourceCodeStyle        = new GUIStyle(log.Style);
            stackTrace.PreviewSourceCodeStyle.margin = new RectOffset();

            if (stackTrace.keywords.Length >= 3)
            {
                if (stackTrace.keywords[0].keywords.Length > 0 &&
                    stackTrace.keywords[0].keywords[0] == ";")
                {
                    stackTrace.keywords[0].color = new Color(4F / 255F, 255F / 255F, 224F / 255F);
                }
                if (stackTrace.keywords[1].keywords.Length > 0 &&
                    stackTrace.keywords[1].keywords[0] == "this")
                {
                    stackTrace.keywords[1].color = new Color(92F / 255F, 193F / 255, 114F / 255F);
                }
                if (stackTrace.keywords[2].keywords.Length > 0 &&
                    stackTrace.keywords[2].keywords[0] == "var")
                {
                    stackTrace.keywords[2].color = new Color(52F / 255F, 193F / 255, 94F / 255F);
                }
            }

            ConsoleUtility.files.Reset();
        }
Пример #13
0
        public static string    ToString(string prefix, StackTraceSettings settings)
        {
            // Append prefix.
            StringBuilder buffer = Utility.GetBuffer();

            buffer.Append(prefix);

            // Append return type.
            if (settings.displayReturnValue == true)
            {
                buffer.Append(FrameBuilder.returnType, settings.returnValueColor);
                if (settings.indentAfterReturnType == true)
                {
                    if (FrameBuilder.returnType.Length < 8)
                    {
                        buffer.Append('	');
                    }
                    else
                    {
                        buffer.Append(' ');
                    }
                }
                else
                {
                    buffer.Append(' ');
                }
            }

            // Append class type and method name.
            if (settings.displayReflectedType == StackTraceSettings.DisplayReflectedType.None ||
                string.IsNullOrEmpty(FrameBuilder.classType) == true)
            {
                buffer.Append(FrameBuilder.methodName, settings.methodNameColor);
            }
            else
            {
                if (settings.displayReflectedType == StackTraceSettings.DisplayReflectedType.NamespaceAndClass)
                {
                    buffer.AppendStartColor(settings.reflectedTypeColor);
                    buffer.Append(FrameBuilder.namespaceName);
                    buffer.Append('.');
                    buffer.Append(FrameBuilder.classType);
                }
                else
                {
                    buffer.AppendStartColor(settings.reflectedTypeColor);
                    buffer.Append(FrameBuilder.classType);
                }

                if (FrameBuilder.genericTypes.Count > 0)
                {
                    buffer.Append('<');

                    for (int i = 0; i < FrameBuilder.genericTypes.Count; i++)
                    {
                        buffer.Append(FrameBuilder.genericTypes[i], settings.argumentTypeColor);
                        buffer.Append(',');
                    }

                    buffer.Length -= 1;
                    buffer.Append('>');
                }

                if (FrameBuilder.isStaticMethod == true)
                {
                    buffer.Append(':');
                }
                else
                {
                    buffer.Append('.');
                }
                buffer.AppendEndColor();
                buffer.Append(methodName, settings.methodNameColor);
            }

            buffer.Append("(");

            // Append parameters.
            for (int i = 0; i < parameterTypes.Count; i++)
            {
                if (settings.displayArgumentType == true)
                {
                    buffer.Append(parameterTypes[i], settings.argumentTypeColor);
                    if (settings.displayArgumentName == true && i < parameterNames.Count)
                    {
                        buffer.Append(' ');
                        buffer.Append(parameterNames[i], settings.argumentNameColor);
                    }
                }
                else if (settings.displayArgumentName == true && i < parameterNames.Count)
                {
                    buffer.Append(parameterNames[i], settings.argumentNameColor);
                }
                buffer.Append(", ");
            }
            if (parameterTypes.Count > 0)
            {
                buffer.Remove(buffer.Length - 2, 2);
            }

            buffer.Append(")");

            if (settings.indentAfterArgument == true)
            {
                buffer.Append('	');
            }
            else
            {
                buffer.Append(' ');
            }

            // Append frame file and line.
            if (string.IsNullOrEmpty(FrameBuilder.fileName) == false &&
                settings.displayFilepath != StackTraceSettings.PathDisplay.Hidden)
            {
                if (settings.displayFilepath == StackTraceSettings.PathDisplay.Visible ||
                    (settings.displayFilepath == StackTraceSettings.PathDisplay.OnlyIfExist &&
                     FrameBuilder.fileExist == true))
                {
                    // Change filename
                    if (settings.displayRelativeToAssets == true &&
                        FrameBuilder.fileExist == true &&
                        FrameBuilder.fileName.StartsWith("Assets") == false)
                    {
                        FrameBuilder.fileName = FrameBuilder.fileName.Substring(Application.dataPath.Length + 1);
                    }

                    buffer.Append(FrameBuilder.fileName, settings.filepathColor);
                    buffer.Append(' ');
                    buffer.Append(FrameBuilder.line.ToString(), settings.lineColor);
                }
            }

            return(Utility.ReturnBuffer(buffer));
        }
Пример #14
0
        private void    VerifySettingsStyles()
        {
            GeneralSettings    generalSettings    = this.settings.Get <GeneralSettings>();
            LogSettings        logSettings        = this.settings.Get <LogSettings>();
            StackTraceSettings stackTraceSettings = this.settings.Get <StackTraceSettings>();
            int totalNull = 0;

            if (generalSettings.MenuButtonStyle.normal.background == null)
            {
                ++totalNull;
            }
            if (generalSettings.MenuButtonStyle.active.background == null)
            {
                ++totalNull;
            }
            if (generalSettings.MenuButtonStyle.onNormal.background == null)
            {
                ++totalNull;
            }
            if (generalSettings.MenuButtonStyle.onActive.background == null)
            {
                ++totalNull;
            }
            if (generalSettings.MenuButtonStyle.font == null)
            {
                ++totalNull;
            }

            if (generalSettings.ToolbarStyle.normal.background == null)
            {
                ++totalNull;
            }
            if (generalSettings.ToolbarStyle.font == null)
            {
                ++totalNull;
            }

            if (logSettings.Style.font == null)
            {
                ++totalNull;
            }
            if (logSettings.TimeStyle.font == null)
            {
                ++totalNull;
            }
            if (logSettings.CollapseLabelStyle.normal == null)
            {
                ++totalNull;
            }
            if (logSettings.ContentStyle.font == null)
            {
                ++totalNull;
            }

            if (stackTraceSettings.Style.font == null)
            {
                ++totalNull;
            }
            if (stackTraceSettings.PreviewSourceCodeStyle.font == null)
            {
                ++totalNull;
            }

            if (totalNull >= 10)             // This number is based on nothing, well hakuna matata...
            {
                if (EditorGUIUtility.isProSkin == true)
                {
                    new DarkTheme().SetTheme(this.settings);
                }
                else
                {
                    new LightTheme().SetTheme(this.settings);
                }

                InternalNGDebug.LogError(NGConsoleWindow.Title + " has detected a potential corruption of GUIStyles. Recovered by applying the " + (EditorGUIUtility.isProSkin == true ? "Dark theme" : "Light theme") + ".");
            }
        }
Пример #15
0
        private static void     DrawPreview(Rect bodyRect)
        {
            Rect r = RowUtility.previewRect;

            r.x += bodyRect.x;
            r.y += bodyRect.y;

            // Out of window.
            if (EditorWindow.mouseOverWindow != RowUtility.previewEditorWindow)
            {
                RowUtility.ClearPreview();
                return;
            }
            // Out of stacktrace.
            //else if (Event.current.type == EventType.MouseMove)
            if (Event.current.type == EventType.MouseMove && r.Contains(Event.current.mousePosition) == false)
            {
                RowUtility.ClearPreview();
                return;
            }

            if (RowUtility.previewFrame.line <= RowUtility.previewLines.Length)
            {
                StackTraceSettings stackTrace = HQ.Settings.Get <StackTraceSettings>();
                float maxWidth = float.MinValue;

                r.x      = Event.current.mousePosition.x + stackTrace.previewOffset.x;
                r.y      = Event.current.mousePosition.y + stackTrace.previewOffset.y;
                r.width  = RowUtility.previewRect.width;
                r.height = stackTrace.previewHeight;

                for (int i = RowUtility.previewFrame.line - stackTrace.previewLinesBeforeStackFrame - 1,
                     max = Mathf.Min(RowUtility.previewFrame.line + stackTrace.previewLinesAfterStackFrame, RowUtility.previewLines.Length);
                     i < max; i++)
                {
                    Utility.content.text = RowUtility.previewLines[i];
                    Vector2 size = stackTrace.PreviewSourceCodeStyle.CalcSize(Utility.content);
                    if (size.x > maxWidth)
                    {
                        maxWidth = size.x;
                    }
                }

                r.width = maxWidth;
                for (int i = RowUtility.previewFrame.line - stackTrace.previewLinesBeforeStackFrame - 1,
                     max = Mathf.Min(RowUtility.previewFrame.line + stackTrace.previewLinesAfterStackFrame, RowUtility.previewLines.Length);
                     i < max; i++)
                {
                    if (Event.current.type == EventType.Repaint)
                    {
                        if (i + 1 != RowUtility.previewFrame.line)
                        {
                            EditorGUI.DrawRect(r, stackTrace.previewSourceCodeBackgroundColor);
                        }
                        else
                        {
                            EditorGUI.DrawRect(r, stackTrace.previewSourceCodeMainLineBackgroundColor);
                        }
                    }

                    GUI.Label(r, RowUtility.previewLines[i], stackTrace.PreviewSourceCodeStyle);
                    r.y += r.height;
                }

                RowUtility.drawingWindow.Repaint();
            }
        }
Пример #16
0
        private static void     GoToLine(Rect r, Frame frame)
        {
            StackTraceSettings stackTrace = HQ.Settings.Get <StackTraceSettings>();

            if (Event.current.button == 0 &&
                frame.fileExist == true)
            {
                // Ping folder on click + modifiers.
                if ((Event.current.modifiers & stackTrace.pingFolderOnModifier) != 0)
                {
                    int i = frame.frameString.LastIndexOf('	') + 1;

                    Utility.content.text = frame.frameString.Substring(0, i);
                    var v = stackTrace.Style.CalcSize(Utility.content);

                    StringBuilder buffer = Utility.GetBuffer();

                    if (Event.current.mousePosition.x >= v.x)
                    {
                        int i2 = frame.frameString.IndexOf('/', i + 1);

                        // Skip Assets folder.
                        string folder = frame.frameString.Substring(i, i2 - i).Split('>')[1];

                        Utility.content.text += folder;
                        v = stackTrace.Style.CalcSize(Utility.content);

                        if (Event.current.mousePosition.x > v.x)
                        {
                            i = i2;
                            buffer.Append(folder);

                            while (Event.current.mousePosition.x >= v.x)
                            {
                                i2 = frame.frameString.IndexOf('/', i + 1);
                                if (i2 == -1)
                                {
                                    break;
                                }

                                folder = frame.frameString.Substring(i, i2 - i);
                                buffer.Append(folder);
                                Utility.content.text += folder;
                                v = stackTrace.Style.CalcSize(Utility.content);
                                i = i2;
                            }

                            EditorGUIUtility.PingObject(AssetDatabase.LoadAssetAtPath(buffer.ToString(), typeof(Object)));
                        }
                    }

                    Utility.RestoreBuffer(buffer);
                }
                // Or go to line.
                else
                {
                    bool focus = (Event.current.modifiers & HQ.Settings.Get <LogSettings>().forceFocusOnModifier) != 0;

                    RowUtility.GoToFileLine(frame.fileName, frame.line, focus);

                    Event.current.Use();
                }
            }
        }
Пример #17
0
        /// <summary>
        /// Appends parameters' type and name. It only handles ref, out, default and nullable parameter.
        /// </summary>
        /// <param name="parameters"></param>
        private void    AppendParameters(ParameterInfo[] parameters)
        {
            StackTraceSettings stackTrace = HQ.Settings.Get <StackTraceSettings>();

            for (int i = 0; i < parameters.Length; i++)
            {
                if (stackTrace.displayArgumentType == true)
                {
                    StringBuilder buffer = Utility.GetBuffer();

                    if (parameters[i].IsOptional == true)
                    {
                        buffer.Append('[');
                    }

                    // Handle type constraints.
                    if (parameters[i].IsOut == true)
                    {
                        buffer.Append("out ");

                        // Handle nullable type.
                        if (parameters[i].ParameterType.GetElementType().UnderlyingSystemType.IsGenericType == true &&
                            parameters[i].ParameterType.GetElementType().UnderlyingSystemType.GetGenericTypeDefinition() == typeof(Nullable <>))
                        {
                            buffer.Append(Nullable.GetUnderlyingType(parameters[i].ParameterType.GetElementType().UnderlyingSystemType).Name);
                            buffer.Append('?');
                        }
                        else
                        {
                            buffer.Append(parameters[i].ParameterType.Name);
                        }
                    }
                    else if (parameters[i].ParameterType.IsByRef == true)
                    {
                        buffer.Append("ref ");

                        // Handle nullable type.
                        if (parameters[i].ParameterType.GetElementType().UnderlyingSystemType.IsGenericType == true &&
                            parameters[i].ParameterType.GetElementType().UnderlyingSystemType.GetGenericTypeDefinition() == typeof(Nullable <>))
                        {
                            buffer.Append(Nullable.GetUnderlyingType(parameters[i].ParameterType.GetElementType().UnderlyingSystemType).Name);
                            buffer.Append('?');
                        }
                        else
                        {
                            buffer.Append(parameters[i].ParameterType.Name);
                        }
                    }
                    else
                    {
                        // Handle nullable type.
                        if (parameters[i].ParameterType.IsGenericType == true &&
                            parameters[i].ParameterType.GetGenericTypeDefinition() == typeof(Nullable <>))
                        {
                            buffer.Append(Nullable.GetUnderlyingType(parameters[i].ParameterType).Name);
                            buffer.Append('?');
                        }
                        else
                        {
                            buffer.Append(parameters[i].ParameterType.Name);
                        }
                    }

                    if (!(parameters[i].RawDefaultValue is DBNull))
                    {
                        buffer.Append(" = ");
                        if (parameters[i].RawDefaultValue == null)
                        {
                            buffer.Append("null");
                        }
                        else
                        {
                            buffer.Append(parameters[i].RawDefaultValue);
                        }
                    }

                    if (parameters[i].IsOptional == true)
                    {
                        buffer.Append(']');
                    }

                    FrameBuilder.parameterTypes.Add(Utility.ReturnBuffer(buffer));

                    if (stackTrace.displayArgumentName == true)
                    {
                        FrameBuilder.parameterNames.Add(parameters[i].Name);
                    }
                }
                else if (stackTrace.displayArgumentName == true)
                {
                    FrameBuilder.parameterNames.Add(parameters[i].Name);
                }
            }
        }
Пример #18
0
        /// <summary>
        /// Colors keywords given by StackSettings.
        /// </summary>
        /// <param name="line"></param>
        /// <returns></returns>
        public static string    ColorLine(string line)
        {
            StackTraceSettings settings = HQ.Settings.Get <StackTraceSettings>();
            StringBuilder      buffer   = Utility.GetBuffer();

            buffer.Append(' ');
            buffer.AppendStartColor(settings.previewTextColor);
            for (int i = 0; i < line.Length; i++)
            {
                int previousKeywordColor = -1;

                // Convert tab to spaces.
                if (line[i] == '	'&&
                    settings.displayTabAsSpaces > 0)
                {
                    buffer.Append(' ', settings.displayTabAsSpaces);
                    continue;
                }
                // Color only visible char.
                else if (line[i] != ' ')
                {
                    for (int j = 0; j < settings.keywords.Length; ++j)
                    {
                        for (int k = 0; k < settings.keywords[j].keywords.Length; k++)
                        {
                            if (Utility.Compare(line, settings.keywords[j].keywords[k], i) == true)
                            {
                                // Save some color tags.
                                if (previousKeywordColor != -1 &&
                                    settings.keywords[previousKeywordColor].color != settings.keywords[j].color)
                                {
                                    previousKeywordColor = j;
                                    buffer.AppendEndColor();
                                    buffer.AppendStartColor(settings.keywords[j].color);
                                }
                                else if (previousKeywordColor == -1)
                                {
                                    previousKeywordColor = j;
                                    buffer.AppendStartColor(settings.keywords[j].color);
                                }

                                buffer.Append(settings.keywords[j].keywords[k]);
                                i += settings.keywords[j].keywords[k].Length - 1;
                                goto skip;
                            }
                        }
                    }
                }

                buffer.Append(line[i]);
skip:

                if (previousKeywordColor != -1)
                {
                    buffer.AppendEndColor();
                }

                continue;
            }

            buffer.AppendEndColor();

            return(Utility.ReturnBuffer(buffer));
        }
Пример #19
0
        public static Rect      DrawStackTrace(ILogContentGetter log, RowsDrawer rowsDrawer, Rect r, int i, Row row)
        {
            StackTraceSettings settings = HQ.Settings.Get <StackTraceSettings>();
            float width = r.width;

            // Substract viewRect to avoid scrollbar.
            r.height = settings.height;

            // Display the stack trace.
            int j = 0;

            foreach (var frame in log.Frames)
            {
                // Hide invisible frames.
                if (r.y - rowsDrawer.currentVars.scrollbar.Offset > rowsDrawer.bodyRect.height)
                {
                    break;
                }

                r.x     = 0F;
                r.width = width - 16F;
                GUI.SetNextControlName("SF" + i + j);
                if (GUI.Button(r, frame.frameString, settings.Style) == true)
                {
                    if (RowUtility.CheckLowestRowGoToLineAllowed(j) == true)
                    {
                        GUI.FocusControl("SF" + i + j);

                        r.y -= rowsDrawer.currentVars.scrollbar.Offset;
                        RowUtility.GoToLine(r, frame);
                        r.y += rowsDrawer.currentVars.scrollbar.Offset;
                    }
                }

                // Handle hover overflow.
                if (r.y - rowsDrawer.currentVars.scrollbar.Offset + r.height > rowsDrawer.bodyRect.height)
                {
                    r.height = rowsDrawer.bodyRect.height - r.y + rowsDrawer.currentVars.scrollbar.Offset;
                }

                if (Event.current.type == EventType.MouseMove && r.Contains(Event.current.mousePosition) == true)
                {
                    r.y -= rowsDrawer.currentVars.scrollbar.Offset;
                    RowUtility.PreviewStackFrame(rowsDrawer, r, frame);
                    r.y += rowsDrawer.currentVars.scrollbar.Offset;
                }

                r.x     = r.width;
                r.width = 16F;
                if (GUI.Button(r, "+", settings.Style) == true)
                {
                    StackTraceSettings stackTrace = HQ.Settings.Get <StackTraceSettings>();
                    GenericMenu        menu       = new GenericMenu();

                    if (frame.raw == null)
                    {
                        InternalNGDebug.LogError("The frame stack is invalid." + Environment.NewLine + frame);
                    }

                    menu.AddItem(new GUIContent("Set as Category"), false, RowUtility.SetAsCategory, frame.raw);

                    string f = RowUtility.GetFilterNamespace(frame.raw);
                    if (f != null)
                    {
                        if (stackTrace.filters.Contains(f) == false)
                        {
                            menu.AddItem(new GUIContent("Skip Namespace \"" + f + "\""), false, RowUtility.AddFilter, f);
                        }
                        else
                        {
                            menu.AddDisabledItem(new GUIContent("Skip Namespace \"" + f + "\""));
                        }
                    }

                    f = RowUtility.GetFilterClass(frame.raw);
                    if (f != null)
                    {
                        if (stackTrace.filters.Contains(f) == false)
                        {
                            menu.AddItem(new GUIContent("Skip Class \"" + f + "\""), false, RowUtility.AddFilter, f);
                        }
                        else
                        {
                            menu.AddDisabledItem(new GUIContent("Skip Class \"" + f + "\""));
                        }
                    }

                    f = RowUtility.GetFilterMethod(frame.raw);
                    if (f != null)
                    {
                        if (stackTrace.filters.Contains(f) == false)
                        {
                            menu.AddItem(new GUIContent("Skip Method \"" + f + "\""), false, RowUtility.AddFilter, f);
                        }
                        else
                        {
                            menu.AddDisabledItem(new GUIContent("Skip Method \"" + f + "\""));
                        }
                    }

                    menu.AddItem(new GUIContent("Manage filters"), false, RowUtility.GoToSettings);
                    menu.ShowAsContext();
                }

                ++j;
                r.y += r.height;
            }

            return(r);
        }