public void DrawLine(ref Rect rect) { rect.AdjustVerticallyBy(2); var col = GUI.color; GUI.color = col * new Color(1f, 1f, 1f, 0.4f); Widgets.DrawLineHorizontal(rect.x, rect.y, rect.width); GUI.color = col; rect.AdjustVerticallyBy(2); }
public void Draw(Rect rect, GeneralInformation?info) { if (info == null || info.Value.method == null) { return; } currentMethod = info.Value.method as MethodInfo; var panelWidth = Mathf.Clamp(rect.width / 4, 0, 65); var leftHandPanel = rect.LeftPartPixels(panelWidth); rect.AdjustHorizonallyBy(panelWidth + 4f); DrawLeftColumn(leftHandPanel, currentMethod); var statusBox = rect.TopPartPixels(30f); rect.AdjustVerticallyBy(30f); DrawCurrentStatus(statusBox, currentMethod); if (currentTrace == 0) { if (StackTraceUtility.traces.Count > 0) { currentTrace = StackTraceUtility.traces.MaxBy(t => t.Value.Count).Key; } } else { DrawStackTrace(rect, StackTraceUtility.traces[currentTrace]); } }
public static void DrawLogs(Rect rect) { Widgets.DrawMenuSection(rect); if (!GUIController.CurrentEntry?.isPatched ?? true) { DubGUI.Heading(rect, $"Loading{GenText.MarchingEllipsis(0f)}"); return; } var columnsR = rect.TopPartPixels(50f); DrawColumns(columnsR); columns[(int)SortBy.Average].total = 0; rect.AdjustVerticallyBy(columnsR.height + 4); rect.height -= 2f; rect.width -= 2; Rect innerRect = rect.AtZero(); innerRect.height = listing.curY; if (innerRect.height > rect.height) { innerRect.width -= 17f; } viewFrustum = rect.AtZero(); // Our view frustum starts at 0,0 from the rect we are given viewFrustum.y += ScrollPosition.y; // adjust our view frustum vertically based on the scroll position { // Begin scope for Scroll View Widgets.BeginScrollView(rect, ref ScrollPosition, innerRect); GUI.BeginGroup(innerRect); listing.Begin(innerRect); Text.Anchor = TextAnchor.MiddleCenter; Text.Font = GameFont.Tiny; float currentListHeight = BOX_HEIGHT; Text.Anchor = TextAnchor.MiddleLeft; lock (Analyzer.LogicLock) { foreach (ProfileLog log in Analyzer.Logs) { DrawLog(log, ref currentListHeight); } } listing.End(); GUI.EndGroup(); Widgets.EndScrollView(); } DubGUI.ResetFont(); }
public void Draw(Rect r, GeneralInformation?info) { if (GUIController.CurrentProfiler == null) { return; } if (file != null) { UpdateFile(); } var colWidth = Mathf.Max(300, r.width / 3); var columnRect = r.RightPartPixels(colWidth); r.width -= colWidth; DrawColumn(columnRect); var top = r.TopPartPixels(20f); r.AdjustVerticallyBy(20f); DrawTopRow(top); if (FileUtility.PreviousEntriesFor(GUIController.CurrentProfiler.label).Any()) { DrawComparison(r); } }
// Horizontal column which offers the option to // Enable, Disable, View Different Stacktrace, Summary public void DrawLeftColumn(Rect rect, MethodInfo method) { var col = GUI.color; GUI.color = col * new Color(1f, 1f, 1f, 0.4f); Widgets.DrawLineVertical(rect.x + rect.width, rect.y, rect.height); GUI.color = col; var ts = Text.Font; Text.Font = GameFont.Small; var height = rect.height - 12; var individualHeight = height / 3f; var methodString = Utility.GetSignature(method, false); // Enable var enableRect = rect.TopPartPixels(individualHeight); rect.AdjustVerticallyBy(individualHeight); DrawEnableButton(enableRect, method, methodString); DrawLine(ref rect); // Disable var disableRect = rect.TopPartPixels(individualHeight); rect.AdjustVerticallyBy(individualHeight); DrawDisableButton(disableRect, method); DrawLine(ref rect); // Change var changeTraceRect = rect.TopPartPixels(individualHeight); rect.AdjustVerticallyBy(individualHeight); DrawChangeTraceButton(changeTraceRect); Text.Font = ts; }
private void DrawChangeTraceButton(Rect rect) { var height = rect.height; if (height > 25f + Text.LineHeight) { DubGUI.CenterText(() => Widgets.Label(rect.TopPartPixels(Text.LineHeight), "Change")); rect.AdjustVerticallyBy(Text.LineHeight); } var tooltip = $"Change the currently viewed stacktrace"; if (currentTrackedStacktraces == 0) { GUI.color = Color.gray; } var centerRect = rect.CenterWithDimensions(25, 25); TooltipHandler.TipRegion(centerRect, tooltip); if (Widgets.ButtonImage(centerRect, Textures.Burger)) { if (currentTrackedStacktraces != 0) { var traces = StackTraceUtility.traces.Values.ToList(); CalculateHeaders(traces, traces.MaxBy(t => t.Depth).Depth); var options = StackTraceUtility.traces .OrderBy(p => p.Value.Count) .Reverse() .Select(st => new FloatMenuOption($"{st.Value.Header} : {st.Value.Count}", () => { currentTrace = st.Key; })) .ToList(); Find.WindowStack.Add(new FloatMenu(options)); } } if (currentTrackedStacktraces == 0) { GUI.color = Color.white; } }
private void DrawEnableButton(Rect rect, MethodInfo method, string methodString) { var tooltip = $"Enable stack trace profiling"; var height = rect.height; if (height > 25f + Text.LineHeight) { DubGUI.CenterText(() => Widgets.Label(rect.TopPartPixels(Text.LineHeight), "Enable")); rect.AdjustVerticallyBy(Text.LineHeight); } if (currentlyTracking) { Widgets.DrawHighlightSelected(rect); } var centerRect = rect.CenterWithDimensions(25, 25); TooltipHandler.TipRegion(centerRect, tooltip); if (Widgets.ButtonImage(centerRect, Widgets.CheckboxOnTex)) { if (currentlyTracking is false) { StackTraceUtility.Reset(); currentTrace = 0; currentTrackedStacktraces = 0; Modbase.Harmony.Patch(method, postfix: new HarmonyMethod(postfix)); } else { ThreadSafeLogger.ErrorOnce($"Can not retrace {methodString} while currently tracing", method.GetHashCode()); } currentlyTracking = true; } }
public static void Draw(Rect rect, GeneralInformation?info) { if (info == null || info.Value.method == null) { return; } var method = info.Value.method as MethodInfo; if (currentMethod != method) { Reset(currentMethod); currentMethod = method; } var enableBox = rect.TopPartPixels(30.0f); var checkBoxWidth = DrawCheckbox(ref enableBox, method); enableBox.AdjustHorizonallyBy(checkBoxWidth); var unpatchWidth = DrawUnpatch(ref enableBox, method); enableBox.AdjustHorizonallyBy(unpatchWidth); var strings = DrawSelectStacktrace(ref enableBox, method); rect.AdjustVerticallyBy(30f); StringBuilder sb = new StringBuilder(); foreach (var str in strings) { sb.AppendLine(str); } Widgets.Label(rect, sb.ToString().TrimEndNewlines()); }
private void DrawDisableButton(Rect rect, MethodInfo method) { var height = rect.height; if (height > 25f + Text.LineHeight) { DubGUI.CenterText(() => Widgets.Label(rect.TopPartPixels(Text.LineHeight), "Disable")); rect.AdjustVerticallyBy(Text.LineHeight); } var tooltip = $"Disable stack trace profiling"; if (currentlyTracking is false) { GUI.color = Color.gray; } var centerRect = rect.CenterWithDimensions(25, 25); TooltipHandler.TipRegion(centerRect, tooltip); if (Widgets.ButtonImage(centerRect, Widgets.CheckboxOffTex)) { if (currentlyTracking) { Modbase.Harmony.CreateProcessor(method).Unpatch(postfix); } currentlyTracking = false; } if (currentlyTracking is false) { GUI.color = Color.white; } }
private static void DrawSettings(Panel_Graph instance, ref Rect position) { // [ - Calls ] [ - Times ] [ Lines ] [ Entries ------ ] [ - Bg Col ] var width = position.width; var currentHeight = 32; var currentSlice = position.TopPartPixels(currentHeight); position.AdjustVerticallyBy(currentHeight); Text.Anchor = TextAnchor.MiddleCenter; // [ - Times ] var str = " Times "; var contentWidth = 20 + str.GetWidthCached(); var rect = currentSlice.LeftPartPixels(contentWidth); currentSlice.AdjustHorizonallyBy(contentWidth); DrawButton(instance, rect, " Times ", 0); // [ - Calls ] str = " Calls "; contentWidth = 20 + str.GetWidthCached(); rect = currentSlice.LeftPartPixels(contentWidth); currentSlice.AdjustHorizonallyBy(contentWidth); DrawButton(instance, rect, " Calls ", 1); // [ - Background ] str = " Background "; contentWidth = 20 + str.GetWidthCached(); rect = currentSlice.LeftPartPixels(contentWidth); currentSlice.AdjustHorizonallyBy(contentWidth); DrawButton(instance, rect, " Background ", 2); Text.Anchor = TextAnchor.UpperLeft; // [ - Entries ] contentWidth = 150; if (currentSlice.width < contentWidth) { currentSlice = position.TopPartPixels(currentHeight); position.AdjustVerticallyBy(currentHeight); } rect = currentSlice.LeftPartPixels(contentWidth); instance.entryCount = (int)Widgets.HorizontalSlider(rect.BottomPartPixels(30f), instance.entryCount, 10, 2000, true, string.Intern($"{instance.entryCount} Entries ")); currentSlice.AdjustHorizonallyBy(contentWidth); Text.Anchor = TextAnchor.MiddleCenter; // [ - Show Axis ] str = " Axis"; contentWidth = str.GetWidthCached() + 30; if (currentSlice.width < contentWidth) { currentSlice = position.TopPartPixels(currentHeight); position.AdjustVerticallyBy(currentHeight); } rect = currentSlice.LeftPartPixels(contentWidth); DubGUI.Checkbox(rect, str, ref GraphSettings.showAxis); currentSlice.AdjustHorizonallyBy(contentWidth); // [ - Show Grid ] str = " Grid " + 30; contentWidth = str.GetWidthCached(); if (currentSlice.width < contentWidth) { currentSlice = position.TopPartPixels(currentHeight); position.AdjustVerticallyBy(currentHeight); } rect = currentSlice.LeftPartPixels(contentWidth); DubGUI.Checkbox(rect, str, ref GraphSettings.showGrid); currentSlice.AdjustHorizonallyBy(contentWidth); // [ - Show Max ] str = " Max "; contentWidth = str.GetWidthCached() + 30; if (currentSlice.width < contentWidth) { currentSlice = position.TopPartPixels(currentHeight); position.AdjustVerticallyBy(currentHeight); } rect = currentSlice.LeftPartPixels(contentWidth); DubGUI.Checkbox(rect, str, ref GraphSettings.showMax); currentSlice.AdjustHorizonallyBy(contentWidth); // [ - Aliasing ] str = " Aliasing: " + (GraphSettings.lineAliasing == 0 ? "none" : GraphSettings.lineAliasing.ToString()) + " "; contentWidth = str.GetWidthCached(); if (currentSlice.width < contentWidth) { currentSlice = position.TopPartPixels(currentHeight); position.AdjustVerticallyBy(currentHeight); } rect = currentSlice.LeftPartPixels(contentWidth); if (Widgets.ButtonText(rect, str, false)) { GraphSettings.lineAliasing = GraphSettings.lineAliasing switch { 7.5f => 12.5f, 12.5f => 0.0f, 0.0f => 5.0f, 5.0f => 7.5f, _ => 0.0f }; } currentSlice.AdjustHorizonallyBy(contentWidth); Text.Anchor = TextAnchor.UpperLeft; }
private static void DrawButtonColumn(Rect rect, float availWidth) { if (Widgets.ButtonText(rect.TopPartPixels(Text.LineHeight), " + ")) { var widthMinusGrabBars = availWidth - (18 * panels.Count); var avWidth = widthMinusGrabBars / (panels.Count + 1.0f); var increment = avWidth / panels.Count; increment = Mathf.Round(increment); for (int i = 0; i < panels.Count; i++) { var panel = panels[i]; panel.width -= increment; panel.xStart += increment * (panels.Count - i); } if (panels.Count >= 1) { panels[0].xStart += 18; panels[0].width -= 18; panels.Insert(0, new BottomRowPanel(RowName.Graph, 0, panels[0].xStart - 18)); } else { panels.Add(new BottomRowPanel(RowName.Graph, 0, availWidth)); } } rect.AdjustVerticallyBy(Text.LineHeight); if (Widgets.ButtonText(rect.TopPartPixels(Text.LineHeight), " - ")) { if (panels.Count == 1) { return; } var delta = panels[0].width + 18; var increment = delta / (panels.Count - 1.0f); for (int i = 0; i < panels.Count; i++) { var panel = panels[i]; panel.width += increment; panel.xStart -= (increment * (panels.Count - i)); } if (panels.Count == 2) { panels[1].xStart = 0; panels[1].width = availWidth; } else if (panels.Count > 2) { panels[1].xStart = 0; panels[1].width = panels[2].xStart - 18; } panels.RemoveAt(0); } }
public static void DrawGraph(Panel_Graph instance, Rect rect, int entries) { var statline = rect.TopPartPixels(20f); rect.AdjustVerticallyBy(20f); Widgets.DrawRectFast(statline, Settings.GraphCol); Widgets.DrawRectFast(rect, Settings.GraphCol); Text.Anchor = TextAnchor.UpperCenter; Widgets.Label(statline, hoverValStr); var primaryEntry = instance.times.visible ? instance.times : instance.calls; var suffix = instance.times.visible ? "ms" : "calls"; var maxminStr = $"Max:{primaryEntry.absMax:0.0000}{suffix}"; if (Analyzer.CurrentlyPaused || Find.TickManager.Paused) { maxminStr = $"Max:{primaryEntry.absMax:0.0000}{suffix} Min:{visibleMin:0.0000}{suffix}"; } Text.Anchor = TextAnchor.UpperRight; Widgets.Label(statline, maxminStr); Text.Anchor = TextAnchor.UpperLeft; GUI.BeginGroup(rect); rect = rect.AtZero(); AdjustDimensions(instance, rect, entries); if (GraphSettings.showAxis) { var axis = rect; axis.height -= Text.LineHeight; DrawAxis(axis, primaryEntry.max, instance.times.visible ? "ms" : "calls"); rect.x += 25; rect.width -= 25; Text.Font = GameFont.Tiny; Text.Anchor = TextAnchor.LowerLeft; int xAxisValue = Mathf.CeilToInt(entries + (int)instance.settings.offsets.x); Widgets.Label(rect, Mathf.CeilToInt(xAxisValue).ToString()); Text.Anchor = TextAnchor.LowerCenter; xAxisValue = Mathf.CeilToInt((entries / 2f) + (int)instance.settings.offsets.x); Widgets.Label(rect, Mathf.CeilToInt(xAxisValue).ToString()); Text.Anchor = TextAnchor.LowerRight; xAxisValue = Mathf.CeilToInt((int)instance.settings.offsets.x); Widgets.Label(rect, Mathf.CeilToInt(xAxisValue).ToString()); Text.Anchor = TextAnchor.UpperLeft; rect.height -= Text.LineHeight; DrawGrid(rect); GUI.BeginGroup(rect); rect = rect.AtZero(); } if (GraphSettings.showMax) { DrawMaxLine(rect, primaryEntry.absMax, primaryEntry.max, suffix); } DrawEntries(rect, instance, entries, GraphSettings.lineAliasing); if (GraphSettings.showAxis) { GUI.EndGroup(); } GUI.EndGroup(); }
public static void Draw(Rect rect, Rect bigRect) { if (currentProfilerInformation == null || (GUIController.CurrentProfiler != null && currentProfilerInformation.Value.method != GUIController.CurrentProfiler.meth)) { GetGeneralSidePanelInformation(); } var buttonColumn = rect.LeftPartPixels(" + ".GetWidthCached()); rect.AdjustHorizonallyBy(" + ".GetWidthCached()); DrawButtonColumn(buttonColumn, rect.width); panels[panels.Count - 1].width = (panels.Count <= 1) ? rect.width : rect.width - (panels[panels.Count - 2].xStart + panels[panels.Count - 2].width) - 18; for (int i = panels.Count - 1; i >= 0; i--) { var panel = panels[i]; var panelRect = new Rect(rect.x + panel.xStart, rect.y, panel.width, rect.height); if (i != 0) // Drag Rct { var r = new Rect(rect.x + (panel.xStart - Window_Analyzer.DRAGGABLE_RECT_DIM), rect.y, Window_Analyzer.DRAGGABLE_RECT_DIM, rect.height); Widgets.DrawHighlightIfMouseover(r); if (Input.GetMouseButtonDown(0) && Mouse.IsOver(r) && !panel.dragging) { panel.dragging = true; } if (panel.dragging) { var newPos = Event.current.mousePosition.x - (rect.x - Window_Analyzer.DRAGGABLE_RECT_DIM / 2.0f); var delta = panel.xStart - newPos; panel.xStart = newPos; panel.width += delta; panels[i - 1].width -= delta; } if (Input.GetMouseButtonUp(0)) { panel.dragging = false; } } Widgets.DrawMenuSection(panelRect); { var topRect = panelRect.TopPartPixels(Text.LineHeight); panelRect.AdjustVerticallyBy(Text.LineHeight); Widgets.DrawLineHorizontal(panelRect.x, panelRect.y, panelRect.width); panelRect = panelRect.ContractedBy(2f); var label = " " + panel.type.ToString(); var leftPartRect = topRect.LeftPartPixels(label.GetWidthCached()); Widgets.Label(leftPartRect, label); if (Widgets.ButtonImage(topRect.RightPartPixels(Text.LineHeight), ResourceCache.GUI.Menu)) { var enums = typeof(RowName).GetEnumValues(); var list = (from object e in enums select new FloatMenuOption(((RowName)e).ToString(), () => { panel.type = (RowName)e; panel.graph = panel.type == RowName.Graph ? new Panel_Graph() : null; })).ToList(); Find.WindowStack.Add(new FloatMenu(list)); } } panelRect.AdjustVerticallyBy(2f); // ALL OF THESE FUNCTIONS MUST HANDLE THE CASE WHERE CURRENTPROFILERINFORMATION IS NULL. switch (panel.type) { case RowName.Graph: panel.graph.Draw(panelRect); break; case RowName.Stats: Panel_Stats.DrawStats(panelRect, currentProfilerInformation); break; case RowName.Patches: Panel_Patches.Draw(panelRect, currentProfilerInformation); break; case RowName.StackTrace: Panel_StackTraces.Draw(panelRect, currentProfilerInformation); break; } } }
private static void DrawSettings(Panel_Graph instance, ref Rect position) { void CheckNewRow(ref Rect box, ref Rect position) { if (box.xMax > position.xMax) { position.AdjustVerticallyBy(box.height); box.y += box.height; box.x = position.x; } } var currentHeight = 32; var box = position.TopPartPixels(currentHeight).LeftPartPixels(20f); position.AdjustVerticallyBy(currentHeight); Text.Anchor = TextAnchor.MiddleCenter; if (Widgets.ButtonImageFitted(box, Textures.Menu)) { doSettings = !doSettings; } box.ShiftX(5); if (Widgets.ButtonImageFitted(box, TexButton.SpeedButtonTextures[Analyzer.CurrentlyPaused ? 1 : 0])) { Analyzer.CurrentlyPaused = !Analyzer.CurrentlyPaused; GUIController.CurrentEntry.SetActive(!Analyzer.CurrentlyPaused); } box.ShiftX(5); var str = "Times"; box.width = 20 + str.GetWidthCached(); instance.times.visible = ToggleColCombo(box, str, instance.times.visible, Settings.timeColour, () => Settings.timeColour = colourPicker.CurrentCol); box.ShiftX(5); str = "Calls"; box.width = 20 + str.GetWidthCached(); instance.calls.visible = ToggleColCombo(box, str, instance.calls.visible, Settings.callsColour, () => Settings.callsColour = colourPicker.CurrentCol); box.ShiftX(5); str = "Background"; box.width = 20 + str.GetWidthCached(); ToggleColCombo(box, str, true, Settings.GraphCol, () => Settings.GraphCol = colourPicker.CurrentCol); box.ShiftX(5); void jammydodger(ref Rect p, string s, ref bool r) { box.width = 20 + s.GetWidthCached(); CheckNewRow(ref box, ref p); r = DrawButton(box, s, r); box.ShiftX(5); } jammydodger(ref position, "Axis", ref GraphSettings.showAxis); jammydodger(ref position, "Grid", ref GraphSettings.showGrid); jammydodger(ref position, "Max", ref GraphSettings.showMax); Text.Anchor = TextAnchor.UpperLeft; box.width = 100; CheckNewRow(ref box, ref position); instance.entryCount = (int)Widgets.HorizontalSlider(box.BottomPartPixels(30f), instance.entryCount, 10, 2000, true, string.Intern($"{instance.entryCount} Entries")); box.ShiftX(5); Text.Anchor = TextAnchor.MiddleCenter; Text.Font = GameFont.Tiny; str = $"Aliasing:{(GraphSettings.lineAliasing == 0 ? "none" : GraphSettings.lineAliasing.ToString())}"; box.width = str.GetWidthCached() + 10; CheckNewRow(ref box, ref position); if (Widgets.ButtonText(box, str, false)) { GraphSettings.lineAliasing = GraphSettings.lineAliasing switch { 7.5f => 12.5f, 12.5f => 0.0f, 0.0f => 5.0f, 5.0f => 7.5f, _ => 0.0f }; } box.ShiftX(5); DubGUI.ResetFont(); }
private static void DrawSettings(Panel_Graph instance, ref Rect position) { void CheckNewRow(ref Rect box, ref Rect position) { if (box.xMax > position.xMax) { position.AdjustVerticallyBy(box.height); box.y += box.height; box.x = position.x; } } var currentHeight = 32; var box = position.TopPartPixels(currentHeight).LeftPartPixels(20f); position.AdjustVerticallyBy(currentHeight); Text.Anchor = TextAnchor.MiddleCenter; if (Widgets.ButtonImageFitted(box, Textures.Gear)) { doSettings = !doSettings; } box.ShiftX(5); if (Widgets.ButtonImageFitted(box, TexButton.SpeedButtonTextures[Analyzer.CurrentlyPaused ? 1 : 0])) { Analyzer.CurrentlyPaused = !Analyzer.CurrentlyPaused; GUIController.CurrentEntry.SetActive(!Analyzer.CurrentlyPaused); } box.ShiftX(5); var str = "Times"; box.width = 20 + str.GetWidthCached(); instance.times.visible = ToggleColCombo(box, str, instance.times.visible, Settings.timeColour, () => Settings.timeColour = colourPicker.CurrentCol); box.ShiftX(5); str = "Calls"; box.width = 20 + str.GetWidthCached(); instance.calls.visible = ToggleColCombo(box, str, instance.calls.visible, Settings.callsColour, () => Settings.callsColour = colourPicker.CurrentCol); box.ShiftX(5); str = "Background"; box.width = 20 + str.GetWidthCached(); ToggleColCombo(box, str, true, Settings.GraphCol, () => Settings.GraphCol = colourPicker.CurrentCol); box.ShiftX(5); void jammydodger(ref Rect p, string s, ref bool r, string h) { box.width = 20 + s.GetWidthCached(); CheckNewRow(ref box, ref p); r = DrawButton(box, s, r); if (h != null && Mouse.IsOver(box)) { TooltipHandler.TipRegion(box, h); } box.ShiftX(5); } jammydodger(ref position, "Axis", ref GraphSettings.showAxis, null); jammydodger(ref position, "Grid", ref GraphSettings.showGrid, "Grid will only show when the axis is also active"); jammydodger(ref position, "Max", ref GraphSettings.showMax, null); Text.Anchor = TextAnchor.UpperLeft; box.width = 100; CheckNewRow(ref box, ref position); instance.entryCount = (int)Widgets.HorizontalSlider(box.BottomPartPixels(30f), instance.entryCount, 10, 2000, true, string.Intern($"{instance.entryCount} Entries")); }
private void DrawStackTrace(Rect rect, StackTraceInformation stackTrace) { const string dummyLen = "XXXXXXXXXXXXXXXX"; // 16 chars length const string dummyAddition = "XXXX"; var dummyAdditionLen = dummyAddition.GetWidthCached(); var textSize = Text.LineHeight; var patchesLen = "Patches ".GetWidthCached(); var modNameLen = Mathf.Min(dummyLen.GetWidthCached(), stackTrace.Methods.MaxBy(t => t.Mod.GetWidthCached()).Mod.GetWidthCached() + dummyAdditionLen); var availModLen = rect.width - (patchesLen + modNameLen); var methodLen = Mathf.Min(availModLen, stackTrace.Methods.MaxBy(t => t.MethodString.GetWidthCached()).MethodString.GetWidthCached() + dummyAdditionLen); Rect GetMethodColumn(float y, float height) => new Rect(rect.x, y, methodLen, height); Rect GetModColumn(float y, float height) => new Rect(rect.x + methodLen, y, modNameLen, height); Rect GetPatchColumn(float y, float height) => new Rect(rect.x + methodLen + modNameLen, y, patchesLen, height); Widgets.Label(GetMethodColumn(rect.y, textSize), " Method "); var anchor = Text.Anchor; Text.Anchor = TextAnchor.MiddleCenter; Widgets.Label(GetModColumn(rect.y, textSize), " Mod "); Widgets.Label(GetPatchColumn(rect.y, textSize), " Patches "); Text.Anchor = anchor; rect.AdjustVerticallyBy(textSize); var col = GUI.color; GUI.color = col * new Color(1f, 1f, 1f, 0.4f); Widgets.DrawLineHorizontal(rect.x, rect.y, rect.width); Widgets.DrawLineVertical(rect.x + methodLen, rect.y - textSize, rect.height + textSize); Widgets.DrawLineVertical(rect.x + methodLen + modNameLen + 1, rect.y - textSize, rect.height + textSize); GUI.color = col; var inner = new Rect(rect.x, 0, rect.width - 17f, stackTrace.Methods.Count() * textSize); Widgets.BeginScrollView(rect, ref scrollPosition, inner, false); for (int i = 0; i < stackTrace.Methods.Count(); i++) { var trace = stackTrace.Method(i); var methodRect = GetMethodColumn(inner.y + (i * textSize), textSize); DrawStringWithin(methodRect, trace.MethodString, true); Text.Anchor = TextAnchor.MiddleCenter; var modRect = GetModColumn(inner.y + (i * textSize), textSize); DrawStringWithin(modRect, trace.Mod, true); var patchRect = GetPatchColumn(inner.y + (i * textSize), textSize); Widgets.Label(patchRect, trace.Patches.ToString()); TooltipHandler.TipRegion(patchRect, trace.SummaryString); Text.Anchor = anchor; } Widgets.EndScrollView(); }
// [ Left File ] [ Right File ] [ Delta ] // Calls Mean 25000 23000 -2000 ( -8% ) // Time Mean 0.037ms 0.031ms -0.006ms ( - 16% ) private void DrawComparison(Rect r) { var topPart = r.TopPartPixels(50f); // have not selected any entries to compare. if (!DrawSelectEntries(topPart)) { return; } r.AdjustVerticallyBy(50f); var anchor = Text.Anchor; var colours = new Color[] { Color.red, GUI.color, Color.green }; var headerRect = r.TopPartPixels(30f); r.AdjustVerticallyBy(30f); Text.Anchor = TextAnchor.MiddleCenter; // [ Row ] [ Left Stats ] [ Right Stats ] [ Delta ] DubGUI.Heading(headerRect.LeftHalf().LeftHalf(), "Row"); DubGUI.Heading(headerRect.LeftHalf().RightHalf(), "Left Stats"); DubGUI.Heading(headerRect.RightHalf().LeftHalf(), "Right Stats"); DubGUI.Heading(headerRect.RightHalf().RightHalf(), "Delta"); GUI.color *= new Color(1f, 1f, 1f, 0.4f); Widgets.DrawLineHorizontal(r.x, r.y, r.width); GUI.color = Color.white; Text.Anchor = anchor; for (int i = 0; i < 4; i++) { if (i > 0) { Text.Anchor = TextAnchor.MiddleCenter; } var column = new Rect(r.x + i * (r.width / 4.0f), r.y, r.width / 4.0f, r.height); var rect = column.TopPartPixels(Text.LineHeight + 4f); foreach (var row in rows) { // i is the current column, 0 = name, 1 = lhs, 2 = rhs, 3 = delta switch (i) { case 0: Widgets.Label(rect, " " + row.name); break; case 1: Widgets.Label(rect, row.IsInt() ? row.Int(lhsStats).ToString() : $"{row.Double(lhsStats):F5}"); break; case 2: Widgets.Label(rect, row.IsInt() ? row.Int(rhsStats).ToString() : $"{row.Double(rhsStats):F5}"); break; case 3: var sb = new StringBuilder(); var sign = ""; double delta, dP = 0; if (row.IsInt()) { delta = row.Int(rhsStats) - row.Int(lhsStats); dP = (delta / (double)row.Int(lhsStats)) * 100; } else { delta = row.Double(rhsStats) - row.Double(lhsStats); dP = (delta / row.Double(lhsStats)) * 100; } sign = (delta > 0) ? "+" : ""; sb.Append($"{sign}{delta:F5} ( {sign}{dP:F2}% )"); var color = dP switch { < -2.5 => colours[2], > 2.5 => colours[0], _ => colours[1], }; GUI.color = color; Widgets.Label(rect, sb.ToString()); GUI.color = colours[1]; break; } column.AdjustVerticallyBy(Text.LineHeight + 4f); rect = column.TopPartPixels(Text.LineHeight + 4f); }