void DrawEventInfoPanel(float height, TraceRecord activeTrace, SandboxChart.ItemNode?selectedNode) { if (ImGui.BeginChild("#SandboxTabbaseRightPane", ImGui.GetContentRegionAvail() - new Vector2(0, 0), true)) { if (!APIDetailsWin.Loaded) { ImGui.PushStyleColor(ImGuiCol.ChildBg, 0x5f88705f); if (ImGui.BeginChild("#SandboxTabtopRightPane", new Vector2(100, 100)))// new Vector2(ImGui.GetContentRegionAvail().X, tr_height))) { ImGui.PushStyleColor(ImGuiCol.ChildBg, Themes.GetThemeColourUINT(Themes.eThemeColour.BadStateColour)); if (ImGui.BeginChild("#LoadErrFrame", new Vector2(ImGui.GetContentRegionAvail().X - 2, 80))) { ImGui.Indent(5); ImGui.TextWrapped("Error - No API datafile was loaded"); ImGui.TextWrapped("See error details in the logs tab"); ImGui.EndChild(); } ImGui.PopStyleColor(); } //ImGui.EndTable(); ImGui.EndChild(); ImGui.PopStyleColor(); } //ImGui.PushStyleColor(ImGuiCol.ChildBg, 0x8f48009f); if (selectedNode != null) { switch (selectedNode.TLtype) { case eTimelineEvent.ProcessStart: DrawProcessNodeTable((TraceRecord)selectedNode.reference); break; case eTimelineEvent.ThreadStart: DrawThreadNodeTable((ProtoGraph)selectedNode.reference); break; case eTimelineEvent.APICall: DrawAPIInfoTable((Logging.TIMELINE_EVENT)selectedNode.reference); break; default: ImGui.Text($"We don't do {selectedNode.TLtype} here"); break; } } else { if (chart !.SelectedAPIEvent != null) { DrawAPIInfoTable(chart.SelectedAPIEvent); } } ImGui.EndChild(); } }
public static void MouseoverText(string?text) { if (text is not null && text.Length > 0 && ImGui.IsItemHovered()) { ImGui.PushStyleColor(ImGuiCol.Text, Themes.GetThemeColourUINT(Themes.eThemeColour.WindowText)); ImGui.PushStyleColor(ImGuiCol.FrameBg, Themes.GetThemeColourUINT(Themes.eThemeColour.Frame)); ImGui.PushStyleVar(ImGuiStyleVar.WindowPadding, new Vector2(6, 5)); ImGui.SetTooltip(text); ImGui.PopStyleVar(); ImGui.PopStyleColor(2); } }
private void DrawSymbolsSelectBox(float reserveSize) { PlottedGraph?graph = _ActiveGraph; if (graph == null) { return; } if (_activeHighlights.LastExternNodeCount < graph.InternalProtoGraph.ExternalNodesCount) { RefreshExternHighlightData(graph.InternalProtoGraph.copyExternalNodeList()); } ImGui.Text("Filter"); ImGui.SameLine(); ImGui.InputText("##SymFilter", ref _activeHighlights.SymFilterText, 255); ImGui.SameLine(); if (ImGui.Button($"{ImGuiController.FA_ICON_TRASHCAN}")) { _activeHighlights.SymFilterText = ""; } //ImGui.PushStyleColor(ImGuiCol.Text, 0xFF000000); ImGui.PushStyleColor(ImGuiCol.ChildBg, Themes.GetThemeColourUINT(Themes.eThemeColour.WindowBackground)); ImGui.PushStyleVar(ImGuiStyleVar.WindowPadding, Vector2.Zero); if (ImGui.BeginChild(ImGui.GetID("htSymsFrameHeader"), new Vector2(ImGui.GetContentRegionAvail().X - 3, 20), true)) { ImGui.SameLine(10); ImGui.Text("Symbol"); ImGui.SameLine(200); ImGui.Text("Address"); ImGui.SameLine(315); ImGui.Text("Unique Nodes"); ImGui.EndChild(); } ImGui.PopStyleVar(); ImGui.PopStyleColor(); ImGui.PushStyleColor(ImGuiCol.ChildBg, Themes.GetThemeColourUINT(Themes.eThemeColour.Frame)); if (ImGui.BeginChild("htSymsFrame", new Vector2(ImGui.GetContentRegionAvail().X - 3, ImGui.GetContentRegionAvail().Y - reserveSize))) { DrawModSymTreeNodes(graph); ImGui.EndChild(); } //ImGui.PopStyleColor(); ImGui.PopStyleColor(); }
private static void DrawPreviewZoomEnvelope(PlottedGraph plot, Vector2 subGraphPosition) { ImDrawListPtr imdp = ImGui.GetWindowDrawList(); float previewBaseY = subGraphPosition.Y + EachGraphHeight; plot.GetPreviewVisibleRegion(new Vector2(EachGraphWidth, EachGraphHeight), PreviewProjection, out Vector2 TopLeft, out Vector2 BaseRight); float C1Y = previewBaseY - TopLeft.Y; float C2Y = previewBaseY - BaseRight.Y; bool verySmall = Math.Abs(C1Y - C2Y) < 20; uint colour = verySmall ? Themes.GetThemeColourUINT(Themes.eThemeColour.Emphasis1) : Themes.GetThemeColourUINT(Themes.eThemeColour.PreviewZoomEnvelope); float C1X = Math.Max(subGraphPosition.X + TopLeft.X, subGraphPosition.X); float C2X = Math.Min(subGraphPosition.X + BaseRight.X, subGraphPosition.X + EachGraphWidth - 1); C1Y = Math.Min(previewBaseY - 1, C1Y); C2Y = Math.Max(subGraphPosition.Y, C2Y); if (C1Y > subGraphPosition.Y && C1Y < previewBaseY && C2X > subGraphPosition.X) { imdp.AddLine(new Vector2(C1X, C1Y), new Vector2(C2X, C1Y), colour); } if (C2Y > subGraphPosition.Y && C2Y < previewBaseY) { imdp.AddLine(new Vector2(C2X, C2Y), new Vector2(C1X, C2Y), colour); } if (C2Y < previewBaseY && C1Y > subGraphPosition.Y) { C2Y = Math.Max(C2Y, subGraphPosition.Y); if (C2X > subGraphPosition.X && C2X < subGraphPosition.X + EachGraphWidth) { imdp.AddLine(new Vector2(C2X, C1Y), new Vector2(C2X, C2Y), colour); } if (C1X > subGraphPosition.X && C1X < subGraphPosition.X + EachGraphWidth) { imdp.AddLine(new Vector2(C1X, C2Y), new Vector2(C1X, C1Y), colour); } } }
public static bool DisableableButton(string text, bool enabled, Vector2?size = null) { bool activated = false; if (!enabled) { ImGui.PushStyleColor(ImGuiCol.Button, Themes.GetThemeColourUINT(Themes.eThemeColour.Dull2)); ImGui.PushStyleColor(ImGuiCol.ButtonHovered, Themes.GetThemeColourUINT(Themes.eThemeColour.Dull2)); ImGui.PushStyleColor(ImGuiCol.ButtonActive, Themes.GetThemeColourUINT(Themes.eThemeColour.Dull2)); } activated = (size.HasValue) ? ImGui.Button(text, size.Value) : ImGui.Button(text); if (!enabled) { ImGui.PopStyleColor(3); } return(enabled && activated); }
private static void DrawThreadSelectorCombo(TraceRecord?trace, out PlottedGraph?selectedGraph, bool abbreviate) { selectedGraph = null; ProtoGraph?graph = rgatState.ActiveGraph?.InternalProtoGraph; if (trace is not null && graph is not null) { string selString = $"{(abbreviate ? "TID" : "Thread")} {graph.ThreadID}: {graph.FirstInstrumentedModuleName}"; if (graph.NodeCount == 0) { selString += " [Uninstrumented]"; } List <PlottedGraph> graphs = trace.GetPlottedGraphs(); if (ImGui.TableNextColumn()) { ImGui.AlignTextToFramePadding(); ImGuiUtils.DrawHorizCenteredText($"{graphs.Count}x"); SmallWidgets.MouseoverText($"This trace has {graphs.Count} thread{(graphs.Count != 1 ? 's' : "")}"); } if (ImGui.TableNextColumn()) { ImGui.SetNextItemWidth(ImGui.GetContentRegionAvail().X - 35); if (ImGui.BeginCombo("##SelectorThreadCombo", selString)) { foreach (PlottedGraph selectablegraph in graphs) { string caption = $"{selectablegraph.TID}: {selectablegraph.InternalProtoGraph.FirstInstrumentedModuleName}"; int nodeCount = selectablegraph.GraphNodeCount(); if (nodeCount == 0) { ImGui.PushStyleColor(ImGuiCol.Text, Themes.GetThemeColourUINT(Themes.eThemeColour.Dull1)); caption += " [Uninstrumented]"; } else { ImGui.PushStyleColor(ImGuiCol.Text, Themes.GetThemeColourUINT(Themes.eThemeColour.WindowText)); caption += $" [{nodeCount} nodes]"; } if (ImGui.Selectable(caption, graph.ThreadID == selectablegraph.TID) && nodeCount > 0) { selectedGraph = selectablegraph; } if (ImGui.IsItemHovered()) { ImGui.BeginTooltip(); ImGui.Text($"Thread Start: 0x{selectablegraph.InternalProtoGraph.StartAddress:X} [{selectablegraph.InternalProtoGraph.StartModuleName}]"); if (selectablegraph.InternalProtoGraph.NodeList.Count > 0) { NodeData?n = selectablegraph.InternalProtoGraph.GetNode(0); if (n is not null) { string insBase = System.IO.Path.GetFileName(graph.ProcessData.GetModulePath(n.GlobalModuleID)); ImGui.Text($"First Instrumented: 0x{n.Address:X} [{insBase}]"); } } ImGui.EndTooltip(); } ImGui.PopStyleColor(); } ImGui.EndCombo(); } ImGui.SameLine(); ImGui.Text($"{ImGuiController.FA_ICON_COG}"); } } }
private void DrawSplash(rgatSettings.PathRecord[] recentBins, rgatSettings.PathRecord[] recentTraces) { ImGui.PushStyleVar(ImGuiStyleVar.CellPadding, Vector2.Zero); ImGui.PushStyleVar(ImGuiStyleVar.FramePadding, Vector2.Zero); ImGui.PushStyleVar(ImGuiStyleVar.WindowPadding, Vector2.Zero); ImGui.PushStyleVar(ImGuiStyleVar.ItemSpacing, Vector2.Zero); ImGui.PushStyleVar(ImGuiStyleVar.ItemInnerSpacing, Vector2.Zero); float regionHeight = ImGui.GetContentRegionAvail().Y; float regionWidth = ImGui.GetContentRegionAvail().X; float buttonBlockWidth = Math.Min(400f, regionWidth / 2.1f); float headerHeight = ImGui.GetWindowSize().Y / 3; float blockHeight = (regionHeight * 0.95f) - headerHeight; float blockStart = headerHeight + 40f; ImFontPtr titleFont = Controller.rgatLargeFont ?? Controller._originalFont !.Value; ImGui.PushFont(titleFont); Vector2 titleSize = ImGui.CalcTextSize("rgat"); ImGui.SetCursorScreenPos(new Vector2((ImGui.GetWindowContentRegionMax().X / 2) - (titleSize.X / 2), (ImGui.GetWindowContentRegionMax().Y / 5) - (titleSize.Y / 2))); ImGui.Text("rgat"); ImGui.PopFont(); //ImGui.PushStyleColor(ImGuiCol.ChildBg, 0xff0000ff); //ImGui.PushStyleColor(ImGuiCol.ChildBg, new WritableRgbaFloat(0, 0, 0, 255).ToUint()); bool boxBorders = false; //ImGui.PushStyleColor(ImGuiCol.HeaderHovered, 0x45ffffff); _splashHeaderHover = ImGui.GetMousePos().Y < (ImGui.GetWindowSize().Y / 3f); //ImGui.PopStyleColor(); //Run group float voidspace = Math.Max(0, (regionWidth - (2 * buttonBlockWidth)) / 3); float runGrpX = voidspace; float iconTableYSep = 18; float iconTitleYSep = 10; ImGuiTableFlags tblflags = ImGuiTableFlags.NoHostExtendX; if (boxBorders) { tblflags |= ImGuiTableFlags.Borders; } ImGui.SetCursorPos(new Vector2(runGrpX, blockStart)); ImGui.PushStyleColor(ImGuiCol.ChildBg, Themes.GetThemeColourUINT(Themes.eThemeColour.WindowBackground)); if (ImGui.BeginChild("##RunGroup", new Vector2(buttonBlockWidth, blockHeight), boxBorders)) { ImGui.PushFont(Controller.SplashLargeFont ?? Controller._originalFont !.Value); float captionHeight = ImGui.CalcTextSize("Load Binary").Y; if (ImGui.BeginTable("##LoadBinBtnBox", 3, tblflags)) { Vector2 LargeIconSize = Controller.LargeIconSize; float iconColumnWidth = 200; float paddingX = (buttonBlockWidth - iconColumnWidth) / 2; ImGui.TableSetupColumn("##BBSPadL", ImGuiTableColumnFlags.WidthFixed, paddingX); ImGui.TableSetupColumn("##LoadBinBtnIcn", ImGuiTableColumnFlags.WidthFixed, iconColumnWidth); ImGui.TableSetupColumn("##BBSPadR", ImGuiTableColumnFlags.WidthFixed, paddingX); ImGui.TableNextRow(); ImGui.TableSetColumnIndex(1); Vector2 selectableSize = new Vector2(iconColumnWidth, captionHeight + LargeIconSize.Y + iconTitleYSep + 12); if (ImGui.Selectable("##Load Binary", false, ImGuiSelectableFlags.None, selectableSize)) { ToggleLoadExeWindow(); } Controller.PushUnicodeFont(); Widgets.SmallWidgets.MouseoverText("Load an executable or DLL for examination. It will not be executed at this stage."); ImGui.PopFont(); ImGui.SetCursorPosY(ImGui.GetCursorPosY() - ImGui.GetItemRectSize().Y); ImGuiUtils.DrawHorizCenteredText("Load Binary"); ImGui.SetCursorPosX(ImGui.GetCursorPosX() + (iconColumnWidth / 2) - (LargeIconSize.X / 2)); ImGui.SetCursorPosY(ImGui.GetCursorPosY() + iconTitleYSep); Controller.PushBigIconFont(); ImGui.Text($"{ImGuiController.FA_ICON_SAMPLE}"); //If you change this be sure to update ImGuiController.BuildFonts ImGui.PopFont(); ImGui.EndTable(); } ImGui.PopFont(); ImGui.SetCursorPosY(ImGui.GetCursorPosY() + iconTableYSep); Vector2 tableSz = new Vector2(buttonBlockWidth, ImGui.GetContentRegionAvail().Y - 25); ImGui.PushStyleVar(ImGuiStyleVar.CellPadding, new Vector2(0, 2)); if (ImGui.BeginTable("#RecentBinTableList", 1, ImGuiTableFlags.ScrollY, tableSz)) { ImGui.Indent(5); ImGui.TableSetupColumn("Recent Binaries" + $"{(rgatState.ConnectedToRemote ? " (Remote Files)" : "")}"); ImGui.TableSetupScrollFreeze(0, 1); ImGui.TableHeadersRow(); if (recentBins?.Length > 0) { int bincount = Math.Min(GlobalConfig.Settings.UI.MaxStoredRecentPaths, recentBins.Length); for (var bini = 0; bini < bincount; bini++) { var entry = recentBins[bini]; ImGui.TableNextRow(); if (ImGui.TableNextColumn()) { if (DrawRecentPathEntry(entry, menu: false)) { if (File.Exists(entry.Path) || rgatState.ConnectedToRemote) { if (!LoadSelectedBinary(entry.Path, rgatState.ConnectedToRemote) && !_badPaths.Contains(entry.Path)) { _badPaths.Add(entry.Path); } } else if (!_missingPaths.Contains(entry.Path) && rgatState.ConnectedToRemote is false) { _scheduleMissingPathCheck = true; _missingPaths.Add(entry.Path); } } } } } ImGui.EndTable(); } ImGui.PopStyleVar(); ImGui.EndChild(); } ImGui.SetCursorPosY(blockStart); ImGui.SetCursorPosX(runGrpX + buttonBlockWidth + voidspace); if (ImGui.BeginChild("##LoadGroup", new Vector2(buttonBlockWidth, blockHeight), boxBorders)) { ImGui.PushFont(Controller.SplashLargeFont ?? Controller._originalFont !.Value); float captionHeight = ImGui.CalcTextSize("Load Trace").Y; if (ImGui.BeginTable("##LoadBtnBox", 3, tblflags)) { Vector2 LargeIconSize = Controller.LargeIconSize; float iconColumnWidth = 200; float paddingX = (buttonBlockWidth - iconColumnWidth) / 2; ImGui.TableSetupColumn("##LBSPadL", ImGuiTableColumnFlags.WidthFixed, paddingX); ImGui.TableSetupColumn("##LoadBtnIcn", ImGuiTableColumnFlags.WidthFixed, iconColumnWidth); ImGui.TableSetupColumn("##LBSPadR", ImGuiTableColumnFlags.WidthFixed, paddingX); ImGui.TableNextRow(); ImGui.TableSetColumnIndex(1); Vector2 selectableSize = new Vector2(iconColumnWidth, captionHeight + LargeIconSize.Y + iconTitleYSep + 12); if (ImGui.Selectable("##Load Trace", false, ImGuiSelectableFlags.None, selectableSize)) { ToggleLoadTraceWindow(); } Controller.PushUnicodeFont(); Widgets.SmallWidgets.MouseoverText("Load a previously generated trace"); ImGui.PopFont(); ImGui.SetCursorPosY(ImGui.GetCursorPosY() - ImGui.GetItemRectSize().Y); ImGuiUtils.DrawHorizCenteredText("Load Trace"); ImGui.SetCursorPosX(ImGui.GetCursorPosX() + (iconColumnWidth / 2) - (LargeIconSize.X / 2) + 8); //shift a bit to the right to balance it ImGui.SetCursorPosY(ImGui.GetCursorPosY() + iconTitleYSep); Controller.PushBigIconFont(); ImGui.Text($"{ImGuiController.FA_ICON_LOADFILE}");//If you change this be sure to update ImGuiController.BuildFonts ImGui.PopFont(); ImGui.EndTable(); } ImGui.PopFont(); ImGui.SetCursorPosY(ImGui.GetCursorPosY() + iconTableYSep); Vector2 tableSz = new Vector2(buttonBlockWidth, ImGui.GetContentRegionAvail().Y - 25); ImGui.PushStyleVar(ImGuiStyleVar.CellPadding, new Vector2(0, 2)); if (ImGui.BeginTable("#RecentTraceTableList", 1, ImGuiTableFlags.ScrollY, tableSz)) { ImGui.Indent(5); ImGui.TableSetupColumn("Recent Traces"); ImGui.TableSetupScrollFreeze(0, 1); ImGui.TableHeadersRow(); if (recentTraces?.Length > 0) { int traceCount = Math.Min(GlobalConfig.Settings.UI.MaxStoredRecentPaths, recentTraces.Length); for (var traceI = 0; traceI < traceCount; traceI++) { var entry = recentTraces[traceI]; ImGui.TableNextRow(); if (ImGui.TableNextColumn()) { if (DrawRecentPathEntry(entry, false)) { if (File.Exists(entry.Path)) { System.Threading.Tasks.Task.Run(() => LoadTraceByPath(entry.Path)); /* * if (!LoadTraceByPath(entry.Path) && !_badPaths.Contains(entry.Path)) * { * _badPaths.Add(entry.Path); * }*/ } else if (!_missingPaths.Contains(entry.Path)) { _scheduleMissingPathCheck = true; _missingPaths.Add(entry.Path); } } } } } ImGui.EndTable(); } ImGui.PopStyleVar(); ImGui.EndChild(); } ImGui.PopStyleVar(5); ImGui.BeginGroup(); string versionString = $"rgat {CONSTANTS.PROGRAMVERSION.RGAT_VERSION}"; float width = ImGui.CalcTextSize(versionString).X; ImGui.SetCursorPos(ImGui.GetContentRegionMax() - new Vector2(width + 25, 40)); ImGui.Text(versionString); if (GlobalConfig.NewVersionAvailable) { Version currentVersion = CONSTANTS.PROGRAMVERSION.RGAT_VERSION_SEMANTIC; Version newVersion = GlobalConfig.Settings.Updates.UpdateLastCheckVersion; string updateString; if (newVersion.Major > currentVersion.Major || (newVersion.Major == currentVersion.Major && newVersion.Minor > currentVersion.Minor)) { updateString = "New version available "; } else { updateString = "Updates available "; } updateString += $"({newVersion})"; Vector2 textSize = ImGui.CalcTextSize(updateString); ImGui.SetCursorPos(ImGui.GetContentRegionMax() - new Vector2(textSize.X + 25, 55)); if (ImGui.Selectable(updateString, false, flags: ImGuiSelectableFlags.None, size: new Vector2(textSize.X, textSize.Y))) { ImGui.OpenPopup("New Version Available"); } if (ImGui.IsItemHovered()) { Updates.ChangesCounts(out int changes, out int versions); if (changes > 0) { ImGui.BeginTooltip(); ImGui.Text($"Click to see {changes} changes in {versions} newer rgat versions"); ImGui.EndTooltip(); } } } ImGui.EndGroup(); ImGui.PopStyleColor(); if (GlobalConfig.Settings.UI.EnableTortoise) { _splashRenderer?.Draw(); } if (StartupProgress < 1) { float originalY = ImGui.GetCursorPosY(); float ypos = ImGui.GetWindowSize().Y - 12; ImGui.SetCursorPosY(ypos); ImGui.ProgressBar((float)StartupProgress, new Vector2(-1, 4f)); ImGui.SetCursorPosY(originalY); } if (ImGui.IsPopupOpen("New Version Available")) { ImGui.SetNextWindowSize(new Vector2(600, 500), ImGuiCond.FirstUseEver); ImGui.SetNextWindowPos((ImGui.GetWindowSize() / 2) - new Vector2(600f / 2f, 500f / 2f), ImGuiCond.Appearing); bool isopen = true; if (ImGui.BeginPopupModal("New Version Available", ref isopen, flags: ImGuiWindowFlags.Modal)) { Updates.DrawChangesDialog(); isopen = isopen && !ImGui.IsKeyDown(ImGui.GetKeyIndex(ImGuiKey.Escape)); if (!isopen) { ImGui.CloseCurrentPopup(); } ImGui.EndPopup(); } } }
private void DrawEventListTable(TraceRecord trace, SandboxChart.ItemNode?selectedNode) { if (chart is null) { return; } ImGui.PushStyleColor(ImGuiCol.Header, Themes.GetThemeColourUINT(Themes.eThemeColour.Emphasis2, 40)); TIMELINE_EVENT[] events = trace.GetTimeLineEntries(); if (ImGui.BeginTable("#TaTTFullList", 4, ImGuiTableFlags.Borders | ImGuiTableFlags.ScrollY | ImGuiTableFlags.Resizable | ImGuiTableFlags.RowBg)) { ImGui.TableSetupScrollFreeze(0, 1); ImGui.TableSetupColumn("#", ImGuiTableColumnFlags.WidthFixed, 50); ImGui.TableSetupColumn("Type", ImGuiTableColumnFlags.WidthFixed, 70); ImGui.TableSetupColumn("Module", ImGuiTableColumnFlags.WidthFixed, 70); ImGui.TableSetupColumn("Details", ImGuiTableColumnFlags.None); ImGui.TableHeadersRow(); var SelectedEntity = chart.SelectedEntity; var SelectedAPIEvent = chart.SelectedAPIEvent; bool ThreadNodeSelected = selectedNode is not null && Equals(selectedNode.reference.GetType(), typeof(ProtoGraph)); bool ProcessNodeSelected = selectedNode is not null && Equals(selectedNode.reference.GetType(), typeof(TraceRecord)); int i = 0; foreach (TIMELINE_EVENT TLevent in events) { i += 1; ImGui.TableNextRow(); if (TLevent.MetaError != null) { ImGui.TableSetBgColor(ImGuiTableBgTarget.RowBg0, Themes.GetThemeColourUINT(Themes.eThemeColour.BadStateColour)); ImGui.TableSetBgColor(ImGuiTableBgTarget.RowBg1, Themes.GetThemeColourUINT(Themes.eThemeColour.BadStateColour)); } bool selected = false; string eventType = ""; string module = ""; if (ImGui.TableNextColumn()) { switch (TLevent.TimelineEventType) { case eTimelineEvent.ProcessStart: case eTimelineEvent.ProcessEnd: eventType = "Process"; if (selectedNode != null) { selected = (ProcessNodeSelected && TLevent.ID == ((TraceRecord)selectedNode.reference).PID); } break; case eTimelineEvent.ThreadStart: case eTimelineEvent.ThreadEnd: eventType = "Thread"; if (selectedNode != null) { ProtoGraph currentEntryGraph = (ProtoGraph)TLevent.Item; selected = (ThreadNodeSelected && currentEntryGraph.ThreadID == ((ProtoGraph)selectedNode.reference).ThreadID); selected = selected || (ProcessNodeSelected && currentEntryGraph.TraceData.PID == ((TraceRecord)(selectedNode.reference)).PID); } break; case eTimelineEvent.APICall: { Logging.APICALL call = (Logging.APICALL)(TLevent.Item); selected = TLevent == SelectedAPIEvent; if (call.Node !.IsExternal) { eventType = "API - " + call.APIType(); module = Path.GetFileNameWithoutExtension(trace.DisassemblyData.GetModulePath(call.Node.GlobalModuleID)); //api call is selected if it is either directly activated, or interacts with a reference to the active entity //eg: if the file.txt node is selected, writefile to the relevant handle will also be selected selected = selected || (SelectedEntity != null && SelectedEntity == chart.GetInteractedEntity(TLevent)); if (!selected && selectedNode != null) { //select all apis called by selected thread node selected = selected || (ThreadNodeSelected && call.Graph !.ThreadID == ((ProtoGraph)selectedNode.reference).ThreadID); //select all apis called by selected process node selected = selected || (ProcessNodeSelected && call.Graph !.TraceData.PID == ((TraceRecord)selectedNode.reference).PID); } //WinAPIDetails.API_ENTRY = call.APIEntry; } else { eventType = "Internal"; } } break; } if (ImGui.Selectable(i.ToString(), selected, ImGuiSelectableFlags.SpanAllColumns) && !selected) { chart.SelectAPIEvent(TLevent); } }
private void DrawAnalysisTab(TraceRecord?activeTrace) { if (activeTrace == null || !ImGui.BeginTabItem("Timeline") || chart is null) { return; } _currentTab = "Timeline"; float height = ImGui.GetContentRegionAvail().Y; float width = ImGui.GetContentRegionAvail().X; float sidePaneWidth = 300; if (height < 50 || width < 50) { ImGui.EndTabItem(); return; } chart !.InitChartFromTrace(activeTrace); SandboxChart.ItemNode?selectedNode = chart.GetSelectedNode; if (ImGui.BeginTable("#TaTTable", 2, ImGuiTableFlags.Resizable)) { ImGui.TableSetupColumn("#TaTTEntryList", ImGuiTableColumnFlags.None | ImGuiTableColumnFlags.WidthFixed, sidePaneWidth * 2f); ImGui.TableSetupColumn("#TaTTChart"); ImGui.TableNextRow(); if (ImGui.TableNextColumn()) { if (ImGui.BeginChild("#ijdcccfgo", ImGui.GetContentRegionAvail() - new Vector2(0, 5))) { TraceSelector.Draw(activeTrace); ImGui.Separator(); ImGui.Text("Event Listing"); if (ImGui.BeginChild("#iosfjhvs", ImGui.GetContentRegionAvail() - new Vector2(0, selectedNode is null ? 0 : 250))) { DrawEventListTable(activeTrace, selectedNode); ImGui.EndChild(); } if (selectedNode is not null) { ImGui.PushStyleColor(ImGuiCol.ChildBg, Themes.GetThemeColourUINT(Themes.eThemeColour.Frame)); if (ImGui.BeginChild(ImGui.GetID("#ijdcccfgo"), new Vector2(ImGui.GetContentRegionAvail().X, 245))) { DrawEventInfoPanel(height, activeTrace, selectedNode); ImGui.EndChild(); } ImGui.PopStyleColor(); } ImGui.EndChild(); } } if (ImGui.TableNextColumn()) { chart.Draw(_controller !.UnicodeFont); } ImGui.EndTable(); } ImGui.EndTabItem(); }
/// <summary> /// Draw a preview graph texture on the preview pane /// </summary> /// <param name="plot">The graph being drawn</param> /// <param name="xPadding">horizontal padding</param> /// <param name="captionHeight">height of the caption</param> /// <param name="captionBackgroundcolor">contrast background colour of the caption</param> /// <param name="canHover">output flag states if we can safely draw a mouseover tooltip</param> /// <param name="mainWidgetSize">Size of the maingraph widget, used for projecting the zoom envelope</param> /// <returns>The graph was clicked</returns> private bool DrawPreviewGraph(PlottedGraph plot, float xPadding, float captionHeight, uint captionBackgroundcolor, out bool canHover, Vector2 mainWidgetSize) { ImDrawListPtr imdp = ImGui.GetWindowDrawList(); //draw on and clipped to this window bool clicked = false; canHover = false; if (plot == null) { return(clicked); } int graphNodeCount = plot.GraphNodeCount(); if (graphNodeCount == 0) { return(clicked); } plot.GetLatestTexture(out Texture previewTexture); if (previewTexture == null) { return(clicked); } bool isSelected = plot.TID == selectedGraphTID; canHover = true; //copy in the actual rendered graph ImGui.SetCursorPosY(ImGui.GetCursorPosY()); Vector2 subGraphPosition = ImGui.GetCursorScreenPos() + new Vector2(xPadding, 0); IntPtr CPUframeBufferTextureId = _ImGuiController !.GetOrCreateImGuiBinding(_gd !.ResourceFactory, previewTexture, $"PreviewPlot{plot.TID}"); imdp.AddImage(user_texture_id: CPUframeBufferTextureId, p_min: subGraphPosition, p_max: new Vector2(subGraphPosition.X + EachGraphWidth, subGraphPosition.Y + EachGraphHeight), uv_min: new Vector2(0, 1), uv_max: new Vector2(1, 0)); float borderThickness = Themes.GetThemeSize(Themes.eThemeSize.PreviewSelectedBorder); float halfBorderThickness = (float)Math.Floor(borderThickness / 2f); if (isSelected) { DrawPreviewZoomEnvelope(plot, subGraphPosition); //Draw the thicker selected graph border if (borderThickness > 0) { imdp.AddRect( p_min: new Vector2(subGraphPosition.X + halfBorderThickness, subGraphPosition.Y + halfBorderThickness), p_max: new Vector2((subGraphPosition.X + EachGraphWidth - halfBorderThickness), subGraphPosition.Y + EachGraphHeight - halfBorderThickness), col: GetGraphBorderColour(plot), 0, ImDrawFlags.None, borderThickness); } } //write the caption string Caption = $"TID:{plot.TID} {graphNodeCount} nodes {(isSelected ? "[Selected]" : "")}"; ImGui.SetCursorPosX(ImGui.GetCursorPosX()); Vector2 captionBGStart = subGraphPosition + new Vector2(borderThickness, borderThickness); Vector2 captionBGEnd = new Vector2((captionBGStart.X + EachGraphWidth - borderThickness * 2), captionBGStart.Y + captionHeight); imdp.AddRectFilled(p_min: captionBGStart, p_max: captionBGEnd, col: captionBackgroundcolor); ImGui.PushStyleColor(ImGuiCol.Text, Themes.GetThemeColourUINT(Themes.eThemeColour.PreviewText)); ImGui.SetCursorPosX(ImGui.GetCursorPosX() + CONSTANTS.UI.PREVIEW_PANE_X_PADDING + borderThickness + 1); ImGui.SetCursorPosY(ImGui.GetCursorPosY() + borderThickness); ImGui.Text(Caption); ImGui.PopStyleColor(); ImGui.SetCursorPosX(ImGui.GetCursorPosX() + EachGraphWidth - 48); //live thread activity plot if (ActiveTrace is not null && !ActiveTrace.WasLoadedFromSave) { ImGui.SetCursorPosY(ImGui.GetCursorPosY() - captionHeight); float maxVal; float[]? invalues = null; if (plot.InternalProtoGraph.TraceReader != null) { plot.InternalProtoGraph.TraceReader.RecentMessageRates(out invalues); } if (invalues == null || invalues.Length == 0) { invalues = new List <float>() { 0, 0, 0, 0, 0 }.ToArray(); maxVal = 100; } else { maxVal = invalues.Max(); } ImGui.PushStyleColor(ImGuiCol.FrameBg, captionBackgroundcolor); ImGui.PlotLines("", ref invalues[0], invalues.Length, 0, "", 0, maxVal, new Vector2(40, captionHeight)); if (ImGui.IsItemHovered()) { canHover = false; //The PlotLines widget doesn't allow disabling the mouseover, so have to prevent our mousover to avoid a merged tooltip } ImGui.PopStyleColor(); } //invisible button to detect graph click ImGui.SetCursorPos(new Vector2(1, ImGui.GetCursorPosY() - (float)(captionHeight))); if (ImGui.InvisibleButton("PrevGraphBtn" + plot.TID, new Vector2(EachGraphWidth, EachGraphHeight - 2)) || ImGui.IsItemActive()) { clicked = true; if (isSelected) { Vector2 clickPos = ImGui.GetMousePos(); Vector2 clickOffset = clickPos - subGraphPosition; clickOffset.Y = EachGraphHeight - clickOffset.Y; plot.MoveCameraToPreviewClick(clickOffset, new Vector2(EachGraphWidth, EachGraphHeight), mainGraphWidgetSize: mainWidgetSize, PreviewProjection); } } return(clicked); }
/// <summary> /// Draw the preview graph widget /// </summary> public void DrawWidget(Vector2 mainWidgetSize) { bool showToolTip = false; PlottedGraph?latestHoverGraph = null; TraceRecord? activeTrace = ActiveTrace; if (activeTrace == null) { return; } float captionHeight = ImGui.CalcTextSize("123456789").Y; DrawnPreviewGraphs = activeTrace.GetPlottedGraphs(); List <int> indexes = GetGraphOrder(trace: activeTrace, graphs: DrawnPreviewGraphs); uint captionBackgroundcolor = Themes.GetThemeColourUINT(Themes.eThemeColour.PreviewTextBackground); ImGui.PushStyleVar(ImGuiStyleVar.CellPadding, new Vector2(0, CONSTANTS.UI.PREVIEW_PANE_Y_SEP)); //Graph drawing loop if (ImGui.BeginTable("PrevGraphsTable", 1, ImGuiTableFlags.Borders, new Vector2(CONSTANTS.UI.PREVIEW_PANE_WIDTH, ImGui.GetContentRegionAvail().Y))) { foreach (int graphIdx in indexes) { PlottedGraph plot = DrawnPreviewGraphs[graphIdx]; float xPadding = CONSTANTS.UI.PREVIEW_PANE_X_PADDING; if (plot == null || plot.GraphNodeCount() == 0) { continue; } ImGui.TableNextRow(); ImGui.TableSetColumnIndex(0); if (DrawPreviewGraph(plot, xPadding, captionHeight, captionBackgroundcolor, out bool canHover, mainWidgetSize)) { var MainGraphs = plot.InternalProtoGraph.TraceData.GetPlottedGraphs(); HandleClickedGraph(MainGraphs[graphIdx]); } if (canHover && ImGui.IsItemHovered(ImGuiHoveredFlags.None) && !(ImGui.IsMouseDown(ImGuiMouseButton.Left))) { latestHoverGraph = plot; showToolTip = true; } } ImGui.EndTable(); } ImGui.PopStyleVar(); ImGui.PushStyleVar(ImGuiStyleVar.FramePadding, new Vector2(5, 5)); ImGui.PushStyleVar(ImGuiStyleVar.WindowPadding, new Vector2(5, 5)); ImGui.PushStyleVar(ImGuiStyleVar.ItemSpacing, new Vector2(5, 5)); ImGui.PushStyleColor(ImGuiCol.Border, 0x77999999); HoveredGraph = latestHoverGraph; bool showedCtx = HandlePreviewGraphContextMenu(); bool veryRecentPopup = showedCtx || _lastCtxMenu.AddMilliseconds(250) > DateTime.Now; if (showToolTip && !veryRecentPopup && HoveredGraph is not null) { DrawGraphTooltip(HoveredGraph); } ImGui.PopStyleVar(3); ImGui.PopStyleColor(); }
public void Draw(ImFontPtr font) { Vector2 availArea = ImGui.GetContentRegionAvail(); Vector2 targetSize = availArea - new Vector2(0, 6); if (targetSize != chartSize && targetSize.X > 50 && targetSize.Y > 50) { StopLayout(); chartSize = targetSize; layout.Parameters.Width = targetSize.X; layout.Parameters.Height = targetSize.Y; FitNodesToChart(); } if (_fittingActive) { DoLayoutFittingCycle(); } if (_computeRequired && !_layoutActive) { _layoutActive = true; _computeRequired = false; Task.Run(() => { layout.Compute(); _layoutActive = false; }); } ImGui.PushStyleColor(ImGuiCol.ChildBg, Themes.GetThemeColourUINT(Themes.eThemeColour.SandboxChartBG)); bool nodeClicked = false; Vector2 cursorPos = ImGui.GetCursorPos(); Vector2 chartPos = cursorPos + chartOffset + new Vector2(padding, padding); if (ImGui.BeginChild("ChartFrame", chartSize, false, ImGuiWindowFlags.NoScrollbar)) { MouseOverWidget = ImGui.IsMouseHoveringRect(cursorPos, cursorPos + chartSize); if (MouseOverWidget) { HandleMouseInput(); } var edges = sbgraph.Edges; List <Tuple <ItemNode, ItemNode> > drawnEdges = new List <Tuple <ItemNode, ItemNode> >(); var positions = new Dictionary <ItemNode, GraphShape.Point>(layout.VerticesPositions); foreach (var edge in edges) { if (positions.TryGetValue(edge.Source, out GraphShape.Point srcPoint) && positions.TryGetValue(edge.Target, out GraphShape.Point targPoint)) { Vector2 sourcePos = chartPos + Point2Vec(srcPoint); Vector2 targPos = chartPos + Point2Vec(targPoint); Tuple <ItemNode, ItemNode> edgeTuple = new Tuple <ItemNode, ItemNode>(edge.Source, edge.Target); if (drawnEdges.Contains(edgeTuple)) { continue; } drawnEdges.Add(edgeTuple); ImGui.GetWindowDrawList().AddLine(sourcePos, targPos, 0xffff00ff); if (_edgeLabels.TryGetValue(edgeTuple, out List <string>?edgeLabels)) { ImGui.GetWindowDrawList().AddText(Vector2.Lerp(sourcePos, targPos, 0.5f), 0xff000000, string.Join(",", edgeLabels)); } } } foreach (var node in positions) { Vector2 nCenter = chartPos + Point2Vec(node.Value); nodeClicked = nodeClicked || DrawNode(node.Key, nCenter, font); } ImGui.PushStyleVar(ImGuiStyleVar.FramePadding, new Vector2(5, 5)); ImGui.SetCursorPos(chartSize - new Vector2(60, 30)); ImGui.BeginGroup(); if (ImGui.Button($"{ImGuiController.FA_ICON_REFRESH}", new Vector2(26, 27))) //refresh button { timelineItemsOnChartDraw = 0; } SmallWidgets.MouseoverText("Force Replot"); if (!_fittingActive) { ImGui.SameLine(30); if (ImGui.Button($"{ImGuiController.FA_ICON_MOVEMENT}", new Vector2(26, 27))) //centering button { FitNodesToChart(); } SmallWidgets.MouseoverText("Center graph"); } ImGui.EndGroup(); ImGui.PopStyleVar(); ImGui.SetCursorScreenPos(cursorPos); ImGui.EndChild(); } ImGui.PopStyleColor(); if (ImGui.IsMouseClicked(ImGuiMouseButton.Left) is true && nodeClicked is false) { _selectedNode = null; } }
public void Draw(ref bool show) { ImGui.SetNextWindowSize(new Vector2(800, 500), ImGuiCond.Appearing); ImGui.PushStyleColor(ImGuiCol.ChildBg, Themes.GetThemeColourUINT(Themes.eThemeColour.Frame)); if (ImGui.Begin("Logged Events", ref show)) { //string label = $"{msgs.Length} log entries displayed from ({activeCount}/{_LogFilters.Length}) sources"; Vector2 boxSize = new Vector2(75, 40); Vector2 marginSize = new Vector2(70, 40); ImGuiSelectableFlags flags = ImGuiSelectableFlags.DontClosePopups; uint tableHdrBG = 0xff333333; var textFilterCounts = Logging.GetTextFilterCounts(); List <Tuple <string, LogFilterType> > filters = new List <Tuple <string, LogFilterType> >() { new Tuple <string, LogFilterType>("Debug", LogFilterType.Debug), new Tuple <string, LogFilterType>("Info", LogFilterType.Info), new Tuple <string, LogFilterType>("Alert", LogFilterType.Alert), new Tuple <string, LogFilterType>("Error", LogFilterType.Error) }; if (ImGui.BeginTable("LogFilterTable", filters.Count + 1, ImGuiTableFlags.Borders, new Vector2(boxSize.X * (filters.Count + 1), 41))) { ImGui.TableNextRow(); ImGui.TableSetColumnIndex(0); ImGui.TableSetBgColor(ImGuiTableBgTarget.CellBg, tableHdrBG); if (ImGui.Selectable("Message", false, flags, marginSize)) { rowLastSelected[0] = !rowLastSelected[0]; filters.ForEach((filter) => { _LogFilters[(int)filter.Item2] = rowLastSelected[0]; }); } foreach (var filter in filters) { if (ImGui.TableNextColumn()) { ImGui.Selectable($"{filter.Item1} ({textFilterCounts[filter.Item2]})", ref _LogFilters[(int)filter.Item2], flags, boxSize); } } ImGui.EndTable(); if (ImGui.BeginPopupContextItem("FlterTableRightCtx", ImGuiPopupFlags.MouseButtonRight)) { if (ImGui.MenuItem("Clear All Source Filters")) { Array.Clear(_LogFilters, 0, _LogFilters.Length); } if (ImGui.MenuItem("Apply All Source Filters")) { _LogFilters = Enumerable.Repeat(true, _LogFilters.Length).ToArray(); } ImGui.EndPopup(); } ImGui.SameLine(); ImGui.BeginGroup(); //filter text box { ImGui.SetCursorPosY(ImGui.GetCursorPosY() + 4); ImGui.Indent(8); ImGui.Text("Filter"); ImGui.SameLine(); ImGui.SetNextItemWidth(Math.Min(ImGui.GetContentRegionAvail().X - 50, 350)); ImGui.InputText("##IT1", textFilterValue, (uint)textFilterValue.Length); if (_textFilterLen > 0) { ImGui.SameLine(); if (ImGui.Button("Clear")) { textFilterValue = new byte[textFilterValue.Length]; } } ImGui.EndGroup(); } WriteLogContentTable(); } ImGui.End(); } ImGui.PopStyleColor(); }